toolnet-memory 0.3.14 → 0.3.15

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.
Files changed (48) hide show
  1. package/.env.example +0 -1
  2. package/.release-target +1 -1
  3. package/README.md +25 -1
  4. package/bin/toolnet-memory +5 -0
  5. package/bundle/agy-hook.js +67 -67
  6. package/bundle/agy.js +61 -61
  7. package/bundle/api.js +15 -15
  8. package/bundle/auto-integrate.js +28 -28
  9. package/bundle/background-refresh.js +7 -7
  10. package/bundle/claude-hook.js +51 -50
  11. package/bundle/codex-context.js +25 -24
  12. package/bundle/codex.js +71 -71
  13. package/bundle/context-runtime.js +45 -44
  14. package/bundle/context.js +15 -15
  15. package/bundle/continuity-certify.js +13 -13
  16. package/bundle/copilot-hook.js +87 -85
  17. package/bundle/copilot.js +4 -4
  18. package/bundle/cursor-hook.js +87 -85
  19. package/bundle/cursor.js +4 -4
  20. package/bundle/doctor.js +4 -4
  21. package/bundle/full-index.js +20 -20
  22. package/bundle/gc.js +3 -0
  23. package/bundle/graph-index.js +4 -4
  24. package/bundle/graph-ui.js +3 -3
  25. package/bundle/grok-hook.js +60 -59
  26. package/bundle/grok.js +5 -5
  27. package/bundle/handoff-refresh.js +10 -10
  28. package/bundle/help-cli.js +4 -4
  29. package/bundle/impact.js +4 -4
  30. package/bundle/incremental.js +5 -4
  31. package/bundle/init.js +37 -37
  32. package/bundle/integration-status.js +4 -4
  33. package/bundle/kiro-hook.js +82 -81
  34. package/bundle/learner.js +6 -6
  35. package/bundle/mcp.js +17 -17
  36. package/bundle/memory-agent.js +7 -7
  37. package/bundle/memory-query.js +7 -7
  38. package/bundle/opencode.js +80 -80
  39. package/bundle/project-manual.js +7 -7
  40. package/bundle/recovery-certify.js +15 -15
  41. package/bundle/runtime.js +13 -12
  42. package/bundle/semantic.js +5 -5
  43. package/bundle/snapshot.js +4 -4
  44. package/bundle/status-cli.js +4 -4
  45. package/bundle/toolnet-cli.js +60 -60
  46. package/bundle/work-continuity.js +7 -7
  47. package/package.json +9 -3
  48. package/release-manifest.json +54 -3
package/bundle/agy.js CHANGED
@@ -1,61 +1,61 @@
1
- import{existsSync as Ne}from"node:fs";import{existsSync as Xs,readFileSync as Qs}from"node:fs";import{homedir as Zs}from"node:os";import{join as eo}from"node:path";function to(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 no(){let e=process.env.TOOLNET_GLOBAL_ENV??eo(Zs(),".config","toolnet-memory",".env");if(!Xs(e))return;let t=Qs(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]=to(r.slice(s+1)))}}no();function de(e,t){return e===void 0?t:["1","true","yes","on"].includes(e.toLowerCase())}function pe(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function $e(){return{memory:{autoCapture:de(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:de(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:de(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:de(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:pe(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:pe(process.env.MEMORY_RERANK_TOP,10),finalContext:pe(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:pe(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:de(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:pe(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ro}from"node:crypto";import{existsSync as At,mkdirSync as so,readFileSync as oo,renameSync as io,writeFileSync as ao}from"node:fs";import{basename as co,dirname as Ke,join as We,parse as un,resolve as fe}from"node:path";var ln=".toolnet",uo="project.json";function lo(e){return ro("sha256").update(e).digest("hex").slice(0,16)}function jt(e){return We(e,ln,uo)}function po(e){return At(jt(e))}function fo(e,t){let n=fe(e),r=un(n).root;for(;;){if(po(n))return n;if(n===r||t&&n===fe(t))break;let s=Ke(n);if(s===n)break;n=s}return null}function mo(e){let t=fe(e),n=un(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>At(We(t,o))))return t;if(t===n)break;let s=Ke(t);if(s===t)break;t=s}return fe(e)}function go(e){let t;try{t=JSON.parse(oo(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:Ke(Ke(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 an(e,t){let n=We(e,ln);so(n,{recursive:!0});let r=jt(e),s=`${r}.tmp-${process.pid}`;ao(s,JSON.stringify(t,null,2)+`
3
- `,{encoding:"utf8",mode:384}),io(s,r)}function cn(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 Le=class{detect(t=process.cwd()){let n=fe(t),r=mo(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>At(We(r,l))),i=fo(n,o?r:void 0);if(i){let l=jt(i),d=go(l);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),an(i,d)),cn(d,i)}let a=new Date().toISOString(),c=co(r),u={version:1,id:lo(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return an(r,u),cn(u,r)}};var yo=[{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}],Fe=class{scan(t){let n=[];for(let r of yo){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 Fe;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 Wo}from"node:os";import{join as Fo}from"node:path";import{DeleteObjectCommand as ho,GetObjectCommand as So,HeadObjectCommand as ko,ListObjectsV2Command as vo,PutObjectCommand as wo,S3Client as bo}from"@aws-sdk/client-s3";import{getSignedUrl as xo}from"@aws-sdk/s3-request-presigner";var De=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new bo({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 wo({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await xo(this.client,new So({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 ko({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 ho({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new vo({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as dn,mkdir as Ao,readFile as jo,readdir as Mo,rm as Io,stat as pn,writeFile as Co}from"node:fs/promises";import{dirname as Po,join as Eo,relative as fn,resolve as Oo}from"node:path";var me=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return Oo(this.root,n)}async put(t,n){let r=this.path(t);await Ao(Po(r),{recursive:!0}),await Co(r,n)}async get(t){try{return await jo(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 dn(this.path(t)),!0}catch{return!1}}async delete(t){await Io(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await dn(n)}catch{return r}let s=async i=>{let a=await Mo(i,{withFileTypes:!0});for(let c of a){let u=Eo(i,c.name);if(c.isDirectory()){await s(u);continue}let l=await pn(u);r.push({key:fn(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},o=await pn(n);return o.isDirectory()?await s(n):r.push({key:fn(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as To,GetObjectCommand as Ro,HeadObjectCommand as No,ListObjectsV2Command as _o,PutObjectCommand as $o,S3Client as Ko}from"@aws-sdk/client-s3";import{getSignedUrl as Lo}from"@aws-sdk/s3-request-presigner";var ge=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new Ko({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 $o({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await Lo(this.client,new Ro({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 No({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 To({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new _o({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 Mt(e,t){return console.warn(t),new me(e)}function mn(e){let t=e.localRoot??Fo(Wo(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new ge({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Mt(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 ge({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Mt(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 De({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Mt(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new me(t)}function Do(e){return new Promise(t=>setTimeout(t,e))}async function gn(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,s=t.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(o=a,i>=n)break;let c=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Do(c+u)}throw o}var zo=new Set(["put","get","getText","delete","list"]);function yn(e,t={}){return new Proxy(e,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:zo.has(r)?(...o)=>gn(()=>Promise.resolve(s.apply(n,o)),t):s.bind(n)}})}function hn(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 Sn(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 ze=class{constructor(t,n,r,s){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=hn(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let t=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(t);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(o,null,2)+`
4
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=Sn(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{homedir as sn}from"node:os";import{join as $s,resolve as Ol}from"node:path";import{join as Uo}from"node:path";import{createHash as qo}from"node:crypto";import{dirname as Jo}from"node:path";import{mkdirSync as Vo,readFileSync as Bo,renameSync as Ho,writeFileSync as Go}from"node:fs";function v(e){return qo("sha256").update(e).digest("hex")}function It(e){if(Array.isArray(e))return e.map(It);if(e&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=It(t[r]);return n}return e}function kn(e){return JSON.stringify(It(e))}function vn(e){try{return JSON.parse(Bo(e,"utf8"))}catch{return null}}function O(e,t){Vo(Jo(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;Go(n,JSON.stringify(t,null,2)+`
5
- `,{encoding:"utf8",mode:384}),Ho(n,e)}function wn(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 bn(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=wn(r.toLowerCase(),"agent"),i=wn(s,"session");return{projectId:e.id,projectName:e.name,projectRoot:e.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",e.id,"runtime","sources",o,i].join("/"),localDirectory:Uo(e.rootPath,".toolnet","runtime","sources",o,i)}}function xn(e){return String(e).padStart(12,"0")}var qe=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)+`
1
+ import{existsSync as $e}from"node:fs";import{existsSync as ro,readFileSync as so}from"node:fs";import{homedir as oo}from"node:os";import{join as io}from"node:path";function ao(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 co(){let e=process.env.TOOLNET_GLOBAL_ENV??io(oo(),".config","toolnet-memory",".env");if(!ro(e))return;let t=so(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]=ao(r.slice(s+1)))}}co();function pe(e,t){return e===void 0?t:["1","true","yes","on"].includes(e.toLowerCase())}function fe(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function We(){return{memory:{autoCapture:pe(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:pe(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:pe(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:pe(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:fe(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:fe(process.env.MEMORY_RERANK_TOP,10),finalContext:fe(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:fe(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:pe(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:fe(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as uo}from"node:crypto";import{existsSync as Fe,mkdirSync as lo,readFileSync as po,renameSync as fo,writeFileSync as mo}from"node:fs";import{basename as go,dirname as De,join as me,parse as fn,resolve as ne}from"node:path";var mn=".toolnet",yo="project.json";function ho(e){return uo("sha256").update(e).digest("hex").slice(0,16)}function ze(e){return me(e,mn,yo)}function So(e){return Fe(ze(e))}function un(e,t){let n=ne(e),r=fn(n).root;for(;;){if(So(n))return n;if(n===r||t&&n===ne(t))break;let s=De(n);if(s===n)break;n=s}return null}function ln(e){let t=ne(e),n=fn(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>Fe(me(t,o))))return t;if(t===n)break;let s=De(t);if(s===t)break;t=s}return ne(e)}function dn(e){let t;try{t=JSON.parse(po(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:De(De(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 pn(e,t){let n=me(e,mn);lo(n,{recursive:!0});let r=ze(e),s=`${r}.tmp-${process.pid}`;mo(s,JSON.stringify(t,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),fo(s,r)}function Ct(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 qe=class{findExisting(t=process.cwd()){let n=ne(t),r=ln(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>Fe(me(r,c))),i=un(n,o?r:void 0);if(!i)return null;let a=dn(ze(i));return Ct(a,i)}requireExisting(t=process.cwd()){let n=this.findExisting(t);if(!n)throw new Error("PROJECT_NOT_INITIALIZED");return n}detect(t=process.cwd()){let n=ne(t),r=ln(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>Fe(me(r,l))),i=un(n,o?r:void 0);if(i){let l=ze(i),d=dn(l);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),pn(i,d)),Ct(d,i)}let a=new Date().toISOString(),c=go(r),u={version:1,id:ho(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return pn(r,u),Ct(u,r)}};var ko=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,confidence:"exact"},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g,confidence:"exact"},{type:"aws_access_key",regex:/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,confidence:"exact"},{type:"github_token",regex:/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{40,255})\b/g,confidence:"exact"},{type:"stripe_secret_key",regex:/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,confidence:"exact"},{type:"google_api_key",regex:/\bAIza[A-Za-z0-9_-]{30,}\b/g,confidence:"exact"},{type:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{16,}\b/g,confidence:"exact"},{type:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,confidence:"high"},{type:"jwt",regex:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,confidence:"exact"},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,confidence:"exact"},{type:"password_assignment",regex:/\b(?:password|passwd|pwd)\s*[:=]\s*["']?[^"' \t\r\n]{6,}["']?/gi,confidence:"high"},{type:"secret_assignment",regex:/\b(?:secret|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*["']?[^"' \t\r\n]{8,}["']?/gi,confidence:"high"},{type:"cookie",regex:/\b(?:cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi,confidence:"high"},{type:"url_credentials",regex:/\bhttps?:\/\/[^:/@\s]+:[^/@\s]{4,}@[^/\s]+/gi,confidence:"high"}],vo=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function gn(e){return e.normalize("NFKC").trim().toLowerCase()}function wo(e){if(e.length===0)return 0;let t=new Map;for(let r of e)t.set(r,(t.get(r)??0)+1);let n=0;for(let r of t.values()){let s=r/e.length;n-=s*Math.log2(s)}return n}function bo(e){return/^[a-f0-9]{32}$/iu.test(e)||/^[a-f0-9]{40}$/iu.test(e)||/^[a-f0-9]{64}$/iu.test(e)}function xo(e,t,n){let r=e.slice(Math.max(0,t-48),t),s=e.slice(n,Math.min(e.length,n+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${r} ${s}`)}function Ao(e,t){return e.start<t.end&&t.start<e.end}function yn(e){return e.sort((t,n)=>t.start!==n.start?t.start-n.start:n.end-n.start-(t.end-t.start))}var Je=class{allowValues=new Set;enableEntropyHeuristic;constructor(t={}){for(let n of t.allowValues??[]){let r=gn(n);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=t.enableEntropyHeuristic??!0}scan(t){let n=[];for(let o of ko){let i=new RegExp(o.regex.source,o.regex.flags);for(let a of t.matchAll(i))a.index===void 0||!a[0]||this.allowed(a[0])||n.push({type:o.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:o.confidence})}this.enableEntropyHeuristic&&n.push(...this.entropyMatches(t));let r=yn(n),s=[];for(let o of r)s.some(i=>Ao(i,o))||s.push(o);return yn(s)}hasSecrets(t){return this.scan(t).length>0}allowed(t){let n=gn(t);return vo.has(n)?!0:this.allowValues.has(n)}entropyMatches(t){let n=[],r=/[A-Za-z0-9_+/=-]{32,160}/g;for(let s of t.matchAll(r)){if(s.index===void 0||!s[0])continue;let o=s[0];this.allowed(o)||bo(o)||!/[A-Za-z]/u.test(o)||!/[0-9]/u.test(o)||xo(t,s.index,s.index+o.length)&&(wo(o)<3.7||n.push({type:"high_entropy_secret",value:o,start:s.index,end:s.index+o.length,confidence:"heuristic"}))}return n}};var J=class{scanner;constructor(t={}){this.scanner=new Je(t)}sanitize(t){let n=this.scanner.scan(t);if(n.length===0)return{text:t,redacted:0,secretTypes:[]};let r=t,s=[...n].sort((i,a)=>a.start-i.start),o=new Set;for(let i of s)o.add(i.type),r=r.slice(0,i.start)+`[REDACTED:${i.type}]`+r.slice(i.end);return{text:r,redacted:n.length,secretTypes:[...o].sort()}}sanitizeValue(t){if(typeof t=="string")return this.sanitize(t).text;if(Array.isArray(t))return t.map(n=>this.sanitizeValue(n));if(t&&typeof t=="object"){let n={};for(let[r,s]of Object.entries(t)){let o=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(o.includes("password")||o.includes("passwd")||o==="pwd"||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")||o.includes("apikey")||o.includes("accesskey")||o.includes("privatekey")||o.includes("clientsecret")||o.includes("credential")){n[r]="[REDACTED]";continue}n[r]=this.sanitizeValue(s)}return n}return t}};var jo=new J;function ge(e){return jo.sanitizeValue(e)}import{homedir as Go}from"node:os";import{join as Uo}from"node:path";import{DeleteObjectCommand as Mo,GetObjectCommand as Io,HeadObjectCommand as Co,ListObjectsV2Command as Po,PutObjectCommand as Eo,S3Client as Oo}from"@aws-sdk/client-s3";import{getSignedUrl as To}from"@aws-sdk/s3-request-presigner";var Ve=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new Oo({region:"us-east-1",endpoint:`https://s3.hf.co/${t.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Eo({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await To(this.client,new Io({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await this.client.send(new Co({Bucket:this.bucket,Key:t})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(t){await this.client.send(new Mo({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new Po({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 hn,mkdir as Ro,readFile as No,readdir as _o,rm as $o,stat as Sn,writeFile as Ko}from"node:fs/promises";import{dirname as Lo,join as Wo,relative as kn,resolve as Fo}from"node:path";var ye=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return Fo(this.root,n)}async put(t,n){let r=this.path(t);await Ro(Lo(r),{recursive:!0}),await Ko(r,n)}async get(t){try{return await No(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 hn(this.path(t)),!0}catch{return!1}}async delete(t){await $o(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await hn(n)}catch{return r}let s=async i=>{let a=await _o(i,{withFileTypes:!0});for(let c of a){let u=Wo(i,c.name);if(c.isDirectory()){await s(u);continue}let l=await Sn(u);r.push({key:kn(this.root,u),size:l.size,updatedAt:l.mtime.toISOString()})}},o=await Sn(n);return o.isDirectory()?await s(n):r.push({key:kn(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as Do,GetObjectCommand as zo,HeadObjectCommand as qo,ListObjectsV2Command as Jo,PutObjectCommand as Vo,S3Client as Bo}from"@aws-sdk/client-s3";import{getSignedUrl as Ho}from"@aws-sdk/s3-request-presigner";var he=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new Bo({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 Vo({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await Ho(this.client,new zo({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 qo({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 Do({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new Jo({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 ye(e)}function vn(e){let t=e.localRoot??Uo(Go(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new he({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 he({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 Ve({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Pt(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new ye(t)}function Yo(e){return new Promise(t=>setTimeout(t,e))}async function wn(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,s=t.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(o=a,i>=n)break;let c=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Yo(c+u)}throw o}var Xo=new Set(["put","get","getText","delete","list"]);function bn(e,t={}){return new Proxy(e,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:Xo.has(r)?(...o)=>wn(()=>Promise.resolve(s.apply(n,o)),t):s.bind(n)}})}function xn(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 An(e){let t=e.replace(/^\/+/,"");if(t.startsWith("memories/"))return"memory/records/"+t.slice(9);if(t.startsWith("vectors/"))return"memory/vectors/"+t.slice(8);if(t.startsWith("graph/"))return"code/graph/"+t.slice(6);let n=t.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=t.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=t.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=t.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:t))}var Be=class{constructor(t,n,r,s){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=xn(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let t=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(t);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(o,null,2)+`
4
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=An(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{homedir as cn}from"node:os";import{join as zs,resolve as Fl}from"node:path";import{join as si}from"node:path";import{createHash as Zo}from"node:crypto";import{dirname as Qo}from"node:path";import{mkdirSync as ei,readFileSync as ti,renameSync as ni,writeFileSync as ri}from"node:fs";function w(e){return Zo("sha256").update(e).digest("hex")}function Et(e){if(Array.isArray(e))return e.map(Et);if(e&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=Et(t[r]);return n}return e}function jn(e){return JSON.stringify(Et(e))}function Mn(e){try{return JSON.parse(ti(e,"utf8"))}catch{return null}}function T(e,t){ei(Qo(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;ri(n,JSON.stringify(t,null,2)+`
5
+ `,{encoding:"utf8",mode:384}),ni(n,e)}function In(e,t){let n=e.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=w(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 Cn(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=In(r.toLowerCase(),"agent"),i=In(s,"session");return{projectId:e.id,projectName:e.name,projectRoot:e.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",e.id,"runtime","sources",o,i].join("/"),localDirectory:si(e.rootPath,".toolnet","runtime","sources",o,i)}}function Pn(e){return String(e).padStart(12,"0")}var He=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)+`
6
6
  `,"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 a=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!a)continue;let c=Number(a[1]),u=Number(a[2]);!Number.isFinite(c)||!Number.isFinite(u)||(s.push({key:i.key,start:c,end:u}),o=Math.max(o,u))}return s.sort((i,a)=>i.start-a.start),{chunks:s,maxSequence:o}}split(t){let n=[],r=[],s=0;for(let o of t){let i=Buffer.byteLength(JSON.stringify(o)+`
7
- `,"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),a=n.filter(y=>y.sequence>i.maxSequence),c=0;for(let y of this.split(a)){let h=y[0],k=y[y.length-1],C=y.map(E=>JSON.stringify(E)).join(`
7
+ `,"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),a=n.filter(g=>g.sequence>i.maxSequence),c=0;for(let g of this.split(a)){let h=g[0],v=g[g.length-1],x=g.map(O=>JSON.stringify(O)).join(`
8
8
  `)+`
9
- `,P=v(C).slice(0,16),I=[t.remotePrefix,"events",`${xn(h.sequence)}-${xn(k.sequence)}-${P}.jsonl`].join("/");await this.storage.exists(I)||await this.storage.put(I,C,"application/x-ndjson"),c+=y.length}let u=await this.scan(t),l=n[n.length-1],d=o?.status??"active";l?.type==="session_end"||l?.type==="session_idle"?d="idle":l?.type==="error"?d="error":n.length>0&&(d="active");let p=new Date().toISOString(),f=n[0],g={version:1,projectId:t.projectId,projectName:t.projectName,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,status:d,createdAt:o?.createdAt??f?.timestamp??p,updatedAt:l?.timestamp??p,firstEventAt:o?.firstEventAt??f?.timestamp,lastEventAt:l?.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 S={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:u.maxSequence,lastRemoteSequence:u.maxSequence,sourceCursors:r,updatedAt:p};return await this.putJson(`${t.remotePrefix}/cursor.json`,S),await this.putJson(`${t.remotePrefix}/session.json`,g),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:g.eventCount,chunkCount:g.chunkCount,status:d}}};import{closeSync as Se,existsSync as Ge,fsyncSync as _t,mkdirSync as pi,openSync as ke,readFileSync as Ln,readSync as fi,rmSync as _n,statSync as Rt,truncateSync as mi,writeSync as gi}from"node:fs";import{join as Nt}from"node:path";var Yo=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),Xo=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function Qo(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function Zo(e){for(let t of["type","kind"]){let n=e[t];if(typeof n=="string"){let r=n.toLowerCase();if(Xo.has(r))return n}}return null}function Ct(e,t=0){if(t>12)return"[ToolNet nested value omitted]";if(Array.isArray(e))return e.map(o=>Ct(o,t+1));if(!e||typeof e!="object")return e;let n=e,r=Zo(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let s={};for(let[o,i]of Object.entries(n))Yo.has(Qo(o))||(s[o]=Ct(i,t+1));return s}function ei(e){if(!e)return new Date().toISOString();let t=new Date(e);return Number.isNaN(t.getTime())?new Date().toISOString():t.toISOString()}function G(e){return e?.trim()||void 0}function An(e,t={}){let n={...e.provenance??{}},r=G(e.source)??G(t.source)??G(n.source);return{...e,timestamp:ei(e.timestamp),source:r,turnId:G(e.turnId)??G(t.turnId),cwd:G(e.cwd)??G(t.cwd),data:Ct(e.data??{}),provenance:n}}import{randomUUID as Pt}from"node:crypto";import{closeSync as te,existsSync as ne,fsyncSync as ye,mkdirSync as Et,openSync as he,readFileSync as Ot,readdirSync as ti,renameSync as ni,rmSync as Je,statSync as ri,writeSync as Ve}from"node:fs";import{join as q}from"node:path";var si=12e4,oi=80,ii="reconcile-required";function ai(e){e<=0||Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function re(e){return q(e,".toolnet","journal")}function In(e){return q(re(e),"events.jsonl")}function Be(e){return q(re(e),ii)}function ci(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function Cn(e){if(!ne(e))return null;try{let t=JSON.parse(Ot(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function ui(e){if(!ne(e))return!1;let t=0;try{t=Date.now()-ri(e).mtimeMs}catch{return!1}if(t<=si)return!1;let n=Cn(e);return n?!ci(n.pid):!0}function li(e){if(!ui(e))return!1;try{return Je(e,{force:!0}),!0}catch{return!1}}function Pn(e){for(let t=0;t<oi;t+=1){let n=Pt();try{let r=he(e,"wx",384),s={version:1,token:n,pid:process.pid,acquiredAt:new Date().toISOString()};try{return Ve(r,`${JSON.stringify(s)}
10
- `,null,"utf8"),ye(r),{fd:r,token:n}}catch(o){throw te(r),Je(e,{force:!0}),o}}catch(r){if(r?.code!=="EEXIST")throw r;if(li(e))continue;ai(25)}}throw new Error(`Shared project journal is locked: ${e}`)}function En(e,t){te(t.fd),Cn(e)?.token===t.token&&Je(e,{force:!0})}function jn(e){if(!ne(e))return[];let t="";try{t=Ot(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let s=r.trim();if(s)try{let o=JSON.parse(s);if(o.version!==1||typeof o.id!="string"||o.id.length===0||typeof o.projectId!="string"||o.projectId.length===0)continue;n.push(o)}catch{}}return n}function On(e){if(!ne(e))return[];let t=[];for(let n of ti(e,{withFileTypes:!0})){let r=q(e,n.name);if(n.isDirectory()){t.push(...On(r));continue}n.isFile()&&n.name==="events.jsonl"&&t.push(r)}return t.sort()}function He(e){let t=null;try{t=he(e,"r"),ye(t)}catch{}finally{if(t===null)return;te(t)}}function Mn(e){let t=Be(e);if(!ne(t))return null;try{return Ot(t,"utf8").trim()||null}catch{return null}}function Tt(e){let t=re(e);Et(t,{recursive:!0,mode:448});let n=Be(e),r=[Pt(),new Date().toISOString()].join("|"),s=he(n,"w",384);try{Ve(s,`${r}
11
- `,null,"utf8"),ye(s)}finally{te(s)}He(t)}function di(e,t,n){let r=q(e,`.events.jsonl.tmp-${process.pid}-${Pt()}`),s=he(r,"w",384);try{let o=n.length===0?"":`${n.map(i=>JSON.stringify(i)).join(`
9
+ `,E=w(x).slice(0,16),C=[t.remotePrefix,"events",`${Pn(h.sequence)}-${Pn(v.sequence)}-${E}.jsonl`].join("/");await this.storage.exists(C)||await this.storage.put(C,x,"application/x-ndjson"),c+=g.length}let u=await this.scan(t),l=n[n.length-1],d=o?.status??"active";l?.type==="session_end"||l?.type==="session_idle"?d="idle":l?.type==="error"?d="error":n.length>0&&(d="active");let p=new Date().toISOString(),f=n[0],m={version:1,projectId:t.projectId,projectName:t.projectName,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,status:d,createdAt:o?.createdAt??f?.timestamp??p,updatedAt:l?.timestamp??p,firstEventAt:o?.firstEventAt??f?.timestamp,lastEventAt:l?.timestamp??o?.lastEventAt,eventCount:u.maxSequence,chunkCount:u.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(m.title=s.title??o?.title);let S={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:u.maxSequence,lastRemoteSequence:u.maxSequence,sourceCursors:r,updatedAt:p};return await this.putJson(`${t.remotePrefix}/cursor.json`,S),await this.putJson(`${t.remotePrefix}/session.json`,m),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:m.eventCount,chunkCount:m.chunkCount,status:d}}};import{closeSync as ve,existsSync as Ze,fsyncSync as Lt,mkdirSync as wi,openSync as we,readFileSync as Jn,readSync as bi,rmSync as Dn,statSync as $t,truncateSync as xi,writeSync as Ai}from"node:fs";import{join as Kt}from"node:path";var oi=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),ii=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function ai(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function ci(e){for(let t of["type","kind"]){let n=e[t];if(typeof n=="string"){let r=n.toLowerCase();if(ii.has(r))return n}}return null}function Ot(e,t=0){if(t>12)return"[ToolNet nested value omitted]";if(Array.isArray(e))return e.map(o=>Ot(o,t+1));if(!e||typeof e!="object")return e;let n=e,r=ci(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let s={};for(let[o,i]of Object.entries(n))oi.has(ai(o))||(s[o]=Ot(i,t+1));return s}function ui(e){if(!e)return new Date().toISOString();let t=new Date(e);return Number.isNaN(t.getTime())?new Date().toISOString():t.toISOString()}function U(e){return e?.trim()||void 0}function En(e,t={}){let n={...e.provenance??{}},r=U(e.source)??U(t.source)??U(n.source);return{...e,timestamp:ui(e.timestamp),source:r,turnId:U(e.turnId)??U(t.turnId),cwd:U(e.cwd)??U(t.cwd),data:Ot(e.data??{}),provenance:n}}import{randomUUID as Tt}from"node:crypto";import{closeSync as re,existsSync as se,fsyncSync as Se,mkdirSync as Rt,openSync as ke,readFileSync as Nt,readdirSync as li,renameSync as di,rmSync as Ge,statSync as pi,writeSync as Ue}from"node:fs";import{join as V}from"node:path";var fi=12e4,mi=80,gi="reconcile-required";function yi(e){e<=0||Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function oe(e){return V(e,".toolnet","journal")}function Rn(e){return V(oe(e),"events.jsonl")}function Ye(e){return V(oe(e),gi)}function hi(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function Nn(e){if(!se(e))return null;try{let t=JSON.parse(Nt(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function Si(e){if(!se(e))return!1;let t=0;try{t=Date.now()-pi(e).mtimeMs}catch{return!1}if(t<=fi)return!1;let n=Nn(e);return n?!hi(n.pid):!0}function ki(e){if(!Si(e))return!1;try{return Ge(e,{force:!0}),!0}catch{return!1}}function _n(e){for(let t=0;t<mi;t+=1){let n=Tt();try{let r=ke(e,"wx",384),s={version:1,token:n,pid:process.pid,acquiredAt:new Date().toISOString()};try{return Ue(r,`${JSON.stringify(s)}
10
+ `,null,"utf8"),Se(r),{fd:r,token:n}}catch(o){throw re(r),Ge(e,{force:!0}),o}}catch(r){if(r?.code!=="EEXIST")throw r;if(ki(e))continue;yi(25)}}throw new Error(`Shared project journal is locked: ${e}`)}function $n(e,t){re(t.fd),Nn(e)?.token===t.token&&Ge(e,{force:!0})}function On(e){if(!se(e))return[];let t="";try{t=Nt(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let s=r.trim();if(s)try{let o=JSON.parse(s);if(o.version!==1||typeof o.id!="string"||o.id.length===0||typeof o.projectId!="string"||o.projectId.length===0)continue;n.push(o)}catch{}}return n}function Kn(e){if(!se(e))return[];let t=[];for(let n of li(e,{withFileTypes:!0})){let r=V(e,n.name);if(n.isDirectory()){t.push(...Kn(r));continue}n.isFile()&&n.name==="events.jsonl"&&t.push(r)}return t.sort()}function Xe(e){let t=null;try{t=ke(e,"r"),Se(t)}catch{}finally{if(t===null)return;re(t)}}function Tn(e){let t=Ye(e);if(!se(t))return null;try{return Nt(t,"utf8").trim()||null}catch{return null}}function _t(e){let t=oe(e);Rt(t,{recursive:!0,mode:448});let n=Ye(e),r=[Tt(),new Date().toISOString()].join("|"),s=ke(n,"w",384);try{Ue(s,`${r}
11
+ `,null,"utf8"),Se(s)}finally{re(s)}Xe(t)}function vi(e,t,n){let r=V(e,`.events.jsonl.tmp-${process.pid}-${Tt()}`),s=ke(r,"w",384);try{let o=n.length===0?"":`${n.map(i=>JSON.stringify(i)).join(`
12
12
  `)}
13
- `;o&&Ve(s,o,null,"utf8"),ye(s)}finally{te(s)}ni(r,t),He(e)}function Tn(e){let t=re(e),n=In(e),r=q(e,".toolnet","runtime","sources"),s=Mn(e),o=On(r),i=[],a=new Set;for(let d of jn(n))a.has(d.id)||(a.add(d.id),i.push(d));let c=i.length,u=[];for(let d of o)for(let p of jn(d))a.has(p.id)||(a.add(p.id),u.push(p));u.sort((d,p)=>{let f=d.timestamp.localeCompare(p.timestamp);return f!==0?f:d.id.localeCompare(p.id)}),i.push(...u),di(t,n,i);let l=Mn(e);return s&&l===s&&(Je(Be(e),{force:!0}),He(t)),{filesScanned:o.length,existingEvents:c,recoveredEvents:u.length,totalEvents:i.length}}function Rn(e){let t=re(e);Et(t,{recursive:!0,mode:448});let n=q(t,"journal.lock"),r=Pn(n);try{return Tn(e)}finally{En(n,r)}}function Nn(e,t){if(t.length===0)return;let n=re(e);Et(n,{recursive:!0,mode:448});let r=In(e),s=q(n,"journal.lock"),o=Pn(s);try{if(ne(Be(e))){Tn(e);return}let i=`${t.map(c=>JSON.stringify(c)).join(`
13
+ `;o&&Ue(s,o,null,"utf8"),Se(s)}finally{re(s)}di(r,t),Xe(e)}function Ln(e){let t=oe(e),n=Rn(e),r=V(e,".toolnet","runtime","sources"),s=Tn(e),o=Kn(r),i=[],a=new Set;for(let d of On(n))a.has(d.id)||(a.add(d.id),i.push(d));let c=i.length,u=[];for(let d of o)for(let p of On(d))a.has(p.id)||(a.add(p.id),u.push(p));u.sort((d,p)=>{let f=d.timestamp.localeCompare(p.timestamp);return f!==0?f:d.id.localeCompare(p.id)}),i.push(...u),vi(t,n,i);let l=Tn(e);return s&&l===s&&(Ge(Ye(e),{force:!0}),Xe(t)),{filesScanned:o.length,existingEvents:c,recoveredEvents:u.length,totalEvents:i.length}}function Wn(e){let t=oe(e);Rt(t,{recursive:!0,mode:448});let n=V(t,"journal.lock"),r=_n(n);try{return Ln(e)}finally{$n(n,r)}}function Fn(e,t){if(t.length===0)return;let n=oe(e);Rt(n,{recursive:!0,mode:448});let r=Rn(e),s=V(n,"journal.lock"),o=_n(s);try{if(se(Ye(e))){Ln(e);return}let i=`${t.map(c=>JSON.stringify(c)).join(`
14
14
  `)}
15
- `,a=he(r,"a",384);try{Ve(a,i,null,"utf8"),ye(a)}finally{te(a)}He(n)}finally{En(s,o)}}var yi=12e4,hi=80,$n=2e3;function Si(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function Wn(e,t){let n=Buffer.isBuffer(t)?t:Buffer.from(t,"utf8"),r=0;for(;r<n.length;){let s=gi(e,n,r,n.length-r);if(s<=0)throw new Error("Unable to write session WAL");r+=s}}function $t(e){let t=e.trim();if(!t)return null;try{let n=JSON.parse(t);return n.version!==1||typeof n.id!="string"||!n.id||typeof n.sequence!="number"||!Number.isFinite(n.sequence)||typeof n.projectId!="string"||!n.projectId||typeof n.timestamp!="string"?null:n}catch{return null}}function ki(e){if(!Ge(e))return[];let t="";try{t=Ln(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let s=$t(r);s&&n.push(s)}return n}function Kn(e){return e.type==="session_end"||e.type==="session_idle"?"idle":e.type==="error"?"error":"active"}function vi(e){if(!Ge(e))return!1;let t;try{t=Ln(e)}catch{return!1}if(t.length===0||t[t.length-1]===10)return!1;let n=t.lastIndexOf(10),r=n>=0?n+1:0,s=t.subarray(r).toString("utf8").trim();if($t(s)){let i=ke(e,"a");try{Wn(i,`
16
- `),_t(i)}finally{Se(i)}return!0}mi(e,r);let o=ke(e,"a");try{_t(o)}finally{Se(o)}return!0}function wi(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}var Ue=class{constructor(t,n={}){this.identity=t;this.eventContext=n;pi(t.localDirectory,{recursive:!0}),this.eventsFile=Nt(t.localDirectory,"events.jsonl"),this.stateFile=Nt(t.localDirectory,"state.json"),this.lockFile=Nt(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 vn(this.stateFile)??this.initialState()}recoverStateUnsafe(){vi(this.eventsFile);let t=this.loadStateUnsafe(),n=ki(this.eventsFile);if(n.length===0)return t;let r=n[0];for(let d of n)d.sequence<=r.sequence||(r=d);let s=n.slice(-$n).map(d=>d.id),o=Ge(this.eventsFile)?Rt(this.eventsFile).size:0,i=Math.max(t.lastSequence,r.sequence),a=Math.min(t.remoteByteOffset,o),c=r.sequence>t.lastSequence;if(!(c||a!==t.remoteByteOffset||!wi(t.recentEventIds,s)||t.lastLocalEventAt!==r.timestamp))return t;let l={...t,status:Kn(r),updatedAt:r.timestamp,lastLocalEventAt:r.timestamp,lastSequence:i,remoteByteOffset:a,recentEventIds:s};if(this.saveStateUnsafe(l),!c)return l;try{Tt(this.identity.projectRoot)}catch{return l}try{Rn(this.identity.projectRoot)}catch{}return l}loadState(){return this.withLock(()=>this.recoverStateUnsafe())}saveStateUnsafe(t){O(this.stateFile,t)}acquireLock(){for(let t=0;t<hi;t+=1)try{return ke(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-Rt(this.lockFile).mtimeMs>yi){_n(this.lockFile,{force:!0});continue}}catch{}Si(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(t){let n=this.acquireLock();try{return t()}finally{Se(n),_n(this.lockFile,{force:!0})}}append(t){return t.length===0?[]:this.withLock(()=>{let n=this.recoverStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let d of t){let p=An(d,this.eventContext),f=p.timestamp??new Date().toISOString(),g=p.data??{},S=p.provenance?.rawDigest??v(kn(g)),y=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,f,S].join("|"),h=v(y).slice(0,32);if(r.has(h))continue;s+=1;let k={version:1,id:h,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:p.type,timestamp:f,source:p.source??p.provenance?.source??this.identity.agent,data:g,provenance:{...p.provenance,rawDigest:S}};p.role!==void 0&&(k.role=p.role),p.turnId!==void 0&&(k.turnId=p.turnId),p.cwd!==void 0&&(k.cwd=p.cwd),p.sourceEventId!==void 0&&(k.sourceEventId=p.sourceEventId),p.sourceSequence!==void 0&&(k.sourceSequence=p.sourceSequence),o.push(k),r.add(h)}if(o.length===0)return[];let i=o.map(d=>JSON.stringify(d)).join(`
15
+ `,a=ke(r,"a",384);try{Ue(a,i,null,"utf8"),Se(a)}finally{re(a)}Xe(n)}finally{$n(s,o)}}var ji=12e4,Mi=80,zn=2e3;function Ii(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}function Vn(e,t){let n=Buffer.isBuffer(t)?t:Buffer.from(t,"utf8"),r=0;for(;r<n.length;){let s=Ai(e,n,r,n.length-r);if(s<=0)throw new Error("Unable to write session WAL");r+=s}}function Wt(e){let t=e.trim();if(!t)return null;try{let n=JSON.parse(t);return n.version!==1||typeof n.id!="string"||!n.id||typeof n.sequence!="number"||!Number.isFinite(n.sequence)||typeof n.projectId!="string"||!n.projectId||typeof n.timestamp!="string"?null:n}catch{return null}}function Ci(e){if(!Ze(e))return[];let t="";try{t=Jn(e,"utf8")}catch{return[]}let n=[];for(let r of t.split(/\r?\n/)){let s=Wt(r);s&&n.push(s)}return n}function qn(e){return e.type==="session_end"||e.type==="session_idle"?"idle":e.type==="error"?"error":"active"}function Pi(e){if(!Ze(e))return!1;let t;try{t=Jn(e)}catch{return!1}if(t.length===0||t[t.length-1]===10)return!1;let n=t.lastIndexOf(10),r=n>=0?n+1:0,s=t.subarray(r).toString("utf8").trim();if(Wt(s)){let i=we(e,"a");try{Vn(i,`
16
+ `),Lt(i)}finally{ve(i)}return!0}xi(e,r);let o=we(e,"a");try{Lt(o)}finally{ve(o)}return!0}function Ei(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}var Qe=class{constructor(t,n={}){this.identity=t;this.eventContext=n;wi(t.localDirectory,{recursive:!0}),this.eventsFile=Kt(t.localDirectory,"events.jsonl"),this.stateFile=Kt(t.localDirectory,"state.json"),this.lockFile=Kt(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 Mn(this.stateFile)??this.initialState()}recoverStateUnsafe(){Pi(this.eventsFile);let t=this.loadStateUnsafe(),n=Ci(this.eventsFile);if(n.length===0)return t;let r=n[0];for(let d of n)d.sequence<=r.sequence||(r=d);let s=n.slice(-zn).map(d=>d.id),o=Ze(this.eventsFile)?$t(this.eventsFile).size:0,i=Math.max(t.lastSequence,r.sequence),a=Math.min(t.remoteByteOffset,o),c=r.sequence>t.lastSequence;if(!(c||a!==t.remoteByteOffset||!Ei(t.recentEventIds,s)||t.lastLocalEventAt!==r.timestamp))return t;let l={...t,status:qn(r),updatedAt:r.timestamp,lastLocalEventAt:r.timestamp,lastSequence:i,remoteByteOffset:a,recentEventIds:s};if(this.saveStateUnsafe(l),!c)return l;try{_t(this.identity.projectRoot)}catch{return l}try{Wn(this.identity.projectRoot)}catch{}return l}loadState(){return this.withLock(()=>this.recoverStateUnsafe())}saveStateUnsafe(t){T(this.stateFile,t)}acquireLock(){for(let t=0;t<Mi;t+=1)try{return we(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-$t(this.lockFile).mtimeMs>ji){Dn(this.lockFile,{force:!0});continue}}catch{}Ii(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(t){let n=this.acquireLock();try{return t()}finally{ve(n),Dn(this.lockFile,{force:!0})}}append(t){return t.length===0?[]:this.withLock(()=>{let n=this.recoverStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let d of t){let p=En(d,this.eventContext),f=p.timestamp??new Date().toISOString(),m=p.data??{},S=p.provenance?.rawDigest??w(jn(m)),g=ge(m),h=p.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,p.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,p.type,f,S].join("|"),v=w(h).slice(0,32);if(r.has(v))continue;s+=1;let x={version:1,id:v,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:p.type,timestamp:f,source:p.source??p.provenance?.source??this.identity.agent,data:g,provenance:{...p.provenance,rawDigest:S}};p.role!==void 0&&(x.role=p.role),p.turnId!==void 0&&(x.turnId=p.turnId),p.cwd!==void 0&&(x.cwd=p.cwd),p.sourceEventId!==void 0&&(x.sourceEventId=p.sourceEventId),p.sourceSequence!==void 0&&(x.sourceSequence=p.sourceSequence),o.push(x),r.add(v)}if(o.length===0)return[];let i=o.map(d=>JSON.stringify(d)).join(`
17
17
  `)+`
18
- `,a=ke(this.eventsFile,"a",384);try{Wn(a,i),_t(a)}finally{Se(a)}try{Nn(this.identity.projectRoot,o)}catch{try{Tt(this.identity.projectRoot)}catch{}}let c=o[o.length-1],u=Kn(c),l=Array.from(r).slice(-$n);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:l}),o})}readPending(){return this.withLock(()=>{let t=this.recoverStateUnsafe();if(!Ge(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=Rt(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=ke(this.eventsFile,"r");try{fi(i,o,0,s,r)}finally{Se(i)}let a=[];for(let c of o.toString("utf8").split(/\r?\n/)){let u=$t(c);u&&a.push(u)}return{events:a,startOffset:r,endOffset:n}})}markRemote(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe(),s=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,t),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:s,updatedAt:s})})}setSourceCursor(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[t]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as yc,existsSync as hc,openSync as Sc,readSync as kc,statSync as vc}from"node:fs";var bi=new Set(["rule","blocker","architecture","deploy"]),xi=new Set(["fix","todo","context","next_action"]);function Kt(e){return e<0?0:e>1?1:e}function Fn(e,t){let n=Number.parseFloat(e??"");return Number.isFinite(n)?n:t}function Ai(e){return e==="off"?"off":e==="balanced"?"balanced":e==="aggressive"?"aggressive":"conservative"}function Lt(){return{mode:Ai(process.env.TOOLNET_MEMORY_PROMOTION),minScore:Kt(Fn(process.env.TOOLNET_PROMOTE_MIN_SCORE,.65)),minConfidence:Kt(Fn(process.env.TOOLNET_PROMOTE_MIN_CONFIDENCE,.78))}}function ji(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Mi(e){let t=Kt(ji(e.importance)*.75+e.confidence*.25);return Math.round(t*1e6)/1e6}function Ii(e){return e.evidence?e.evidence:{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1}}function Ci(e,t=Lt()){if(e.importance==="temporary"||e.confidence<t.minConfidence)return"transient";let n=Ii(e);return e.kind==="rule"&&n.userExplicit?"permanent":e.kind==="rule"?"session":e.kind==="architecture"&&(n.userExplicit||n.sourceVerified||n.testVerified||n.crossSessionConfirmations>=2)?"permanent":e.kind==="architecture"?"session":e.kind==="decision"||e.kind==="todo"||e.kind==="fix"?"task":"session"}function Pi(e,t=Lt()){if(t.mode==="off")return Number.POSITIVE_INFINITY;let n=0;t.mode==="balanced"&&(n=.1),t.mode==="aggressive"&&(n=.15);let r=Math.max(t.mode==="aggressive"?.5:.55,t.minScore-n);return bi.has(e)&&(r=Math.max(.5,r-.1)),xi.has(e)&&(r=Math.max(.5,r-.05)),r}function Wt(e,t=Lt()){let n=Ci(e,t),r=Mi(e),s=Pi(e.kind,t);return n==="transient"?{knowledgeClass:n,score:r,threshold:s,persist:!1}:t.mode==="off"?{knowledgeClass:n,score:r,threshold:s,persist:!1}:{knowledgeClass:n,score:r,threshold:s,persist:r>=s}}function Dn(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 Vn=[/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],Ei=[/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],Oi=[/\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],Ti=[/\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],Ri=[/đã 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],zn=[/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],Ni=[/\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],_i=[/đườ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],$i=[/\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],qn=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Ki=new Set(["payload","data","content","message","messages","parts","summary"]);function T(e,t){return t.some(n=>n.test(e))}function Bn(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Li(e){return Bn(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Wi(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 Ft(e,t,n,r=0){if(!(r>6)&&!(typeof e=="string"&&t&&!qn.has(t))){if(typeof e=="string"){n.push(e);return}if(Array.isArray(e)){for(let s of e.slice(0,50))Ft(s,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[s,o]of Object.entries(e))(qn.has(s)||Ki.has(s))&&Ft(o,s,n,r+1)}}function Fi(e){let t=[];Ft(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=Bn(o);if(Wi(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function Jn(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function Di(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&&T(e,Vn)?{kind:"rule",confidence:.98}:r&&T(e,Ei)?{kind:"rule",confidence:.92}:T(e,Oi)?{kind:T(e,zn)?"architecture":"decision",confidence:r?.93:.86}:r&&T(e,Ti)?{kind:"todo",confidence:.87}:T(e,zn)&&T(e,Ni)?{kind:"architecture",confidence:r?.88:.82}:s&&T(e,Ri)?{kind:"fix",confidence:.8}:r&&T(e,_i)&&T(e,$i)?{kind:"context",confidence:.79}:null}function zi(e,t,n){let r=t==="user"||n.type==="user_prompt",s=t==="assistant"||n.type==="assistant_message",o=!!n.provenance.sourcePath&&(e==="architecture"||e==="context"||e==="fix"),i=e==="fix"&&/(?:test|tests|pass|passed|passing)/iu.test(JSON.stringify(n.data));return{userExplicit:r,sourceVerified:o,testVerified:i,crossSessionConfirmations:1,assistantDerived:s}}function qi(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Ji(e,t,n){return e==="rule"&&T(n,Vn)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":Dn(t,n)}function Hn(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,a=Jn(o);i&&a&&s.set(i,a)}for(let o of t){let i=Jn(o),a=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&a&&(i=s.get(a)??"");for(let c of Fi(o)){let u=Di(c,i,o);if(!u||u.confidence<.75)continue;let l=qi(u.kind),d=Li(c),p=v([e.projectId,u.kind,d].join("|"));if(r.has(p))continue;r.add(p);let f=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:l,content:c,confidence:u.confidence,importance:Ji(u.kind,l,c),evidence:zi(u.kind,i,o),tags:[l],provenance:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventIds:[o.id],sourceEventIds:g,sourcePaths:f,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}import{createHash as Vi}from"node:crypto";var Bi=["project-knowledge","implementation","continuation","session-context"],Hi={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function Dt(e){return Vi("sha256").update(e).digest("hex")}function Ye(e,t){return`${e}:${Dt(t).slice(0,24)}`}function Gi(e){try{return Dt(JSON.stringify(e))}catch{return Dt(String(e))}}function U(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 Un(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 Ui(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function Gn(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function Yi(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=>Un(t.content)).join(" | ")}function Xi(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=>Un(t.content)).join(`
19
- `)}function Yn(e,t){let n=e.slice().sort((p,f)=>p.sequence-f.sequence||p.timestamp.localeCompare(f.timestamp)||p.id.localeCompare(f.id)),r=n.map(p=>({id:Ye("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:Gi(p.data)})),s=new Map,o=new Map;n.forEach((p,f)=>{let g=r[f];g&&(s.set(p.id,g.id),p.sourceEventId&&o.set(p.sourceEventId,g.id))});let i=t.map(p=>{let f=U([...p.provenance.eventIds.map(g=>s.get(g)),...p.provenance.sourceEventIds.map(g=>o.get(g))]);return{id:Ye("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:U([...p.tags,"level:fact",`class:${p.knowledgeClass}`,`kind:${p.kind}`]),rawIds:f,sourcePaths:U(p.provenance.sourcePaths)}}),a=new Map;for(let p of i){let f=Ui(p.kind),g=a.get(f)??[];g.push(p),a.set(f,g)}let c=[];for(let p of Bi){let f=a.get(p);if(!f?.length)continue;let g=f.slice().sort((y,h)=>h.importanceScore-y.importanceScore||h.confidence-y.confidence||y.id.localeCompare(h.id)),S=g.map(y=>y.id);c.push({id:Ye("scene",`${p}|${S.join("|")}`),level:"scene",kind:p,title:Hi[p],summary:Yi(g),factIds:S,importanceScore:Math.max(...g.map(y=>y.importanceScore)),confidence:Gn(g.map(y=>y.confidence)),tags:U(["level:scene",`scene:${p}`,...g.flatMap(y=>y.tags)]),sourcePaths:U(g.flatMap(y=>y.sourcePaths))})}let u=new Map(i.map(p=>[p.id,p])),l=[];for(let p of c){let g=p.factIds.map(h=>u.get(h)).filter(h=>!!h).filter(h=>(h.knowledgeClass==="permanent"||h.knowledgeClass==="task")&&h.importanceScore>=.55);if(g.length===0)continue;let S=g.some(h=>h.knowledgeClass==="permanent")?"permanent":"task",y=Xi(g);l.push({id:Ye("knowledge",`${p.id}|${S}|${g.map(h=>h.id).join("|")}`),level:"knowledge",knowledgeClass:S,title:p.title,content:y,sceneIds:[p.id],factIds:g.map(h=>h.id),importanceScore:Math.max(...g.map(h=>h.importanceScore)),confidence:Gn(g.map(h=>h.confidence)),tags:U(["level:knowledge",`class:${S}`,`scene:${p.kind}`,...g.flatMap(h=>h.tags)]),sourcePaths:U(g.flatMap(h=>h.sourcePaths))})}let d=[];for(let p of i)for(let f of p.rawIds)d.push({from:f,to:p.id,type:"supports"});for(let p of c)for(let f of p.factIds)d.push({from:f,to:p.id,type:"belongs_to"});for(let p of l)for(let f of p.sceneIds)d.push({from:f,to:p.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:l,links:d,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:l.length,links:d.length}}}function Qi(e){return e?Math.ceil(e.length/3.5):0}function Xn(e,t){if(!e)return"";if(Qi(e)<=t)return e;let r=Math.floor(t*3.5),s=e.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
20
- `),a=Math.max(o,i);return a>r*.7?s.slice(0,a+1):s}function Y(){let e=$e(),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),a=n,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function Qn(e){return(e||Y()).rawTranscript}function Zn(e){return(e||Y()).durableMemoryMaxItemsPerSession}function er(e){return(e||Y()).sessionSummaryMaxTokens}function tr(e){return(e||Y()).archiveRemote}var nr=new H;function rr(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(nr.sanitizeValue(r))}catch{}let n=nr.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 Zi(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 ea(e,t){let n=[],r=new Set;for(let i of e){let a=i.split(`
21
- `).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let l=u.toLowerCase().replace(/\s+/g," ");if(r.has(l))continue;r.add(l);let d="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(u)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(u)?d="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?d="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?d="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?d="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?d="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?d="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(d="file");let p=Zi(u,d);if(p<.3)continue;let f=rr(u);n.push({category:d,text:f,importance:p,sourceSessionId:t})}}let s=Y(),o=Zn(s);return n.sort((i,a)=>a.importance-i.importance).slice(0,o)}function ta(e){let t=Y(),n=er(t),o=e.join(`
18
+ `,a=we(this.eventsFile,"a",384);try{Vn(a,i),Lt(a)}finally{ve(a)}try{Fn(this.identity.projectRoot,o)}catch{try{_t(this.identity.projectRoot)}catch{}}let c=o[o.length-1],u=qn(c),l=Array.from(r).slice(-zn);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:l}),o})}readPending(){return this.withLock(()=>{let t=this.recoverStateUnsafe();if(!Ze(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=$t(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=we(this.eventsFile,"r");try{bi(i,o,0,s,r)}finally{ve(i)}let a=[];for(let c of o.toString("utf8").split(/\r?\n/)){let u=Wt(c);u&&a.push(u)}return{events:a,startOffset:r,endOffset:n}})}markRemote(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe(),s=new Date().toISOString();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,t),remoteByteOffset:Math.max(r.remoteByteOffset,n),lastRemoteAt:s,updatedAt:s})})}setSourceCursor(t,n){this.withLock(()=>{let r=this.recoverStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[t]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as jc,existsSync as Mc,openSync as Ic,readSync as Cc,statSync as Pc}from"node:fs";var Oi=new Set(["rule","blocker","architecture","deploy"]),Ti=new Set(["fix","todo","context","next_action"]);function Ft(e){return e<0?0:e>1?1:e}function Bn(e,t){let n=Number.parseFloat(e??"");return Number.isFinite(n)?n:t}function Ri(e){return e==="off"?"off":e==="balanced"?"balanced":e==="aggressive"?"aggressive":"conservative"}function Dt(){return{mode:Ri(process.env.TOOLNET_MEMORY_PROMOTION),minScore:Ft(Bn(process.env.TOOLNET_PROMOTE_MIN_SCORE,.65)),minConfidence:Ft(Bn(process.env.TOOLNET_PROMOTE_MIN_CONFIDENCE,.78))}}function Ni(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function _i(e){let t=Ft(Ni(e.importance)*.75+e.confidence*.25);return Math.round(t*1e6)/1e6}function $i(e){return e.evidence?e.evidence:{userExplicit:!1,sourceVerified:!1,testVerified:!1,crossSessionConfirmations:0,assistantDerived:!1}}function Ki(e,t=Dt()){if(e.importance==="temporary"||e.confidence<t.minConfidence)return"transient";let n=$i(e);return e.kind==="rule"&&n.userExplicit?"permanent":e.kind==="rule"?"session":e.kind==="architecture"&&(n.userExplicit||n.sourceVerified||n.testVerified||n.crossSessionConfirmations>=2)?"permanent":e.kind==="architecture"?"session":e.kind==="decision"||e.kind==="todo"||e.kind==="fix"?"task":"session"}function Li(e,t=Dt()){if(t.mode==="off")return Number.POSITIVE_INFINITY;let n=0;t.mode==="balanced"&&(n=.1),t.mode==="aggressive"&&(n=.15);let r=Math.max(t.mode==="aggressive"?.5:.55,t.minScore-n);return Oi.has(e)&&(r=Math.max(.5,r-.1)),Ti.has(e)&&(r=Math.max(.5,r-.05)),r}function zt(e,t=Dt()){let n=Ki(e,t),r=_i(e),s=Li(e.kind,t);return n==="transient"?{knowledgeClass:n,score:r,threshold:s,persist:!1}:t.mode==="off"?{knowledgeClass:n,score:r,threshold:s,persist:!1}:{knowledgeClass:n,score:r,threshold:s,persist:r>=s}}function Hn(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 Xn=[/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],Wi=[/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],Fi=[/\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],Di=[/\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],zi=[/đã 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],Gn=[/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],qi=[/\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],Ji=[/đườ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],Vi=[/\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],Un=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Bi=new Set(["payload","data","content","message","messages","parts","summary"]);function R(e,t){return t.some(n=>n.test(e))}function Zn(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Hi(e){return Zn(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Gi(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 qt(e,t,n,r=0){if(!(r>6)&&!(typeof e=="string"&&t&&!Un.has(t))){if(typeof e=="string"){n.push(e);return}if(Array.isArray(e)){for(let s of e.slice(0,50))qt(s,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[s,o]of Object.entries(e))(Un.has(s)||Bi.has(s))&&qt(o,s,n,r+1)}}function Ui(e){let t=[];qt(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=Zn(o);if(Gi(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function Yn(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function Yi(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&&R(e,Xn)?{kind:"rule",confidence:.98}:r&&R(e,Wi)?{kind:"rule",confidence:.92}:R(e,Fi)?{kind:R(e,Gn)?"architecture":"decision",confidence:r?.93:.86}:r&&R(e,Di)?{kind:"todo",confidence:.87}:R(e,Gn)&&R(e,qi)?{kind:"architecture",confidence:r?.88:.82}:s&&R(e,zi)?{kind:"fix",confidence:.8}:r&&R(e,Ji)&&R(e,Vi)?{kind:"context",confidence:.79}:null}function Xi(e,t,n){let r=t==="user"||n.type==="user_prompt",s=t==="assistant"||n.type==="assistant_message",o=!!n.provenance.sourcePath&&(e==="architecture"||e==="context"||e==="fix"),i=e==="fix"&&/(?:test|tests|pass|passed|passing)/iu.test(JSON.stringify(n.data));return{userExplicit:r,sourceVerified:o,testVerified:i,crossSessionConfirmations:1,assistantDerived:s}}function Zi(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Qi(e,t,n){return e==="rule"&&R(n,Xn)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":Hn(t,n)}function Qn(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,a=Yn(o);i&&a&&s.set(i,a)}for(let o of t){let i=Yn(o),a=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&a&&(i=s.get(a)??"");for(let c of Ui(o)){let u=Yi(c,i,o);if(!u||u.confidence<.75)continue;let l=Zi(u.kind),d=Hi(c),p=w([e.projectId,u.kind,d].join("|"));if(r.has(p))continue;r.add(p);let f=o.provenance.sourcePath?[o.provenance.sourcePath]:[],m=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:l,content:c,confidence:u.confidence,importance:Qi(u.kind,l,c),evidence:Xi(u.kind,i,o),tags:[l],provenance:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventIds:[o.id],sourceEventIds:m,sourcePaths:f,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}import{createHash as ea}from"node:crypto";var ta=["project-knowledge","implementation","continuation","session-context"],na={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function Jt(e){return ea("sha256").update(e).digest("hex")}function et(e,t){return`${e}:${Jt(t).slice(0,24)}`}function ra(e){try{return Jt(JSON.stringify(e))}catch{return Jt(String(e))}}function Y(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 tr(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 sa(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function er(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function oa(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=>tr(t.content)).join(" | ")}function ia(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=>tr(t.content)).join(`
19
+ `)}function nr(e,t){let n=e.slice().sort((p,f)=>p.sequence-f.sequence||p.timestamp.localeCompare(f.timestamp)||p.id.localeCompare(f.id)),r=n.map(p=>({id:et("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:ra(p.data)})),s=new Map,o=new Map;n.forEach((p,f)=>{let m=r[f];m&&(s.set(p.id,m.id),p.sourceEventId&&o.set(p.sourceEventId,m.id))});let i=t.map(p=>{let f=Y([...p.provenance.eventIds.map(m=>s.get(m)),...p.provenance.sourceEventIds.map(m=>o.get(m))]);return{id:et("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:Y([...p.tags,"level:fact",`class:${p.knowledgeClass}`,`kind:${p.kind}`]),rawIds:f,sourcePaths:Y(p.provenance.sourcePaths)}}),a=new Map;for(let p of i){let f=sa(p.kind),m=a.get(f)??[];m.push(p),a.set(f,m)}let c=[];for(let p of ta){let f=a.get(p);if(!f?.length)continue;let m=f.slice().sort((g,h)=>h.importanceScore-g.importanceScore||h.confidence-g.confidence||g.id.localeCompare(h.id)),S=m.map(g=>g.id);c.push({id:et("scene",`${p}|${S.join("|")}`),level:"scene",kind:p,title:na[p],summary:oa(m),factIds:S,importanceScore:Math.max(...m.map(g=>g.importanceScore)),confidence:er(m.map(g=>g.confidence)),tags:Y(["level:scene",`scene:${p}`,...m.flatMap(g=>g.tags)]),sourcePaths:Y(m.flatMap(g=>g.sourcePaths))})}let u=new Map(i.map(p=>[p.id,p])),l=[];for(let p of c){let m=p.factIds.map(h=>u.get(h)).filter(h=>!!h).filter(h=>(h.knowledgeClass==="permanent"||h.knowledgeClass==="task")&&h.importanceScore>=.55);if(m.length===0)continue;let S=m.some(h=>h.knowledgeClass==="permanent")?"permanent":"task",g=ia(m);l.push({id:et("knowledge",`${p.id}|${S}|${m.map(h=>h.id).join("|")}`),level:"knowledge",knowledgeClass:S,title:p.title,content:g,sceneIds:[p.id],factIds:m.map(h=>h.id),importanceScore:Math.max(...m.map(h=>h.importanceScore)),confidence:er(m.map(h=>h.confidence)),tags:Y(["level:knowledge",`class:${S}`,`scene:${p.kind}`,...m.flatMap(h=>h.tags)]),sourcePaths:Y(m.flatMap(h=>h.sourcePaths))})}let d=[];for(let p of i)for(let f of p.rawIds)d.push({from:f,to:p.id,type:"supports"});for(let p of c)for(let f of p.factIds)d.push({from:f,to:p.id,type:"belongs_to"});for(let p of l)for(let f of p.sceneIds)d.push({from:f,to:p.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:l,links:d,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:l.length,links:d.length}}}function aa(e){return e?Math.ceil(e.length/3.5):0}function rr(e,t){if(!e)return"";if(aa(e)<=t)return e;let r=Math.floor(t*3.5),s=e.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
20
+ `),a=Math.max(o,i);return a>r*.7?s.slice(0,a+1):s}function X(){let e=We(),t=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||t==="archive"||t==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",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),a=n,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function sr(e){return(e||X()).rawTranscript}function or(e){return(e||X()).durableMemoryMaxItemsPerSession}function ir(e){return(e||X()).sessionSummaryMaxTokens}function ar(e){return(e||X()).archiveRemote}var cr=new J;function ur(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(cr.sanitizeValue(r))}catch{}let n=cr.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 ca(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 ua(e,t){let n=[],r=new Set;for(let i of e){let a=i.split(`
21
+ `).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let l=u.toLowerCase().replace(/\s+/g," ");if(r.has(l))continue;r.add(l);let d="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(u)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(u)?d="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?d="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?d="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?d="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?d="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?d="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(d="file");let p=ca(u,d);if(p<.3)continue;let f=ur(u);n.push({category:d,text:f,importance:p,sourceSessionId:t})}}let s=X(),o=or(s);return n.sort((i,a)=>a.importance-i.importance).slice(0,o)}function la(e){let t=X(),n=ir(t),o=e.join(`
22
22
 
23
23
  `).split(`
24
- `).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>rr(i)).join(`
25
- `);return Xn(o,n)}function Xe(e,t){let r=(Array.isArray(e)?e:e.split(`
24
+ `).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>ur(i)).join(`
25
+ `);return rr(o,n)}function tt(e,t){let r=(Array.isArray(e)?e:e.split(`
26
26
 
27
- `).filter(f=>f.trim())).map(f=>typeof f=="string"?f:JSON.stringify(f)).filter(f=>f.trim()),s=ea(r,t),o=s.filter(f=>f.category==="decision").map(f=>f.text),i=s.filter(f=>f.category==="rule").map(f=>f.text),a=s.filter(f=>f.category==="file").map(f=>f.text),c=s.filter(f=>f.category==="fix").map(f=>f.text),u=s.filter(f=>f.category==="blocker").map(f=>f.text),l=s.filter(f=>f.category==="next_action").map(f=>f.text),d=s.filter(f=>f.category==="deploy").map(f=>f.text);return{summary:ta(r),decisions:o,projectRules:i,filesChanged:a,bugsFixed:c,commands:d,blockers:u,nextActions:l,durableFacts:s}}function J(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 ra(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 sa(e){let t=Wt(e);return{...e,knowledgeClass:t.knowledgeClass,importanceScore:t.score,retrievalTerms:ra(e.content),tags:J([...e.tags,"level:fact",`class:${t.knowledgeClass}`,`kind:${e.kind}`])}}function oa(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 ia(e,t,n){let r=Xe(oa(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),a=J([...s,...r.nextActions]),c=J([...r.nextActions,...s]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:J(r.decisions),files:J([...r.filesChanged,...o]),todos:a,completed:J(r.bugsFixed),blockers:J(r.blockers),nextActions:c,architecture:J(i)}}}function Qe(e,t){let n=na(t),r=Hn(e,n).map(sa),s=r.filter(l=>Wt(l).persist).sort((l,d)=>d.importanceScore-l.importanceScore),{summary:o,state:i}=ia(e,n,s),a=s.map(l=>({fingerprint:l.fingerprint,kind:l.kind,knowledgeClass:l.knowledgeClass,importanceScore:l.importanceScore,content:l.content,terms:l.retrievalTerms})),c=Yn(n,s),u=l=>r.filter(d=>d.knowledgeClass===l).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:a,hierarchy:c,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")}}}import{createHash as aa}from"node:crypto";import{chmodSync as sr,existsSync as ca,mkdirSync as ua,readFileSync as la,renameSync as da,writeFileSync as or}from"node:fs";import{dirname as ir,join as Ze}from"node:path";var Jt="toolnet.context-offload.v1",pa="toolnet.context-offload-asset.v1",fa=256,ma=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function ar(e){return Ze(e,".toolnet","offload")}function ga(e){return Ze(ar(e),"assets")}function cr(e){return Ze(ar(e),"graph.json")}function ur(e){ua(e,{recursive:!0,mode:448});try{sr(e,448)}catch{}}function ya(e,t){ur(ir(e));let n=`${e}.${process.pid}.${Date.now()}.tmp`;or(n,t,{encoding:"utf8",mode:384}),da(n,e);try{sr(e,384)}catch{}}function qt(e){return Array.isArray(e)?e.map(qt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,qt(n)])):e}function ha(e){return aa("sha256").update(JSON.stringify(qt(e)),"utf8").digest("hex")}function zt(){return{schema:Jt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Sa(e){let t=cr(e);if(!ca(t))return zt();try{let n=JSON.parse(la(t,"utf8"));return n.schema!==Jt||n.version!==1||!Array.isArray(n.nodes)?zt():n}catch{return zt()}}function ka(e,t){ya(cr(e),JSON.stringify(t,null,2)+`
28
- `)}function va(e,t=260){if(typeof e!="string")return null;let n=e.replace(/\s+/gu," ").trim();return n?n.slice(0,t):null}function wa(e){let t=[...e.provenance.files??[],e.provenance.sourcePath],n=[];for(let r of t){let s=va(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function ba(e){return`${e.agent}:${e.sourceEventId??e.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function xa(e,t){ur(ir(e));try{return or(e,t,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function Aa(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:Jt,version:1,updatedAt:new Date().toISOString(),nodes:[...e.nodes.filter(s=>s.id!==t.id),r].slice(-fa)}}function lr(e,t){let n=Sa(e),r=0,s=0,o=0,i=[];for(let a of t){if(!ma.has(a.type))continue;r+=1;let c=ha({type:a.type,data:a.data}),u={schema:pa,version:1,assetId:c,event:{type:a.type,agent:a.agent,nativeSessionId:a.nativeSessionId,timestamp:a.timestamp,sourceEventId:a.sourceEventId,provenance:a.provenance,data:a.data}},l=JSON.stringify(u,null,2)+`
29
- `;xa(Ze(ga(e),`${c}.json`),l)?s+=1:o+=1,i.push(c),n=Aa(n,{id:c,kind:a.type,bytes:Buffer.byteLength(l,"utf8"),createdAt:a.timestamp,sourceRefs:[ba(a)],files:wa(a)})}return r>0&&ka(e,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}import{createHash as Ta}from"node:crypto";import{existsSync as Ra,readdirSync as Na,readFileSync as _a}from"node:fs";import{basename as $a,join as Ir}from"node:path";import{randomUUID as fr}from"node:crypto";var A=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};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 Q(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 dr(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(Q(r))}return ve(t)}function ja(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function pr(e){return{id:`revision-${fr()}`,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 X(e){return structuredClone(e)}var et=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:ve(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 X([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=Q(t),s=n.pages.find(o=>o.slug===r||o.id===t);if(!s)throw new A(`Wiki page not found: ${t}`,404);return X(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=Q(t.slug??r);if(n.pages.some(c=>c.slug===o))throw new A(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${fr()}`,slug:o,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:s,tags:ve(t.tags??[]),links:dr(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(pr(a)),X(a)})}async updatePage(t,n){return this.mutate(r=>{let s=Q(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=dr(o.content)),n.tags!==void 0&&(o.tags=ve(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(pr(o)),X(o)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return X(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 X(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=ve(ja(t));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),l=a.summary?.toLowerCase()??"",d=a.content.toLowerCase(),p=a.tags.map(g=>g.toLowerCase()),f=0;for(let g of s)u===g&&(f+=12),c===g&&(f+=10),c.includes(g)&&(f+=6),u.includes(g)&&(f+=5),p.some(S=>S===g)?f+=5:p.some(S=>S.includes(g))&&(f+=3),l.includes(g)&&(f+=2),d.includes(g)&&(f+=1);f>0&&i.push({page:X(a),score:f})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var mr="wiki/state.v1.json";function Ma(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function Ia(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 tt=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(mr);if(!t){let n=Ma(this.project);return await this.save(n),n}return Ia(t,this.project)}async save(t){await this.storage.put(mr,JSON.stringify(t,null,2),"application/json")}};import{createHash as Ca,randomUUID as gr}from"node:crypto";var yr="wiki/governance.v1.json",vr="toolnet.knowledge-governance.v1",hr=500,we={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Pa(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function Vt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Sr(e){return Ca("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Ea(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 Oa(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),Pa(t)}function kr(e){let t=new Date().toISOString();return{schema:vr,version:1,projectId:e,policy:{...we},reviews:[],audit:[],createdAt:t,updatedAt:t}}function wr(e){let t=e.autoApproveThreshold??we.autoApproveThreshold,n=e.criticalApproveThreshold??we.criticalApproveThreshold,r=e.staleAfterDays??we.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 nt=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(yr);if(!t){let n=kr(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==vr||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:wr(n.policy??we)}}catch{let n=kr(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(yr,JSON.stringify(t,null,2),"application/json")}},rt=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:gr(),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>hr&&(t.audit=t.audit.slice(-hr))}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=wr({...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=Oa(t),o=Vt(t.title),i=n.filter(l=>l.slug!==t.slug&&Vt(l.title)===o&&Sr(l.content)!==Sr(t.content)).map(l=>l.slug),a=Ea(t),c=[];s<r.policy.autoApproveThreshold&&c.push(`confidence:${s.toFixed(2)}`),a&&s<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||a&&s<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(s=>{let o=s.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(o?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(o)};if(o?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(o)};if(!r.requiresReview)return this.audit(s,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(o?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(o)};let i=new Date().toISOString(),a={id:gr(),sourceKey:t.sourceKey,sourceType:t.sourceType,slug:t.slug,marker:t.marker,digest:t.digest,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...new Set([...t.tags,t.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return s.reviews.push(a),this.audit(s,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(t,n){await this.mutate(r=>{let s=r.reviews.find(o=>o.sourceKey===t&&o.digest===n&&o.status==="approved");s&&(s.appliedAt=new Date().toISOString(),s.updatedAt=s.appliedAt,this.audit(r,"knowledge:applied",s.reviewedBy??"system",{reviewId:s.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async s=>{let o=s.reviews.find(u=>u.id===t);if(!o)throw new A(`Governance review not found: ${t}`,404);if(o.status!=="pending")throw new A("Governance review is already resolved",409);let i=new Date().toISOString();if(o.reviewedAt=i,o.reviewedBy=n.principal,o.updatedAt=i,n.note?.trim()&&(o.reviewNote=n.note.trim()),n.action==="reject")return o.status="rejected",this.audit(s,"knowledge:rejected",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o);if(n.action==="supersede")return o.status="superseded",n.targetReviewId&&(o.supersededBy=n.targetReviewId),this.audit(s,"knowledge:superseded",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(o);if(n.action==="merge"){if(!n.targetReviewId)throw new A("targetReviewId is required for merge",400);let u=s.reviews.find(l=>l.id===n.targetReviewId);if(!u)throw new A("Merge target review not found",404);return o.status="superseded",o.mergedInto=u.id,this.audit(s,"knowledge:merged",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let c=(await r.listPages()).find(u=>u.slug===o.slug);if(c&&!c.tags.includes(o.marker))throw new A(`Wiki page '${o.slug}' is manually managed`,409);return c?await r.updatePage(o.slug,{title:o.title,summary:o.summary??"",content:o.content,tags:o.tags}):await r.createPage({slug:o.slug,title:o.title,...o.summary?{summary:o.summary}:{},content:o.content,tags:o.tags}),o.appliedAt=i,this.audit(s,"knowledge:approved",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),s=Date.now(),o=n.policy.staleAfterDays*864e5,i=r.map(l=>{let d=s-Date.parse(l.updatedAt);return{slug:l.slug,title:l.title,updatedAt:l.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>o}}).filter(l=>l.stale).map(({stale:l,...d})=>d),a=new Map;for(let l of r){let d=Vt(l.title),p=a.get(d)??[];p.push(l),a.set(d,p)}let c=[...a.entries()].filter(([,l])=>l.length>1).map(([l,d])=>({title:l,pages:d.map(p=>p.slug)})),u=n.reviews.filter(l=>l.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(l=>l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,manualPages:r.filter(l=>!l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(l=>l.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(l=>l.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Cr="wiki/automation.v1.json",Pr="toolnet.wiki-automation.v1",Gt=8e3,br=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function xe(e){return Ta("sha256").update(JSON.stringify(e)).digest("hex")}function be(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function xr(e){return Array.isArray(e)?e:[]}function Er(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function Bt(e){return Array.isArray(e)?e.map(Er).filter(t=>!!t):[]}function _(e,t){for(let n of t){let r=Er(e[n]);if(r)return r}}function Ae(e){let t=new Set,n=[];for(let r of e){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function st(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(br.has(r))return[];if(typeof e=="string"){let i=e.replace(/\s+/gu," ").trim();return i.length<8?[]:[i]}if(Array.isArray(e))return e.flatMap(i=>st(i,t+1,n));let s=be(e);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();br.has(c)||o.push(...st(a,t+1,i))}return o}function Ar(e){let n=Ae(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>st(e[s],0,s)));return(n.length>0?n:Ae(st(e))).join(`
27
+ `).filter(f=>f.trim())).map(f=>typeof f=="string"?f:JSON.stringify(f)).filter(f=>f.trim()),s=ua(r,t),o=s.filter(f=>f.category==="decision").map(f=>f.text),i=s.filter(f=>f.category==="rule").map(f=>f.text),a=s.filter(f=>f.category==="file").map(f=>f.text),c=s.filter(f=>f.category==="fix").map(f=>f.text),u=s.filter(f=>f.category==="blocker").map(f=>f.text),l=s.filter(f=>f.category==="next_action").map(f=>f.text),d=s.filter(f=>f.category==="deploy").map(f=>f.text);return{summary:la(r),decisions:o,projectRules:i,filesChanged:a,bugsFixed:c,commands:d,blockers:u,nextActions:l,durableFacts:s}}function B(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 da(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 pa(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=zt(e);return{...e,knowledgeClass:t.knowledgeClass,importanceScore:t.score,retrievalTerms:pa(e.content),tags:B([...e.tags,"level:fact",`class:${t.knowledgeClass}`,`kind:${e.kind}`])}}function ma(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 ga(e,t,n){let r=tt(ma(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),a=B([...s,...r.nextActions]),c=B([...r.nextActions,...s]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:B(r.decisions),files:B([...r.filesChanged,...o]),todos:a,completed:B(r.bugsFixed),blockers:B(r.blockers),nextActions:c,architecture:B(i)}}}function nt(e,t){let n=da(t),r=Qn(e,n).map(fa),s=r.filter(l=>zt(l).persist).sort((l,d)=>d.importanceScore-l.importanceScore),{summary:o,state:i}=ga(e,n,s),a=s.map(l=>({fingerprint:l.fingerprint,kind:l.kind,knowledgeClass:l.knowledgeClass,importanceScore:l.importanceScore,content:l.content,terms:l.retrievalTerms})),c=nr(n,s),u=l=>r.filter(d=>d.knowledgeClass===l).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:a,hierarchy:c,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")}}}import{createHash as ya}from"node:crypto";import{chmodSync as lr,existsSync as ha,mkdirSync as Sa,readFileSync as ka,renameSync as va,writeFileSync as dr}from"node:fs";import{dirname as pr,join as rt}from"node:path";var Ht="toolnet.context-offload.v1",wa="toolnet.context-offload-asset.v1",ba=256,xa=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function fr(e){return rt(e,".toolnet","offload")}function Aa(e){return rt(fr(e),"assets")}function mr(e){return rt(fr(e),"graph.json")}function gr(e){Sa(e,{recursive:!0,mode:448});try{lr(e,448)}catch{}}function ja(e,t){gr(pr(e));let n=`${e}.${process.pid}.${Date.now()}.tmp`;dr(n,t,{encoding:"utf8",mode:384}),va(n,e);try{lr(e,384)}catch{}}function Bt(e){return Array.isArray(e)?e.map(Bt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,Bt(n)])):e}function Ma(e){return ya("sha256").update(JSON.stringify(Bt(e)),"utf8").digest("hex")}function Vt(){return{schema:Ht,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Ia(e){let t=mr(e);if(!ha(t))return Vt();try{let n=JSON.parse(ka(t,"utf8"));return n.schema!==Ht||n.version!==1||!Array.isArray(n.nodes)?Vt():n}catch{return Vt()}}function Ca(e,t){ja(mr(e),JSON.stringify(t,null,2)+`
28
+ `)}function Pa(e,t=260){if(typeof e!="string")return null;let n=e.replace(/\s+/gu," ").trim();return n?n.slice(0,t):null}function Ea(e){let t=[...e.provenance.files??[],e.provenance.sourcePath],n=[];for(let r of t){let s=Pa(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function Oa(e){return`${e.agent}:${e.sourceEventId??e.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function Ta(e,t){gr(pr(e));try{return dr(e,t,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function Ra(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:Ht,version:1,updatedAt:new Date().toISOString(),nodes:[...e.nodes.filter(s=>s.id!==t.id),r].slice(-ba)}}function yr(e,t){let n=Ia(e),r=0,s=0,o=0,i=[];for(let a of t){if(!xa.has(a.type))continue;r+=1;let c=Ma({type:a.type,data:a.data}),u={schema:wa,version:1,assetId:c,event:{type:a.type,agent:a.agent,nativeSessionId:a.nativeSessionId,timestamp:a.timestamp,sourceEventId:a.sourceEventId,provenance:a.provenance,data:a.data}},l=JSON.stringify(u,null,2)+`
29
+ `;Ta(rt(Aa(e),`${c}.json`),l)?s+=1:o+=1,i.push(c),n=Ra(n,{id:c,kind:a.type,bytes:Buffer.byteLength(l,"utf8"),createdAt:a.timestamp,sourceRefs:[Oa(a)],files:Ea(a)})}return r>0&&Ca(e,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}import{createHash as Da}from"node:crypto";import{existsSync as za,readdirSync as qa,readFileSync as Ja}from"node:fs";import{basename as Va,join as Rr}from"node:path";import{randomUUID as kr}from"node:crypto";var j=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function be(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 Q(e){let t=e.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!t)throw new j("Invalid Wiki slug",400);return t}function hr(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(Q(r))}return be(t)}function Na(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function Sr(e){return{id:`revision-${kr()}`,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 Z(e){return structuredClone(e)}var st=class{constructor(t){this.store=t}store;state;queue=Promise.resolve();async initialize(){await this.ensureState()}async ensureState(){return this.state||(this.state=await this.store.load()),this.state}async mutate(t){let n,r=this.queue.then(async()=>{let 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:be(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 Z([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=Q(t),s=n.pages.find(o=>o.slug===r||o.id===t);if(!s)throw new j(`Wiki page not found: ${t}`,404);return Z(s)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),s=t.content.trim();if(!r)throw new j("Wiki title is required",400);let o=Q(t.slug??r);if(n.pages.some(c=>c.slug===o))throw new j(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${kr()}`,slug:o,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:s,tags:be(t.tags??[]),links:hr(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(Sr(a)),Z(a)})}async updatePage(t,n){return this.mutate(r=>{let s=Q(t),o=r.pages.find(i=>i.slug===s||i.id===t);if(!o)throw new j(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new j("Wiki title is required",400);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=hr(o.content)),n.tags!==void 0&&(o.tags=be(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(Sr(o)),Z(o)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return Z(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 Z(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=be(Na(t));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),l=a.summary?.toLowerCase()??"",d=a.content.toLowerCase(),p=a.tags.map(m=>m.toLowerCase()),f=0;for(let m of s)u===m&&(f+=12),c===m&&(f+=10),c.includes(m)&&(f+=6),u.includes(m)&&(f+=5),p.some(S=>S===m)?f+=5:p.some(S=>S.includes(m))&&(f+=3),l.includes(m)&&(f+=2),d.includes(m)&&(f+=1);f>0&&i.push({page:Z(a),score:f})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var vr="wiki/state.v1.json";function _a(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function $a(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 ot=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(vr);if(!t){let n=_a(this.project);return await this.save(n),n}return $a(t,this.project)}async save(t){await this.storage.put(vr,JSON.stringify(t,null,2),"application/json")}};import{createHash as Ka,randomUUID as wr}from"node:crypto";var br="wiki/governance.v1.json",Mr="toolnet.knowledge-governance.v1",xr=500,xe={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function La(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function Gt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function Ar(e){return Ka("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Wa(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 Fa(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),La(t)}function jr(e){let t=new Date().toISOString();return{schema:Mr,version:1,projectId:e,policy:{...xe},reviews:[],audit:[],createdAt:t,updatedAt:t}}function Ir(e){let t=e.autoApproveThreshold??xe.autoApproveThreshold,n=e.criticalApproveThreshold??xe.criticalApproveThreshold,r=e.staleAfterDays??xe.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new j("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new j("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new j("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var it=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(br);if(!t){let n=jr(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==Mr||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:Ir(n.policy??xe)}}catch{let n=jr(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(br,JSON.stringify(t,null,2),"application/json")}},at=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:wr(),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>xr&&(t.audit=t.audit.slice(-xr))}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=Ir({...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=Fa(t),o=Gt(t.title),i=n.filter(l=>l.slug!==t.slug&&Gt(l.title)===o&&Ar(l.content)!==Ar(t.content)).map(l=>l.slug),a=Wa(t),c=[];s<r.policy.autoApproveThreshold&&c.push(`confidence:${s.toFixed(2)}`),a&&s<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||a&&s<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(s=>{let o=s.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(o?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(o)};if(o?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(o)};if(!r.requiresReview)return this.audit(s,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(o?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(o)};let i=new Date().toISOString(),a={id:wr(),sourceKey:t.sourceKey,sourceType:t.sourceType,slug:t.slug,marker:t.marker,digest:t.digest,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...new Set([...t.tags,t.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return s.reviews.push(a),this.audit(s,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(t,n){await this.mutate(r=>{let s=r.reviews.find(o=>o.sourceKey===t&&o.digest===n&&o.status==="approved");s&&(s.appliedAt=new Date().toISOString(),s.updatedAt=s.appliedAt,this.audit(r,"knowledge:applied",s.reviewedBy??"system",{reviewId:s.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async s=>{let o=s.reviews.find(u=>u.id===t);if(!o)throw new j(`Governance review not found: ${t}`,404);if(o.status!=="pending")throw new j("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 j("targetReviewId is required for merge",400);let u=s.reviews.find(l=>l.id===n.targetReviewId);if(!u)throw new j("Merge target review not found",404);return o.status="superseded",o.mergedInto=u.id,this.audit(s,"knowledge:merged",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let c=(await r.listPages()).find(u=>u.slug===o.slug);if(c&&!c.tags.includes(o.marker))throw new j(`Wiki page '${o.slug}' is manually managed`,409);return c?await r.updatePage(o.slug,{title:o.title,summary:o.summary??"",content:o.content,tags:o.tags}):await r.createPage({slug:o.slug,title:o.title,...o.summary?{summary:o.summary}:{},content:o.content,tags:o.tags}),o.appliedAt=i,this.audit(s,"knowledge:approved",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),s=Date.now(),o=n.policy.staleAfterDays*864e5,i=r.map(l=>{let d=s-Date.parse(l.updatedAt);return{slug:l.slug,title:l.title,updatedAt:l.updatedAt,ageDays:Math.max(0,Math.floor(d/864e5)),stale:Number.isFinite(d)&&d>o}}).filter(l=>l.stale).map(({stale:l,...d})=>d),a=new Map;for(let l of r){let d=Gt(l.title),p=a.get(d)??[];p.push(l),a.set(d,p)}let c=[...a.entries()].filter(([,l])=>l.length>1).map(([l,d])=>({title:l,pages:d.map(p=>p.slug)})),u=n.reviews.filter(l=>l.status==="pending");return{schema:"toolnet.knowledge-quality.v1",totalPages:r.length,automatedPages:r.filter(l=>l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,manualPages:r.filter(l=>!l.tags.some(d=>d.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,pendingReviews:u.length,lowConfidenceReviews:u.filter(l=>l.confidence<n.policy.autoApproveThreshold).length,conflicts:u.filter(l=>l.risk==="conflict").length,generatedAt:new Date().toISOString()}}};var Nr="wiki/automation.v1.json",_r="toolnet.wiki-automation.v1",Xt=8e3,Cr=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function je(e){return Da("sha256").update(JSON.stringify(e)).digest("hex")}function Ae(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function Pr(e){return Array.isArray(e)?e:[]}function $r(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function Ut(e){return Array.isArray(e)?e.map($r).filter(t=>!!t):[]}function $(e,t){for(let n of t){let r=$r(e[n]);if(r)return r}}function Me(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 ct(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(Cr.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=>ct(i,t+1,n));let s=Ae(e);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();Cr.has(c)||o.push(...ct(a,t+1,i))}return o}function Er(e){let n=Me(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>ct(e[s],0,s)));return(n.length>0?n:Me(ct(e))).join(`
30
30
 
31
- `).slice(0,Gt)}function jr(e,t){return _(e,["id","key","fingerprint","knowledgeId","sceneId"])??t}function Mr(e,t){return _(e,["title","name","topic","label","task","kind","type"])??t}function Ka(e){return(_(e,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function La(e){return(_(e,["kind","sceneKind","type"])??"").toLowerCase()}function Wa(e){let t=be(e);if(!t)return[];let n=[],r=xr(t.knowledge);for(let[o,i]of r.entries()){let a=be(i);if(!a)continue;let c=Ka(a);if(c==="session"||c==="transient")continue;let u=Ar(a);if(u.length<20)continue;let l=jr(a,xe(a).slice(0,16)),d=Mr(a,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${l}`,sourceType:"memory",title:d,summary:_(a,["summary","description"]),content:u,tags:Ae(["toolnet","auto","memory",...c?[c]:[]])})}let s=xr(t.scenes);for(let[o,i]of s.entries()){let a=be(i);if(!a)continue;let c=La(a);if(c==="session-context")continue;let u=Ar(a);if(u.length<20)continue;let l=jr(a,xe(a).slice(0,16)),d=Mr(a,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${l}`,sourceType:"scene",title:d,summary:_(a,["summary","description"]),content:u,tags:Ae(["toolnet","auto","scene",...c?[c]:[]])})}return n}function Fa(e){return Ir(e,".toolnet","memory","skills")}function Da(e){let t=Fa(e);if(!Ra(t))return{candidates:[],failed:0};let n=[],r=0,s=Na(t).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(_a(Ir(t,o),"utf8")),a=be(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=_(a,["id","fingerprint"])??$a(o,".json"),u=_(a,["task"])??"",l=_(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,d=_(a,["summary"])??void 0,p=Bt(a.steps),f=Bt(a.verification),g=Bt(a.files),S=[];u&&S.push(`## Task
31
+ `).slice(0,Xt)}function Or(e,t){return $(e,["id","key","fingerprint","knowledgeId","sceneId"])??t}function Tr(e,t){return $(e,["title","name","topic","label","task","kind","type"])??t}function Ba(e){return($(e,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function Ha(e){return($(e,["kind","sceneKind","type"])??"").toLowerCase()}function Ga(e){let t=Ae(e);if(!t)return[];let n=[],r=Pr(t.knowledge);for(let[o,i]of r.entries()){let a=Ae(i);if(!a)continue;let c=Ba(a);if(c==="session"||c==="transient")continue;let u=Er(a);if(u.length<20)continue;let l=Or(a,je(a).slice(0,16)),d=Tr(a,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${l}`,sourceType:"memory",title:d,summary:$(a,["summary","description"]),content:u,tags:Me(["toolnet","auto","memory",...c?[c]:[]])})}let s=Pr(t.scenes);for(let[o,i]of s.entries()){let a=Ae(i);if(!a)continue;let c=Ha(a);if(c==="session-context")continue;let u=Er(a);if(u.length<20)continue;let l=Or(a,je(a).slice(0,16)),d=Tr(a,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${l}`,sourceType:"scene",title:d,summary:$(a,["summary","description"]),content:u,tags:Me(["toolnet","auto","scene",...c?[c]:[]])})}return n}function Ua(e){return Rr(e,".toolnet","memory","skills")}function Ya(e){let t=Ua(e);if(!za(t))return{candidates:[],failed:0};let n=[],r=0,s=qa(t).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(Ja(Rr(t,o),"utf8")),a=Ae(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=$(a,["id","fingerprint"])??Va(o,".json"),u=$(a,["task"])??"",l=$(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,d=$(a,["summary"])??void 0,p=Ut(a.steps),f=Ut(a.verification),m=Ut(a.files),S=[];u&&S.push(`## Task
32
32
  ${u}`),d&&S.push(`## Summary
33
33
  ${d}`),p.length>0&&S.push(`## Procedure
34
- ${p.map((h,k)=>`${k+1}. ${h}`).join(`
34
+ ${p.map((h,v)=>`${v+1}. ${h}`).join(`
35
35
  `)}`),f.length>0&&S.push(`## Verification
36
36
  ${f.map(h=>`- ${h}`).join(`
37
- `)}`),g.length>0&&S.push(`## Relevant Files
38
- ${g.map(h=>`- \`${h}\``).join(`
39
- `)}`);let y=S.join(`
40
-
41
- `).slice(0,Gt);if(y.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:l,summary:d,content:y,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function Ht(e){let t=new Date().toISOString();return{schema:Pr,version:1,projectId:e,entries:[],createdAt:t,updatedAt:t}}async function za(e,t){let n=await e.getText(Cr);if(!n)return Ht(t);try{let r=JSON.parse(n);return r.schema!==Pr||r.version!==1||r.projectId!==t||!Array.isArray(r.entries)?Ht(t):r}catch{return Ht(t)}}async function qa(e,t){await e.put(Cr,JSON.stringify(t,null,2),"application/json")}function Ja(e){return`toolnet-auto-${xe(e).slice(0,12)}`}function Va(e){let t=Q(e.title).slice(0,72),n=xe(e.sourceKey).slice(0,10);return Q(`auto-${e.sourceType}-${t}-${n}`)}function Ba(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(`
42
- `).slice(0,Gt)}function Ha(e){return xe({sourceType:e.sourceType,title:e.title,summary:e.summary,content:e.content,tags:e.tags})}function Ga(e,t){return e.tags.includes(t)}async function Or(e){let t=Wa(e.hierarchy),n=Da(e.project.rootPath),r=new Map;for(let f of[...t,...n.candidates])r.set(f.sourceKey,f);let s=[...r.values()].sort((f,g)=>f.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 et(new tt(e.storage,e.project));await i.initialize();let a=new rt(new nt(e.storage,e.project));await a.initialize();let c=await za(e.storage,e.project.id),u=await i.listPages(),l=new Map(u.map(f=>[f.slug,f])),d=new Map(c.entries.map(f=>[f.sourceKey,f]));for(let f of s)try{let g=Ja(f.sourceKey),S=Ha(f),y=d.get(f.sourceKey),h=y?.slug??Va(f),k=l.get(h);if(k&&!Ga(k,g)){o.skipped+=1;continue}let C=Ae([...f.tags,g]),P=Ba(f),I=await a.gate({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:h,marker:g,digest:S,title:f.title,...f.summary?{summary:f.summary}:{},content:P,tags:C},[...l.values()]);if(!I.allowed){I.mode==="pending-review"?o.reviewPending+=1:o.skipped+=1;continue}I.mode==="auto-approved"?o.autoApproved+=1:I.mode==="review-approved"&&(o.reviewApproved+=1),k?y?.digest!==S?(k=await i.updatePage(h,{title:f.title,summary:f.summary??"",content:P,tags:C}),l.set(k.slug,k),o.updated+=1,o.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:k.slug,action:"updated"})):(o.unchanged+=1,o.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:h,action:"unchanged"})):(k=await i.createPage({slug:h,title:f.title,summary:f.summary,content:P,tags:C}),l.set(k.slug,k),o.created+=1,o.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:k.slug,action:"created"}));let E=new Date().toISOString(),x={sourceKey:f.sourceKey,sourceType:f.sourceType,slug:h,digest:S,marker:g,updatedAt:E},w=c.entries.findIndex(W=>W.sourceKey===f.sourceKey);w>=0?c.entries[w]=x:c.entries.push(x),d.set(f.sourceKey,x),await a.markApplied(f.sourceKey,S)}catch(g){if(g instanceof A&&g.statusCode===409){o.skipped+=1;continue}o.failed+=1}let p=new Date().toISOString();return c.updatedAt=p,c.lastRunAt=p,c.entries.sort((f,g)=>f.sourceKey.localeCompare(g.sourceKey)),await qa(e.storage,c),o}import{createHash as Ua}from"node:crypto";import{chmodSync as Rr,existsSync as Ya,mkdirSync as Xa,readFileSync as km,readdirSync as vm,renameSync as Qa,statSync as wm,writeFileSync as Za}from"node:fs";import{join as Nr}from"node:path";var ec="toolnet.skill-memory.v1",Tr=5,tc=16,nc=24,rc=32;function sc(e){return Ua("sha256").update(e).digest("hex")}function Me(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 Ut(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 oc(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 D(e,t=360){return e&&Ut(oc(e),t)||void 0}function Ie(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}}function _r(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 $r(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 Kr(e){let t=e.data??{};if($r(t,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=_r(t,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=Ie(t,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function je(e){let t=e.data??{};if(Kr(e))return!1;if($r(t,["passed","pass","success","succeeded","ok"])===!0||_r(t,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=Ie(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 Lr(e){let t=e.data??{},n=Ie(t,["path","file","filePath","filename","target"]);if(n)return D(n,260);let r=e.provenance?.files;return D(r?.[0],260)}function Yt(e){return D(Ie(e.data??{},["command","cmd","script"]),420)}function se(e){return D(Ie(e.data??{},["name","test","suite","title","message","text","result","status"]),300)}function ic(e){let t=[];for(let n of[...e].sort((r,s)=>r.sequence-s.sequence))if(je(n)){if(n.type==="test"){let r=se(n)??Yt(n)??"Tests passed";t.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=se(n);t.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=se(n);t.push(r?`Deploy: ${r}`:"Deployment completed")}}return Me(t,10)}function ac(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=Lr(r);s&&n.push(`Update ${s}`);break}case"command":{if(Kr(r))break;let s=Yt(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!je(r))break;let s=se(r)??Yt(r)??"project tests";n.push(`Verify: ${s}`);break}case"commit":{if(!je(r))break;let s=se(r);n.push(s?`Commit: ${s}`:"Commit verified changes");break}case"deploy":{if(!je(r))break;let s=se(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=D(r,260);s&&n.push(`Update ${s}`)}return Me(n,tc)}function cc(e,t){let n=[...t.files];for(let r of e){let s=Lr(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=D(o,260);i&&n.push(i)}}return Me(n,nc)}function uc(e){return Me(e.filter(t=>["file_write","file_edit","command","test","commit","deploy"].includes(t.type)).map(t=>t.id),rc)}function lc(e){return e.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function Wr(e,t,n){if(t.length===0)return[];let r=ic(t),s=Me(n.completed.map(g=>D(g,280)??""),Tr);if(!(s.length>0||t.some(g=>["test","commit","deploy"].includes(g.type)&&je(g))))return[];let i=D(n.task,280)??D(n.nextActions[0],280),a=s.length>0?s:i?[i]:[];if(a.length===0)return[];let c=ac(t,n);if(c.length===0)return[];let u=cc(t,n),l=uc(t),d=Math.min(...t.map(g=>g.sequence)),p=Math.max(...t.map(g=>g.sequence)),f=lc(t);return a.slice(0,Tr).map(g=>{let S=[`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),y=JSON.stringify({projectId:e.projectId,task:g,steps:c,verification:r,files:u}),h=sc(y);return{schema:ec,version:1,id:`skill-${h.slice(0,24)}`,fingerprint:h,projectId:e.projectId,title:Ut(`SOP: ${g}`,180),task:g,summary:Ut(S.join(" "),900),steps:c,verification:r,files:u,source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:d,lastSequence:p,eventIds:l},createdAt:f}})}function dc(e){return Nr(e.rootPath,".toolnet","memory","skills")}function pc(e){let t=dc(e);return Xa(t,{recursive:!0,mode:448}),Rr(t,448),t}function Fr(e,t){if(t.length===0)return{written:0,deduped:0,files:[]};let n=pc(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 a=Nr(n,`${i.id}.json`);if(o.push(a),Ya(a)){s+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;Za(c,JSON.stringify(i,null,2)+`
43
- `,{encoding:"utf8",mode:384}),Qa(c,a),Rr(a,384),r+=1}return{written:r,deduped:s,files:o}}function Dr(e){return String(e).padStart(12,"0")}function fc(e){return`projects/${e.projectId}/memory/learned`}var ot=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(d=>d.sequence)),o=Math.max(...n.map(d=>d.sequence)),i={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
44
- `,c=v(r.map(d=>d.fingerprint).sort().join("|")).slice(0,16),u=v(t.sessionKey).slice(0,12),l=[fc(t),"batches",`${Dr(s)}-${Dr(o)}-${u}-${c}.json`].join("/");return await this.storage.exists(l)||await this.storage.put(l,a,"application/json"),l}};import{createHash as mc}from"node:crypto";function zr(e){return String(e).padStart(12,"0")}function qr(e){return mc("sha256").update(e).digest("hex")}function gc(e){return`projects/${e.projectId}/memory/hierarchy`}var it=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(l=>l.sequence)),o=Math.max(...n.map(l=>l.sequence)),i={schema:"toolnet.memory-hierarchy-batch.v1",version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,hierarchy:r},a=qr([...r.facts.map(l=>l.id),...r.knowledge.map(l=>l.id)].sort().join("|")).slice(0,16),c=qr(t.sessionKey).slice(0,12),u=[gc(t),"batches",`${zr(s)}-${zr(o)}-${c}-${a}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,`${JSON.stringify(i,null,2)}
45
- `,"application/json"),u}};function wc(e,t){if(!hc(e))return{events:[],nextOffset:t};let n=vc(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=Sc(e,"r");try{kc(i,o,0,s,r)}finally{yc(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
37
+ `)}`),m.length>0&&S.push(`## Relevant Files
38
+ ${m.map(h=>`- \`${h}\``).join(`
39
+ `)}`);let g=S.join(`
40
+
41
+ `).slice(0,Xt);if(g.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:l,summary:d,content:g,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function Yt(e){let t=new Date().toISOString();return{schema:_r,version:1,projectId:e,entries:[],createdAt:t,updatedAt:t}}async function Xa(e,t){let n=await e.getText(Nr);if(!n)return Yt(t);try{let r=JSON.parse(n);return r.schema!==_r||r.version!==1||r.projectId!==t||!Array.isArray(r.entries)?Yt(t):r}catch{return Yt(t)}}async function Za(e,t){await e.put(Nr,JSON.stringify(t,null,2),"application/json")}function Qa(e){return`toolnet-auto-${je(e).slice(0,12)}`}function ec(e){let t=Q(e.title).slice(0,72),n=je(e.sourceKey).slice(0,10);return Q(`auto-${e.sourceType}-${t}-${n}`)}function tc(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(`
42
+ `).slice(0,Xt)}function nc(e){return je({sourceType:e.sourceType,title:e.title,summary:e.summary,content:e.content,tags:e.tags})}function rc(e,t){return e.tags.includes(t)}async function Kr(e){let t=Ga(e.hierarchy),n=Ya(e.project.rootPath),r=new Map;for(let f of[...t,...n.candidates])r.set(f.sourceKey,f);let s=[...r.values()].sort((f,m)=>f.sourceKey.localeCompare(m.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 st(new ot(e.storage,e.project));await i.initialize();let a=new at(new it(e.storage,e.project));await a.initialize();let c=await Xa(e.storage,e.project.id),u=await i.listPages(),l=new Map(u.map(f=>[f.slug,f])),d=new Map(c.entries.map(f=>[f.sourceKey,f]));for(let f of s)try{let m=Qa(f.sourceKey),S=nc(f),g=d.get(f.sourceKey),h=g?.slug??ec(f),v=l.get(h);if(v&&!rc(v,m)){o.skipped+=1;continue}let x=Me([...f.tags,m]),E=tc(f),C=await a.gate({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:h,marker:m,digest:S,title:f.title,...f.summary?{summary:f.summary}:{},content:E,tags:x},[...l.values()]);if(!C.allowed){C.mode==="pending-review"?o.reviewPending+=1:o.skipped+=1;continue}C.mode==="auto-approved"?o.autoApproved+=1:C.mode==="review-approved"&&(o.reviewApproved+=1),v?g?.digest!==S?(v=await i.updatePage(h,{title:f.title,summary:f.summary??"",content:E,tags:x}),l.set(v.slug,v),o.updated+=1,o.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:v.slug,action:"updated"})):(o.unchanged+=1,o.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:h,action:"unchanged"})):(v=await i.createPage({slug:h,title:f.title,summary:f.summary,content:E,tags:x}),l.set(v.slug,v),o.created+=1,o.pages.push({sourceKey:f.sourceKey,sourceType:f.sourceType,slug:v.slug,action:"created"}));let O=new Date().toISOString(),A={sourceKey:f.sourceKey,sourceType:f.sourceType,slug:h,digest:S,marker:m,updatedAt:O},b=c.entries.findIndex(F=>F.sourceKey===f.sourceKey);b>=0?c.entries[b]=A:c.entries.push(A),d.set(f.sourceKey,A),await a.markApplied(f.sourceKey,S)}catch(m){if(m instanceof j&&m.statusCode===409){o.skipped+=1;continue}o.failed+=1}let p=new Date().toISOString();return c.updatedAt=p,c.lastRunAt=p,c.entries.sort((f,m)=>f.sourceKey.localeCompare(m.sourceKey)),await Za(e.storage,c),o}import{createHash as sc}from"node:crypto";import{chmodSync as Wr,existsSync as oc,mkdirSync as ic,readFileSync as Tm,readdirSync as Rm,renameSync as ac,statSync as Nm,writeFileSync as cc}from"node:fs";import{join as Fr}from"node:path";var uc="toolnet.skill-memory.v1",Lr=5,lc=16,dc=24,pc=32;function fc(e){return sc("sha256").update(e).digest("hex")}function Ce(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 Zt(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 mc(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&&Zt(mc(e),t)||void 0}function Pe(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}}function Dr(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 zr(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 qr(e){let t=e.data??{};if(zr(t,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=Dr(t,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=Pe(t,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function Ie(e){let t=e.data??{};if(qr(e))return!1;if(zr(t,["passed","pass","success","succeeded","ok"])===!0||Dr(t,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=Pe(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 Jr(e){let t=e.data??{},n=Pe(t,["path","file","filePath","filename","target"]);if(n)return z(n,260);let r=e.provenance?.files;return z(r?.[0],260)}function Qt(e){return z(Pe(e.data??{},["command","cmd","script"]),420)}function ie(e){return z(Pe(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(Ie(n)){if(n.type==="test"){let r=ie(n)??Qt(n)??"Tests passed";t.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=ie(n);t.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=ie(n);t.push(r?`Deploy: ${r}`:"Deployment completed")}}return Ce(t,10)}function yc(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=Jr(r);s&&n.push(`Update ${s}`);break}case"command":{if(qr(r))break;let s=Qt(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!Ie(r))break;let s=ie(r)??Qt(r)??"project tests";n.push(`Verify: ${s}`);break}case"commit":{if(!Ie(r))break;let s=ie(r);n.push(s?`Commit: ${s}`:"Commit verified changes");break}case"deploy":{if(!Ie(r))break;let s=ie(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 Ce(n,lc)}function hc(e,t){let n=[...t.files];for(let r of e){let s=Jr(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=z(o,260);i&&n.push(i)}}return Ce(n,dc)}function Sc(e){return Ce(e.filter(t=>["file_write","file_edit","command","test","commit","deploy"].includes(t.type)).map(t=>t.id),pc)}function kc(e){return e.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function Vr(e,t,n){if(t.length===0)return[];let r=gc(t),s=Ce(n.completed.map(m=>z(m,280)??""),Lr);if(!(s.length>0||t.some(m=>["test","commit","deploy"].includes(m.type)&&Ie(m))))return[];let i=z(n.task,280)??z(n.nextActions[0],280),a=s.length>0?s:i?[i]:[];if(a.length===0)return[];let c=yc(t,n);if(c.length===0)return[];let u=hc(t,n),l=Sc(t),d=Math.min(...t.map(m=>m.sequence)),p=Math.max(...t.map(m=>m.sequence)),f=kc(t);return a.slice(0,Lr).map(m=>{let S=[`Reusable procedure learned from successful task: ${m}.`,u.length>0?`Files: ${u.slice(0,6).join(", ")}.`:"",r.length>0?`Verification: ${r.slice(0,4).join("; ")}.`:""].filter(Boolean),g=JSON.stringify({projectId:e.projectId,task:m,steps:c,verification:r,files:u}),h=fc(g);return{schema:uc,version:1,id:`skill-${h.slice(0,24)}`,fingerprint:h,projectId:e.projectId,title:Zt(`SOP: ${m}`,180),task:m,summary:Zt(S.join(" "),900),steps:c,verification:r,files:u,source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:d,lastSequence:p,eventIds:l},createdAt:f}})}function vc(e){return Fr(e.rootPath,".toolnet","memory","skills")}function wc(e){let t=vc(e);return ic(t,{recursive:!0,mode:448}),Wr(t,448),t}function Br(e,t){if(t.length===0)return{written:0,deduped:0,files:[]};let n=wc(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 a=Fr(n,`${i.id}.json`);if(o.push(a),oc(a)){s+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;cc(c,JSON.stringify(i,null,2)+`
43
+ `,{encoding:"utf8",mode:384}),ac(c,a),Wr(a,384),r+=1}return{written:r,deduped:s,files:o}}function Hr(e){return String(e).padStart(12,"0")}function bc(e){return`projects/${e.projectId}/memory/learned`}var ut=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(d=>d.sequence)),o=Math.max(...n.map(d=>d.sequence)),i={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},a=JSON.stringify(i,null,2)+`
44
+ `,c=w(r.map(d=>d.fingerprint).sort().join("|")).slice(0,16),u=w(t.sessionKey).slice(0,12),l=[bc(t),"batches",`${Hr(s)}-${Hr(o)}-${u}-${c}.json`].join("/");return await this.storage.exists(l)||await this.storage.put(l,a,"application/json"),l}};import{createHash as xc}from"node:crypto";function Gr(e){return String(e).padStart(12,"0")}function Ur(e){return xc("sha256").update(e).digest("hex")}function Ac(e){return`projects/${e.projectId}/memory/hierarchy`}var lt=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(l=>l.sequence)),o=Math.max(...n.map(l=>l.sequence)),i={schema:"toolnet.memory-hierarchy-batch.v1",version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,hierarchy:r},a=Ur([...r.facts.map(l=>l.id),...r.knowledge.map(l=>l.id)].sort().join("|")).slice(0,16),c=Ur(t.sessionKey).slice(0,12),u=[Ac(t),"batches",`${Gr(s)}-${Gr(o)}-${c}-${a}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,`${JSON.stringify(i,null,2)}
45
+ `,"application/json"),u}};function Ec(e,t){if(!Mc(e))return{events:[],nextOffset:t};let n=Pc(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=Ic(e,"r");try{Cc(i,o,0,s,r)}finally{jc(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
46
46
  `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
47
- `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var at=class{constructor(t){this.options=t;this.journal=new ot(t.storage),this.hierarchyJournal=new it(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=wc(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Qe(this.options.identity,s.events),i=o.candidates,a=!1;i.length>0&&(a=!!await this.journal.write(this.options.identity,s.events,i));let c=!1;o.hierarchy.facts.length>0&&(c=!!await this.hierarchyJournal.write(this.options.identity,s.events,o.hierarchy));let u=Wr(this.options.identity,s.events,o.state),l=Fr(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",c?1:0),this.options.wal.setSourceCursor("memory.skill.assets",u.length),this.options.wal.setSourceCursor("memory.skill.written",l.written),this.options.wal.setSourceCursor("memory.skill.deduped",l.deduped);try{let d=lr(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 Or({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:a,nextOffset:s.nextOffset}}};import{closeSync as Lc,existsSync as Wc,openSync as Fc,readSync as Dc,statSync as zc}from"node:fs";function Jr(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function Pe(e){return e.toLowerCase().replace(/[^a-z0-9]/gu,"")}function Ce(e,t,n=0){if(n>8)return;if(Array.isArray(e)){for(let s of e.slice(0,50))Ce(s,t,n+1);return}let r=Jr(e);if(r)for(let[s,o]of Object.entries(r))t(s,o,r),Ce(o,t,n+1)}function oe(e,t){let n=[];return Ce(e,(r,s)=>{t.has(Pe(r))&&typeof s=="string"&&s.trim()&&n.push(s.trim())}),n}function bc(e){let t=e.trim();if(!t.startsWith("{"))return null;try{return Jr(JSON.parse(t))}catch{return null}}function xc(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 Ce(t,(r,s,o)=>{if(n)return;let i=Pe(r);if(["tool","toolname"].includes(i)&&typeof s=="string"){n=s.trim().toLowerCase();return}if(i!=="name"||typeof s!="string")return;let a=typeof o.type=="string"?o.type.toLowerCase():"";(a.includes("tool")||a.includes("function")||a.includes("command"))&&(n=s.trim().toLowerCase())}),n}function Ac(e){let t=oe(e.data,new Set(["command","cmd","script"])),n=oe(e.data,new Set(["arguments","args"]));for(let r of n){let s=bc(r);if(s)for(let o of oe(s,new Set(["command","cmd","script"])))t.push(o)}return Array.from(new Set(t.map(r=>r.trim()).filter(Boolean)))}function jc(e){let t=oe(e.data,new Set(["filepath","file_path","filename","file","path","target"].map(Pe)));return Array.from(new Set(t.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
48
- `))))}function Mc(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 Ic(e){let t=oe(e.data,new Set(["patch","diff","arguments","input"].map(Pe))),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 a=i[1]?.trim();a&&n.push({kind:"file",text:a,fileAction:o.action,confidence:.99})}}return n}function Cc(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 Pc(e){let t=null;return Ce(e,(n,r)=>{if(t===null&&["exitcode","code"].includes(Pe(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 Ec(e){return oe(e,new Set(["status","state","result","output","outputsummary","message","text"]))}function Oc(e){let t=Pc(e.data);if(t!==null)return t===0?"passed":"failed";let n=Ec(e.data).join(`
49
- `).toLowerCase();return/\b(error|failed|failure|failing)\b/u.test(n)&&!/\b0\s+failed\b/u.test(n)?"failed":/\b(success|successful|completed|passed|green)\b/u.test(n)||/\b\d+\s+passed\b/u.test(n)?"passed":/\b(running|started|in[_ -]?progress)\b/u.test(n)?"running":"unknown"}function Tc(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 Vr(e){let t=[],n=xc(e),r=Mc(e,n);if(r)for(let s of jc(e))t.push({kind:"file",text:s,fileAction:r,confidence:e.type==="file_edit"||e.type==="file_write"?1:.96});t.push(...Ic(e));for(let s of Ac(e)){t.push({kind:"command",text:s,confidence:.98});let o=Cc(s);o&&t.push({kind:"test",text:s,checkKind:o,checkStatus:Oc(e),confidence:.98})}return Tc(t)}var Rc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ee(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Hr(e){return ee(e).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function Z(e,t,n=0){if(!(n>6)){if(typeof e=="string"){t.push(e);return}if(Array.isArray(e)){for(let r of e.slice(0,50))Z(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(Rc.has(r)||["data","payload","parts","messages"].includes(r))&&Z(s,t,n+1)}}function ct(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 Br(e){let t=ee(e);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(t)}function j(e,t,n,r,s={}){let o=ee(r),i=s.key??Hr(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 Nc(e,t,n){let r=ee(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 a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&s.push(j(e,t,"plan",a[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,u;for(;!o&&(u=c.exec(r));){let p=Number(u[1]),f=ee(u[2]??""),g=f&&!Br(f)?`Phase ${p} - ${f}`:`Phase ${p}`;s.push(j(e,t,"phase",g,{key:`phase:${p}`,order:p,status:ct(r),confidence:.93}))}let l=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);l?.[2]&&s.push(j(e,t,"task",l[2],{status:l[1].trim()?"completed":ct(l[2]),confidence:.96}));let d=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(d?.[2]){let p=d[1]?Number(d[1]):void 0,f=ee(d[2]),g=Br(f);s.push(j(e,t,"task",g&&p!==void 0?`TODO ${p}`:f,{key:p!==void 0?`task:${p}`:Hr(f),order:p,status:ct(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 ut(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 c=[];Z(i.data,c);let u=c.map(l=>ee(l)).find(l=>l.length>=8&&l.length<=1200&&!/^\[?toolnet\b/iu.test(l));u&&s(j(e,i,"request",u,{confidence:.96}))}for(let c of Vr(i))s(j(e,i,c.kind,c.text,{fileAction:c.fileAction,checkKind:c.checkKind,checkStatus:c.checkStatus,status:c.kind==="test"?c.checkStatus==="passed"?"completed":c.checkStatus==="failed"?"blocked":c.checkStatus==="running"?"in_progress":"pending":void 0,confidence:c.confidence}));if(i.type==="decision"){let c=[];Z(i.data,c);for(let u of c)s(j(e,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];Z(i.data,c);for(let u of c)s(j(e,i,"task",u,{status:ct(u),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let u=i.data[c];typeof u=="string"&&u&&s(j(e,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];Z(i.data,c);for(let u of c)s(j(e,i,"test",u,{confidence:1}))}let a=[];Z(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let l of Nc(e,i,u))s(l)}let o=t[t.length-1];return s(j(e,o,"session",`${e.agent}:${e.nativeSessionId}`,{key:e.sessionKey,confidence:1})),n}function Gr(e){return String(e).padStart(12,"0")}var lt=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(l=>l.sequence)),s=Math.max(...n.map(l=>l.sequence)),o={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:n.map(l=>l.occurredAt).sort().at(-1)??new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
50
- `,a=v(n.map(l=>JSON.stringify(l)).sort().join(`
51
- `)).slice(0,24),c=v(t.sessionKey).slice(0,12),u=[`projects/${t.projectId}`,"work","observations",`${Gr(r)}-${Gr(s)}-${c}-${a}.json`].join("/");return await this.storage.put(u,i,"application/json"),u}};import{join as Ur}from"node:path";import{mkdirSync as _c}from"node:fs";function Xr(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=Xr(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=t))break}return n.reverse()}function $c(e,t=20){let n=new Map;for(let r of e){let s=`${r.kind}|${Xr(r.command)}`;n.delete(s),n.set(s,r)}return Array.from(n.values()).slice(-t)}function Kc(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 Yr(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&&Kc(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 Qr(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,a)=>i.key.localeCompare(a.key))){let i=await t.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}async function Ee(e,t){let r=(await Qr(e,t)).flatMap(m=>m.observations).sort((m,b)=>{let z=m.occurredAt.localeCompare(b.occurredAt);if(z!==0)return z;let on=m.sequence-b.sequence;return on!==0?on:m.id.localeCompare(b.id)}),s=new Map,o=new Map,i,a,c,u,l,d=[],p=[],f=[],g=[],S=[],y=new Map,h=[],k=[],C=[],P=[],I=[],E=[];for(let m of r)switch(m.kind){case"request":i=m.text;break;case"activity":a=m.text;break;case"goal":c=m.text;break;case"plan":u=m.text;break;case"phase":s.set(m.key,Yr(s.get(m.key),m));break;case"task":o.set(m.key,Yr(o.get(m.key),m));break;case"decision":d.push(m.text);break;case"blocker":p.push(m.text);break;case"warning":f.push(m.text);break;case"next_action":g.push(m.text);break;case"file":{S.push(m.text);let b=m.fileAction??"active";y.delete(m.text),y.set(m.text,b),b==="modified"?h.push(m.text):b==="created"?k.push(m.text):b==="deleted"&&C.push(m.text);break}case"command":P.push(m.text);break;case"test":I.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":l={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)),W=x.find(m=>m.status==="in_progress")??x.find(m=>m.status==="blocked")??x.find(m=>m.status==="pending"),F=w.find(m=>m.status==="in_progress")??w.find(m=>m.status==="blocked")??w.find(m=>m.status==="pending"),bt=$([...g,...F?[F.title]:[],...!F&&W?[W.title]:[],...w.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),xt=$([...p,...x.filter(m=>m.status==="blocked").map(m=>m.title),...w.filter(m=>m.status==="blocked").map(m=>m.title)],20),ue={version:1,projectId:e.id,projectName:e.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:x,tasks:w,decisions:$(d,20),blockers:xt,warnings:$(f,20),nextActions:bt,filesTouched:$(S,30),activeFiles:Array.from(y.entries()).filter(([,m])=>m!=="deleted").map(([m])=>m).slice(-5),modifiedFiles:$(h,30),createdFiles:$(k,30),deletedFiles:$(C,30),commands:$(P,20),tests:$(I,20),checks:$c(E,20),currentPhase:W,currentTask:F,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:l,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},le=Ur(e.rootPath,".toolnet","work");return _c(le,{recursive:!0}),O(Ur(le,"current.json"),ue),await t.put(`projects/${e.id}/work/current.json`,JSON.stringify(ue,null,2)+`
52
- `,"application/json"),ue}async function Zr(e,t){if((await Qr(e,t)).length>0)return Ee(e,t);let r=await t.getText(`projects/${e.id}/work/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}function qc(e,t){if(!Wc(e))return{events:[],nextOffset:t};let n=zc(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=Fc(e,"r");try{Dc(i,o,0,s,r)}finally{Lc(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
47
+ `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var dt=class{constructor(t){this.options=t;this.journal=new ut(t.storage),this.hierarchyJournal=new lt(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=Ec(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=nt(this.options.identity,s.events),i=o.candidates,a=!1;i.length>0&&(a=!!await this.journal.write(this.options.identity,s.events,i));let c=!1;o.hierarchy.facts.length>0&&(c=!!await this.hierarchyJournal.write(this.options.identity,s.events,o.hierarchy));let u=Vr(this.options.identity,s.events,o.state),l=Br(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",c?1:0),this.options.wal.setSourceCursor("memory.skill.assets",u.length),this.options.wal.setSourceCursor("memory.skill.written",l.written),this.options.wal.setSourceCursor("memory.skill.deduped",l.deduped);try{let d=yr(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 Kr({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:a,nextOffset:s.nextOffset}}};import{closeSync as Hc,existsSync as Gc,openSync as Uc,readSync as Yc,statSync as Xc}from"node:fs";function Yr(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function Oe(e){return e.toLowerCase().replace(/[^a-z0-9]/gu,"")}function Ee(e,t,n=0){if(n>8)return;if(Array.isArray(e)){for(let s of e.slice(0,50))Ee(s,t,n+1);return}let r=Yr(e);if(r)for(let[s,o]of Object.entries(r))t(s,o,r),Ee(o,t,n+1)}function ae(e,t){let n=[];return Ee(e,(r,s)=>{t.has(Oe(r))&&typeof s=="string"&&s.trim()&&n.push(s.trim())}),n}function Oc(e){let t=e.trim();if(!t.startsWith("{"))return null;try{return Yr(JSON.parse(t))}catch{return null}}function Tc(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 Ee(t,(r,s,o)=>{if(n)return;let i=Oe(r);if(["tool","toolname"].includes(i)&&typeof s=="string"){n=s.trim().toLowerCase();return}if(i!=="name"||typeof s!="string")return;let a=typeof o.type=="string"?o.type.toLowerCase():"";(a.includes("tool")||a.includes("function")||a.includes("command"))&&(n=s.trim().toLowerCase())}),n}function Rc(e){let t=ae(e.data,new Set(["command","cmd","script"])),n=ae(e.data,new Set(["arguments","args"]));for(let r of n){let s=Oc(r);if(s)for(let o of ae(s,new Set(["command","cmd","script"])))t.push(o)}return Array.from(new Set(t.map(r=>r.trim()).filter(Boolean)))}function Nc(e){let t=ae(e.data,new Set(["filepath","file_path","filename","file","path","target"].map(Oe)));return Array.from(new Set(t.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
48
+ `))))}function _c(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 $c(e){let t=ae(e.data,new Set(["patch","diff","arguments","input"].map(Oe))),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 a=i[1]?.trim();a&&n.push({kind:"file",text:a,fileAction:o.action,confidence:.99})}}return n}function Kc(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 Lc(e){let t=null;return Ee(e,(n,r)=>{if(t===null&&["exitcode","code"].includes(Oe(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 Wc(e){return ae(e,new Set(["status","state","result","output","outputsummary","message","text"]))}function Fc(e){let t=Lc(e.data);if(t!==null)return t===0?"passed":"failed";let n=Wc(e.data).join(`
49
+ `).toLowerCase();return/\b(error|failed|failure|failing)\b/u.test(n)&&!/\b0\s+failed\b/u.test(n)?"failed":/\b(success|successful|completed|passed|green)\b/u.test(n)||/\b\d+\s+passed\b/u.test(n)?"passed":/\b(running|started|in[_ -]?progress)\b/u.test(n)?"running":"unknown"}function Dc(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 Xr(e){let t=[],n=Tc(e),r=_c(e,n);if(r)for(let s of Nc(e))t.push({kind:"file",text:s,fileAction:r,confidence:e.type==="file_edit"||e.type==="file_write"?1:.96});t.push(...$c(e));for(let s of Rc(e)){t.push({kind:"command",text:s,confidence:.98});let o=Kc(s);o&&t.push({kind:"test",text:s,checkKind:o,checkStatus:Fc(e),confidence:.98})}return Dc(t)}var zc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function te(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Qr(e){return te(e).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function ee(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))ee(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(zc.has(r)||["data","payload","parts","messages"].includes(r))&&ee(s,t,n+1)}}function pt(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 Zr(e){let t=te(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 M(e,t,n,r,s={}){let o=te(r),i=s.key??Qr(o);return{version:1,id:w([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 qc(e,t,n){let r=te(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(M(e,t,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&s.push(M(e,t,"plan",a[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,u;for(;!o&&(u=c.exec(r));){let p=Number(u[1]),f=te(u[2]??""),m=f&&!Zr(f)?`Phase ${p} - ${f}`:`Phase ${p}`;s.push(M(e,t,"phase",m,{key:`phase:${p}`,order:p,status:pt(r),confidence:.93}))}let l=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);l?.[2]&&s.push(M(e,t,"task",l[2],{status:l[1].trim()?"completed":pt(l[2]),confidence:.96}));let d=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(d?.[2]){let p=d[1]?Number(d[1]):void 0,f=te(d[2]),m=Zr(f);s.push(M(e,t,"task",m&&p!==void 0?`TODO ${p}`:f,{key:p!==void 0?`task:${p}`:Qr(f),order:p,status:pt(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(M(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(M(e,t,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(M(e,t,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(M(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(M(e,t,"activity",r,{confidence:.86})),s}function ft(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 c=[];ee(i.data,c);let u=c.map(l=>te(l)).find(l=>l.length>=8&&l.length<=1200&&!/^\[?toolnet\b/iu.test(l));u&&s(M(e,i,"request",u,{confidence:.96}))}for(let c of Xr(i))s(M(e,i,c.kind,c.text,{fileAction:c.fileAction,checkKind:c.checkKind,checkStatus:c.checkStatus,status:c.kind==="test"?c.checkStatus==="passed"?"completed":c.checkStatus==="failed"?"blocked":c.checkStatus==="running"?"in_progress":"pending":void 0,confidence:c.confidence}));if(i.type==="decision"){let c=[];ee(i.data,c);for(let u of c)s(M(e,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];ee(i.data,c);for(let u of c)s(M(e,i,"task",u,{status:pt(u),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let u=i.data[c];typeof u=="string"&&u&&s(M(e,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];ee(i.data,c);for(let u of c)s(M(e,i,"test",u,{confidence:1}))}let a=[];ee(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let l of qc(e,i,u))s(l)}let o=t[t.length-1];return s(M(e,o,"session",`${e.agent}:${e.nativeSessionId}`,{key:e.sessionKey,confidence:1})),n}function es(e){return String(e).padStart(12,"0")}var mt=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(l=>l.sequence)),s=Math.max(...n.map(l=>l.sequence)),o={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,createdAt:n.map(l=>l.occurredAt).sort().at(-1)??new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
50
+ `,a=w(n.map(l=>JSON.stringify(l)).sort().join(`
51
+ `)).slice(0,24),c=w(t.sessionKey).slice(0,12),u=[`projects/${t.projectId}`,"work","observations",`${es(r)}-${es(s)}-${c}-${a}.json`].join("/");return await this.storage.put(u,i,"application/json"),u}};import{join as ts}from"node:path";import{mkdirSync as Jc}from"node:fs";function rs(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function K(e,t=20){let n=[],r=new Set;for(let s of e.slice().reverse()){let o=rs(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=t))break}return n.reverse()}function Vc(e,t=20){let n=new Map;for(let r of e){let s=`${r.kind}|${rs(r.command)}`;n.delete(s),n.set(s,r)}return Array.from(n.values()).slice(-t)}function Bc(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 ns(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&&Bc(t)?e.title:t.text;return{id:e?.id??w(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 ss(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,a)=>i.key.localeCompare(a.key))){let i=await t.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}async function Te(e,t){let r=(await ss(e,t)).flatMap(y=>y.observations).sort((y,k)=>{let P=y.occurredAt.localeCompare(k.occurredAt);if(P!==0)return P;let q=y.sequence-k.sequence;return q!==0?q:y.id.localeCompare(k.id)}),s=new Map,o=new Map,i,a,c,u,l,d=[],p=[],f=[],m=[],S=[],g=new Map,h=[],v=[],x=[],E=[],C=[],O=[];for(let y of r)switch(y.kind){case"request":i=y.text;break;case"activity":a=y.text;break;case"goal":c=y.text;break;case"plan":u=y.text;break;case"phase":s.set(y.key,ns(s.get(y.key),y));break;case"task":o.set(y.key,ns(o.get(y.key),y));break;case"decision":d.push(y.text);break;case"blocker":p.push(y.text);break;case"warning":f.push(y.text);break;case"next_action":m.push(y.text);break;case"file":{S.push(y.text);let k=y.fileAction??"active";g.delete(y.text),g.set(y.text,k),k==="modified"?h.push(y.text):k==="created"?v.push(y.text):k==="deleted"&&x.push(y.text);break}case"command":E.push(y.text);break;case"test":C.push(y.text),y.checkKind&&O.push({kind:y.checkKind,command:y.text,status:y.checkStatus??"unknown",updatedAt:y.occurredAt,agent:y.agent,nativeSessionId:y.nativeSessionId});break;case"session":l={agent:y.agent,nativeSessionId:y.nativeSessionId,sessionKey:y.sessionKey,updatedAt:y.occurredAt};break}let A=Array.from(s.values()).sort((y,k)=>(y.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),b=Array.from(o.values()).sort((y,k)=>(y.order??Number.MAX_SAFE_INTEGER)-(k.order??Number.MAX_SAFE_INTEGER)),F=A.find(y=>y.status==="in_progress")??A.find(y=>y.status==="blocked")??A.find(y=>y.status==="pending"),D=b.find(y=>y.status==="in_progress")??b.find(y=>y.status==="blocked")??b.find(y=>y.status==="pending"),Mt=K([...m,...D?[D.title]:[],...!D&&F?[F.title]:[],...b.filter(y=>y.status==="pending").slice(0,5).map(y=>y.title)],8),It=K([...p,...A.filter(y=>y.status==="blocked").map(y=>y.title),...b.filter(y=>y.status==="blocked").map(y=>y.title)],20),de={version:1,projectId:e.id,projectName:e.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:A,tasks:b,decisions:K(d,20),blockers:It,warnings:K(f,20),nextActions:Mt,filesTouched:K(S,30),activeFiles:Array.from(g.entries()).filter(([,y])=>y!=="deleted").map(([y])=>y).slice(-5),modifiedFiles:K(h,30),createdFiles:K(v,30),deletedFiles:K(x,30),commands:K(E,20),tests:K(C,20),checks:Vc(O,20),currentPhase:F,currentTask:D,progress:{phasesTotal:A.length,phasesCompleted:A.filter(y=>y.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(y=>y.status==="completed").length,blocked:A.filter(y=>y.status==="blocked").length+b.filter(y=>y.status==="blocked").length},lastSession:l,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},Le=ts(e.rootPath,".toolnet","work");return Jc(Le,{recursive:!0}),T(ts(Le,"current.json"),de),await t.put(`projects/${e.id}/work/current.json`,JSON.stringify(de,null,2)+`
52
+ `,"application/json"),de}async function os(e,t){if((await ss(e,t)).length>0)return Te(e,t);let r=await t.getText(`projects/${e.id}/work/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}function Zc(e,t){if(!Gc(e))return{events:[],nextOffset:t};let n=Xc(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=Uc(e,"r");try{Yc(i,o,0,s,r)}finally{Hc(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
53
53
  `);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
54
- `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var dt=class{constructor(t){this.options=t;this.journal=new lt(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.continuity.offset"]??0),r=qc(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=ut(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Ee(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{closeSync as Qc,existsSync as Zc,openSync as eu,readSync as tu,statSync as nu}from"node:fs";var Jc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ie(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Xt(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))Xt(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(Jc.has(r)||["data","payload","parts","messages"].includes(r))&&Xt(s,t,n+1)}}function R(e,t,n,r,s,o=.95){let i=ie(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 ie(e.slice(r.length+1))}return null}function Vc(e){let t=e.trimStart();return t.startsWith("- ")||t.startsWith("* ")||/^\d+[.)]\s+/u.test(t)}function Bc(e){return ie(e.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function es(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=[];Xt(o.data,i);for(let a of i){let c={type:"project"},u=null;for(let l of a.split(/\r?\n/u)){let d=ie(l);if(!d){u=null;continue}let p=d.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let w=Number(p[1]);c={type:"phase",key:`phase:${w}`,order:w,title:ie(p[2]??"")},u=null;continue}let f=d.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(f){let w=Number(f[1]);c={type:"task",key:`task:${w}`,order:w,title:ie(f[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 S=K(d,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(S){s(R(e,o,c.type==="phase"?"phase_objective":"objective",S,c,.98)),u=null;continue}let y=K(d,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(y){s(R(e,o,c.type==="phase"?"phase_why":"why",y,c,.98)),u=null;continue}let h=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(h){s(R(e,o,"desired_outcome",h,{type:"project"},.98)),u=null;continue}let k=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(k){s(R(e,o,"plan_rationale",k,{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,c,.97)),u=null;continue}let P=K(d,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(P){s(R(e,o,"acceptance_criterion",P,c,.98)),u="acceptance_criterion";continue}let I=K(d,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(I){s(R(e,o,"dependency",I,c,.97)),u="dependency";continue}let E=K(d,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(E){s(R(e,o,"open_question",E,c,.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,c,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(d)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(d)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(d)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(d)){u="constraint";continue}if(u&&Vc(l)){s(R(e,o,u,Bc(l),c,.96));continue}u=null}}}return n}function ts(e){return String(e).padStart(12,"0")}var pt=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.evidence.sequence)),s=Math.max(...n.map(u=>u.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(u=>u.id).sort().join("|")).slice(0,16),a=v(t.sessionKey).slice(0,12),c=[`projects/${t.projectId}`,"work","semantic","observations",`${ts(r)}-${ts(s)}-${a}-${i}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,JSON.stringify(o,null,2)+`
55
- `,"application/json"),c}};import{mkdirSync as Hc}from"node:fs";import{join as ns}from"node:path";function Gc(e){return{value:e.value,confidence:e.confidence,evidence:e.evidence}}function Uc(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 V(e,t){return Uc(t,e)?t:e}function B(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 Yc(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,a)=>i.key.localeCompare(a.key))){let i=await t.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}function Xc(e){return{key:e.scopeKey??`phase:${e.scopeOrder??0}`,order:e.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function rs(e,t){let r=(await Yc(e,t)).flatMap(S=>S.observations).sort((S,y)=>{let h=S.evidence.occurredAt.localeCompare(y.evidence.occurredAt);return h!==0?h:S.evidence.sessionKey===y.evidence.sessionKey?S.evidence.sequence-y.evidence.sequence:S.id.localeCompare(y.id)}),s,o,i,a,c,u=new Map,l=[],d=[],p=[];for(let S of r){let y=Gc(S);if(S.scope==="phase"&&S.scopeKey){let h=u.get(S.scopeKey)??Xc(S);switch(S.kind){case"phase_objective":h.objective=V(h.objective,y);break;case"phase_why":h.why=V(h.why,y);break;case"phase_deliverable":h.deliverable=V(h.deliverable,y);break;case"acceptance_criterion":h.acceptanceCriteria.push(y);break;case"dependency":h.dependencies.push(y);break;case"open_question":h.openQuestions.push(y);break;case"constraint":h.constraints.push(y);break;case"note":h.notes.push(y);break}u.set(h.key,h);continue}switch(S.kind){case"mission":s=V(s,y);break;case"objective":o=V(o,y);break;case"why":i=V(i,y);break;case"desired_outcome":a=V(a,y);break;case"plan_rationale":c=V(c,y);break;case"open_question":l.push(y);break;case"constraint":d.push(y);break;case"note":p.push(y);break}}for(let S of u.values())S.acceptanceCriteria=B(S.acceptanceCriteria,20),S.dependencies=B(S.dependencies,15),S.openQuestions=B(S.openQuestions,15),S.constraints=B(S.constraints,15),S.notes=B(S.notes,20);let f={version:1,projectId:e.id,projectName:e.name,mission:s,activeObjective:o,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((S,y)=>S.order-y.order),openQuestions:B(l,20),constraints:B(d,20),notes:B(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},g=ns(e.rootPath,".toolnet","work");return Hc(g,{recursive:!0}),O(ns(g,"semantic-current.json"),f),await t.put(`projects/${e.id}/work/semantic/current.json`,JSON.stringify(f,null,2)+`
56
- `,"application/json"),f}function ru(e,t){if(!Zc(e))return{events:[],nextOffset:t};let n=nu(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=eu(e,"r");try{tu(o,s,0,s.length,r)}finally{Qc(o)}let i=s.toString("utf8"),a=i.lastIndexOf(`
54
+ `).filter(Boolean).flatMap(d=>{try{return[JSON.parse(d)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var gt=class{constructor(t){this.options=t;this.journal=new mt(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.continuity.offset"]??0),r=Zc(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=ft(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Te(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{closeSync as au,existsSync as cu,openSync as uu,readSync as lu,statSync as du}from"node:fs";var Qc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ce(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function en(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))en(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(Qc.has(r)||["data","payload","parts","messages"].includes(r))&&en(s,t,n+1)}}function N(e,t,n,r,s,o=.95){let i=ce(r);return{version:1,id:w([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 L(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 ce(e.slice(r.length+1))}return null}function eu(e){let t=e.trimStart();return t.startsWith("- ")||t.startsWith("* ")||/^\d+[.)]\s+/u.test(t)}function tu(e){return ce(e.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function is(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=[];en(o.data,i);for(let a of i){let c={type:"project"},u=null;for(let l of a.split(/\r?\n/u)){let d=ce(l);if(!d){u=null;continue}let p=d.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(p){let b=Number(p[1]);c={type:"phase",key:`phase:${b}`,order:b,title:ce(p[2]??"")},u=null;continue}let f=d.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(f){let b=Number(f[1]);c={type:"task",key:`task:${b}`,order:b,title:ce(f[2]??"")},u=null;continue}let m=L(d,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(m){s(N(e,o,"mission",m,{type:"project"},.99)),u=null;continue}let S=L(d,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(S){s(N(e,o,c.type==="phase"?"phase_objective":"objective",S,c,.98)),u=null;continue}let g=L(d,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(g){s(N(e,o,c.type==="phase"?"phase_why":"why",g,c,.98)),u=null;continue}let h=L(d,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(h){s(N(e,o,"desired_outcome",h,{type:"project"},.98)),u=null;continue}let v=L(d,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(v){s(N(e,o,"plan_rationale",v,{type:"project"},.98)),u=null;continue}let x=L(d,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(x){s(N(e,o,"phase_deliverable",x,c,.97)),u=null;continue}let E=L(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,c,.98)),u="acceptance_criterion";continue}let C=L(d,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(C){s(N(e,o,"dependency",C,c,.97)),u="dependency";continue}let O=L(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,c,.95)),u="open_question";continue}let A=L(d,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(A){s(N(e,o,"constraint",A,c,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(d)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(d)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(d)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(d)){u="constraint";continue}if(u&&eu(l)){s(N(e,o,u,tu(l),c,.96));continue}u=null}}}return n}function as(e){return String(e).padStart(12,"0")}var yt=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.evidence.sequence)),s=Math.max(...n.map(u=>u.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=w(n.map(u=>u.id).sort().join("|")).slice(0,16),a=w(t.sessionKey).slice(0,12),c=[`projects/${t.projectId}`,"work","semantic","observations",`${as(r)}-${as(s)}-${a}-${i}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,JSON.stringify(o,null,2)+`
55
+ `,"application/json"),c}};import{mkdirSync as nu}from"node:fs";import{join as cs}from"node:path";function ru(e){return{value:e.value,confidence:e.confidence,evidence:e.evidence}}function su(e,t){if(!t)return!0;let n=e.evidence.occurredAt.localeCompare(t.evidence.occurredAt);return n!==0?n>0:e.evidence.sessionKey===t.evidence.sessionKey?e.evidence.sequence>=t.evidence.sequence:e.confidence>=t.confidence}function H(e,t){return su(t,e)?t:e}function G(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 ou(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,a)=>i.key.localeCompare(a.key))){let i=await t.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}function iu(e){return{key:e.scopeKey??`phase:${e.scopeOrder??0}`,order:e.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function us(e,t){let r=(await ou(e,t)).flatMap(S=>S.observations).sort((S,g)=>{let h=S.evidence.occurredAt.localeCompare(g.evidence.occurredAt);return h!==0?h:S.evidence.sessionKey===g.evidence.sessionKey?S.evidence.sequence-g.evidence.sequence:S.id.localeCompare(g.id)}),s,o,i,a,c,u=new Map,l=[],d=[],p=[];for(let S of r){let g=ru(S);if(S.scope==="phase"&&S.scopeKey){let h=u.get(S.scopeKey)??iu(S);switch(S.kind){case"phase_objective":h.objective=H(h.objective,g);break;case"phase_why":h.why=H(h.why,g);break;case"phase_deliverable":h.deliverable=H(h.deliverable,g);break;case"acceptance_criterion":h.acceptanceCriteria.push(g);break;case"dependency":h.dependencies.push(g);break;case"open_question":h.openQuestions.push(g);break;case"constraint":h.constraints.push(g);break;case"note":h.notes.push(g);break}u.set(h.key,h);continue}switch(S.kind){case"mission":s=H(s,g);break;case"objective":o=H(o,g);break;case"why":i=H(i,g);break;case"desired_outcome":a=H(a,g);break;case"plan_rationale":c=H(c,g);break;case"open_question":l.push(g);break;case"constraint":d.push(g);break;case"note":p.push(g);break}}for(let S of u.values())S.acceptanceCriteria=G(S.acceptanceCriteria,20),S.dependencies=G(S.dependencies,15),S.openQuestions=G(S.openQuestions,15),S.constraints=G(S.constraints,15),S.notes=G(S.notes,20);let f={version:1,projectId:e.id,projectName:e.name,mission:s,activeObjective:o,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((S,g)=>S.order-g.order),openQuestions:G(l,20),constraints:G(d,20),notes:G(p,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},m=cs(e.rootPath,".toolnet","work");return nu(m,{recursive:!0}),T(cs(m,"semantic-current.json"),f),await t.put(`projects/${e.id}/work/semantic/current.json`,JSON.stringify(f,null,2)+`
56
+ `,"application/json"),f}function pu(e,t){if(!cu(e))return{events:[],nextOffset:t};let n=du(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=uu(e,"r");try{lu(o,s,0,s.length,r)}finally{au(o)}let i=s.toString("utf8"),a=i.lastIndexOf(`
57
57
  `);if(a<0)return{events:[],nextOffset:r};let c=i.slice(0,a+1);return{events:c.split(`
58
- `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var ft=class{constructor(t){this.options=t;this.journal=new pt(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.semantic.offset"]??0),r=ru(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=es(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await rs(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 Yu,mkdirSync as Xu}from"node:fs";import{join as Zt}from"node:path";import{existsSync as is,mkdirSync as su,readFileSync as ou,statSync as ss,writeFileSync as iu}from"node:fs";import{dirname as au,join as cu}from"node:path";var os=64*1024,uu=`# ToolNet Project Operating Manual
58
+ `).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var ht=class{constructor(t){this.options=t;this.journal=new yt(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.semantic.offset"]??0),r=pu(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=is(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await us(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 ol,mkdirSync as il}from"node:fs";import{join as nn}from"node:path";import{existsSync as ps,mkdirSync as fu,readFileSync as mu,statSync as ls,writeFileSync as gu}from"node:fs";import{dirname as yu,join as hu}from"node:path";var ds=64*1024,Su=`# ToolNet Project Operating Manual
59
59
 
60
60
  This file contains persistent instructions for AI agents working on this project.
61
61
 
@@ -98,24 +98,24 @@ Things an AI agent should always remember.
98
98
  <!--
99
99
  - [advisory] Prefer small focused files.
100
100
  -->
101
- `;function as(e){return cu(e.rootPath,".toolnet","PROJECT.md")}function lu(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function du(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=lu(s[2]);if(!i)continue;let a=`${o}:${i.toLowerCase()}`;n.has(a)||(n.add(a),t.push({id:v(a).slice(0,24),mode:o,text:i,source:"manual"}))}return t}function pu(e){let t=as(e);return is(t)||(su(au(t),{recursive:!0}),iu(t,uu,{encoding:"utf8",mode:384})),t}function cs(e,t=!1){let n=t?pu(e):as(e);if(!is(n))return null;if(ss(n).size>os)throw new Error(`PROJECT.md exceeds ${os} bytes`);let s=ou(n,"utf8");return{path:n,content:s,digest:v(s),rules:du(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(ss(n).mtimeMs).toISOString()}}import{randomUUID as fu}from"node:crypto";import{closeSync as mu,existsSync as us,fsyncSync as gu,mkdirSync as yu,openSync as hu,readFileSync as Su,statSync as ku,unlinkSync as ls,writeFileSync as vu}from"node:fs";import{dirname as wu,join as bu}from"node:path";var xu=new Int32Array(new SharedArrayBuffer(4));function Au(e){e<=0||Atomics.wait(xu,0,0,e)}function ju(e){return bu(e.rootPath,".toolnet","work",".current.lock")}function Mu(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function ds(e){if(!us(e))return null;try{let t=JSON.parse(Su(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function Iu(e){try{return Date.now()-ku(e).mtimeMs}catch{return 0}}function Cu(e,t){if(!us(e)||Iu(e)<t)return!1;let n=ds(e);return n?!Mu(n.pid):!0}function Pu(e,t){if(!Cu(e,t))return!1;try{return ls(e),!0}catch{return!1}}function Eu(e,t){let n={version:1,token:t,pid:process.pid,acquiredAt:new Date().toISOString()},r=hu(e,"wx",384);try{vu(r,`${JSON.stringify(n,null,2)}
102
- `,{encoding:"utf8"}),gu(r)}finally{mu(r)}}function Ou(e,t){if(ds(e)?.token===t)try{ls(e)}catch{}}function Tu(e,t={}){let n=Math.max(100,t.timeoutMs??5e3),r=Math.max(5,t.retryMs??20),s=Math.max(n*2,t.staleMs??3e4),o=ju(e);yu(wu(o),{recursive:!0});let i=fu(),a=Date.now()+n;for(;;)try{Eu(o,i);let c=!1;return()=>{c||(c=!0,Ou(o,i))}}catch(c){if(c?.code!=="EEXIST")throw c;if(Pu(o,s))continue;if(Date.now()>=a)throw new Error(`Timed out acquiring project work lock: ${o}`);Au(r)}}function ps(e,t,n={}){let r=Tu(e,n);try{return t()}finally{r()}}import{closeSync as Ru,existsSync as Nu,fsyncSync as _u,mkdirSync as $u,openSync as Ku,readFileSync as Lu,renameSync as Wu,writeFileSync as Fu}from"node:fs";import{dirname as Du,join as zu}from"node:path";function qu(e,t){$u(Du(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`,r=Ku(n,"w",384);try{Fu(r,`${JSON.stringify(t,null,2)}
103
- `,{encoding:"utf8"}),_u(r)}finally{Ru(r)}Wu(n,e)}function Ss(e){return zu(e.rootPath,".toolnet","work","current.json")}function Qt(e){let t=Ss(e);if(!Nu(t))return null;try{let n=JSON.parse(Lu(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function mt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function N(e,t,n){let r=[],s=new Set;for(let o of[...e,...t].reverse()){let i=mt(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function Ju(e,t,n=20){let r=new Map;for(let s of[...e,...t]){let o=`${s.kind}|${mt(s.command)}`;r.delete(o),r.set(o,s)}return Array.from(r.values()).slice(-n)}function Vu(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 fs(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&&Vu(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 ms(e){let t=new Map;for(let n of e){let r=n.order!==void 0?`order:${n.order}`:mt(n.title);t.set(r,n)}return t}function gs(e){return e.order!==void 0?`order:${e.order}`:mt(e.key||e.text)}function ys(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 hs(e){return e.find(t=>t.status==="in_progress")??e.find(t=>t.status==="blocked")??e.find(t=>t.status==="pending")}function Bu(e,t){let n=Qt(e),r=ms(n?.phases??[]),s=ms(n?.tasks??[]),o=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,l=[],d=[],p=[],f=[],g=[],S=[...n?.activeFiles??[]],y=[],h=[],k=[],C=[],P=[],I=[],E=[...t].sort((m,b)=>{let z=m.occurredAt.localeCompare(b.occurredAt);return z!==0?z:m.sequence-b.sequence});for(let m of E)switch(m.kind){case"request":o=m.text;break;case"activity":i=m.text;break;case"goal":a=m.text;break;case"plan":c=m.text;break;case"phase":{let b=gs(m);r.set(b,fs(r.get(b),m));break}case"task":{let b=gs(m);s.set(b,fs(s.get(b),m));break}case"decision":l.push(m.text);break;case"blocker":d.push(m.text);break;case"warning":p.push(m.text);break;case"next_action":f.push(m.text);break;case"file":{g.push(m.text);let b=m.fileAction??"active",z=S.indexOf(m.text);z>=0&&S.splice(z,1),b!=="deleted"&&S.push(m.text),b==="modified"?y.push(m.text):b==="created"?h.push(m.text):b==="deleted"&&k.push(m.text);break}case"command":C.push(m.text);break;case"test":P.push(m.text),m.checkKind&&I.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=ys(r.values()),w=ys(s.values()),W=hs(x),F=hs(w),bt=N(n?.nextActions??[],[...f,...F?[F.title]:[],...!F&&W?[W.title]:[],...w.filter(m=>m.status==="pending").slice(0,5).map(m=>m.title)],8),xt=N(n?.blockers??[],[...d,...x.filter(m=>m.status==="blocked").map(m=>m.title),...w.filter(m=>m.status==="blocked").map(m=>m.title)],20),ue=E.length>0?E[E.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),le={version:1,projectId:e.id,projectName:e.name,currentRequest:o,currentActivity:i,goal:a,plan:c,phases:x,tasks:w,decisions:N(n?.decisions??[],l,20),blockers:xt,warnings:N(n?.warnings??[],p,20),nextActions:bt,filesTouched:N(n?.filesTouched??[],g,30),activeFiles:N([],S,5),modifiedFiles:N(n?.modifiedFiles??[],y,30),createdFiles:N(n?.createdFiles??[],h,30),deletedFiles:N(n?.deletedFiles??[],k,30),commands:N(n?.commands??[],C,20),tests:N(n?.tests??[],P,20),checks:Ju(n?.checks??[],I,20),currentPhase:W,currentTask:F,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:ue};return qu(Ss(e),le),le}function ks(e,t){return ps(e,()=>Bu(e,t))}function M(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 vs(e){if(e)return{id:e.id,title:e.title,status:e.status}}function Hu(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(`
104
- `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function Gu(e){return v(JSON.stringify(e))}function Uu(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 M(t,30)}function ws(e){let{project:t,identity:n,state:r}=e,s=r.activeFiles?.at(-1)??r.filesTouched.at(-1),o=r.phases.filter(k=>k.status==="completed").map(k=>k.title),i=r.tasks.filter(k=>k.status==="completed").map(k=>k.title),a=r.phases.filter(k=>k.status!=="completed"&&k.status!=="cancelled").map(k=>k.title),c=r.tasks.filter(k=>k.status!=="completed"&&k.status!=="cancelled").map(k=>k.title),u=new Set(r.tasks.filter(k=>k.status==="completed").map(k=>k.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),l=M(r.nextActions.filter(k=>!u.has(k.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),d=M([...c,...l],15),p=M(r.tests.slice().reverse(),10),f=M([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),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:vs(r.currentPhase),task:vs(r.currentTask),file:s},completed:{phases:M(o,20),tasks:M(i,30)},remaining:{phases:M(a,20),tasks:M(c,30),todos:d},nextAction:l[0],blockers:M(r.blockers.slice().reverse(),10),decisions:M(r.decisions.slice().reverse(),10),files:{current:s,recent:f,active:M(r.activeFiles??[],10),modified:M(r.modifiedFiles??[],20),created:M(r.createdFiles??[],20),deleted:M(r.deletedFiles??[],20)},tests:{status:Hu(r.tests,r.checks),recent:p,checks:(r.checks??[]).slice(-10).map(k=>({kind:k.kind,status:k.status,command:k.command}))},evidence:{commands:M((r.commands??[]).slice().reverse(),20),references:Uu([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(k=>k.command)])},attention:M(e.attention??[],20),progress:r.progress},{capturedAt:S,source:y,...h}=g;return{...g,stateDigest:Gu(h)}}function Qu(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 bs(e,t,n,r,s){if(!Qu(n))return null;let o=cs(e,!1),a=[...o?o.rules.filter(d=>d.mode==="enforce").map(d=>d.text):[],...n.warnings].slice(0,20),c=ws({project:e,identity:t,state:n,reason:r,sequence:s,attention:a}),u=c.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:c.remaining.todos.slice(0,10),blockers:n.blockers.slice(-10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:a,filesTouched:n.filesTouched.slice(-20),activeFiles:n.activeFiles?.slice(-10),modifiedFiles:n.modifiedFiles?.slice(-20),createdFiles:n.createdFiles?.slice(-20),deletedFiles:n.deletedFiles?.slice(-20),tests:n.tests.slice(-15),checks:n.checks?.slice(-10),stateDigest:u,continuity:c}}function xs(e,t){let n=Zt(e.rootPath,".toolnet","work","handoffs");Xu(n,{recursive:!0});let r=Zt(n,`${t.id}.json`);Yu(r)||O(r,t),O(Zt(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function As(e){let t=bs(e.project,e.identity,e.state,e.reason,e.sequence);return t?(xs(e.project,t),t):null}var gt=class{constructor(t){this.options=t}options;async capture(t,n){let r=Qt(this.options.project);r||(r=await Zr(this.options.project,this.options.storage)),r||(r=await Ee(this.options.project,this.options.storage));let s=bs(this.options.project,this.options.identity,r,t,n);if(!s)return null;xs(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)+`
101
+ `;function fs(e){return hu(e.rootPath,".toolnet","PROJECT.md")}function ku(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function vu(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=ku(s[2]);if(!i)continue;let a=`${o}:${i.toLowerCase()}`;n.has(a)||(n.add(a),t.push({id:w(a).slice(0,24),mode:o,text:i,source:"manual"}))}return t}function wu(e){let t=fs(e);return ps(t)||(fu(yu(t),{recursive:!0}),gu(t,Su,{encoding:"utf8",mode:384})),t}function ms(e,t=!1){let n=t?wu(e):fs(e);if(!ps(n))return null;if(ls(n).size>ds)throw new Error(`PROJECT.md exceeds ${ds} bytes`);let s=mu(n,"utf8");return{path:n,content:s,digest:w(s),rules:vu(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(ls(n).mtimeMs).toISOString()}}import{randomUUID as bu}from"node:crypto";import{closeSync as xu,existsSync as gs,fsyncSync as Au,mkdirSync as ju,openSync as Mu,readFileSync as Iu,statSync as Cu,unlinkSync as ys,writeFileSync as Pu}from"node:fs";import{dirname as Eu,join as Ou}from"node:path";var Tu=new Int32Array(new SharedArrayBuffer(4));function Ru(e){e<=0||Atomics.wait(Tu,0,0,e)}function Nu(e){return Ou(e.rootPath,".toolnet","work",".current.lock")}function _u(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code!=="ESRCH"}}function hs(e){if(!gs(e))return null;try{let t=JSON.parse(Iu(e,"utf8"));return t.version!==1||typeof t.token!="string"||typeof t.pid!="number"||typeof t.acquiredAt!="string"?null:{version:1,token:t.token,pid:t.pid,acquiredAt:t.acquiredAt}}catch{return null}}function $u(e){try{return Date.now()-Cu(e).mtimeMs}catch{return 0}}function Ku(e,t){if(!gs(e)||$u(e)<t)return!1;let n=hs(e);return n?!_u(n.pid):!0}function Lu(e,t){if(!Ku(e,t))return!1;try{return ys(e),!0}catch{return!1}}function Wu(e,t){let n={version:1,token:t,pid:process.pid,acquiredAt:new Date().toISOString()},r=Mu(e,"wx",384);try{Pu(r,`${JSON.stringify(n,null,2)}
102
+ `,{encoding:"utf8"}),Au(r)}finally{xu(r)}}function Fu(e,t){if(hs(e)?.token===t)try{ys(e)}catch{}}function Du(e,t={}){let n=Math.max(100,t.timeoutMs??5e3),r=Math.max(5,t.retryMs??20),s=Math.max(n*2,t.staleMs??3e4),o=Nu(e);ju(Eu(o),{recursive:!0});let i=bu(),a=Date.now()+n;for(;;)try{Wu(o,i);let c=!1;return()=>{c||(c=!0,Fu(o,i))}}catch(c){if(c?.code!=="EEXIST")throw c;if(Lu(o,s))continue;if(Date.now()>=a)throw new Error(`Timed out acquiring project work lock: ${o}`);Ru(r)}}function Ss(e,t,n={}){let r=Du(e,n);try{return t()}finally{r()}}import{closeSync as zu,existsSync as qu,fsyncSync as Ju,mkdirSync as Vu,openSync as Bu,readFileSync as Hu,renameSync as Gu,writeFileSync as Uu}from"node:fs";import{dirname as Yu,join as Xu}from"node:path";function Zu(e,t){Vu(Yu(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`,r=Bu(n,"w",384);try{Uu(r,`${JSON.stringify(t,null,2)}
103
+ `,{encoding:"utf8"}),Ju(r)}finally{zu(r)}Gu(n,e)}function As(e){return Xu(e.rootPath,".toolnet","work","current.json")}function tn(e){let t=As(e);if(!qu(t))return null;try{let n=JSON.parse(Hu(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function St(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=St(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function Qu(e,t,n=20){let r=new Map;for(let s of[...e,...t]){let o=`${s.kind}|${St(s.command)}`;r.delete(o),r.set(o,s)}return Array.from(r.values()).slice(-n)}function el(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 ks(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&&el(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 vs(e){let t=new Map;for(let n of e){let r=n.order!==void 0?`order:${n.order}`:St(n.title);t.set(r,n)}return t}function ws(e){return e.order!==void 0?`order:${e.order}`:St(e.key||e.text)}function bs(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 xs(e){return e.find(t=>t.status==="in_progress")??e.find(t=>t.status==="blocked")??e.find(t=>t.status==="pending")}function tl(e,t){let n=tn(e),r=vs(n?.phases??[]),s=vs(n?.tasks??[]),o=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,l=[],d=[],p=[],f=[],m=[],S=[...n?.activeFiles??[]],g=[],h=[],v=[],x=[],E=[],C=[],O=[...t].sort((k,P)=>{let q=k.occurredAt.localeCompare(P.occurredAt);return q!==0?q:k.sequence-P.sequence});for(let k of O)switch(k.kind){case"request":o=k.text;break;case"activity":i=k.text;break;case"goal":a=k.text;break;case"plan":c=k.text;break;case"phase":{let P=ws(k);r.set(P,ks(r.get(P),k));break}case"task":{let P=ws(k);s.set(P,ks(s.get(P),k));break}case"decision":l.push(k.text);break;case"blocker":d.push(k.text);break;case"warning":p.push(k.text);break;case"next_action":f.push(k.text);break;case"file":{m.push(k.text);let P=k.fileAction??"active",q=S.indexOf(k.text);q>=0&&S.splice(q,1),P!=="deleted"&&S.push(k.text),P==="modified"?g.push(k.text):P==="created"?h.push(k.text):P==="deleted"&&v.push(k.text);break}case"command":x.push(k.text);break;case"test":E.push(k.text),k.checkKind&&C.push({kind:k.checkKind,command:k.text,status:k.checkStatus??"unknown",updatedAt:k.occurredAt,agent:k.agent,nativeSessionId:k.nativeSessionId});break;case"session":u={agent:k.agent,nativeSessionId:k.nativeSessionId,sessionKey:k.sessionKey,updatedAt:k.occurredAt};break}let A=bs(r.values()),b=bs(s.values()),F=xs(A),D=xs(b),Mt=_(n?.nextActions??[],[...f,...D?[D.title]:[],...!D&&F?[F.title]:[],...b.filter(k=>k.status==="pending").slice(0,5).map(k=>k.title)],8),It=_(n?.blockers??[],[...d,...A.filter(k=>k.status==="blocked").map(k=>k.title),...b.filter(k=>k.status==="blocked").map(k=>k.title)],20),de=O.length>0?O[O.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),Le={version:1,projectId:e.id,projectName:e.name,currentRequest:o,currentActivity:i,goal:a,plan:c,phases:A,tasks:b,decisions:_(n?.decisions??[],l,20),blockers:It,warnings:_(n?.warnings??[],p,20),nextActions:Mt,filesTouched:_(n?.filesTouched??[],m,30),activeFiles:_([],S,5),modifiedFiles:_(n?.modifiedFiles??[],g,30),createdFiles:_(n?.createdFiles??[],h,30),deletedFiles:_(n?.deletedFiles??[],v,30),commands:_(n?.commands??[],x,20),tests:_(n?.tests??[],E,20),checks:Qu(n?.checks??[],C,20),currentPhase:F,currentTask:D,progress:{phasesTotal:A.length,phasesCompleted:A.filter(k=>k.status==="completed").length,tasksTotal:b.length,tasksCompleted:b.filter(k=>k.status==="completed").length,blocked:A.filter(k=>k.status==="blocked").length+b.filter(k=>k.status==="blocked").length},lastSession:u,updatedAt:de},y=ge(Le);return Zu(As(e),y),y}function js(e,t){return Ss(e,()=>tl(e,t))}function I(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 Ms(e){if(e)return{id:e.id,title:e.title,status:e.status}}function nl(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(`
104
+ `).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function rl(e){return w(JSON.stringify(e))}function sl(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 I(t,30)}function Is(e){let{project:t,identity:n,state:r}=e,s=r.activeFiles?.at(-1)??r.filesTouched.at(-1),o=r.phases.filter(v=>v.status==="completed").map(v=>v.title),i=r.tasks.filter(v=>v.status==="completed").map(v=>v.title),a=r.phases.filter(v=>v.status!=="completed"&&v.status!=="cancelled").map(v=>v.title),c=r.tasks.filter(v=>v.status!=="completed"&&v.status!=="cancelled").map(v=>v.title),u=new Set(r.tasks.filter(v=>v.status==="completed").map(v=>v.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),l=I(r.nextActions.filter(v=>!u.has(v.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),d=I([...c,...l],15),p=I(r.tests.slice().reverse(),10),f=I([...(r.activeFiles??[]).slice().reverse(),...r.filesTouched.slice().reverse()],20),m={schema:"toolnet.handoff.v2",version:2,project:{id:t.id,name:t.name},source:{agent:n.agent,nativeSessionId:n.nativeSessionId,sessionKey:n.sessionKey,sequence:e.sequence,reason:e.reason},capturedAt:e.capturedAt??new Date().toISOString(),goal:r.goal,request:r.currentRequest,activity:r.currentActivity,current:{phase:Ms(r.currentPhase),task:Ms(r.currentTask),file:s},completed:{phases:I(o,20),tasks:I(i,30)},remaining:{phases:I(a,20),tasks:I(c,30),todos:d},nextAction:l[0],blockers:I(r.blockers.slice().reverse(),10),decisions:I(r.decisions.slice().reverse(),10),files:{current:s,recent:f,active:I(r.activeFiles??[],10),modified:I(r.modifiedFiles??[],20),created:I(r.createdFiles??[],20),deleted:I(r.deletedFiles??[],20)},tests:{status:nl(r.tests,r.checks),recent:p,checks:(r.checks??[]).slice(-10).map(v=>({kind:v.kind,status:v.status,command:v.command}))},evidence:{commands:I((r.commands??[]).slice().reverse(),20),references:sl([r.currentRequest,r.currentActivity,r.goal,r.plan,...r.decisions,...r.blockers,...r.warnings,...r.nextActions,...r.filesTouched,...r.commands??[],...r.tests,...(r.checks??[]).map(v=>v.command)])},attention:I(e.attention??[],20),progress:r.progress},{capturedAt:S,source:g,...h}=m;return{...m,stateDigest:rl(h)}}function al(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 Cs(e,t,n,r,s){if(!al(n))return null;let o=ms(e,!1),a=[...o?o.rules.filter(d=>d.mode==="enforce").map(d=>d.text):[],...n.warnings].slice(0,20),c=Is({project:e,identity:t,state:n,reason:r,sequence:s,attention:a}),u=c.stateDigest;return{version:1,id:w([e.id,t.sessionKey,u].join("|")).slice(0,24),projectId:e.id,projectName:e.name,createdAt:new Date().toISOString(),reason:r,sourceSession:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,sequence: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:c.remaining.todos.slice(0,10),blockers:n.blockers.slice(-10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:a,filesTouched:n.filesTouched.slice(-20),activeFiles:n.activeFiles?.slice(-10),modifiedFiles:n.modifiedFiles?.slice(-20),createdFiles:n.createdFiles?.slice(-20),deletedFiles:n.deletedFiles?.slice(-20),tests:n.tests.slice(-15),checks:n.checks?.slice(-10),stateDigest:u,continuity:c}}function Ps(e,t){let n=nn(e.rootPath,".toolnet","work","handoffs");il(n,{recursive:!0});let r=nn(n,`${t.id}.json`);ol(r)||T(r,t),T(nn(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function Es(e){let t=Cs(e.project,e.identity,e.state,e.reason,e.sequence);return t?(Ps(e.project,t),t):null}var kt=class{constructor(t){this.options=t}options;async capture(t,n){let r=tn(this.options.project);r||(r=await os(this.options.project,this.options.storage)),r||(r=await Te(this.options.project,this.options.storage));let s=Cs(this.options.project,this.options.identity,r,t,n);if(!s)return null;Ps(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)+`
105
105
  `,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(s,null,2)+`
106
- `,"application/json"),s}};import{existsSync as Zu,readFileSync as el,writeFileSync as tl}from"node:fs";import{join as nl}from"node:path";var Ms="<!-- TOOLNET:STABLE-WORK:BEGIN -->",en="<!-- TOOLNET:STABLE-WORK:END -->";function tn(e){switch(e.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function L(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${n}`)]:[]}function js(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${tn(n)} ${n.title}`)]:[]}function rl(e){let t=[Ms,"# 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:",`${tn(e.currentPhase)} ${e.currentPhase.title}`),e.currentTask&&t.push("","Current task:",`${tn(e.currentTask)} ${e.currentTask.title}`),t.push(...js("Phases",e.phases)),t.push(...js("TODO / Tasks",e.tasks)),t.push(...L("Next actions",e.nextActions)),t.push(...L("Blockers",e.blockers)),t.push(...L("Important decisions",e.decisions)),t.push(...L("Active files",e.activeFiles??[])),t.push(...L("Modified files",e.modifiedFiles??[])),t.push(...L("Created files",e.createdFiles??[])),t.push(...L("Deleted files",e.deletedFiles??[])),t.push(...L("Files touched",e.filesTouched)),t.push(...L("Recent commands",e.commands??[])),t.push(...L("Checks",(e.checks??[]).map(n=>`[${n.status}] ${n.kind}: ${n.command}`))),t.push("","Progress:",`- Phases: ${e.progress.phasesCompleted}/${e.progress.phasesTotal}`,`- Tasks: ${e.progress.tasksCompleted}/${e.progress.tasksTotal}`,`- Blocked: ${e.progress.blocked}`,"","Continuation:","- Resume current unfinished task.","- Never redo completed TODO/Phase unless explicitly requested.","- Ask ToolNet Memory for deeper history only when necessary.",en),t.join(`
107
- `)}function Is(e,t){let n=nl(e.rootPath,".toolnet","current.md"),r="";if(Zu(n))try{r=el(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=rl(t),o=r.indexOf(Ms),i=r.indexOf(en),a;o>=0&&i>=o?a=[r.slice(0,o).trimEnd(),s,r.slice(i+en.length).trimStart()].filter(Boolean).join(`
106
+ `,"application/json"),s}};import{existsSync as cl,readFileSync as ul,writeFileSync as ll}from"node:fs";import{join as dl}from"node:path";var Ts="<!-- TOOLNET:STABLE-WORK:BEGIN -->",rn="<!-- TOOLNET:STABLE-WORK:END -->";function sn(e){switch(e.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function W(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${n}`)]:[]}function Os(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${sn(n)} ${n.title}`)]:[]}function pl(e){let t=[Ts,"# 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:",`${sn(e.currentPhase)} ${e.currentPhase.title}`),e.currentTask&&t.push("","Current task:",`${sn(e.currentTask)} ${e.currentTask.title}`),t.push(...Os("Phases",e.phases)),t.push(...Os("TODO / Tasks",e.tasks)),t.push(...W("Next actions",e.nextActions)),t.push(...W("Blockers",e.blockers)),t.push(...W("Important decisions",e.decisions)),t.push(...W("Active files",e.activeFiles??[])),t.push(...W("Modified files",e.modifiedFiles??[])),t.push(...W("Created files",e.createdFiles??[])),t.push(...W("Deleted files",e.deletedFiles??[])),t.push(...W("Files touched",e.filesTouched)),t.push(...W("Recent commands",e.commands??[])),t.push(...W("Checks",(e.checks??[]).map(n=>`[${n.status}] ${n.kind}: ${n.command}`))),t.push("","Progress:",`- Phases: ${e.progress.phasesCompleted}/${e.progress.phasesTotal}`,`- Tasks: ${e.progress.tasksCompleted}/${e.progress.tasksTotal}`,`- Blocked: ${e.progress.blocked}`,"","Continuation:","- Resume current unfinished task.","- Never redo completed TODO/Phase unless explicitly requested.","- Ask ToolNet Memory for deeper history only when necessary.",rn),t.join(`
107
+ `)}function Rs(e,t){let n=dl(e.rootPath,".toolnet","current.md"),r="";if(cl(n))try{r=ul(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=pl(t),o=r.indexOf(Ts),i=r.indexOf(rn),a;o>=0&&i>=o?a=[r.slice(0,o).trimEnd(),s,r.slice(i+rn.length).trimStart()].filter(Boolean).join(`
108
108
 
109
109
  `):a=r.trim()?`${r.trim()}
110
110
 
111
- ${s}`:s,tl(n,`${a.trim()}
112
- `,{encoding:"utf8",mode:384})}import{existsSync as Gg,mkdirSync as sl,readFileSync as Ug,renameSync as ol,writeFileSync as il}from"node:fs";import{dirname as al,join as cl}from"node:path";function ul(e){return cl(e.rootPath,".toolnet","context","session-origin.json")}function ll(e,t){sl(al(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;il(n,`${JSON.stringify(t,null,2)}
113
- `,{encoding:"utf8",mode:384}),ol(n,e)}function yt(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 Cs(e,t){let n=yt(t.observations,"file"),r=yt(t.observations,"next_action"),s=yt(t.observations,"blocker"),o=yt(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 ll(ul(e),i),i}import{existsSync as Ps,mkdirSync as dl,readFileSync as pl}from"node:fs";import{join as nn}from"node:path";function Es(e){return nn(e.rootPath,".toolnet","memory","checkpoints")}function Os(e){return nn(Es(e),"latest.json")}function fl(e){let t=Os(e);if(!Ps(t))return null;try{let n=JSON.parse(pl(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function ml(e){return["rule","architecture","decision","fix"].includes(e)}function gl(e,t){return t.length===0?[]:Qe(e,t).candidates.filter(r=>ml(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 yl(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 hl(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 Ts(e,t,n,r){let s=fl(e),o=yl(s?.durableFacts??[],gl(t,n)),i=n.at(-1)?.sequence??s?.source.sequence??0,a=r.phases.filter(y=>y.status==="completed").map(y=>y.title),c=r.tasks.filter(y=>y.status==="completed").map(y=>y.title),u=r.phases.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),l=r.tasks.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),d={work:hl(r),durableFacts:o.map(y=>y.fingerprint).sort()},p=v(JSON.stringify(d)).slice(0,32),f={schema:"toolnet.memory.checkpoint.v1",version:1,project:{id:e.id,name:e.name},source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,sequence:i},capturedAt:new Date().toISOString(),request:r.currentRequest,activity:r.currentActivity,goal:r.goal,current:{phase:r.currentPhase,task:r.currentTask},completed:{phases:a,tasks:c},remaining:{phases:u,tasks:l},files:{active:r.activeFiles??[],modified:r.modifiedFiles??[],created:r.createdFiles??[],deleted:r.deletedFiles??[]},checks:r.checks??[],blockers:r.blockers.slice(-10),decisions:r.decisions.slice(-15),nextActions:r.nextActions.slice(0,10),durableFacts:o,stateDigest:p},g=Es(e);dl(g,{recursive:!0,mode:448});let S=nn(g,`${p}.json`);return Ps(S)||O(S,f),O(Os(e),f),f}function Rs(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=ut(t,n);if(r.length===0)return{updated:!1,observations:0};let s=ks(e,r);Is(e,s),Cs(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:s});try{Ts(e,t,n,s)}catch{}try{As({project:e,identity:t,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var ht=class{identity;wal;remote;sanitizer=new H;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=bn(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new Ue(this.identity,t.eventContext),this.remote=new qe(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new at({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new dt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new ft({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new gt({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{Rs(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 Sl,openSync as kl,closeSync as vl,readSync as wl,statSync as bl}from"node:fs";function xl(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 Al(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 Ns(e,t={offset:0}){if(!Sl(e))return{events:[],nextOffset:t.offset,reset:!1};let n=bl(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),a=kl(e,"r");try{wl(a,i,0,o,s)}finally{vl(a)}let c=i.toString("utf8"),u=c.lastIndexOf(`
114
- `);if(u<0)return{events:[],nextOffset:s,reset:r};let l=c.slice(0,u+1),d=Buffer.byteLength(l,"utf8"),p=[],f=0;for(let g of l.split(`
115
- `)){if(!g)continue;let S=Buffer.byteLength(g+`
116
- `,"utf8"),y=s+f;f+=S;let h;try{h=JSON.parse(g)}catch{p.push({type:"custom",sourceEventId:`transcript:${y}`,sourceSequence:y,data:{format:"raw-line",content:g},provenance:{source:"agy-transcript",sourcePath:e,sourceOffset:y}});continue}let k=h&&typeof h=="object"&&!Array.isArray(h)?h:{value:h};p.push({type:xl(k),timestamp:Al(k),role:typeof k.role=="string"?k.role:void 0,sourceEventId:`transcript:${y}`,sourceSequence:y,data:k,provenance:{source:"agy-transcript",sourcePath:e,sourceOffset:y}})}return{events:p,nextOffset:s+d,reset:r}}var jl=[/^<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*$/],Ml=[/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],Il=["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 Cl(e){let t=e.toLowerCase();return Il.some(n=>t.includes(n))}function Pl(e){if(!e.trim())return!0;for(let t of jl)if(t.test(e))return!0;return Cl(e),!1}function El(e){let t=e;for(let n of Ml)t=t.replace(n,r=>{let s=r.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return t}function rn(e){let t=e.trim();return t?Pl(t)?{content:"",filtered:!0,reason:"noise"}:{content:El(t),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function St(e){let t={};for(let[n,r]of Object.entries(e))if(typeof r=="string"){let s=rn(r);s.filtered||(t[n]=s.content)}else r&&typeof r=="object"&&!Array.isArray(r)?t[n]=St(r):Array.isArray(r)?t[n]=r.map(s=>{if(typeof s=="string"){let o=rn(s);return o.filtered?null:o.content}return s&&typeof s=="object"?St(s):s}).filter(s=>s!==null):t[n]=r;return t}function _s(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&&rn(r).filtered)return!0}return!1}function Tl(e){return e==="~"?sn():e.startsWith("~/")?$s(sn(),e.slice(2)):e}async function kt(e){let t=e.conversationId.trim();if(!t)throw new Error("Agy conversationId is required");let n=Ol(Tl(e.transcriptPath)),r=new ht({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,a=Ns(n,{offset:Number.isFinite(i)?i:0}),c=[];s.lastSequence===0&&c.push({type:"session_start",sourceEventId:`agy:${t}:start`,data:{workspacePaths:e.workspacePaths??[],transcriptPath:n,modelName:e.modelName},provenance:{source:"antigravity-hook",sourcePath:n}}),a.reset&&c.push({type:"custom",sourceEventId:`agy:${t}:transcript-reset:${a.nextOffset}`,data:{event:"transcript_reset",transcriptPath:n},provenance:{source:"agy-transcript",sourcePath:n}});let u=a.events.filter(p=>!_s(p.data)).map(p=>({...p,data:St(p.data)}));c.push(...u),e.phase==="stop"&&(e.error&&c.push({type:"error",sourceEventId:["agy",t,"stop-error",e.terminationReason??"",a.nextOffset].join(":"),data:{error:e.error,terminationReason:e.terminationReason,fullyIdle:e.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),e.fullyIdle&&c.push({type:"session_idle",sourceEventId:["agy",t,"idle",a.nextOffset].join(":"),data:{terminationReason:e.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let l=r.recordMany(c);if(r.setSourceCursor("agy.transcript.offset",a.nextOffset),e.phase&&r.setSourceCursor("agy.last.phase",e.phase),u.length>0)try{let p=u.map(g=>JSON.stringify(g.data)),f=Xe(p,t);r.setSourceCursor("agy.session.summary",f.summary),r.setSourceCursor("agy.session.facts_count",f.durableFacts.length),Qn()&&(tr()||r.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let d=await r.flush();return{conversationId:t,imported:l.length,eventCount:d.eventCount,chunkCount:d.chunkCount,status:d.status,transcriptOffset:a.nextOffset,reset:a.reset}}function Ks(e){return $s(sn(),".gemini","antigravity-cli","brain",e,".system_generated","logs","transcript.jsonl")}import{existsSync as ed,mkdirSync as Js,readFileSync as td,renameSync as nd,writeFileSync as rd}from"node:fs";import{dirname as sd,join as wt}from"node:path";import{existsSync as $l,mkdirSync as Kl,readFileSync as Ll,renameSync as Wl,rmSync as Fl,writeFileSync as Dl}from"node:fs";import{dirname as zl,join as ql}from"node:path";import{homedir as Rl}from"node:os";import{join as ae}from"node:path";function Ls(e={}){return ae(e.home??Rl(),".gemini")}function Nl(e={}){return ae(Ls(e),"antigravity-cli")}function _l(e={}){return ae(Ls(e),"config")}function Oe(e={}){return ae(_l(e),"mcp_config.json")}function Te(e={}){let t=e.cwd??process.cwd();return ae(t,".agents","mcp_config.json")}function ce(e="toolnet-memory",t={}){return ae(Nl(t),"plugins",e)}function Jl(e){return`'${e.replace(/'/g,"'\\''")}'`}function Vl(e){if(!$l(e))return{};let t;try{t=JSON.parse(Ll(e,"utf8"))}catch{throw new Error(`Invalid existing Agy hooks.json at ${e}: parse error. Not overwriting.`)}if(typeof t!="object"||t===null||Array.isArray(t))throw new Error(`Invalid existing Agy hooks.json at ${e}: root must be a JSON object.`);return t}function Bl(e,t){Kl(zl(e),{recursive:!0,mode:448});let n=`${e}.tmp-${process.pid}-${Date.now()}`;try{Dl(n,`${JSON.stringify(t,null,2)}
117
- `,{encoding:"utf8",mode:384}),Wl(n,e)}finally{Fl(n,{force:!0})}}function Ws(e={}){let t=e.pluginName??"toolnet-memory",n=e.hooksFile??ql(ce(t),"hooks.json"),r=Vl(n),s=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=`${Jl(s)} session:agy-hook`;return r["toolnet-memory"]={enabled:!0,PreToolUse:[{matcher:"view_file|list_dir|find_by_name|grep_search|run_command",hooks:[{type:"command",command:`${o} pre-tool`,timeout:5}]}],PreInvocation:[{type:"command",command:`${o} pre`,timeout:15}],PostInvocation:[{type:"command",command:`${o} post`,timeout:15}],Stop:[{type:"command",command:`${o} stop`,timeout:30}]},Bl(n,r),n}import{existsSync as Hl,mkdirSync as Gl,readFileSync as Ul,renameSync as Yl,writeFileSync as Xl}from"node:fs";import{dirname as Ql}from"node:path";function Re(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Zl(e,t){Gl(Ql(e),{recursive:!0,mode:448});let n=`${e}.tmp-${process.pid}-${Date.now()}`;Xl(n,`${JSON.stringify(t,null,2)}
118
- `,{encoding:"utf8",mode:384}),Yl(n,e)}function Fs(e){if(!Hl(e))return{};let t=Ul(e,"utf8").trim();if(!t)return{};let n;try{n=JSON.parse(t)}catch{throw new Error(`Invalid existing Agy MCP config at ${e}: parse error. Not overwriting.`)}if(!Re(n))throw new Error(`Invalid existing Agy MCP config at ${e}: root must be a JSON object. Not overwriting.`);return n}function Ds(e,t){return Re(e)?e.command===t&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp":!1}function vt(e,t,n,r){let s=Fs(e),o=s.mcpServers;if(o!==void 0&&!Re(o))throw new Error(`Invalid existing Agy MCP config: mcpServers must be an object in ${e}.`);let i=Re(o)?{...o}:{},a=i[n];if(Ds(a,t)&&!r)return{installed:!0,changed:!1};i[n]={command:t,args:["mcp"]};let c={...s,mcpServers:i};Zl(e,c);let l=Fs(e).mcpServers;if(!Re(l)||!Ds(l[n],t))throw new Error(`Agy MCP configuration was written but verification failed for ${e}.`);return{installed:!0,changed:!0}}function zs(e={}){let t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=e.serverName??"toolnet-memory",r=e.scope??"global";if(e.configFile)return{...vt(e.configFile,t,n,e.force??!1),configFile:e.configFile,serverName:n,command:t,args:["mcp"]};if(r==="both"){let i=Oe(),a=Te({cwd:e.cwd}),c=vt(i,t,n,e.force??!1),u=vt(a,t,n,e.force??!1);return{installed:!0,changed:c.changed||u.changed,configFile:i,serverName:n,command:t,args:["mcp"]}}let s=r==="workspace"?Te({cwd:e.cwd}):Oe();return{...vt(s,t,n,e.force??!1),configFile:s,serverName:n,command:t,args:["mcp"]}}var od=`# ToolNet Memory Continuity
111
+ ${s}`:s,ll(n,`${a.trim()}
112
+ `,{encoding:"utf8",mode:384})}import{existsSync as cy,mkdirSync as fl,readFileSync as uy,renameSync as ml,writeFileSync as gl}from"node:fs";import{dirname as yl,join as hl}from"node:path";function Sl(e){return hl(e.rootPath,".toolnet","context","session-origin.json")}function kl(e,t){fl(yl(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;gl(n,`${JSON.stringify(t,null,2)}
113
+ `,{encoding:"utf8",mode:384}),ml(n,e)}function vt(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 Ns(e,t){let n=vt(t.observations,"file"),r=vt(t.observations,"next_action"),s=vt(t.observations,"blocker"),o=vt(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 kl(Sl(e),i),i}import{existsSync as _s,mkdirSync as vl,readFileSync as wl}from"node:fs";import{join as on}from"node:path";function $s(e){return on(e.rootPath,".toolnet","memory","checkpoints")}function Ks(e){return on($s(e),"latest.json")}function bl(e){let t=Ks(e);if(!_s(t))return null;try{let n=JSON.parse(wl(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function xl(e){return["rule","architecture","decision","fix"].includes(e)}function Al(e,t){return t.length===0?[]:nt(e,t).candidates.filter(r=>xl(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 jl(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 Ml(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 Ls(e,t,n,r){let s=bl(e),o=jl(s?.durableFacts??[],Al(t,n)),i=n.at(-1)?.sequence??s?.source.sequence??0,a=r.phases.filter(g=>g.status==="completed").map(g=>g.title),c=r.tasks.filter(g=>g.status==="completed").map(g=>g.title),u=r.phases.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),l=r.tasks.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),d={work:Ml(r),durableFacts:o.map(g=>g.fingerprint).sort()},p=w(JSON.stringify(d)).slice(0,32),f={schema:"toolnet.memory.checkpoint.v1",version:1,project:{id:e.id,name:e.name},source:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,sequence:i},capturedAt:new Date().toISOString(),request:r.currentRequest,activity:r.currentActivity,goal:r.goal,current:{phase:r.currentPhase,task:r.currentTask},completed:{phases:a,tasks:c},remaining:{phases:u,tasks:l},files:{active:r.activeFiles??[],modified:r.modifiedFiles??[],created:r.createdFiles??[],deleted:r.deletedFiles??[]},checks:r.checks??[],blockers:r.blockers.slice(-10),decisions:r.decisions.slice(-15),nextActions:r.nextActions.slice(0,10),durableFacts:o,stateDigest:p},m=$s(e);vl(m,{recursive:!0,mode:448});let S=on(m,`${p}.json`);return _s(S)||T(S,f),T(Ks(e),f),f}function Ws(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=ft(t,n);if(r.length===0)return{updated:!1,observations:0};let s=js(e,r);Rs(e,s),Ns(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:s});try{Ls(e,t,n,s)}catch{}try{Es({project:e,identity:t,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var wt=class{identity;wal;remote;sanitizer=new J;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=Cn(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 He(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new dt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new gt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new ht({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new kt({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{Ws(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 Il,openSync as Cl,closeSync as Pl,readSync as El,statSync as Ol}from"node:fs";function Tl(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 Rl(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 Fs(e,t={offset:0}){if(!Il(e))return{events:[],nextOffset:t.offset,reset:!1};let n=Ol(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),a=Cl(e,"r");try{El(a,i,0,o,s)}finally{Pl(a)}let c=i.toString("utf8"),u=c.lastIndexOf(`
114
+ `);if(u<0)return{events:[],nextOffset:s,reset:r};let l=c.slice(0,u+1),d=Buffer.byteLength(l,"utf8"),p=[],f=0;for(let m of l.split(`
115
+ `)){if(!m)continue;let S=Buffer.byteLength(m+`
116
+ `,"utf8"),g=s+f;f+=S;let h;try{h=JSON.parse(m)}catch{p.push({type:"custom",sourceEventId:`transcript:${g}`,sourceSequence:g,data:{format:"raw-line",content:m},provenance:{source:"agy-transcript",sourcePath:e,sourceOffset:g}});continue}let v=h&&typeof h=="object"&&!Array.isArray(h)?h:{value:h};p.push({type:Tl(v),timestamp:Rl(v),role:typeof v.role=="string"?v.role:void 0,sourceEventId:`transcript:${g}`,sourceSequence:g,data:v,provenance:{source:"agy-transcript",sourcePath:e,sourceOffset:g}})}return{events:p,nextOffset:s+d,reset:r}}var Nl=[/^<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*$/],_l=[/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],$l=["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 Kl(e){let t=e.toLowerCase();return $l.some(n=>t.includes(n))}function Ll(e){if(!e.trim())return!0;for(let t of Nl)if(t.test(e))return!0;return Kl(e),!1}function Wl(e){let t=e;for(let n of _l)t=t.replace(n,r=>{let s=r.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return t}function an(e){let t=e.trim();return t?Ll(t)?{content:"",filtered:!0,reason:"noise"}:{content:Wl(t),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function bt(e){let t={};for(let[n,r]of Object.entries(e))if(typeof r=="string"){let s=an(r);s.filtered||(t[n]=s.content)}else r&&typeof r=="object"&&!Array.isArray(r)?t[n]=bt(r):Array.isArray(r)?t[n]=r.map(s=>{if(typeof s=="string"){let o=an(s);return o.filtered?null:o.content}return s&&typeof s=="object"?bt(s):s}).filter(s=>s!==null):t[n]=r;return t}function Ds(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&&an(r).filtered)return!0}return!1}function Dl(e){return e==="~"?cn():e.startsWith("~/")?zs(cn(),e.slice(2)):e}async function xt(e){let t=e.conversationId.trim();if(!t)throw new Error("Agy conversationId is required");let n=Fl(Dl(e.transcriptPath)),r=new wt({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,a=Fs(n,{offset:Number.isFinite(i)?i:0}),c=[];s.lastSequence===0&&c.push({type:"session_start",sourceEventId:`agy:${t}:start`,data:{workspacePaths:e.workspacePaths??[],transcriptPath:n,modelName:e.modelName},provenance:{source:"antigravity-hook",sourcePath:n}}),a.reset&&c.push({type:"custom",sourceEventId:`agy:${t}:transcript-reset:${a.nextOffset}`,data:{event:"transcript_reset",transcriptPath:n},provenance:{source:"agy-transcript",sourcePath:n}});let u=a.events.filter(p=>!Ds(p.data)).map(p=>({...p,data:bt(p.data)}));c.push(...u),e.phase==="stop"&&(e.error&&c.push({type:"error",sourceEventId:["agy",t,"stop-error",e.terminationReason??"",a.nextOffset].join(":"),data:{error:e.error,terminationReason:e.terminationReason,fullyIdle:e.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),e.fullyIdle&&c.push({type:"session_idle",sourceEventId:["agy",t,"idle",a.nextOffset].join(":"),data:{terminationReason:e.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let l=r.recordMany(c);if(r.setSourceCursor("agy.transcript.offset",a.nextOffset),e.phase&&r.setSourceCursor("agy.last.phase",e.phase),u.length>0)try{let p=u.map(m=>JSON.stringify(m.data)),f=tt(p,t);r.setSourceCursor("agy.session.summary",f.summary),r.setSourceCursor("agy.session.facts_count",f.durableFacts.length),sr()&&(ar()||r.setSourceCursor("agy.raw_transcript.archived","local"))}catch{}let d=await r.flush();return{conversationId:t,imported:l.length,eventCount:d.eventCount,chunkCount:d.chunkCount,status:d.status,transcriptOffset:a.nextOffset,reset:a.reset}}function qs(e){return zs(cn(),".gemini","antigravity-cli","brain",e,".system_generated","logs","transcript.jsonl")}import{existsSync as ud,mkdirSync as Ys,readFileSync as ld,renameSync as dd,writeFileSync as pd}from"node:fs";import{dirname as fd,join as jt}from"node:path";import{existsSync as Vl,mkdirSync as Bl,readFileSync as Hl,renameSync as Gl,rmSync as Ul,writeFileSync as Yl}from"node:fs";import{dirname as Xl,join as Zl}from"node:path";import{homedir as zl}from"node:os";import{join as ue}from"node:path";function Js(e={}){return ue(e.home??zl(),".gemini")}function ql(e={}){return ue(Js(e),"antigravity-cli")}function Jl(e={}){return ue(Js(e),"config")}function Re(e={}){return ue(Jl(e),"mcp_config.json")}function Ne(e={}){let t=e.cwd??process.cwd();return ue(t,".agents","mcp_config.json")}function le(e="toolnet-memory",t={}){return ue(ql(t),"plugins",e)}function Ql(e){return`'${e.replace(/'/g,"'\\''")}'`}function ed(e){if(!Vl(e))return{};let t;try{t=JSON.parse(Hl(e,"utf8"))}catch{throw new Error(`Invalid existing Agy hooks.json at ${e}: parse error. Not overwriting.`)}if(typeof t!="object"||t===null||Array.isArray(t))throw new Error(`Invalid existing Agy hooks.json at ${e}: root must be a JSON object.`);return t}function td(e,t){Bl(Xl(e),{recursive:!0,mode:448});let n=`${e}.tmp-${process.pid}-${Date.now()}`;try{Yl(n,`${JSON.stringify(t,null,2)}
117
+ `,{encoding:"utf8",mode:384}),Gl(n,e)}finally{Ul(n,{force:!0})}}function Vs(e={}){let t=e.pluginName??"toolnet-memory",n=e.hooksFile??Zl(le(t),"hooks.json"),r=ed(n),s=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",o=`${Ql(s)} session:agy-hook`;return r["toolnet-memory"]={enabled:!0,PreToolUse:[{matcher:"view_file|list_dir|find_by_name|grep_search|run_command",hooks:[{type:"command",command:`${o} pre-tool`,timeout:5}]}],PreInvocation:[{type:"command",command:`${o} pre`,timeout:15}],PostInvocation:[{type:"command",command:`${o} post`,timeout:15}],Stop:[{type:"command",command:`${o} stop`,timeout:30}]},td(n,r),n}import{existsSync as nd,mkdirSync as rd,readFileSync as sd,renameSync as od,writeFileSync as id}from"node:fs";import{dirname as ad}from"node:path";function _e(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function cd(e,t){rd(ad(e),{recursive:!0,mode:448});let n=`${e}.tmp-${process.pid}-${Date.now()}`;id(n,`${JSON.stringify(t,null,2)}
118
+ `,{encoding:"utf8",mode:384}),od(n,e)}function Bs(e){if(!nd(e))return{};let t=sd(e,"utf8").trim();if(!t)return{};let n;try{n=JSON.parse(t)}catch{throw new Error(`Invalid existing Agy MCP config at ${e}: parse error. Not overwriting.`)}if(!_e(n))throw new Error(`Invalid existing Agy MCP config at ${e}: root must be a JSON object. Not overwriting.`);return n}function Hs(e,t){return _e(e)?e.command===t&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp":!1}function At(e,t,n,r){let s=Bs(e),o=s.mcpServers;if(o!==void 0&&!_e(o))throw new Error(`Invalid existing Agy MCP config: mcpServers must be an object in ${e}.`);let i=_e(o)?{...o}:{},a=i[n];if(Hs(a,t)&&!r)return{installed:!0,changed:!1};i[n]={command:t,args:["mcp"]};let c={...s,mcpServers:i};cd(e,c);let l=Bs(e).mcpServers;if(!_e(l)||!Hs(l[n],t))throw new Error(`Agy MCP configuration was written but verification failed for ${e}.`);return{installed:!0,changed:!0}}function Gs(e={}){let t=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",n=e.serverName??"toolnet-memory",r=e.scope??"global";if(e.configFile)return{...At(e.configFile,t,n,e.force??!1),configFile:e.configFile,serverName:n,command:t,args:["mcp"]};if(r==="both"){let i=Re(),a=Ne({cwd:e.cwd}),c=At(i,t,n,e.force??!1),u=At(a,t,n,e.force??!1);return{installed:!0,changed:c.changed||u.changed,configFile:i,serverName:n,command:t,args:["mcp"]}}let s=r==="workspace"?Ne({cwd:e.cwd}):Re();return{...At(s,t,n,e.force??!1),configFile:s,serverName:n,command:t,args:["mcp"]}}var md=`# ToolNet Memory Continuity
119
119
 
120
120
  ToolNet Memory is the authoritative continuity layer for previous project work.
121
121
 
@@ -154,9 +154,9 @@ Invoke the MCP tool directly.
154
154
  Current repository evidence overrides stale memory after ToolNet has restored the working context.
155
155
 
156
156
  Do not ask the user to repeat context already available through ToolNet Memory.
157
- `;function id(e,t){Js(sd(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;rd(n,t,{encoding:"utf8",mode:384}),nd(n,e)}function qs(e,t){ed(e)&&td(e,"utf8")===t||id(e,t)}function Vs(e={}){let t=e.pluginName??"toolnet-memory",n=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=e.pluginRoot??ce(t),s=wt(r,"plugin.json"),o=wt(r,"mcp_config.json"),i=wt(r,"hooks.json"),a=wt(r,"rules","toolnet-memory-continuity.md");return Js(r,{recursive:!0,mode:448}),qs(s,`${JSON.stringify({$schema:"https://antigravity.google/schemas/v1/plugin.json",name:t,description:"Persistent project continuity and memory for Antigravity coding sessions."},null,2)}
158
- `),zs({configFile:o,binary:n,serverName:"toolnet-memory",force:e.force}),Ws({hooksFile:i,binary:n,pluginName:t}),qs(a,`${od.trim()}
159
- `),{installed:!0,pluginRoot:r,files:[s,o,i,a]}}import{existsSync as Bs}from"node:fs";import{homedir as ad}from"node:os";import{join as cd,resolve as Hs}from"node:path";import{DatabaseSync as ud}from"node:sqlite";function Gs(e){if(e.startsWith("file://"))try{return decodeURIComponent(new URL(e).pathname)}catch{return e}return e}function ld(e){if(typeof e!="string"||!e)return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.filter(n=>typeof n=="string").map(Gs)}catch{}return[Gs(e)]}function dd(e,t){let n=Hs(e.rootPath);return t.some(r=>{let s=Hs(r);return s===n||s.startsWith(n+"/")||n.startsWith(s+"/")})}async function Us(e,t,n=10){console.log(`Recovering Agy sessions for project: ${e.name}`),console.log(`Limit: ${n} sessions`),console.log("");let r=process.env.AGY_SUMMARY_DB??cd(ad(),".gemini","antigravity-cli","conversation_summaries.db");if(!Bs(r))throw new Error(`Agy summary database not found: ${r}`);let s=new ud(r,{readOnly:!0});s.exec("PRAGMA query_only = ON");let o=s.prepare(`
157
+ `;function gd(e,t){Ys(fd(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;pd(n,t,{encoding:"utf8",mode:384}),dd(n,e)}function Us(e,t){ud(e)&&ld(e,"utf8")===t||gd(e,t)}function Xs(e={}){let t=e.pluginName??"toolnet-memory",n=e.binary??process.env.TOOLNET_MEMORY_BIN??"toolnet-memory",r=e.pluginRoot??le(t),s=jt(r,"plugin.json"),o=jt(r,"mcp_config.json"),i=jt(r,"hooks.json"),a=jt(r,"rules","toolnet-memory-continuity.md");return Ys(r,{recursive:!0,mode:448}),Us(s,`${JSON.stringify({$schema:"https://antigravity.google/schemas/v1/plugin.json",name:t,description:"Persistent project continuity and memory for Antigravity coding sessions."},null,2)}
158
+ `),Gs({configFile:o,binary:n,serverName:"toolnet-memory",force:e.force}),Vs({hooksFile:i,binary:n,pluginName:t}),Us(a,`${md.trim()}
159
+ `),{installed:!0,pluginRoot:r,files:[s,o,i,a]}}import{existsSync as Zs}from"node:fs";import{homedir as yd}from"node:os";import{join as hd,resolve as Qs}from"node:path";import{DatabaseSync as Sd}from"node:sqlite";function eo(e){if(e.startsWith("file://"))try{return decodeURIComponent(new URL(e).pathname)}catch{return e}return e}function kd(e){if(typeof e!="string"||!e)return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.filter(n=>typeof n=="string").map(eo)}catch{}return[eo(e)]}function vd(e,t){let n=Qs(e.rootPath);return t.some(r=>{let s=Qs(r);return s===n||s.startsWith(n+"/")||n.startsWith(s+"/")})}async function to(e,t,n=10){console.log(`Recovering Agy sessions for project: ${e.name}`),console.log(`Limit: ${n} sessions`),console.log("");let r=process.env.AGY_SUMMARY_DB??hd(yd(),".gemini","antigravity-cli","conversation_summaries.db");if(!Zs(r))throw new Error(`Agy summary database not found: ${r}`);let s=new Sd(r,{readOnly:!0});s.exec("PRAGMA query_only = ON");let o=s.prepare(`
160
160
  SELECT
161
161
  conversation_id,
162
162
  title,
@@ -166,7 +166,7 @@ Do not ask the user to repeat context already available through ToolNet Memory.
166
166
  FROM conversation_summaries
167
167
  ORDER BY
168
168
  last_user_input_time DESC
169
- `).all();s.close();let i=[],a=0,c=Math.min(o.length,n);for(let u of o){let l=typeof u.conversation_id=="string"?u.conversation_id:"";if(!l)continue;let d=ld(u.workspace_uris);if(!dd(e,d))continue;let p=Ks(l);if(!Bs(p))continue;a++,console.log(`[${a}/${c}] Processing conversation: ${l.slice(0,8)}...`);let f=await kt({project:e,storage:t,conversationId:l,transcriptPath:p,workspacePaths:d,modelName:typeof u.agent_name=="string"?u.agent_name:void 0,phase:"recover"});if(console.log(` \u2713 Imported ${f.imported} events (${f.eventCount} total, ${f.chunkCount} chunks)`),i.push(f),i.length>=n)break}return console.log(""),console.log(`\u2713 Recovery complete: ${i.length} sessions processed`),console.log(`Total events: ${i.reduce((u,l)=>u+l.eventCount,0)}`),console.log(`Total chunks: ${i.reduce((u,l)=>u+l.chunkCount,0)}`),i}import{spawnSync as pd}from"node:child_process";function _e(e,t){let n=e.indexOf(t);return n>=0?e[n+1]:void 0}function Ys(e,t){return e.includes(t)}function fd(e){let t=$e(),n=yn(mn({provider:t.storage.provider,huggingface:t.storage.huggingface,localRoot:t.storage.localRoot}),{attempts:3});return new ze(n,e.id,e.name,e.remote??e.name)}function md(){return pd("sh",["-lc","command -v agy >/dev/null 2>&1"],{stdio:"ignore"}).status===0}function gd(e){let t=[],n=md();n||t.push("agy binary not found");let r=Oe(),s=Ne(r);s||t.push(`Global MCP config missing: ${r}`);let o=Te({cwd:e}),i=Ne(o),a=ce(),c=Ne(a);c||t.push(`Plugin directory missing: ${a}`);let u=`${a}/hooks.json`,l=Ne(u);!l&&c&&t.push(`Hooks file missing: ${u}`);let d=`${a}/rules/toolnet-memory-continuity.md`,p=Ne(d);return!p&&c&&t.push(`Continuity rule missing: ${d}`),{agyBinaryDetected:n,globalMcpReady:s,workspaceMcpReady:i,pluginReady:c,hooksReady:l,continuityRuleReady:p,errors:t}}async function yd(){let[e="help",...t]=process.argv.slice(2),n=Ys(t,"--json"),r=Ys(t,"--force"),s=_e(t,"--scope")??"global",o=_e(t,"--project")??process.cwd();if(e==="status"){let c=gd(o);if(n)console.log(JSON.stringify(c,null,2));else if(console.log("AGY / Antigravity CLI Integration"),console.log("================================="),console.log(""),console.log(`Binary detected : ${c.agyBinaryDetected?"\u2713":"\u2717"}`),console.log(`Global MCP ready : ${c.globalMcpReady?"\u2713":"\u2717"}`),console.log(`Workspace MCP : ${c.workspaceMcpReady?"\u2713":"\u2717"}`),console.log(`Plugin ready : ${c.pluginReady?"\u2713":"\u2717"}`),console.log(`Hooks ready : ${c.hooksReady?"\u2713":"\u2717"}`),console.log(`Continuity rule : ${c.continuityRuleReady?"\u2713":"\u2717"}`),c.errors.length>0){console.log("");for(let u of c.errors)console.log(` \u26A0 ${u}`)}c.agyBinaryDetected||(process.exitCode=1);return}if(e==="install-hooks"||e==="install-plugin"){let c=Vs({binary:_e(t,"--bin"),scope:s,cwd:o,force:r});if(n)console.log(JSON.stringify(c,null,2));else{console.log(`\u2705 ToolNet Antigravity plugin installed: ${c.pluginRoot}`);for(let u of c.files)console.log(` \u2713 ${u}`);console.log(""),console.log("Restart Antigravity CLI before testing.")}return}let i=new Le().detect(o),a=fd(i);if(e==="sync"){let c=t[0],u=_e(t,"--transcript");if(!c||!u)throw new Error("Usage: sync <conversation-id> --transcript <path>");let l=await kt({project:i,storage:a,conversationId:c,transcriptPath:u,phase:"recover"});console.log(JSON.stringify(l,null,2));return}if(e==="recover"){let c=Number(_e(t,"--limit")??100),u=await Us(i,a,Number.isFinite(c)?c:100);console.log(JSON.stringify({project:i.name,sessions:u.length,imported:u.reduce((l,d)=>l+d.imported,0)},null,2));return}console.log(`Agy Session Adapter
169
+ `).all();s.close();let i=[],a=0,c=Math.min(o.length,n);for(let u of o){let l=typeof u.conversation_id=="string"?u.conversation_id:"";if(!l)continue;let d=kd(u.workspace_uris);if(!vd(e,d))continue;let p=qs(l);if(!Zs(p))continue;a++,console.log(`[${a}/${c}] Processing conversation: ${l.slice(0,8)}...`);let f=await xt({project:e,storage:t,conversationId:l,transcriptPath:p,workspacePaths:d,modelName:typeof u.agent_name=="string"?u.agent_name:void 0,phase:"recover"});if(console.log(` \u2713 Imported ${f.imported} events (${f.eventCount} total, ${f.chunkCount} chunks)`),i.push(f),i.length>=n)break}return console.log(""),console.log(`\u2713 Recovery complete: ${i.length} sessions processed`),console.log(`Total events: ${i.reduce((u,l)=>u+l.eventCount,0)}`),console.log(`Total chunks: ${i.reduce((u,l)=>u+l.chunkCount,0)}`),i}import{spawnSync as wd}from"node:child_process";function Ke(e,t){let n=e.indexOf(t);return n>=0?e[n+1]:void 0}function no(e,t){return e.includes(t)}function bd(e){let t=We(),n=bn(vn({provider:t.storage.provider,huggingface:t.storage.huggingface,localRoot:t.storage.localRoot}),{attempts:3});return new Be(n,e.id,e.name,e.remote??e.name)}function xd(){return wd("sh",["-lc","command -v agy >/dev/null 2>&1"],{stdio:"ignore"}).status===0}function Ad(e){let t=[],n=xd();n||t.push("agy binary not found");let r=Re(),s=$e(r);s||t.push(`Global MCP config missing: ${r}`);let o=Ne({cwd:e}),i=$e(o),a=le(),c=$e(a);c||t.push(`Plugin directory missing: ${a}`);let u=`${a}/hooks.json`,l=$e(u);!l&&c&&t.push(`Hooks file missing: ${u}`);let d=`${a}/rules/toolnet-memory-continuity.md`,p=$e(d);return!p&&c&&t.push(`Continuity rule missing: ${d}`),{agyBinaryDetected:n,globalMcpReady:s,workspaceMcpReady:i,pluginReady:c,hooksReady:l,continuityRuleReady:p,errors:t}}async function jd(){let[e="help",...t]=process.argv.slice(2),n=no(t,"--json"),r=no(t,"--force"),s=Ke(t,"--scope")??"global",o=Ke(t,"--project")??process.cwd();if(e==="status"){let c=Ad(o);if(n)console.log(JSON.stringify(c,null,2));else if(console.log("AGY / Antigravity CLI Integration"),console.log("================================="),console.log(""),console.log(`Binary detected : ${c.agyBinaryDetected?"\u2713":"\u2717"}`),console.log(`Global MCP ready : ${c.globalMcpReady?"\u2713":"\u2717"}`),console.log(`Workspace MCP : ${c.workspaceMcpReady?"\u2713":"\u2717"}`),console.log(`Plugin ready : ${c.pluginReady?"\u2713":"\u2717"}`),console.log(`Hooks ready : ${c.hooksReady?"\u2713":"\u2717"}`),console.log(`Continuity rule : ${c.continuityRuleReady?"\u2713":"\u2717"}`),c.errors.length>0){console.log("");for(let u of c.errors)console.log(` \u26A0 ${u}`)}c.agyBinaryDetected||(process.exitCode=1);return}if(e==="install-hooks"||e==="install-plugin"){let c=Xs({binary:Ke(t,"--bin"),scope:s,cwd:o,force:r});if(n)console.log(JSON.stringify(c,null,2));else{console.log(`\u2705 ToolNet Antigravity plugin installed: ${c.pluginRoot}`);for(let u of c.files)console.log(` \u2713 ${u}`);console.log(""),console.log("Restart Antigravity CLI before testing.")}return}let i=new qe().detect(o),a=bd(i);if(e==="sync"){let c=t[0],u=Ke(t,"--transcript");if(!c||!u)throw new Error("Usage: sync <conversation-id> --transcript <path>");let l=await xt({project:i,storage:a,conversationId:c,transcriptPath:u,phase:"recover"});console.log(JSON.stringify(l,null,2));return}if(e==="recover"){let c=Number(Ke(t,"--limit")??100),u=await to(i,a,Number.isFinite(c)?c:100);console.log(JSON.stringify({project:i.name,sessions:u.length,imported:u.reduce((l,d)=>l+d.imported,0)},null,2));return}console.log(`Agy Session Adapter
170
170
 
171
171
  Commands:
172
172
  install-hooks / install-plugin
@@ -185,4 +185,4 @@ Commands:
185
185
  recover
186
186
  --project PATH Project root
187
187
  --limit N Max sessions (default: 100)
188
- `)}yd().catch(e=>{console.error(e instanceof Error?e.message:e),process.exit(1)});
188
+ `)}jd().catch(e=>{console.error(e instanceof Error?e.message:e),process.exit(1)});