toolnet-memory 0.2.19 → 0.2.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/toolnet-memory +71 -0
- package/bundle/agy-hook.js +40 -39
- package/bundle/agy.js +82 -34
- package/bundle/auto-integrate.js +66 -19
- package/bundle/claude-hook.js +73 -0
- package/bundle/claude.js +3 -0
- package/bundle/codex-context.js +19 -19
- package/bundle/codex.js +61 -60
- package/bundle/context-runtime.js +30 -30
- package/bundle/context.js +15 -14
- package/bundle/continuity-certify.js +49 -0
- package/bundle/doctor.js +4 -4
- package/bundle/full-index.js +18 -8
- package/bundle/graph-index.js +4 -4
- package/bundle/handoff-refresh.js +8 -8
- package/bundle/impact.js +3 -3
- package/bundle/incremental.js +4 -4
- package/bundle/init.js +763 -0
- package/bundle/learner.js +5 -5
- package/bundle/mcp.js +17 -15
- package/bundle/memory-agent.js +10 -11
- package/bundle/memory-query.js +7 -7
- package/bundle/opencode.js +54 -53
- package/bundle/production-certify.js +5 -0
- package/bundle/project-manual.js +6 -6
- package/bundle/recovery-certify.js +55 -0
- package/bundle/runtime.js +10 -10
- package/bundle/semantic.js +6 -6
- package/bundle/setup.js +69 -22
- package/bundle/snapshot.js +4 -4
- package/bundle/update.js +4 -1
- package/bundle/work-continuity.js +6 -6
- package/package.json +1 -1
package/bundle/codex.js
CHANGED
|
@@ -1,26 +1,34 @@
|
|
|
1
|
-
import{existsSync as
|
|
2
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function
|
|
3
|
-
`,{encoding:"utf8",mode:384}),_n(s,r)}function Ve(t,e){return{id:t.id,name:t.name,remote:t.remote,rootPath:e,createdAt:t.createdAt,updatedAt:t.updatedAt,graphVersion:t.graphVersion,memoryVersion:t.memoryVersion,metadata:t.metadata}}var _=class{detect(e=process.cwd()){let n=J(e),r=Bn(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>Pe(Q(r,f))),i=Kn(n,o?r:void 0);if(i){let f=Oe(i),l=zn(f);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),He(i,l)),Ve(l,i)}let c=new Date().toISOString(),u=Fn(r),a={version:1,id:Wn(r),name:u,remote:u,rootPath:r,createdAt:c,updatedAt:c,graphVersion:0,memoryVersion:0};return He(r,a),Ve(a,r)}};var Jn=[{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}],Z=class{scan(e){let n=[];for(let r of Jn){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of e.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(e){return this.scan(e).length>0}};var q=class{scanner=new Z;sanitize(e){let n=e,r=this.scanner.scan(e),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(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(n=>this.sanitizeValue(n));if(e&&typeof e=="object"){let n={};for(let[r,s]of Object.entries(e)){let o=r.toLowerCase();o.includes("password")||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")?n[r]="[REDACTED]":n[r]=this.sanitizeValue(s)}return n}return e}};import{homedir as fr}from"node:os";import{join as mr}from"node:path";import{DeleteObjectCommand as qn,GetObjectCommand as Hn,HeadObjectCommand as Vn,ListObjectsV2Command as Un,PutObjectCommand as Yn,S3Client as Gn}from"@aws-sdk/client-s3";import{getSignedUrl as Xn}from"@aws-sdk/s3-request-presigner";var ee=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Gn({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Yn({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await Xn(this.client,new Hn({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new Vn({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new qn({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new Un({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as Ge,mkdir as Qn,readFile as Zn,readdir as er,rm as tr,stat as Xe,writeFile as nr}from"node:fs/promises";import{dirname as rr,join as sr,relative as Qe,resolve as or}from"node:path";var H=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return or(this.root,n)}async put(e,n){let r=this.path(e);await Qn(rr(r),{recursive:!0}),await nr(r,n)}async get(e){try{return await Zn(this.path(e))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await Ge(this.path(e)),!0}catch{return!1}}async delete(e){await tr(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await Ge(n)}catch{return r}let s=async i=>{let c=await er(i,{withFileTypes:!0});for(let u of c){let a=sr(i,u.name);if(u.isDirectory()){await s(a);continue}let f=await Xe(a);r.push({key:Qe(this.root,a),size:f.size,updatedAt:f.mtime.toISOString()})}},o=await Xe(n);return o.isDirectory()?await s(n):r.push({key:Qe(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as ir,GetObjectCommand as ar,HeadObjectCommand as cr,ListObjectsV2Command as ur,PutObjectCommand as lr,S3Client as dr}from"@aws-sdk/client-s3";import{getSignedUrl as pr}from"@aws-sdk/s3-request-presigner";var V=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new dr({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new lr({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await pr(this.client,new ar({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new cr({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new ir({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new ur({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};function Ee(t,e){return console.warn(e),new H(t)}function Ze(t){let e=t.localRoot??mr(fr(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new V({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Ee(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let n=t.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?new V({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Ee(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let n=t.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new ee({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Ee(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new H(e)}function gr(t){return new Promise(e=>setTimeout(e,t))}async function et(t,e={}){let n=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await t()}catch(c){if(o=c,i>=n)break;let u=Math.min(s,r*2**(i-1)),a=Math.floor(Math.random()*Math.max(1,u*.2));await gr(u+a)}throw o}var hr=new Set(["put","get","getText","delete","list"]);function tt(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:hr.has(r)?(...o)=>et(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function nt(t){let e=t.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function rt(t){let e=t.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let n=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var te=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=nt(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(c){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${c instanceof Error?c.message:String(c)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(e,JSON.stringify(o,null,2)+`
|
|
4
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=
|
|
5
|
-
`,{encoding:"utf8",mode:384}),
|
|
6
|
-
`,"application/json")}async scan(e){let n=`${e.remotePrefix}/events/`,r=await this.storage.list(n),s=[],o=0;for(let i of r){let
|
|
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(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let n=await this.scan(e);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(e,n,r,s={}){let o=await this.loadManifest(e),i=await this.scan(e),
|
|
1
|
+
import{existsSync as Ii,readFileSync as Pi}from"node:fs";import{spawn as Ci}from"node:child_process";import{homedir as Oi}from"node:os";import{join as Mi}from"node:path";import{existsSync as Tn,readFileSync as An}from"node:fs";import{homedir as Rn}from"node:os";import{join as Nn}from"node:path";function _n(t){let e=t.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
|
|
2
|
+
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function $n(){let t=process.env.TOOLNET_GLOBAL_ENV??Nn(Rn(),".config","toolnet-memory",".env");if(!Tn(t))return;let e=An(t,"utf8");for(let n of e.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let 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]=_n(r.slice(s+1)))}}$n();function q(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function J(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}function X(){return{memory:{autoCapture:q(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:q(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:q(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:q(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:J(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:J(process.env.MEMORY_RERANK_TOP,10),finalContext:J(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:J(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:q(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:J(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Fn}from"node:crypto";import{existsSync as Me,mkdirSync as Ln,readFileSync as Wn,renameSync as Dn,writeFileSync as Kn}from"node:fs";import{basename as zn,dirname as Z,join as ee,parse as Qe,resolve as H}from"node:path";var Xe=".toolnet",Bn="project.json";function qn(t){return Fn("sha256").update(t).digest("hex").slice(0,16)}function Ee(t){return ee(t,Xe,Bn)}function Jn(t){return Me(Ee(t))}function Hn(t,e){let n=H(t),r=Qe(n).root;for(;;){if(Jn(n))return n;if(n===r||e&&n===H(e))break;let s=Z(n);if(s===n)break;n=s}return null}function Vn(t){let e=H(t),n=Qe(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>Me(ee(e,o))))return e;if(e===n)break;let s=Z(e);if(s===e)break;e=s}return H(t)}function Un(t){let e;try{e=JSON.parse(Wn(t,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${t}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${t}`);let n=e;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:Z(Z(t)),createdAt:typeof n.createdAt=="string"?n.createdAt:r,updatedAt:typeof n.updatedAt=="string"?n.updatedAt:r,graphVersion:typeof n.graphVersion=="number"?n.graphVersion:0,memoryVersion:typeof n.memoryVersion=="number"?n.memoryVersion:0,metadata:n.metadata&&typeof n.metadata=="object"?n.metadata:void 0}}function Ye(t,e){let n=ee(t,Xe);Ln(n,{recursive:!0});let r=Ee(t),s=`${r}.tmp-${process.pid}`;Kn(s,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),Dn(s,r)}function Ge(t,e){return{id:t.id,name:t.name,remote:t.remote,rootPath:e,createdAt:t.createdAt,updatedAt:t.updatedAt,graphVersion:t.graphVersion,memoryVersion:t.memoryVersion,metadata:t.metadata}}var F=class{detect(e=process.cwd()){let n=H(e),r=Vn(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>Me(ee(r,f))),i=Hn(n,o?r:void 0);if(i){let f=Ee(i),l=Un(f);return l.rootPath!==i&&(l.rootPath=i,l.updatedAt=new Date().toISOString(),Ye(i,l)),Ge(l,i)}let u=new Date().toISOString(),c=zn(r),a={version:1,id:qn(r),name:c,remote:c,rootPath:r,createdAt:u,updatedAt:u,graphVersion:0,memoryVersion:0};return Ye(r,a),Ge(a,r)}};var Yn=[{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}],te=class{scan(e){let n=[];for(let r of Yn){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of e.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(e){return this.scan(e).length>0}};var V=class{scanner=new te;sanitize(e){let n=e,r=this.scanner.scan(e),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(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(n=>this.sanitizeValue(n));if(e&&typeof e=="object"){let n={};for(let[r,s]of Object.entries(e)){let o=r.toLowerCase();o.includes("password")||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")?n[r]="[REDACTED]":n[r]=this.sanitizeValue(s)}return n}return e}};import{homedir as Sr}from"node:os";import{join as kr}from"node:path";import{DeleteObjectCommand as Gn,GetObjectCommand as Qn,HeadObjectCommand as Xn,ListObjectsV2Command as Zn,PutObjectCommand as er,S3Client as tr}from"@aws-sdk/client-s3";import{getSignedUrl as nr}from"@aws-sdk/s3-request-presigner";var ne=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new tr({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new er({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await nr(this.client,new Qn({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new Xn({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new Gn({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new Zn({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as Ze,mkdir as rr,readFile as sr,readdir as or,rm as ir,stat as et,writeFile as ar}from"node:fs/promises";import{dirname as cr,join as ur,relative as tt,resolve as lr}from"node:path";var U=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return lr(this.root,n)}async put(e,n){let r=this.path(e);await rr(cr(r),{recursive:!0}),await ar(r,n)}async get(e){try{return await sr(this.path(e))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await Ze(this.path(e)),!0}catch{return!1}}async delete(e){await ir(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await Ze(n)}catch{return r}let s=async i=>{let u=await or(i,{withFileTypes:!0});for(let c of u){let a=ur(i,c.name);if(c.isDirectory()){await s(a);continue}let f=await et(a);r.push({key:tt(this.root,a),size:f.size,updatedAt:f.mtime.toISOString()})}},o=await et(n);return o.isDirectory()?await s(n):r.push({key:tt(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as dr,GetObjectCommand as pr,HeadObjectCommand as fr,ListObjectsV2Command as mr,PutObjectCommand as gr,S3Client as hr}from"@aws-sdk/client-s3";import{getSignedUrl as yr}from"@aws-sdk/s3-request-presigner";var Y=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new hr({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new gr({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await yr(this.client,new pr({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new fr({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new dr({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new mr({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};function Te(t,e){return console.warn(e),new U(t)}function nt(t){let e=t.localRoot??kr(Sr(),".toolnet-memory","storage");if(t.provider==="r2"){let n=t.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new Y({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Te(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let n=t.s3;return n?.bucket&&n.accessKeyId&&n.secretAccessKey?new Y({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Te(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let n=t.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new ne({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):Te(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new U(e)}function vr(t){return new Promise(e=>setTimeout(e,t))}async function rt(t,e={}){let n=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await t()}catch(u){if(o=u,i>=n)break;let c=Math.min(s,r*2**(i-1)),a=Math.floor(Math.random()*Math.max(1,c*.2));await vr(c+a)}throw o}var br=new Set(["put","get","getText","delete","list"]);function st(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:br.has(r)?(...o)=>rt(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function ot(t){let e=t.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function it(t){let e=t.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let n=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var re=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=ot(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(u){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${u instanceof Error?u.message:String(u)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(e,JSON.stringify(o,null,2)+`
|
|
4
|
+
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=it(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,n,r){return await this.ensureRegistered(),this.provider.put(this.key(e),n,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{join as Or}from"node:path";import{createHash as xr}from"node:crypto";import{dirname as wr}from"node:path";import{mkdirSync as jr,readFileSync as Ir,renameSync as Pr,writeFileSync as Cr}from"node:fs";function k(t){return xr("sha256").update(t).digest("hex")}function Ae(t){if(Array.isArray(t))return t.map(Ae);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=Ae(e[r]);return n}return t}function at(t){return JSON.stringify(Ae(t))}function ct(t){try{return JSON.parse(Ir(t,"utf8"))}catch{return null}}function I(t,e){jr(wr(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;Cr(n,JSON.stringify(e,null,2)+`
|
|
5
|
+
`,{encoding:"utf8",mode:384}),Pr(n,t)}function ut(t,e){let n=t.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=k(n).slice(0,12);if(!r||r==="."||r==="..")return`${e}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function lt(t,e,n){let r=e.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=ut(r.toLowerCase(),"agent"),i=ut(s,"session");return{projectId:t.id,projectName:t.name,projectRoot:t.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",t.id,"sessions",o,i].join("/"),localDirectory:Or(t.rootPath,".toolnet","sessions",o,i)}}function dt(t){return String(t).padStart(12,"0")}var se=class{constructor(e,n=100,r=512*1024){this.storage=e;this.maxEventsPerChunk=n;this.maxChunkBytes=r;if(n<1)throw new Error("maxEventsPerChunk must be positive");if(r<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let n=await this.storage.getText(e);return n?JSON.parse(n):null}async putJson(e,n){await this.storage.put(e,JSON.stringify(n,null,2)+`
|
|
6
|
+
`,"application/json")}async scan(e){let n=`${e.remotePrefix}/events/`,r=await this.storage.list(n),s=[],o=0;for(let i of r){let u=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!u)continue;let c=Number(u[1]),a=Number(u[2]);!Number.isFinite(c)||!Number.isFinite(a)||(s.push({key:i.key,start:c,end:a}),o=Math.max(o,a))}return s.sort((i,u)=>i.start-u.start),{chunks:s,maxSequence:o}}split(e){let n=[],r=[],s=0;for(let o of e){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(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let n=await this.scan(e);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(e,n,r,s={}){let o=await this.loadManifest(e),i=await this.scan(e),u=n.filter(h=>h.sequence>i.maxSequence),c=0;for(let h of this.split(u)){let g=h[0],x=h[h.length-1],T=h.map(M=>JSON.stringify(M)).join(`
|
|
8
8
|
`)+`
|
|
9
|
-
`,A=k(
|
|
9
|
+
`,A=k(T).slice(0,16),j=[e.remotePrefix,"events",`${dt(g.sequence)}-${dt(x.sequence)}-${A}.jsonl`].join("/");await this.storage.exists(j)||await this.storage.put(j,T,"application/x-ndjson"),c+=h.length}let a=await this.scan(e),f=n[n.length-1],l=o?.status??"active";f?.type==="session_end"||f?.type==="session_idle"?l="idle":f?.type==="error"?l="error":n.length>0&&(l="active");let m=new Date().toISOString(),d=n[0],S={version:1,projectId:e.projectId,projectName:e.projectName,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,status:l,createdAt:o?.createdAt??d?.timestamp??m,updatedAt:f?.timestamp??m,firstEventAt:o?.firstEventAt??d?.timestamp,lastEventAt:f?.timestamp??o?.lastEventAt,eventCount:a.maxSequence,chunkCount:a.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(S.title=s.title??o?.title);let y={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:a.maxSequence,lastRemoteSequence:a.maxSequence,sourceCursors:r,updatedAt:m};return await this.putJson(`${e.remotePrefix}/cursor.json`,y),await this.putJson(`${e.remotePrefix}/session.json`,S),{uploadedEvents:c,lastRemoteSequence:a.maxSequence,eventCount:S.eventCount,chunkCount:S.chunkCount,status:l}}};import{closeSync as Re,existsSync as Mr,fsyncSync as Er,mkdirSync as Tr,openSync as Ne,readSync as Ar,rmSync as pt,statSync as ft,writeSync as Rr}from"node:fs";import{join as _e}from"node:path";var Nr=12e4,_r=80,$r=2e3;function Fr(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var oe=class{constructor(e){this.identity=e;Tr(e.localDirectory,{recursive:!0}),this.eventsFile=_e(e.localDirectory,"events.jsonl"),this.stateFile=_e(e.localDirectory,"state.json"),this.lockFile=_e(e.localDirectory,"journal.lock")}identity;eventsFile;stateFile;lockFile;initialState(){let e=new Date().toISOString();return{version:1,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,status:"idle",createdAt:e,updatedAt:e,lastSequence:0,lastRemoteSequence:0,remoteByteOffset:0,sourceCursors:{},recentEventIds:[]}}loadStateUnsafe(){return ct(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){I(this.stateFile,e)}acquireLock(){for(let e=0;e<_r;e+=1)try{return Ne(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-ft(this.lockFile).mtimeMs>Nr){pt(this.lockFile,{force:!0});continue}}catch{}Fr(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{Re(n),pt(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let l of e){let m=l.timestamp??new Date().toISOString(),d=l.data??{},S=l.provenance?.rawDigest??k(at(d)),y=l.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,l.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,l.type,m,S].join("|"),h=k(y).slice(0,32);if(r.has(h))continue;s+=1;let g={version:1,id:h,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,type:l.type,timestamp:m,data:d,provenance:{...l.provenance,rawDigest:S}};l.role!==void 0&&(g.role=l.role),l.sourceEventId!==void 0&&(g.sourceEventId=l.sourceEventId),l.sourceSequence!==void 0&&(g.sourceSequence=l.sourceSequence),o.push(g),r.add(h)}if(o.length===0)return[];let i=o.map(l=>JSON.stringify(l)).join(`
|
|
10
10
|
`)+`
|
|
11
|
-
`,
|
|
12
|
-
`).filter(Boolean).map(a=>JSON.parse(a)),startOffset:r,endOffset:n}})}markRemote(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,e),remoteByteOffset:Math.max(r.remoteByteOffset,n),updatedAt:new Date().toISOString()})})}setSourceCursor(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[e]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as
|
|
13
|
-
|
|
14
|
-
`);if(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
`);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
`,"
|
|
22
|
-
`);if(c<0)return{events:[],nextOffset:r};let u
|
|
23
|
-
`).filter(Boolean).flatMap(
|
|
11
|
+
`,u=Ne(this.eventsFile,"a",384);try{Rr(u,i,null,"utf8"),Er(u)}finally{Re(u)}let c=o[o.length-1],a="active";c.type==="session_end"||c.type==="session_idle"?a="idle":c.type==="error"&&(a="error");let f=Array.from(r).slice(-$r);return this.saveStateUnsafe({...n,status:a,updatedAt:c.timestamp,lastSequence:c.sequence,recentEventIds:f}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!Mr(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=ft(this.eventsFile).size,r=Math.min(e.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let s=n-r,o=Buffer.alloc(s),i=Ne(this.eventsFile,"r");try{Ar(i,o,0,s,r)}finally{Re(i)}return{events:o.toString("utf8").split(`
|
|
12
|
+
`).filter(Boolean).map(a=>JSON.parse(a)),startOffset:r,endOffset:n}})}markRemote(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,e),remoteByteOffset:Math.max(r.remoteByteOffset,n),updatedAt:new Date().toISOString()})})}setSourceCursor(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[e]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as ds,existsSync as ps,openSync as fs,readSync as ms,statSync as gs}from"node:fs";function mt(t,e){let n=e.toLowerCase();return n.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||n.includes("tuy\u1EC7t \u0111\u1ED1i")||n.includes("must not")||n.includes("never ")?"critical":t==="rule"||t==="decision"?"high":t==="todo"||n.includes("error")||n.includes("failed")||n.includes("exception")?"normal":"temporary"}var St=[/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],Lr=[/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],Wr=[/\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],Dr=[/\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],Kr=[/đã 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],gt=[/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],zr=[/\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],Br=[/đườ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],qr=[/\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],ht=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Jr=new Set(["payload","data","content","message","messages","parts","summary"]);function P(t,e){return e.some(n=>n.test(t))}function kt(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Hr(t){return kt(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Vr(t){return!(t.length<12||t.length>1e3||(t.match(new RegExp("\\p{L}","gu"))??[]).length<6||/^(?:https?:\/\/\S+|[A-Za-z0-9+/=]{80,})$/u.test(t))}function $e(t,e,n,r=0){if(!(r>6)){if(typeof t=="string"){(!e||ht.has(e))&&n.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))$e(s,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(ht.has(s)||Jr.has(s))&&$e(o,s,n,r+1)}}function Ur(t){let e=[];$e(t.data,void 0,e);let n=[],r=new Set;for(let s of e)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=kt(o);if(Vr(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function yt(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function Yr(t,e,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=e==="user"||n.type==="user_prompt",s=e==="assistant"||n.type==="assistant_message";return r&&P(t,St)?{kind:"rule",confidence:.98}:r&&P(t,Lr)?{kind:"rule",confidence:.92}:P(t,Wr)?{kind:P(t,gt)?"architecture":"decision",confidence:r?.93:.86}:r&&P(t,Dr)?{kind:"todo",confidence:.87}:P(t,gt)&&P(t,zr)?{kind:"architecture",confidence:r?.88:.82}:s&&P(t,Kr)?{kind:"fix",confidence:.8}:r&&P(t,Br)&&P(t,qr)?{kind:"context",confidence:.79}:null}function Gr(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Qr(t,e,n){return t==="rule"&&P(n,St)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":mt(e,n)}function vt(t,e){let n=[],r=new Set,s=new Map;for(let o of e){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,u=yt(o);i&&u&&s.set(i,u)}for(let o of e){let i=yt(o),u=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&u&&(i=s.get(u)??"");for(let c of Ur(o)){let a=Yr(c,i,o);if(!a||a.confidence<.75)continue;let f=Gr(a.kind),l=Hr(c),m=k([t.projectId,a.kind,l].join("|"));if(r.has(m))continue;r.add(m);let d=o.provenance.sourcePath?[o.provenance.sourcePath]:[],S=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:m,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:a.kind,type:f,content:c,confidence:a.confidence,importance:Qr(a.kind,f,c),tags:[f],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[o.id],sourceEventIds:S,sourcePaths:d,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}function ie(t){return t?Math.ceil(t.length/3.5):0}function ae(t,e){if(!t)return"";if(ie(t)<=e)return t;let r=Math.floor(e*3.5),s=t.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
|
|
13
|
+
`),u=Math.max(o,i);return u>r*.7?s.slice(0,u+1):s}function $(){let t=X(),e=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||e==="archive"||e==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",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),u=n,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||e==="full";return{sessionSave:e,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:u,archiveRemote:c}}function bt(t){return(t||$()).rawTranscript}function xt(t){return(t||$()).durableMemoryMaxItemsPerSession}function wt(t){return(t||$()).sessionSummaryMaxTokens}function jt(t){return(t||$()).archiveRemote}function Xr(t){return t.replace(/\b[A-Za-z0-9_-]{20,}\b/g,"[REDACTED]").replace(/api[_-]?key[:\s=]+[^\s]+/gi,"api_key=[REDACTED]").replace(/token[:\s=]+[^\s]+/gi,"token=[REDACTED]").replace(/secret[:\s=]+[^\s]+/gi,"secret=[REDACTED]").replace(/password[:\s=]+[^\s]+/gi,"password=[REDACTED]")}function Zr(t,e){let n=t.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);e==="rule"||e==="architecture"||e==="blocker"?r+=.2:e==="decision"||e==="deploy"?r+=.15:(e==="fix"||e==="next_action")&&(r+=.1),t.length<20?r-=.3:t.length>500&&(r-=.1);let 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(t)&&(r-=.4);return Math.max(0,Math.min(1,r))}function es(t,e){let n=[],r=new Set;for(let i of t){let u=i.split(`
|
|
14
|
+
`).filter(c=>c.trim());for(let c of u){let a=c.trim();if(a.length<15)continue;let f=a.toLowerCase().replace(/\s+/g," ");if(r.has(f))continue;r.add(f);let l="decision";/\b(rule|quy tắc|policy|standard|convention)\b/i.test(a)||/\b(always|never|must|should|từ giờ|không được)\b/i.test(a)?l="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(a)?l="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(a)?l="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(a)?l="next_action":/\b(deploy|release|publish|ship)\b/i.test(a)?l="deploy":/\b(architecture|design|structure|pattern)\b/i.test(a)?l="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(a)&&(l="file");let m=Zr(a,l);if(m<.3)continue;let d=Xr(a);n.push({category:l,text:d,importance:m,sourceSessionId:e})}}let s=$(),o=xt(s);return n.sort((i,u)=>u.importance-i.importance).slice(0,o)}function ts(t){let e=$(),n=wt(e),o=t.join(`
|
|
15
|
+
|
|
16
|
+
`).split(`
|
|
17
|
+
`).filter(i=>{let u=i.trim();return u.length>20&&!u.startsWith("npm")&&!u.startsWith("\u2713")&&!u.startsWith("Error:")}).slice(0,20).join(`
|
|
18
|
+
`);return ae(o,n)}function ce(t,e){let r=(Array.isArray(t)?t:t.split(`
|
|
19
|
+
|
|
20
|
+
`).filter(d=>d.trim())).map(d=>typeof d=="string"?d:JSON.stringify(d)).filter(d=>d.trim()),s=es(r,e),o=s.filter(d=>d.category==="decision").map(d=>d.text),i=s.filter(d=>d.category==="rule").map(d=>d.text),u=s.filter(d=>d.category==="file").map(d=>d.text),c=s.filter(d=>d.category==="fix").map(d=>d.text),a=s.filter(d=>d.category==="blocker").map(d=>d.text),f=s.filter(d=>d.category==="next_action").map(d=>d.text),l=s.filter(d=>d.category==="deploy").map(d=>d.text);return{summary:ts(r),decisions:o,projectRules:i,filesChanged:u,bugsFixed:c,commands:l,blockers:a,nextActions:f,durableFacts:s}}function R(t){let e=new Set,n=[];for(let r of t){let s=r?.replace(/\s+/g," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();e.has(o)||(e.add(o),n.push(s))}return n}function ns(t){let e=new Map;for(let n of t){if(!n||!n.id||!Number.isFinite(n.sequence))continue;let r=n.sourceEventId?`${n.agent}:${n.sourceEventId}`:n.id,s=e.get(r);(!s||n.sequence>s.sequence)&&e.set(r,n)}return[...e.values()].sort((n,r)=>n.sequence-r.sequence||n.timestamp.localeCompare(r.timestamp))}function rs(t){switch(t){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function ss(t){let e=rs(t.importance);return Math.max(0,Math.min(1,e*.75+t.confidence*.25))}function os(t){return t.importance==="temporary"||t.confidence<.78?"transient":t.kind==="rule"||t.kind==="architecture"?"permanent":t.kind==="decision"||t.kind==="todo"||t.kind==="fix"?"task":"session"}function is(t){let e=t.normalize("NFKC").toLowerCase().match(/[\p{L}\p{N}_./:-]+/gu)??[],n=new Set;for(let r of e)if(!(r.length<2||/^\d+$/u.test(r))&&(n.add(r),n.size>=40))break;return[...n]}function as(t){let e=os(t),n=ss(t),r=is(t.content);return{...t,knowledgeClass:e,importanceScore:n,retrievalTerms:r,tags:R([...t.tags,`class:${e}`,`kind:${t.kind}`])}}function cs(t){return t.map(e=>{try{return JSON.stringify({type:e.type,role:e.role,data:e.data,provenance:{sourcePath:e.provenance.sourcePath,files:e.provenance.files}})}catch{return""}}).filter(Boolean)}function us(t,e,n){let r=ce(cs(e),t.nativeSessionId),s=n.filter(a=>a.kind==="todo").map(a=>a.content),o=n.flatMap(a=>a.provenance.sourcePaths),i=n.filter(a=>a.kind==="architecture").map(a=>a.content),u=R([...s,...r.nextActions]),c=R([...r.nextActions,...s]);return{summary:r.summary,state:{task:c[0]??u[0],decisions:R(r.decisions),files:R([...r.filesChanged,...o]),todos:u,completed:R(r.bugsFixed),blockers:R(r.blockers),nextActions:c,architecture:R(i)}}}function It(t,e){let n=ns(e),r=vt(t,n).map(as),s=r.filter(a=>a.knowledgeClass!=="transient").sort((a,f)=>f.importanceScore-a.importanceScore),{summary:o,state:i}=us(t,n,s),u=s.map(a=>({fingerprint:a.fingerprint,kind:a.kind,knowledgeClass:a.knowledgeClass,importanceScore:a.importanceScore,content:a.content,terms:a.retrievalTerms})),c=a=>r.filter(f=>f.knowledgeClass===a).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:u,stats:{inputEvents:e.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:c("permanent"),task:c("task"),session:c("session"),transient:c("transient")}}}function Pt(t){return String(t).padStart(12,"0")}function ls(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var ue=class{constructor(e){this.storage=e}storage;async write(e,n,r){if(r.length===0||n.length===0)return null;let s=Math.min(...n.map(f=>f.sequence)),o=Math.max(...n.map(f=>f.sequence)),i={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},u=JSON.stringify(i,null,2)+`
|
|
21
|
+
`,c=k(r.map(f=>f.fingerprint).sort().join("|")).slice(0,16),a=[ls(e),"batches",`${Pt(s)}-${Pt(o)}-${c}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,u,"application/json"),a}};function hs(t,e){if(!ps(t))return{events:[],nextOffset:e};let n=gs(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=fs(t,"r");try{ms(i,o,0,s,r)}finally{ds(i)}let u=o.toString("utf8"),c=u.lastIndexOf(`
|
|
22
|
+
`);if(c<0)return{events:[],nextOffset:r};let a=u.slice(0,c+1);return{events:a.split(`
|
|
23
|
+
`).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(a,"utf8")}}var le=class{constructor(e){this.options=e;this.journal=new ue(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,s=hs(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=It(this.options.identity,s.events),i=o.candidates,u=!1;return i.length>0&&(u=!!await this.journal.write(this.options.identity,s.events,i)),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.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:i.length,journalWritten:u,nextOffset:s.nextOffset}}};import{closeSync as ws,existsSync as js,openSync as Is,readSync as Ps,statSync as Cs}from"node:fs";var ys=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function W(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Ot(t){return W(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function L(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))L(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(ys.has(r)||["data","payload","parts","messages"].includes(r))&&L(s,e,n+1)}}function de(t){return/\b(cancelled|canceled)\b|đã hủy|bỏ qua/iu.test(t)?"cancelled":/\b(blocked|blocker)\b|đang vướng|bị vướng|đang kẹt|chưa thể/iu.test(t)?"blocked":/\b(completed|complete|done|finished|passed)\b|hoàn thành|hoàn tất|đã xong|đã làm xong|\bxong\b/iu.test(t)?"completed":/\bin[\s_-]*progress\b|working on|đang làm|đang thực hiện|đang xử lý|đang triển khai/iu.test(t)?"in_progress":"pending"}function Ct(t){let e=W(t);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(e)}function w(t,e,n,r,s={}){let o=W(r),i=s.key??Ot(o);return{version:1,id:k([t.projectId,n,i,e.id,o,s.status??"",s.order??""].join("|")).slice(0,32),projectId:t.projectId,kind:n,key:i,text:o,status:s.status,order:s.order,confidence:s.confidence??.85,occurredAt:e.timestamp,sequence:e.sequence,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId}}function Ss(t,e,n){let r=W(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(w(t,e,"goal",i[1],{confidence:.97}));let u=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);u?.[1]&&s.push(w(t,e,"plan",u[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,a;for(;!o&&(a=c.exec(r));){let m=Number(a[1]),d=W(a[2]??""),S=d&&!Ct(d)?`Phase ${m} - ${d}`:`Phase ${m}`;s.push(w(t,e,"phase",S,{key:`phase:${m}`,order:m,status:de(r),confidence:.93}))}let f=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);f?.[2]&&s.push(w(t,e,"task",f[2],{status:f[1].trim()?"completed":de(f[2]),confidence:.96}));let l=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(l?.[2]){let m=l[1]?Number(l[1]):void 0,d=W(l[2]),S=Ct(d);s.push(w(t,e,"task",S&&m!==void 0?`TODO ${m}`:d,{key:m!==void 0?`task:${m}`:Ot(d),order:m,status:de(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 m=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");m&&s.push(w(t,e,"next_action",m,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(w(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(w(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(w(t,e,"decision",r,{confidence:.9})),s}function pe(t,e){if(e.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 e){if(i.type==="decision"){let c=[];L(i.data,c);for(let a of c)s(w(t,i,"decision",a,{confidence:1}))}if(i.type==="todo"){let c=[];L(i.data,c);for(let a of c)s(w(t,i,"task",a,{status:de(a),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let a=i.data[c];typeof a=="string"&&a&&s(w(t,i,"file",a,{confidence:1}))}if(i.type==="test"){let c=[];L(i.data,c);for(let a of c)s(w(t,i,"test",a,{confidence:1}))}let u=[];L(i.data,u);for(let c of u)for(let a of c.split(/\n+/u))for(let f of Ss(t,i,a))s(f)}let o=e[e.length-1];return s(w(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function Mt(t){return String(t).padStart(12,"0")}var fe=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(a=>a.sequence)),s=Math.max(...n.map(a=>a.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
|
|
24
|
+
`,u=k(n.map(a=>a.id).sort().join("|")).slice(0,16),c=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${Mt(r)}-${Mt(s)}-${u}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as Et}from"node:path";import{mkdirSync as ks}from"node:fs";function vs(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function D(t,e=20){let n=[],r=new Set;for(let s of t.slice().reverse()){let o=vs(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=e))break}return n.reverse()}function bs(t){return t.kind==="phase"?/^Phase\s+\d+$/iu.test(t.text):t.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(t.text):!1}function Tt(t,e){let n=e.status??t?.status??"pending",r=n;t&&(t.status==="completed"&&n!=="completed"?r="completed":n==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(r=t.status));let s=t&&bs(e)?t.title:e.text;return{id:t?.id??k(e.key).slice(0,24),title:s,status:r,order:e.order??t?.order,confidence:Math.max(e.confidence,t?.confidence??0),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}async function xs(t,e){let n=`projects/${t.id}/work/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,u)=>i.key.localeCompare(u.key))){let i=await e.getText(o.key);if(i)try{let u=JSON.parse(i);u.version===1&&Array.isArray(u.observations)&&s.push(u)}catch{}}return s}async function me(t,e){let r=(await xs(t,e)).flatMap(p=>p.observations).sort((p,v)=>{let B=p.occurredAt.localeCompare(v.occurredAt);if(B!==0)return B;let Ue=p.sequence-v.sequence;return Ue!==0?Ue:p.id.localeCompare(v.id)}),s=new Map,o=new Map,i,u,c,a=[],f=[],l=[],m=[],d=[],S=[];for(let p of r)switch(p.kind){case"goal":i=p.text;break;case"plan":u=p.text;break;case"phase":s.set(p.key,Tt(s.get(p.key),p));break;case"task":o.set(p.key,Tt(o.get(p.key),p));break;case"decision":a.push(p.text);break;case"blocker":f.push(p.text);break;case"warning":l.push(p.text);break;case"next_action":m.push(p.text);break;case"file":d.push(p.text);break;case"test":S.push(p.text);break;case"session":c={agent:p.agent,nativeSessionId:p.nativeSessionId,sessionKey:p.sessionKey,updatedAt:p.occurredAt};break}let y=Array.from(s.values()).sort((p,v)=>(p.order??Number.MAX_SAFE_INTEGER)-(v.order??Number.MAX_SAFE_INTEGER)),h=Array.from(o.values()).sort((p,v)=>(p.order??Number.MAX_SAFE_INTEGER)-(v.order??Number.MAX_SAFE_INTEGER)),g=y.find(p=>p.status==="in_progress")??y.find(p=>p.status==="blocked")??y.find(p=>p.status==="pending"),x=h.find(p=>p.status==="in_progress")??h.find(p=>p.status==="blocked")??h.find(p=>p.status==="pending"),T=D([...m,...x?[x.title]:[],...!x&&g?[g.title]:[],...h.filter(p=>p.status==="pending").slice(0,5).map(p=>p.title)],8),A=D([...f,...y.filter(p=>p.status==="blocked").map(p=>p.title),...h.filter(p=>p.status==="blocked").map(p=>p.title)],20),j={version:1,projectId:t.id,projectName:t.name,goal:i,plan:u,phases:y,tasks:h,decisions:D(a,20),blockers:A,warnings:D(l,20),nextActions:T,filesTouched:D(d,30),tests:D(S,20),currentPhase:g,currentTask:x,progress:{phasesTotal:y.length,phasesCompleted:y.filter(p=>p.status==="completed").length,tasksTotal:h.length,tasksCompleted:h.filter(p=>p.status==="completed").length,blocked:y.filter(p=>p.status==="blocked").length+h.filter(p=>p.status==="blocked").length},lastSession:c,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},M=Et(t.rootPath,".toolnet","work");return ks(M,{recursive:!0}),I(Et(M,"current.json"),j),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(j,null,2)+`
|
|
25
|
+
`,"application/json"),j}async function ge(t,e){let n=await e.getText(`projects/${t.id}/work/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function Os(t,e){if(!js(t))return{events:[],nextOffset:e};let n=Cs(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=Is(t,"r");try{Ps(i,o,0,s,r)}finally{ws(i)}let u=o.toString("utf8"),c=u.lastIndexOf(`
|
|
26
|
+
`);if(c<0)return{events:[],nextOffset:r};let a=u.slice(0,c+1);return{events:a.split(`
|
|
27
|
+
`).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(a,"utf8")}}var he=class{constructor(e){this.options=e;this.journal=new fe(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=Os(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=pe(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await me(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 Fs,existsSync as Ls,openSync as Ws,readSync as Ds,statSync as Ks}from"node:fs";var Ms=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function K(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Fe(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))Fe(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(Ms.has(r)||["data","payload","parts","messages"].includes(r))&&Fe(s,e,n+1)}}function C(t,e,n,r,s,o=.95){let i=K(r);return{version:1,id:k([t.projectId,n,s.type,s.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId,sequence:e.sequence,occurredAt:e.timestamp}}}function E(t,e){let n=t.toLowerCase();for(let r of e){let s=r.toLowerCase();if(n.startsWith(`${s}:`)||n.startsWith(`${s} -`)||n.startsWith(`${s} \u2014`))return K(t.slice(r.length+1))}return null}function Es(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function Ts(t){return K(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function At(t,e){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 e){let i=[];Fe(o.data,i);for(let u of i){let c={type:"project"},a=null;for(let f of u.split(/\r?\n/u)){let l=K(f);if(!l){a=null;continue}let m=l.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(m){let v=Number(m[1]);c={type:"phase",key:`phase:${v}`,order:v,title:K(m[2]??"")},a=null;continue}let d=l.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(d){let v=Number(d[1]);c={type:"task",key:`task:${v}`,order:v,title:K(d[2]??"")},a=null;continue}let S=E(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(S){s(C(t,o,"mission",S,{type:"project"},.99)),a=null;continue}let y=E(l,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(y){s(C(t,o,c.type==="phase"?"phase_objective":"objective",y,c,.98)),a=null;continue}let h=E(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(h){s(C(t,o,c.type==="phase"?"phase_why":"why",h,c,.98)),a=null;continue}let g=E(l,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(g){s(C(t,o,"desired_outcome",g,{type:"project"},.98)),a=null;continue}let x=E(l,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(x){s(C(t,o,"plan_rationale",x,{type:"project"},.98)),a=null;continue}let T=E(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(T){s(C(t,o,"phase_deliverable",T,c,.97)),a=null;continue}let A=E(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(A){s(C(t,o,"acceptance_criterion",A,c,.98)),a="acceptance_criterion";continue}let j=E(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(j){s(C(t,o,"dependency",j,c,.97)),a="dependency";continue}let M=E(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(M){s(C(t,o,"open_question",M,c,.95)),a="open_question";continue}let p=E(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(p){s(C(t,o,"constraint",p,c,.97)),a="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(l)){a="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(l)){a="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(l)){a="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(l)){a="constraint";continue}if(a&&Es(f)){s(C(t,o,a,Ts(f),c,.96));continue}a=null}}}return n}function Rt(t){return String(t).padStart(12,"0")}var ye=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(c=>c.evidence.sequence)),s=Math.max(...n.map(c=>c.evidence.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=k(n.map(c=>c.id).sort().join("|")).slice(0,16),u=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${Rt(r)}-${Rt(s)}-${i}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,JSON.stringify(o,null,2)+`
|
|
28
|
+
`,"application/json"),u}};import{mkdirSync as As}from"node:fs";import{join as Nt}from"node:path";function Rs(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function Ns(t,e){if(!e)return!0;let n=t.evidence.occurredAt.localeCompare(e.evidence.occurredAt);return n!==0?n>0:t.evidence.sessionKey===e.evidence.sessionKey?t.evidence.sequence>=e.evidence.sequence:t.confidence>=e.confidence}function N(t,e){return Ns(e,t)?e:t}function _(t,e=30){let n=new Set,r=[];for(let s of t){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-e)}async function _s(t,e){let n=`projects/${t.id}/work/semantic/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,u)=>i.key.localeCompare(u.key))){let i=await e.getText(o.key);if(i)try{let u=JSON.parse(i);u.version===1&&Array.isArray(u.observations)&&s.push(u)}catch{}}return s}function $s(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function _t(t,e){let r=(await _s(t,e)).flatMap(y=>y.observations).sort((y,h)=>{let g=y.evidence.occurredAt.localeCompare(h.evidence.occurredAt);return g!==0?g:y.evidence.sessionKey===h.evidence.sessionKey?y.evidence.sequence-h.evidence.sequence:y.id.localeCompare(h.id)}),s,o,i,u,c,a=new Map,f=[],l=[],m=[];for(let y of r){let h=Rs(y);if(y.scope==="phase"&&y.scopeKey){let g=a.get(y.scopeKey)??$s(y);switch(y.kind){case"phase_objective":g.objective=N(g.objective,h);break;case"phase_why":g.why=N(g.why,h);break;case"phase_deliverable":g.deliverable=N(g.deliverable,h);break;case"acceptance_criterion":g.acceptanceCriteria.push(h);break;case"dependency":g.dependencies.push(h);break;case"open_question":g.openQuestions.push(h);break;case"constraint":g.constraints.push(h);break;case"note":g.notes.push(h);break}a.set(g.key,g);continue}switch(y.kind){case"mission":s=N(s,h);break;case"objective":o=N(o,h);break;case"why":i=N(i,h);break;case"desired_outcome":u=N(u,h);break;case"plan_rationale":c=N(c,h);break;case"open_question":f.push(h);break;case"constraint":l.push(h);break;case"note":m.push(h);break}}for(let y of a.values())y.acceptanceCriteria=_(y.acceptanceCriteria,20),y.dependencies=_(y.dependencies,15),y.openQuestions=_(y.openQuestions,15),y.constraints=_(y.constraints,15),y.notes=_(y.notes,20);let d={version:1,projectId:t.id,projectName:t.name,mission:s,activeObjective:o,why:i,desiredOutcome:u,planRationale:c,phases:Array.from(a.values()).sort((y,h)=>y.order-h.order),openQuestions:_(f,20),constraints:_(l,20),notes:_(m,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},S=Nt(t.rootPath,".toolnet","work");return As(S,{recursive:!0}),I(Nt(S,"semantic-current.json"),d),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(d,null,2)+`
|
|
29
|
+
`,"application/json"),d}async function $t(t,e){let n=await e.getText(`projects/${t.id}/work/semantic/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function zs(t,e){if(!Ls(t))return{events:[],nextOffset:e};let n=Ks(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=Buffer.alloc(n-r),o=Ws(t,"r");try{Ds(o,s,0,s.length,r)}finally{Fs(o)}let i=s.toString("utf8"),u=i.lastIndexOf(`
|
|
30
|
+
`);if(u<0)return{events:[],nextOffset:r};let c=i.slice(0,u+1);return{events:c.split(`
|
|
31
|
+
`).filter(Boolean).flatMap(a=>{try{return[JSON.parse(a)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var Se=class{constructor(e){this.options=e;this.journal=new ye(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=zs(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=At(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await _t(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{mkdirSync as eo}from"node:fs";import{join as Le}from"node:path";import{existsSync as Wt,mkdirSync as Bs,readFileSync as qs,statSync as Ft,writeFileSync as Js}from"node:fs";import{dirname as Hs,join as Vs}from"node:path";var Lt=64*1024,Us=`# ToolNet Project Operating Manual
|
|
24
32
|
|
|
25
33
|
This file contains persistent instructions for AI agents working on this project.
|
|
26
34
|
|
|
@@ -63,58 +71,51 @@ Things an AI agent should always remember.
|
|
|
63
71
|
<!--
|
|
64
72
|
- [advisory] Prefer small focused files.
|
|
65
73
|
-->
|
|
66
|
-
`;function
|
|
67
|
-
|
|
68
|
-
`,"application/json")
|
|
69
|
-
|
|
70
|
-
`);if(
|
|
74
|
+
`;function ke(t){return Vs(t.rootPath,".toolnet","PROJECT.md")}function Ys(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function Gs(t){let e=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=r.exec(t);){let o=s[1].toLowerCase(),i=Ys(s[2]);if(!i)continue;let u=`${o}:${i.toLowerCase()}`;n.has(u)||(n.add(u),e.push({id:k(u).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function Qs(t){let e=ke(t);return Wt(e)||(Bs(Hs(e),{recursive:!0}),Js(e,Us,{encoding:"utf8",mode:384})),e}function ve(t,e=!1){let n=e?Qs(t):ke(t);if(!Wt(n))return null;if(Ft(n).size>Lt)throw new Error(`PROJECT.md exceeds ${Lt} bytes`);let s=qs(n,"utf8");return{path:n,content:s,digest:k(s),rules:Gs(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(Ft(n).mtimeMs).toISOString()}}function O(t,e){let n=new Set,r=[];for(let s of t){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>=e))break}return r}function Dt(t){if(t)return{id:t.id,title:t.title,status:t.status}}function Xs(t){let e=t.slice(-10).join(`
|
|
75
|
+
`).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(e)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(e)?"passing":"unknown"}function Zs(t){return k(JSON.stringify(t))}function Kt(t){let{project:e,identity:n,state:r}=t,s=r.filesTouched.at(-1),o=r.phases.filter(g=>g.status==="completed").map(g=>g.title),i=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),c=r.tasks.filter(g=>g.status!=="completed"&&g.status!=="cancelled").map(g=>g.title),a=O(r.nextActions,10),f=O([...c,...a],15),l=O(r.tests.slice().reverse(),10),m=O(r.filesTouched.slice().reverse(),20),d={schema:"toolnet.handoff.v2",version:2,project:{id:e.id,name:e.name},source:{agent:n.agent,nativeSessionId:n.nativeSessionId,sessionKey:n.sessionKey,sequence:t.sequence,reason:t.reason},capturedAt:t.capturedAt??new Date().toISOString(),goal:r.goal,current:{phase:Dt(r.currentPhase),task:Dt(r.currentTask),file:s},completed:{phases:O(o,20),tasks:O(i,30)},remaining:{phases:O(u,20),tasks:O(c,30),todos:f},nextAction:a[0],blockers:O(r.blockers.slice().reverse(),10),decisions:O(r.decisions.slice().reverse(),10),files:{current:s,recent:m},tests:{status:Xs(r.tests),recent:l},attention:O(t.attention??[],20),progress:r.progress},{capturedAt:S,source:y,...h}=d;return{...d,stateDigest:Zs(h)}}function to(t){return t.phases.some(e=>e.status==="pending"||e.status==="in_progress"||e.status==="blocked")||t.tasks.some(e=>e.status==="pending"||e.status==="in_progress"||e.status==="blocked")||t.nextActions.length>0||t.blockers.length>0}var be=class{constructor(e){this.options=e}options;async capture(e,n){let r=await ge(this.options.project,this.options.storage);if(r||(r=await me(this.options.project,this.options.storage)),!to(r))return null;let s=ve(this.options.project,!1),i=[...s?s.rules.filter(S=>S.mode==="enforce").map(S=>S.text):[],...r.warnings].slice(0,20),u=Kt({project:this.options.project,identity:this.options.identity,state:r,reason:e,sequence:n,attention:i}),c=u.stateDigest,a=k([this.options.project.id,this.options.identity.sessionKey,c].join("|")).slice(0,24),f=new Date().toISOString(),l={version:1,id:a,projectId:this.options.project.id,projectName:this.options.project.name,createdAt:f,reason:e,sourceSession:{agent:this.options.identity.agent,nativeSessionId:this.options.identity.nativeSessionId,sessionKey:this.options.identity.sessionKey,sequence:n},goal:r.goal,plan:r.plan,progress:r.progress,currentPhase:r.currentPhase,currentTask:r.currentTask,incompletePhases:r.phases.filter(S=>S.status!=="completed"&&S.status!=="cancelled"),incompleteTasks:r.tasks.filter(S=>S.status!=="completed"&&S.status!=="cancelled"),nextActions:r.nextActions.slice(0,10),blockers:r.blockers.slice(0,10),decisions:r.decisions.slice(-10),warnings:r.warnings.slice(-10),attention:i,filesTouched:r.filesTouched.slice(-20),tests:r.tests.slice(-15),stateDigest:c,continuity:u},m=`projects/${this.options.project.id}/work/handoffs/${a}.json`;await this.options.storage.exists(m)||await this.options.storage.put(m,JSON.stringify(l,null,2)+`
|
|
76
|
+
`,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(l,null,2)+`
|
|
77
|
+
`,"application/json");let d=Le(this.options.project.rootPath,".toolnet","work","handoffs");return eo(d,{recursive:!0}),I(Le(d,`${a}.json`),l),I(Le(this.options.project.rootPath,".toolnet","work","handoff-latest.json"),l),l}};async function zt(t,e){let n=await e.getText(`projects/${t.id}/work/handoff-latest.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}var xe=class{identity;wal;remote;sanitizer=new V;learner;continuity;semantic;handoff;title;metadata;constructor(e){this.identity=lt(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new oe(this.identity),this.remote=new se(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new le({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new he({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new Se({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new be({project:e.project,storage:e.storage,identity:this.identity})}sanitizeEvent(e){let n=e.provenance?{...e.provenance,metadata:this.sanitizer.sanitizeValue(e.provenance.metadata)}:void 0;return{...e,data:this.sanitizer.sanitizeValue(e.data??{}),provenance:n}}start(e={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:e,provenance:{source:this.identity.agent}})}record(e){return this.wal.append([this.sanitizeEvent(e)])[0]}recordMany(e){return this.wal.append(e.map(n=>this.sanitizeEvent(n)))}setSourceCursor(e,n){this.wal.setSourceCursor(e,n)}async flush(){let e=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,e.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(e.events.length>0){let s=e.events[e.events.length-1];this.wal.markRemote(s.sequence,e.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&e.events.length>0)try{let s=e.events[e.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(e={}){return this.record({type:"session_idle",data:e,provenance:{source:this.identity.agent}}),this.flush()}async end(e={}){return this.record({type:"session_end",data:e,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};import{existsSync as no,readFileSync as ro,readdirSync as so,statSync as Bt}from"node:fs";import{homedir as oo}from"node:os";import{join as we,resolve as qt}from"node:path";function Jt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function io(){return process.env.CODEX_HOME??we(oo(),".codex")}function G(t){let e="";try{e=ro(t,"utf8").slice(0,128*1024)}catch{return{raw:{}}}for(let n of e.split(`
|
|
78
|
+
`))if(n)try{let r=Jt(JSON.parse(n));if(r.type!=="session_meta")continue;let s=Jt(r.payload),o=[s.id,s.thread_id,s.threadId,s.session_id,s.sessionId].find(u=>typeof u=="string"),i=typeof s.cwd=="string"?s.cwd:void 0;return{threadId:o,cwd:i,raw:s}}catch{}return{raw:{}}}function We(t,e){if(!no(t))return;let n;try{n=so(t,{withFileTypes:!0})}catch{return}for(let r of n){let s=we(t,r.name);if(r.isDirectory()){We(s,e);continue}r.isFile()&&r.name.endsWith(".jsonl")&&e.push(s)}}function De(){let t=io(),e=[];return We(we(t,"sessions"),e),We(we(t,"archived_sessions"),e),e.sort((n,r)=>{try{return Bt(r).mtimeMs-Bt(n).mtimeMs}catch{return 0}})}function Ke(t){let e=De(),n=e.find(r=>r.includes(t));if(n)return n;for(let r of e)if(G(r).threadId===t)return r;return null}function je(t,e){let n=qt(t),r=qt(e);return r===n||r.startsWith(n+"/")||n.startsWith(r+"/")}import{closeSync as ao,existsSync as co,openSync as uo,readSync as lo,statSync as po}from"node:fs";function Ht(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function fo(t){let e=t.timestamp;if(typeof e=="string"){let n=new Date(e);if(!Number.isNaN(n.getTime()))return n.toISOString()}return new Date().toISOString()}function mo(t){let e=typeof t.type=="string"?t.type.toLowerCase():"",n=Ht(t.payload),r=typeof n.type=="string"?n.type.toLowerCase():"",s=typeof n.role=="string"?n.role.toLowerCase():void 0;return e==="session_meta"?{type:"custom"}:s==="user"||r==="user_message"?{type:"user_prompt",role:"user"}:s==="assistant"||r==="agent_message"||r==="assistant_message"?{type:"assistant_message",role:"assistant"}:r.includes("function_call")||r.includes("tool_call")||r.includes("exec_command_begin")||r.includes("exec_command_start")?{type:"tool_call"}:r.includes("function_call_output")||r.includes("tool_result")||r.includes("exec_command_end")||r.includes("exec_command_complete")?{type:"tool_result"}:r.includes("error")?{type:"error"}:e.includes("compacted")||r.includes("compacted")?{type:"session_compact"}:{type:"custom",role:s}}function Vt(t,e=0){if(!co(t))return{events:[],nextOffset:e,reset:!1};let n=po(t).size,r=e>n,s=r?0:e;if(s>=n)return{events:[],nextOffset:n,reset:r};let o=n-s,i=Buffer.alloc(o),u=uo(t,"r");try{lo(u,i,0,o,s)}finally{ao(u)}let c=i.toString("utf8"),a=c.lastIndexOf(`
|
|
79
|
+
`);if(a<0)return{events:[],nextOffset:s,reset:r};let f=c.slice(0,a+1),l=0,m=[];for(let d of f.split(`
|
|
71
80
|
`)){if(!d)continue;let S=Buffer.byteLength(d+`
|
|
72
|
-
`,"utf8"),
|
|
73
|
-
|
|
74
|
-
`)
|
|
75
|
-
|
|
76
|
-
`).
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
`)
|
|
83
|
-
|
|
84
|
-
`):c=r.trim()?`${r.trim()}
|
|
85
|
-
|
|
86
|
-
${s}`:s,ko(n,`${c.trim()}
|
|
87
|
-
`,{encoding:"utf8",mode:384})}import{existsSync as bo,mkdirSync as wo,readFileSync as jo,renameSync as Io,writeFileSync as Po}from"node:fs";import{dirname as Oo,join as Eo}from"node:path";function en(t){return Eo(t.rootPath,".toolnet","context","session-origin.json")}function To(t,e){wo(Oo(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;Po(n,`${JSON.stringify(e,null,2)}
|
|
88
|
-
`,{encoding:"utf8",mode:384}),Io(n,t)}function je(t,e){return[...t].filter(n=>n.kind===e).sort((n,r)=>{let s=n.occurredAt.localeCompare(r.occurredAt);return s!==0?s:n.sequence-r.sequence}).at(-1)}function tn(t,e){let n=je(e.observations,"file"),r=je(e.observations,"next_action"),s=je(e.observations,"blocker"),o=je(e.observations,"decision"),i={version:1,projectId:t.id,agent:e.agent,nativeSessionId:e.nativeSessionId,updatedAt:e.workState.updatedAt,currentTask:e.workState.currentTask?.title,currentPhase:e.workState.currentPhase?.title,lastTouchedFile:n?.text??e.workState.filesTouched.at(-1),latestNextAction:r?.text??e.workState.nextActions.at(-1),latestBlocker:s?.text??e.workState.blockers.at(-1),latestDecision:o?.text??e.workState.decisions.at(-1)};return To(en(t),i),i}function Co(t){let e=en(t);if(!bo(e))return null;try{let n=JSON.parse(jo(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function nn(t){let e=Co(t);if(!e)return null;let n=["Previous session:",`- Agent: ${e.agent}`,`- Session: ${e.nativeSessionId}`];return e.currentPhase&&n.push(`- Current phase: ${e.currentPhase}`),e.currentTask&&n.push(`- Current task: ${e.currentTask}`),e.lastTouchedFile&&n.push(`- Last touched file: ${e.lastTouchedFile}`),e.latestBlocker&&n.push(`- Blocker: ${e.latestBlocker}`),e.latestNextAction&&n.push(`- Next action: ${e.latestNextAction}`),e.latestDecision&&n.push(`- Important decision: ${e.latestDecision}`),n.join(`
|
|
89
|
-
`)}async function Y(t){let e=t.threadId.trim();if(!e)throw new Error("Codex thread ID is required");let n=U(t.rolloutPath),r=t.cwd??n.cwd;if(r&&!ke(t.project.rootPath,r))throw new Error(`Codex thread does not belong to project: ${r}`);if(n.threadId&&n.threadId!==e)throw new Error(`Codex rollout thread mismatch: expected ${e}, got ${n.threadId}`);let s=new ye({project:t.project,storage:t.storage,agent:"codex",nativeSessionId:e,metadata:{source:"codex-rollout",rolloutPath:t.rolloutPath,cwd:r,client:t.client}}),o=s.status(),i=o.sourceCursors["codex.rollout.path"],c=Number(o.sourceCursors["codex.rollout.offset"]??0);i&&i!==t.rolloutPath&&(c=0),(!Number.isFinite(c)||c<0)&&(c=0);let u=Ft(t.rolloutPath,c),a=[];o.lastSequence===0&&a.push({type:"session_start",sourceEventId:`codex:${e}:start`,data:{threadId:e,cwd:r,rolloutPath:t.rolloutPath,sessionMeta:n.raw},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}}),i&&i!==t.rolloutPath&&a.push({type:"custom",sourceEventId:`codex:${e}:rollout-rotation:${t.rolloutPath}`,data:{event:"rollout_rotation",previousPath:i,rolloutPath:t.rolloutPath},provenance:{source:"codex-rollout"}}),u.reset&&a.push({type:"custom",sourceEventId:`codex:${e}:rollout-reset:${u.nextOffset}`,data:{event:"rollout_reset"},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}});let f=u.events.filter(d=>!Lt(d.data)).map(d=>({...d,data:ve(d.data)}));if(a.push(...f),t.idle&&f.length>0)try{let d={projectId:t.project.id,projectName:t.project.name,projectRoot:t.project.rootPath,agent:"codex",nativeSessionId:e,sessionKey:`codex:${e}`,remotePrefix:`projects/${t.project.id}/sessions/codex/${e}`,localDirectory:""},S=f.map((y,b)=>({version:1,id:`codex-work-${e}-${y.sourceSequence??b}`,sequence:b+1,projectId:t.project.id,agent:"codex",nativeSessionId:e,type:y.type,timestamp:y.timestamp??new Date().toISOString(),role:y.role,sourceEventId:y.sourceEventId,sourceSequence:y.sourceSequence,data:y.data??{},provenance:y.provenance??{}})),h=ae(d,S),g=Gt(t.project,h);Zt(t.project,g),tn(t.project,{agent:"codex",nativeSessionId:e,observations:h,workState:g})}catch{}t.idle&&t.turnId&&a.push({type:"session_idle",sourceEventId:`codex:${e}:turn:${t.turnId}:idle`,data:{turnId:t.turnId,client:t.client},provenance:{source:"codex-notify"}});let l=s.recordMany(a);if(s.setSourceCursor("codex.rollout.path",t.rolloutPath),s.setSourceCursor("codex.rollout.offset",u.nextOffset),t.turnId&&s.setSourceCursor("codex.last.turn",t.turnId),t.idle&&f.length>0)try{let d=f.map(h=>JSON.stringify(h.data)),S=zt(d,e);s.setSourceCursor("codex.session.summary",S.summary),s.setSourceCursor("codex.session.facts_count",S.durableFacts.length),Wt()&&!Bt()&&s.setSourceCursor("codex.raw_transcript.archived","local")}catch{}let m=await s.flush();return{threadId:e,imported:l.length,rolloutEvents:u.events.length,eventCount:m.eventCount,chunkCount:m.chunkCount,status:m.status,rolloutOffset:u.nextOffset,reset:u.reset}}import{existsSync as Ao}from"node:fs";import{dirname as Mo,join as Ro,parse as No,resolve as _o}from"node:path";function rn(t){let e=_o(t),n=No(e).root;for(;;){if(Ao(Ro(e,".toolnet","project.json")))return new _().detect(e);if(e===n)break;let r=Mo(e);if(r===e)break;e=r}return null}async function sn(t,e,n=100){let r=[];for(let s of Fe()){let o=U(s);if(!(!o.threadId||!o.cwd)&&ke(t.rootPath,o.cwd)&&(r.push(await Y({project:t,storage:e,threadId:o.threadId,rolloutPath:s,cwd:o.cwd})),r.length>=n))break}return r}import{existsSync as $o,mkdirSync as on,readFileSync as Fo,writeFileSync as an}from"node:fs";import{homedir as cn}from"node:os";import{dirname as un,join as ze}from"node:path";function Lo(t){let e=[],n=/"((?:\\.|[^"\\])*)"|'([^']*)'/g,r;for(;r=n.exec(t);){let s=r[1]??r[2]??"";try{e.push(r[1]!==void 0?JSON.parse(`"${s}"`):s)}catch{e.push(s)}}return e}function ln(t={}){let e=t.configFile??ze(process.env.CODEX_HOME??ze(cn(),".codex"),"config.toml"),n=t.previousFile??ze(cn(),".config","toolnet-memory","codex-notify-previous.json");on(un(e),{recursive:!0}),on(un(n),{recursive:!0});let r=$o(e)?Fo(e,"utf8"):"",s=t.binary??"toolnet-memory",o=`notify = [${JSON.stringify(s)}, "session:codex-notify"]`,i=r.split(`
|
|
90
|
-
`),c=i.findIndex(m=>/^\s*\[/.test(m));c<0&&(c=i.length);let u=-1,a=-1;for(let m=0;m<c;m+=1)if(/^\s*notify\s*=/.test(i[m])){if(u=m,a=m,i[m].includes("[")&&!i[m].includes("]"))for(;a+1<c&&(a+=1,!i[a].includes("]")););break}let f=[];if(u>=0){let m=i.slice(u,a+1).join(`
|
|
91
|
-
`);f=Lo(m),i.splice(u,a-u+1,o)}else c=i.findIndex(m=>/^\s*\[/.test(m)),c<0&&(c=i.length),i.splice(c,0,o);let l=f.length>=2&&f[f.length-1]==="session:codex-notify";return f.length>0&&!l&&an(n,JSON.stringify(f,null,2)+`
|
|
81
|
+
`,"utf8"),y=s+l;l+=S;let h;try{h=JSON.parse(d)}catch{continue}let g=Ht(h),x=mo(g);m.push({type:x.type,timestamp:fo(g),role:x.role,sourceEventId:`rollout:${y}`,sourceSequence:y,data:g,provenance:{source:"codex-rollout",sourcePath:t,sourceOffset:y}})}return{events:m,nextOffset:s+Buffer.byteLength(f,"utf8"),reset:r}}var go=[/^<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*$/],ho=[/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],yo=["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 So(t){let e=t.toLowerCase();return yo.some(n=>e.includes(n))}function ko(t){if(!t.trim())return!0;for(let e of go)if(e.test(t))return!0;return So(t),!1}function vo(t){let e=t;for(let n of ho)e=e.replace(n,r=>{let s=r.split(/[:\s=]+/);return s.length>1?`${s[0]}: [REDACTED]`:"[REDACTED]"});return e}function ze(t){let e=t.trim();return e?ko(e)?{content:"",filtered:!0,reason:"noise"}:{content:vo(e),filtered:!1}:{content:"",filtered:!0,reason:"empty"}}function Ie(t){let e={};for(let[n,r]of Object.entries(t))if(typeof r=="string"){let s=ze(r);s.filtered||(e[n]=s.content)}else r&&typeof r=="object"&&!Array.isArray(r)?e[n]=Ie(r):Array.isArray(r)?e[n]=r.map(s=>{if(typeof s=="string"){let o=ze(s);return o.filtered?null:o.content}return s&&typeof s=="object"?Ie(s):s}).filter(s=>s!==null):e[n]=r;return e}function Ut(t){let e=typeof t.type=="string"?t.type.toLowerCase():"";if(e.includes("system")||e.includes("ephemeral")||e==="tool_call"&&!t.result)return!0;if(t.data&&typeof t.data=="object"){let n=t.data,r=typeof n.content=="string"?n.content:"";if(r&&ze(r).filtered)return!0}return!1}import{existsSync as bo,mkdirSync as xo,readFileSync as wo,renameSync as jo,writeFileSync as Io}from"node:fs";import{dirname as Po,join as Co}from"node:path";function Oo(t,e){xo(Po(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;Io(n,`${JSON.stringify(e,null,2)}
|
|
82
|
+
`,{encoding:"utf8",mode:384}),jo(n,t)}function en(t){return Co(t.rootPath,".toolnet","work","current.json")}function Mo(t){let e=en(t);if(!bo(e))return null;try{let n=JSON.parse(wo(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function Be(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function z(t,e,n){let r=[],s=new Set;for(let o of[...t,...e].reverse()){let i=Be(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function Eo(t){return t.kind==="phase"?/^Phase\s+\d+$/iu.test(t.text):t.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(t.text):!1}function Yt(t,e){let n=e.status??t?.status??"pending",r=n;t?.status==="completed"&&n!=="completed"&&(r="completed"),t&&n==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(r=t.status);let s=t&&Eo(e)?t.title:e.text;return{id:t?.id??e.id,title:s,status:r,order:e.order??t?.order,confidence:Math.max(t?.confidence??0,e.confidence),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}function Gt(t){let e=new Map;for(let n of t){let r=n.order!==void 0?`order:${n.order}`:Be(n.title);e.set(r,n)}return e}function Qt(t){return t.order!==void 0?`order:${t.order}`:Be(t.key||t.text)}function Xt(t){return Array.from(t).sort((e,n)=>{let r=e.order??Number.MAX_SAFE_INTEGER,s=n.order??Number.MAX_SAFE_INTEGER;return r!==s?r-s:e.updatedAt.localeCompare(n.updatedAt)})}function Zt(t){return t.find(e=>e.status==="in_progress")??t.find(e=>e.status==="blocked")??t.find(e=>e.status==="pending")}function tn(t,e){let n=Mo(t),r=Gt(n?.phases??[]),s=Gt(n?.tasks??[]),o=n?.goal,i=n?.plan,u=n?.lastSession,c=[],a=[],f=[],l=[],m=[],d=[],S=[...e].sort((p,v)=>{let B=p.occurredAt.localeCompare(v.occurredAt);return B!==0?B:p.sequence-v.sequence});for(let p of S)switch(p.kind){case"goal":o=p.text;break;case"plan":i=p.text;break;case"phase":{let v=Qt(p);r.set(v,Yt(r.get(v),p));break}case"task":{let v=Qt(p);s.set(v,Yt(s.get(v),p));break}case"decision":c.push(p.text);break;case"blocker":a.push(p.text);break;case"warning":f.push(p.text);break;case"next_action":l.push(p.text);break;case"file":m.push(p.text);break;case"test":d.push(p.text);break;case"session":u={agent:p.agent,nativeSessionId:p.nativeSessionId,sessionKey:p.sessionKey,updatedAt:p.occurredAt};break}let y=Xt(r.values()),h=Xt(s.values()),g=Zt(y),x=Zt(h),T=z(n?.nextActions??[],[...l,...x?[x.title]:[],...!x&&g?[g.title]:[],...h.filter(p=>p.status==="pending").slice(0,5).map(p=>p.title)],8),A=z(n?.blockers??[],[...a,...y.filter(p=>p.status==="blocked").map(p=>p.title),...h.filter(p=>p.status==="blocked").map(p=>p.title)],20),j=S.length>0?S[S.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),M={version:1,projectId:t.id,projectName:t.name,goal:o,plan:i,phases:y,tasks:h,decisions:z(n?.decisions??[],c,20),blockers:A,warnings:z(n?.warnings??[],f,20),nextActions:T,filesTouched:z(n?.filesTouched??[],m,30),tests:z(n?.tests??[],d,20),currentPhase:g,currentTask:x,progress:{phasesTotal:y.length,phasesCompleted:y.filter(p=>p.status==="completed").length,tasksTotal:h.length,tasksCompleted:h.filter(p=>p.status==="completed").length,blocked:y.filter(p=>p.status==="blocked").length+h.filter(p=>p.status==="blocked").length},lastSession:u,updatedAt:j};return Oo(en(t),M),M}import{existsSync as To,readFileSync as Ao,writeFileSync as Ro}from"node:fs";import{join as No}from"node:path";var rn="<!-- TOOLNET:STABLE-WORK:BEGIN -->",qe="<!-- TOOLNET:STABLE-WORK:END -->";function Je(t){switch(t.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function Pe(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${n}`)]:[]}function nn(t,e){return e.length?["",`${t}:`,...e.map(n=>`- ${Je(n)} ${n.title}`)]:[]}function _o(t){let e=[rn,"# ToolNet Stable Work State","",`Updated: ${t.updatedAt}`];return t.lastSession&&e.push(`Last agent: ${t.lastSession.agent}`,`Last session: ${t.lastSession.nativeSessionId}`),t.goal&&e.push("","Goal:",t.goal),t.plan&&e.push("","Plan:",t.plan),t.currentPhase&&e.push("","Current phase:",`${Je(t.currentPhase)} ${t.currentPhase.title}`),t.currentTask&&e.push("","Current task:",`${Je(t.currentTask)} ${t.currentTask.title}`),e.push(...nn("Phases",t.phases)),e.push(...nn("TODO / Tasks",t.tasks)),e.push(...Pe("Next actions",t.nextActions)),e.push(...Pe("Blockers",t.blockers)),e.push(...Pe("Important decisions",t.decisions)),e.push(...Pe("Files touched",t.filesTouched)),e.push("","Progress:",`- Phases: ${t.progress.phasesCompleted}/${t.progress.phasesTotal}`,`- Tasks: ${t.progress.tasksCompleted}/${t.progress.tasksTotal}`,`- Blocked: ${t.progress.blocked}`,"","Continuation:","- Resume current unfinished task.","- Never redo completed TODO/Phase unless explicitly requested.","- Ask ToolNet Memory for deeper history only when necessary.",qe),e.join(`
|
|
83
|
+
`)}function sn(t,e){let n=No(t.rootPath,".toolnet","current.md"),r="";if(To(n))try{r=Ao(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=_o(e),o=r.indexOf(rn),i=r.indexOf(qe),u;o>=0&&i>=o?u=[r.slice(0,o).trimEnd(),s,r.slice(i+qe.length).trimStart()].filter(Boolean).join(`
|
|
84
|
+
|
|
85
|
+
`):u=r.trim()?`${r.trim()}
|
|
86
|
+
|
|
87
|
+
${s}`:s,Ro(n,`${u.trim()}
|
|
88
|
+
`,{encoding:"utf8",mode:384})}import{existsSync as $o,mkdirSync as Fo,readFileSync as Lo,renameSync as Wo,writeFileSync as Do}from"node:fs";import{dirname as Ko,join as zo}from"node:path";function on(t){return zo(t.rootPath,".toolnet","context","session-origin.json")}function Bo(t,e){Fo(Ko(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;Do(n,`${JSON.stringify(e,null,2)}
|
|
89
|
+
`,{encoding:"utf8",mode:384}),Wo(n,t)}function Ce(t,e){return[...t].filter(n=>n.kind===e).sort((n,r)=>{let s=n.occurredAt.localeCompare(r.occurredAt);return s!==0?s:n.sequence-r.sequence}).at(-1)}function an(t,e){let n=Ce(e.observations,"file"),r=Ce(e.observations,"next_action"),s=Ce(e.observations,"blocker"),o=Ce(e.observations,"decision"),i={version:1,projectId:t.id,agent:e.agent,nativeSessionId:e.nativeSessionId,updatedAt:e.workState.updatedAt,currentTask:e.workState.currentTask?.title,currentPhase:e.workState.currentPhase?.title,lastTouchedFile:n?.text??e.workState.filesTouched.at(-1),latestNextAction:r?.text??e.workState.nextActions.at(-1),latestBlocker:s?.text??e.workState.blockers.at(-1),latestDecision:o?.text??e.workState.decisions.at(-1)};return Bo(on(t),i),i}function qo(t){let e=on(t);if(!$o(e))return null;try{let n=JSON.parse(Lo(e,"utf8"));return n.version!==1||n.projectId!==t.id?null:n}catch{return null}}function cn(t){let e=qo(t);if(!e)return null;let n=["Previous session:",`- Agent: ${e.agent}`,`- Session: ${e.nativeSessionId}`];return e.currentPhase&&n.push(`- Current phase: ${e.currentPhase}`),e.currentTask&&n.push(`- Current task: ${e.currentTask}`),e.lastTouchedFile&&n.push(`- Last touched file: ${e.lastTouchedFile}`),e.latestBlocker&&n.push(`- Blocker: ${e.latestBlocker}`),e.latestNextAction&&n.push(`- Next action: ${e.latestNextAction}`),e.latestDecision&&n.push(`- Important decision: ${e.latestDecision}`),n.join(`
|
|
90
|
+
`)}async function Q(t){let e=t.threadId.trim();if(!e)throw new Error("Codex thread ID is required");let n=G(t.rolloutPath),r=t.cwd??n.cwd;if(r&&!je(t.project.rootPath,r))throw new Error(`Codex thread does not belong to project: ${r}`);if(n.threadId&&n.threadId!==e)throw new Error(`Codex rollout thread mismatch: expected ${e}, got ${n.threadId}`);let s=new xe({project:t.project,storage:t.storage,agent:"codex",nativeSessionId:e,metadata:{source:"codex-rollout",rolloutPath:t.rolloutPath,cwd:r,client:t.client}}),o=s.status(),i=o.sourceCursors["codex.rollout.path"],u=Number(o.sourceCursors["codex.rollout.offset"]??0);i&&i!==t.rolloutPath&&(u=0),(!Number.isFinite(u)||u<0)&&(u=0);let c=Vt(t.rolloutPath,u),a=[];o.lastSequence===0&&a.push({type:"session_start",sourceEventId:`codex:${e}:start`,data:{threadId:e,cwd:r,rolloutPath:t.rolloutPath,sessionMeta:n.raw},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}}),i&&i!==t.rolloutPath&&a.push({type:"custom",sourceEventId:`codex:${e}:rollout-rotation:${t.rolloutPath}`,data:{event:"rollout_rotation",previousPath:i,rolloutPath:t.rolloutPath},provenance:{source:"codex-rollout"}}),c.reset&&a.push({type:"custom",sourceEventId:`codex:${e}:rollout-reset:${c.nextOffset}`,data:{event:"rollout_reset"},provenance:{source:"codex-rollout",sourcePath:t.rolloutPath}});let f=c.events.filter(d=>!Ut(d.data)).map(d=>({...d,data:Ie(d.data)}));if(a.push(...f),t.idle&&f.length>0)try{let d={projectId:t.project.id,projectName:t.project.name,projectRoot:t.project.rootPath,agent:"codex",nativeSessionId:e,sessionKey:`codex:${e}`,remotePrefix:`projects/${t.project.id}/sessions/codex/${e}`,localDirectory:""},S=f.map((g,x)=>({version:1,id:`codex-work-${e}-${g.sourceSequence??x}`,sequence:x+1,projectId:t.project.id,agent:"codex",nativeSessionId:e,type:g.type,timestamp:g.timestamp??new Date().toISOString(),role:g.role,sourceEventId:g.sourceEventId,sourceSequence:g.sourceSequence,data:g.data??{},provenance:g.provenance??{}})),y=pe(d,S),h=tn(t.project,y);sn(t.project,h),an(t.project,{agent:"codex",nativeSessionId:e,observations:y,workState:h})}catch{}t.idle&&t.turnId&&a.push({type:"session_idle",sourceEventId:`codex:${e}:turn:${t.turnId}:idle`,data:{turnId:t.turnId,client:t.client},provenance:{source:"codex-notify"}});let l=s.recordMany(a);if(s.setSourceCursor("codex.rollout.path",t.rolloutPath),s.setSourceCursor("codex.rollout.offset",c.nextOffset),t.turnId&&s.setSourceCursor("codex.last.turn",t.turnId),t.idle&&f.length>0)try{let d=f.map(y=>JSON.stringify(y.data)),S=ce(d,e);s.setSourceCursor("codex.session.summary",S.summary),s.setSourceCursor("codex.session.facts_count",S.durableFacts.length),bt()&&!jt()&&s.setSourceCursor("codex.raw_transcript.archived","local")}catch{}let m=await s.flush();return{threadId:e,imported:l.length,rolloutEvents:c.events.length,eventCount:m.eventCount,chunkCount:m.chunkCount,status:m.status,rolloutOffset:c.nextOffset,reset:c.reset}}import{existsSync as Jo}from"node:fs";import{dirname as Ho,join as Vo,parse as Uo,resolve as Yo}from"node:path";function un(t){let e=Yo(t),n=Uo(e).root;for(;;){if(Jo(Vo(e,".toolnet","project.json")))return new F().detect(e);if(e===n)break;let r=Ho(e);if(r===e)break;e=r}return null}async function ln(t,e,n=100){let r=[];for(let s of De()){let o=G(s);if(!(!o.threadId||!o.cwd)&&je(t.rootPath,o.cwd)&&(r.push(await Q({project:t,storage:e,threadId:o.threadId,rolloutPath:s,cwd:o.cwd})),r.length>=n))break}return r}import{existsSync as Go,mkdirSync as dn,readFileSync as Qo,writeFileSync as pn}from"node:fs";import{homedir as fn}from"node:os";import{dirname as mn,join as He}from"node:path";function Xo(t){let e=[],n=/"((?:\\.|[^"\\])*)"|'([^']*)'/g,r;for(;r=n.exec(t);){let s=r[1]??r[2]??"";try{e.push(r[1]!==void 0?JSON.parse(`"${s}"`):s)}catch{e.push(s)}}return e}function gn(t={}){let e=t.configFile??He(process.env.CODEX_HOME??He(fn(),".codex"),"config.toml"),n=t.previousFile??He(fn(),".config","toolnet-memory","codex-notify-previous.json");dn(mn(e),{recursive:!0}),dn(mn(n),{recursive:!0});let r=Go(e)?Qo(e,"utf8"):"",s=t.binary??"toolnet-memory",o=`notify = [${JSON.stringify(s)}, "session:codex-notify"]`,i=r.split(`
|
|
91
|
+
`),u=i.findIndex(m=>/^\s*\[/.test(m));u<0&&(u=i.length);let c=-1,a=-1;for(let m=0;m<u;m+=1)if(/^\s*notify\s*=/.test(i[m])){if(c=m,a=m,i[m].includes("[")&&!i[m].includes("]"))for(;a+1<u&&(a+=1,!i[a].includes("]")););break}let f=[];if(c>=0){let m=i.slice(c,a+1).join(`
|
|
92
|
+
`);f=Xo(m),i.splice(c,a-c+1,o)}else u=i.findIndex(m=>/^\s*\[/.test(m)),u<0&&(u=i.length),i.splice(u,0,o);let l=f.length>=2&&f[f.length-1]==="session:codex-notify";return f.length>0&&!l&&pn(n,JSON.stringify(f,null,2)+`
|
|
92
93
|
`,{encoding:"utf8",mode:384}),r=i.join(`
|
|
93
94
|
`),r.endsWith(`
|
|
94
95
|
`)||(r+=`
|
|
95
|
-
`),
|
|
96
|
-
`,{encoding:"utf8",mode:384}),e}import{existsSync as
|
|
97
|
-
`);if(
|
|
98
|
-
`)),i=Math.max(0,e-o);if(i>=16){let
|
|
99
|
-
`).trim()}async function
|
|
96
|
+
`),pn(e,r,{encoding:"utf8",mode:384}),{configFile:e,previousFile:n,preservedPrevious:f.length>0&&!l}}import{existsSync as Zo,mkdirSync as ei,readFileSync as ti,writeFileSync as ni}from"node:fs";import{homedir as ri}from"node:os";import{dirname as si,join as hn}from"node:path";function oi(t){return`'${t.replace(/'/g,"'\\''")}'`}function yn(t={}){let e=t.hooksFile??hn(process.env.CODEX_HOME??hn(ri(),".codex"),"hooks.json");ei(si(e),{recursive:!0});let n={};if(Zo(e))try{n=JSON.parse(ti(e,"utf8"))}catch(u){throw new Error(`Invalid existing Codex hooks.json: ${u instanceof Error?u.message:String(u)}`)}let r=n.hooks&&typeof n.hooks=="object"&&!Array.isArray(n.hooks)?n.hooks:{};n.hooks=r;let o=(Array.isArray(r.SessionStart)?r.SessionStart:[]).filter(u=>{try{return!JSON.stringify(u).includes("session:codex-context")}catch{return!0}}),i=t.binary??"toolnet-memory";return o.push({matcher:"startup|resume|clear|compact",hooks:[{type:"command",command:`${oi(i)} session:codex-context`,timeout:15,additionalContextLimit:1e3,statusMessage:"Loading ToolNet project continuity"}]}),r.SessionStart=o,ni(e,JSON.stringify(n,null,2)+`
|
|
97
|
+
`,{encoding:"utf8",mode:384}),e}import{existsSync as td,mkdirSync as ui,readFileSync as nd,writeFileSync as li}from"node:fs";import{dirname as di,join as kn}from"node:path";function Ve(t){if(!t)return 0;let e=Array.from(t).length,n=t.trim().split(/\s+/u).filter(Boolean).length;return Math.ceil(Math.max(e/3.5,n*1.3))}function b(t,e){let n=t.replace(/\s+/g," ").trim();return n.length<=e?n:n.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function ii(t){let e=[],n=!1;for(let r of t.split(/\r?\n/u)){let s=r.trim();if(s.includes("<!--")&&(n=!0),n){s.includes("-->")&&(n=!1);continue}let o=s.toLowerCase();if(!(!s||s.startsWith("#")||s==="```"||o.startsWith("- [enforce]")||o.startsWith("* [enforce]")||o.startsWith("- [advisory]")||o.startsWith("* [advisory]"))&&(s=s.replace(/^[-*]\s+/u,""),s&&e.push(b(s,280)),e.length>=16))break}return e}function ai(t){let e=[],n=[];for(let r of t.split(/\\r?\\n/u)){let s=r.trim(),o=s.toLowerCase(),u=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(a=>o.startsWith(a));if(!u)continue;let c=s.slice(u.length).trim();c&&(u.includes("enforce")?e.push(c):n.push(c))}return{enforce:e,advisory:n}}function ci(t,e){let n=[];for(let r of t){let s=[...n,r].join(`
|
|
98
|
+
`);if(Ve(s)<=e){n.push(r);continue}let o=Ve(n.join(`
|
|
99
|
+
`)),i=Math.max(0,e-o);if(i>=16){let u=Math.floor(i*3.2),c=b(r,u);c&&n.push(c)}break}return n.join(`
|
|
100
|
+
`).trim()}async function Sn(t){let e=Math.max(256,Math.min(2e3,t.maxTokens??1e3)),n=ve(t.project,!1),r=n?.content??"";r||(r=await t.storage.getText(`projects/${t.project.id}/project/manual.md`)??"");let s=ai(r),o=n?n.rules.filter(d=>d.mode==="enforce").map(d=>d.text):s.enforce,i=n?n.rules.filter(d=>d.mode==="advisory").map(d=>d.text):s.advisory,u=r?ii(r):[],c=await ge(t.project,t.storage),a=await $t(t.project,t.storage),f=await zt(t.project,t.storage),l=[];if(l.push("[TOOLNET PROJECT CONTEXT]"),l.push(`Project: ${t.project.name}`),l.push("Continue existing project state. Do not restart completed work unless evidence shows it is necessary."),r&&l.push(`Full operating manual: ${ke(t.project)}`),o.length){l.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let d of o.slice(0,24))l.push(`- [ENFORCE] ${b(d,240)}`)}if(i.length){l.push("","PROJECT PREFERENCES");for(let d of i.slice(0,10))l.push(`- ${b(d,220)}`)}if(a&&(a.mission&&l.push("","MISSION",b(a.mission.value,420)),a.activeObjective&&l.push("","CURRENT OBJECTIVE",b(a.activeObjective.value,420)),a.why&&l.push("","WHY THIS WORK MATTERS",b(a.why.value,420)),a.desiredOutcome&&l.push("","DESIRED OUTCOME",b(a.desiredOutcome.value,420)),a.planRationale&&l.push("","WHY THIS APPROACH",b(a.planRationale.value,420))),c){if(l.push("","ACTIVE WORK"),c.goal&&l.push(`Goal: ${b(c.goal,320)}`),c.plan&&l.push(`Plan: ${b(c.plan,320)}`),l.push(`Progress: phases ${c.progress.phasesCompleted}/${c.progress.phasesTotal}; tasks ${c.progress.tasksCompleted}/${c.progress.tasksTotal}; blocked ${c.progress.blocked}`),c.currentPhase&&l.push(`Current phase: ${c.currentPhase.title} [${c.currentPhase.status}]`),c.currentPhase&&a){let d=a.phases.find(S=>S.order===c.currentPhase?.order);d&&(d.objective&&l.push(`Phase objective: ${b(d.objective.value,340)}`),d.why?l.push(`Why this phase: ${b(d.why.value,340)}`):l.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),d.deliverable&&l.push(`Deliverable: ${b(d.deliverable.value,340)}`),d.dependencies.length&&l.push(`Depends on: ${d.dependencies.slice(0,4).map(S=>b(S.value,180)).join("; ")}`),d.acceptanceCriteria.length&&(l.push("","DEFINITION OF DONE"),d.acceptanceCriteria.slice(0,6).forEach(S=>{l.push(`- ${b(S.value,260)}`)})),d.openQuestions.length&&(l.push("","OPEN QUESTIONS FOR CURRENT PHASE"),d.openQuestions.slice(0,4).forEach(S=>{l.push(`- ${b(S.value,260)}`)})))}c.currentTask&&l.push(`Current task: ${c.currentTask.title} [${c.currentTask.status}]`),c.nextActions.length&&(l.push("","NEXT ACTIONS"),c.nextActions.slice(0,6).forEach((d,S)=>{l.push(`${S+1}. ${b(d,260)}`)})),c.blockers.length&&(l.push("","BLOCKERS"),c.blockers.slice(0,5).forEach(d=>{l.push(`- ${b(d,260)}`)})),c.warnings.length&&(l.push("","ATTENTION"),c.warnings.slice(-5).forEach(d=>{l.push(`- ${b(d,260)}`)})),c.decisions.length&&(l.push("","RECENT DECISIONS"),c.decisions.slice(-5).forEach(d=>{l.push(`- ${b(d,260)}`)})),c.lastSession&&l.push("",`Last work session: ${c.lastSession.agent} / ${c.lastSession.nativeSessionId}`)}if(a&&a.openQuestions.length&&(l.push("","UNRESOLVED QUESTIONS"),a.openQuestions.slice(0,5).forEach(d=>{l.push(`- ${b(d.value,260)}`)})),f&&l.push(`Latest handoff: ${f.reason} / ${f.sourceSession.agent}`),u.length){l.push("","OPERATING NOTES");for(let d of u)l.push(`- ${d}`)}l.push("","Before changing anything: verify the current repository state and continue from the active phase/task above.");let m=ci(l,e);return{version:1,projectId:t.project.id,projectName:t.project.name,text:m,estimatedTokens:Ve(m),maxTokens:e,hasManual:!!r,hasWorkState:!!c,hasHandoff:!!f,generatedAt:new Date().toISOString()}}function pi(t){return kn(t.rootPath,".toolnet","context","startup.md")}function fi(t){return kn(t.rootPath,".toolnet","context","startup.json")}function mi(t,e){let n=pi(t);ui(di(n),{recursive:!0}),li(n,e.text.endsWith(`
|
|
100
101
|
`)?e.text:e.text+`
|
|
101
|
-
`,{encoding:"utf8",mode:384}),I(
|
|
102
|
+
`,{encoding:"utf8",mode:384}),I(fi(t),e)}async function vn(t,e,n=800){let s=(await Sn({project:t,storage:e,maxTokens:n})).text;ie(s)>n&&(s=ae(s,n),s+=`
|
|
102
103
|
|
|
103
104
|
[Context trimmed by ToolNet Memory token budget]
|
|
104
|
-
`);let i={version:1,projectId:t.id,projectName:t.name,text:s,digest:k(s),estimatedTokens:
|
|
105
|
+
`);let i={version:1,projectId:t.id,projectName:t.name,text:s,digest:k(s),estimatedTokens:ie(s),generatedAt:new Date().toISOString()};return mi(t,i),await e.put(`projects/${t.id}/context/startup.md`,i.text+`
|
|
105
106
|
`,"text/markdown"),await e.put(`projects/${t.id}/context/startup.json`,JSON.stringify(i,null,2)+`
|
|
106
|
-
`,"application/json"),i}import{existsSync as
|
|
107
|
+
`,"application/json"),i}import{existsSync as vi,readFileSync as bi}from"node:fs";import{join as xi}from"node:path";import{existsSync as bn,mkdirSync as gi,readFileSync as xn,renameSync as hi,writeFileSync as yi}from"node:fs";import{dirname as Si,join as wn}from"node:path";function jn(t){return wn(t.rootPath,".toolnet","context","handoff.md")}function In(t){return wn(t.rootPath,".toolnet","context","handoff.json")}function Pn(t,e){gi(Si(t),{recursive:!0});let n=`${t}.tmp-${process.pid}-${Date.now()}`;yi(n,e.endsWith(`
|
|
107
108
|
`)?e:`${e}
|
|
108
|
-
`,{encoding:"utf8",mode:384}),
|
|
109
|
-
`)}function
|
|
110
|
-
`).trim();if(!n)return null;let r={version:1,projectId:t.id,projectName:t.name,text:n,digest:k(n),generatedAt:new Date().toISOString()};return
|
|
109
|
+
`,{encoding:"utf8",mode:384}),hi(n,t)}function ki(t,e){Pn(t,`${JSON.stringify(e,null,2)}
|
|
110
|
+
`)}function Cn(t,e){let n=e.replace(/\r\n/g,`
|
|
111
|
+
`).trim();if(!n)return null;let r={version:1,projectId:t.id,projectName:t.name,text:n,digest:k(n),generatedAt:new Date().toISOString()};return Pn(jn(t),n),ki(In(t),r),r}function On(t){let e=jn(t);if(!bn(e))return null;try{let n=xn(e,"utf8").trim();if(!n)return null;let r=new Date(0).toISOString(),s=In(t);if(bn(s))try{let o=JSON.parse(xn(s,"utf8"));typeof o.generatedAt=="string"&&(r=o.generatedAt)}catch{}return{version:1,projectId:t.id,projectName:t.name,text:n,digest:k(n),generatedAt:r}}catch{return null}}function wi(t){let e=xi(t.rootPath,".toolnet","current.md");if(!vi(e))return null;try{return bi(e,"utf8").trim()}catch{return null}}function ji(t,e){let n=e.replace(/\r\n/g,`
|
|
111
112
|
`).trim(),r=2400,s=n.length>r?`${n.slice(0,r)}
|
|
112
113
|
|
|
113
|
-
[Current work truncated for fast handoff]`:n,o=
|
|
114
|
-
`)}function
|
|
114
|
+
[Current work truncated for fast handoff]`:n,o=cn(t);return["# ToolNet Fast Handoff","",`Project: ${t.name}`,"",...o?[o,""]:[],s,"","---","","Continuation rule:","- Continue unfinished work; do not redo completed steps.","- Query ToolNet Memory only when deeper history is needed."].join(`
|
|
115
|
+
`)}function Mn(t){let e=wi(t);if(e===null)return{updated:!1,reason:"missing-current",chars:0};if(!e.trim())return{updated:!1,reason:"empty-current",chars:0};let n=ji(t,e);return On(t)?.text.trim()===n.trim()?{updated:!1,reason:"unchanged",chars:n.length}:(Cn(t,n),{updated:!0,reason:"updated",chars:n.length})}function Oe(t,e){let n=t.indexOf(e);return n>=0?t[n+1]:void 0}function En(t){let e=X(),n=st(nt({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3});return new re(n,t.id,t.name,t.remote??t.name)}async function Ei(t){for(let e=0;e<10;e+=1){let n=Ke(t);if(n)return n;await new Promise(r=>setTimeout(r,150))}return null}function Ti(t){let e=Mi(Oi(),".config","toolnet-memory","codex-notify-previous.json");if(Ii(e))try{let n=JSON.parse(Pi(e,"utf8"));if(!Array.isArray(n)||n.length===0||!n.every(s=>typeof s=="string"))return;Ci(n[0],[...n.slice(1),t],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function Ai(t){let e;try{e=JSON.parse(t)}catch{return}if(e.type!=="agent-turn-complete")return;let r=typeof e["thread-id"]=="string"?e["thread-id"]:"",s=typeof e["turn-id"]=="string"?e["turn-id"]:"",o=typeof e.cwd=="string"?e.cwd:"",i=typeof e.client=="string"?e.client:void 0;if(!r||!o)return;let u=un(o);if(!u)return;let c=await Ei(r);if(!c)return;let a=En(u);await Q({project:u,storage:a,threadId:r,rolloutPath:c,cwd:o,turnId:s,client:i,idle:!0});try{await vn(u,a,800)}catch{}try{Mn(u)}catch{}}async function Ri(){let[t="help",...e]=process.argv.slice(2);if(t==="install-notify"){let o=Oe(e,"--bin"),i=gn({binary:o}),u=yn({binary:o});console.log(`\u2705 Codex notify installed: ${i.configFile}`),i.preservedPrevious&&console.log(`\u2705 Previous notify preserved: ${i.previousFile}`),console.log(`\u2705 Codex SessionStart context hook: ${u}`);return}if(t==="notify"){let o=e[e.length-1]??"";try{await Ai(o)}finally{Ti(o)}return}let n=Oe(e,"--project")??process.cwd(),r=new F().detect(n),s=En(r);if(t==="sync"){let o=e[0];if(!o)throw new Error("Usage: sync <thread-id>");let i=Oe(e,"--rollout")??Ke(o);if(!i)throw new Error(`Codex rollout not found for ${o}`);let u=await Q({project:r,storage:s,threadId:o,rolloutPath:i,idle:e.includes("--idle")});console.log(JSON.stringify(u,null,2));return}if(t==="recover"){let o=Number(Oe(e,"--limit")??100),i=await ln(r,s,Number.isFinite(o)?o:100);console.log(JSON.stringify({project:r.name,sessions:i.length,imported:i.reduce((u,c)=>u+c.imported,0)},null,2));return}console.log(`Codex Session Adapter
|
|
115
116
|
|
|
116
117
|
Commands:
|
|
117
118
|
install-notify
|
|
118
119
|
sync <thread-id> [--project PATH]
|
|
119
120
|
recover [--project PATH] [--limit N]
|
|
120
|
-
`)}
|
|
121
|
+
`)}Ri().catch(t=>{process.argv[2]==="notify"&&process.exit(0),console.error(t instanceof Error?t.message:t),process.exit(1)});
|