toolnet-memory 0.2.7 → 0.2.9
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/bundle/agy-hook.js +25 -25
- package/package.json +1 -1
package/bundle/agy-hook.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
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}),Tt(s,n)}function
|
|
4
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e
|
|
5
|
-
`,{encoding:"utf8",mode:384}),
|
|
6
|
-
`,u=v(r.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${
|
|
7
|
-
`,"application/json"),E}async function
|
|
1
|
+
import{existsSync as xt,readFileSync as It}from"node:fs";import{homedir as Pt}from"node:os";import{join as Ot}from"node:path";function Et(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 At(){let t=process.env.TOOLNET_GLOBAL_ENV??Ot(Pt(),".config","toolnet-memory",".env");if(!xt(t))return;let e=It(t,"utf8");for(let r of e.split(/\r?\n/)){let n=r.trim();if(!n||n.startsWith("#"))continue;n.startsWith("export ")&&(n=n.slice(7));let s=n.indexOf("=");if(s<=0)continue;let o=n.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=Et(n.slice(s+1)))}}At();function K(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function z(t,e){if(!t)return e;let r=Number(t);return Number.isFinite(r)?r:e}function xe(){return{memory:{autoCapture:K(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:K(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:K(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:K(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:z(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:z(process.env.MEMORY_RERANK_TOP,10),finalContext:z(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:z(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",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:z(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Nt}from"node:crypto";import{existsSync as le,mkdirSync as Mt,readFileSync as Rt,renameSync as Tt,writeFileSync as _t}from"node:fs";import{basename as Ct,dirname as q,join as V,parse as Oe,resolve as W}from"node:path";var Ee=".toolnet",$t="project.json";function Lt(t){return Nt("sha256").update(t).digest("hex").slice(0,16)}function de(t){return V(t,Ee,$t)}function zt(t){return le(de(t))}function Wt(t,e){let r=W(t),n=Oe(r).root;for(;;){if(zt(r))return r;if(r===n||e&&r===W(e))break;let s=q(r);if(s===r)break;r=s}return null}function Ft(t){let e=W(t),r=Oe(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(o=>le(V(e,o))))return e;if(e===r)break;let s=q(e);if(s===e)break;e=s}return W(t)}function Bt(t){let e;try{e=JSON.parse(Rt(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 r=e;if(typeof r.id!="string"||!r.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof r.name!="string"||!r.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let n=new Date().toISOString();return{version:1,id:r.id,name:r.name,remote:typeof r.remote=="string"&&r.remote.trim()?r.remote:r.name,rootPath:typeof r.rootPath=="string"?r.rootPath:q(q(t)),createdAt:typeof r.createdAt=="string"?r.createdAt:n,updatedAt:typeof r.updatedAt=="string"?r.updatedAt:n,graphVersion:typeof r.graphVersion=="number"?r.graphVersion:0,memoryVersion:typeof r.memoryVersion=="number"?r.memoryVersion:0,metadata:r.metadata&&typeof r.metadata=="object"?r.metadata:void 0}}function Ie(t,e){let r=V(t,Ee);Mt(r,{recursive:!0});let n=de(t),s=`${n}.tmp-${process.pid}`;_t(s,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),Tt(s,n)}function Pe(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 J=class{detect(e=process.cwd()){let r=W(e),n=Ft(r),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>le(V(n,d))),i=Wt(r,o?n:void 0);if(i){let d=de(i),p=Bt(d);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),Ie(i,p)),Pe(p,i)}let u=new Date().toISOString(),a=Ct(n),c={version:1,id:Lt(n),name:a,remote:a,rootPath:n,createdAt:u,updatedAt:u,graphVersion:0,memoryVersion:0};return Ie(n,c),Pe(c,n)}};var Dt=[{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}],U=class{scan(e){let r=[];for(let n of Dt){let s=new RegExp(n.regex.source,n.regex.flags);for(let o of e.matchAll(s))r.push({type:n.type,value:o[0]})}return r}hasSecrets(e){return this.scan(e).length>0}};var F=class{scanner=new U;sanitize(e){let r=e,n=this.scanner.scan(e),s=new Set;for(let o of n)s.add(o.type),r=r.split(o.value).join(`[REDACTED:${o.type}]`);return{text:r,redacted:n.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(r=>this.sanitizeValue(r));if(e&&typeof e=="object"){let r={};for(let[n,s]of Object.entries(e)){let o=n.toLowerCase();o.includes("password")||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")?r[n]="[REDACTED]":r[n]=this.sanitizeValue(s)}return r}return e}};import{homedir as sr}from"node:os";import{join as or}from"node:path";import{DeleteObjectCommand as Kt,GetObjectCommand as qt,HeadObjectCommand as Jt,ListObjectsV2Command as Vt,PutObjectCommand as Ut,S3Client as Ht}from"@aws-sdk/client-s3";import{getSignedUrl as Yt}from"@aws-sdk/s3-request-presigner";var H=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Ht({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,r,n="application/octet-stream"){let s=typeof r=="string"?Buffer.from(r,"utf8"):r;await this.client.send(new Ut({Bucket:this.bucket,Key:e,Body:s,ContentType:n}))}async get(e){let r=await Yt(this.client,new qt({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(r,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`HF download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await this.client.send(new Jt({Bucket:this.bucket,Key:e})),!0}catch(r){if(typeof r=="object"&&r!==null&&"$metadata"in r&&r.$metadata?.httpStatusCode===404)return!1;throw r}}async delete(e){await this.client.send(new Kt({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],n;do{let s=await this.client.send(new Vt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let o of s.Contents??[])o.Key&&r.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});n=s.IsTruncated?s.NextContinuationToken:void 0}while(n);return r}};import{access as Ae,mkdir as Gt,readFile as Qt,readdir as Xt,rm as Zt,stat as Ne,writeFile as er}from"node:fs/promises";import{dirname as tr,join as rr,relative as Me,resolve as nr}from"node:path";var B=class{constructor(e){this.root=e}root;name="local";path(e){let r=e.replace(/^\/+/,"");return nr(this.root,r)}async put(e,r){let n=this.path(e);await Gt(tr(n),{recursive:!0}),await er(n,r)}async get(e){try{return await Qt(this.path(e))}catch(r){if(typeof r=="object"&&r!==null&&"code"in r&&r.code==="ENOENT")return null;throw r}}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await Ae(this.path(e)),!0}catch{return!1}}async delete(e){await Zt(this.path(e),{force:!0})}async list(e=""){let r=this.path(e),n=[];try{await Ae(r)}catch{return n}let s=async i=>{let u=await Xt(i,{withFileTypes:!0});for(let a of u){let c=rr(i,a.name);if(a.isDirectory()){await s(c);continue}let d=await Ne(c);n.push({key:Me(this.root,c),size:d.size,updatedAt:d.mtime.toISOString()})}},o=await Ne(r);return o.isDirectory()?await s(r):n.push({key:Me(this.root,r),size:o.size,updatedAt:o.mtime.toISOString()}),n}};function Re(t){let e=t.localRoot??or(sr(),".toolnet-memory","storage");if(t.provider==="huggingface"){let r=t.huggingface;return r?.namespace&&r.bucket&&r.accessKeyId&&r.secretAccessKey?new H({namespace:r.namespace,bucket:r.bucket,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new B(e))}return new B(e)}function ir(t){return new Promise(e=>setTimeout(e,t))}async function Te(t,e={}){let r=Math.max(1,e.attempts??3),n=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=r;i++)try{return await t()}catch(u){if(o=u,i>=r)break;let a=Math.min(s,n*2**(i-1)),c=Math.floor(Math.random()*Math.max(1,a*.2));await ir(a+c)}throw o}var ar=new Set(["put","get","getText","delete","list"]);function _e(t,e={}){return new Proxy(t,{get(r,n){let s=Reflect.get(r,n,r);return typeof s!="function"?s:ar.has(n)?(...o)=>Te(()=>Promise.resolve(s.apply(r,o)),e):s.bind(r)}})}function Ce(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 $e(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 r=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[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 Y=class{constructor(e,r,n,s){this.provider=e;this.name=e.name,this.projectId=r,this.projectName=n,this.folder=Ce(s??n),this.sourcePrefix=`projects/${r}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,r=new Date().toISOString(),n=r,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"&&(n=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:n,updatedAt:r};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=$e(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,r,n){return await this.ensureRegistered(),this.provider.put(this.key(e),r,n)}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{createHash as cr}from"node:crypto";import{dirname as ur}from"node:path";import{mkdirSync as pr,readFileSync as lr,renameSync as dr,writeFileSync as fr}from"node:fs";function v(t){return cr("sha256").update(t).digest("hex")}function fe(t){if(Array.isArray(t))return t.map(fe);if(t&&typeof t=="object"){let e=t,r={};for(let n of Object.keys(e).sort())r[n]=fe(e[n]);return r}return t}function Le(t){return JSON.stringify(fe(t))}function ze(t){try{return JSON.parse(lr(t,"utf8"))}catch{return null}}function x(t,e){pr(ur(t),{recursive:!0});let r=`${t}.${process.pid}.tmp`;fr(r,JSON.stringify(e,null,2)+`
|
|
5
|
+
`,{encoding:"utf8",mode:384}),dr(r,t)}var mr=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function C(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Fe(t){return C(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(t,e,r=0){if(!(r>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let n of t.slice(0,50))_(n,e,r+1);return}if(!(!t||typeof t!="object"))for(let[n,s]of Object.entries(t))(mr.has(n)||["data","payload","parts","messages"].includes(n))&&_(s,e,r+1)}}function G(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 We(t){let e=C(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,r,n,s={}){let o=C(n),i=s.key??Fe(o);return{version:1,id:v([t.projectId,r,i,e.id,o,s.status??"",s.order??""].join("|")).slice(0,32),projectId:t.projectId,kind:r,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 gr(t,e,r){let n=C(r);if(n.length<5||n.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(n),i=n.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(w(t,e,"goal",i[1],{confidence:.97}));let u=n.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);u?.[1]&&s.push(w(t,e,"plan",u[1],{confidence:.95}));let a=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,c;for(;!o&&(c=a.exec(n));){let g=Number(c[1]),l=C(c[2]??""),y=l&&!We(l)?`Phase ${g} - ${l}`:`Phase ${g}`;s.push(w(t,e,"phase",y,{key:`phase:${g}`,order:g,status:G(n),confidence:.93}))}let d=r.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);d?.[2]&&s.push(w(t,e,"task",d[2],{status:d[1].trim()?"completed":G(d[2]),confidence:.96}));let p=n.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(p?.[2]){let g=p[1]?Number(p[1]):void 0,l=C(p[2]),y=We(l);s.push(w(t,e,"task",y&&g!==void 0?`TODO ${g}`:l,{key:g!==void 0?`task:${g}`:Fe(l),order:g,status:G(n),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(n)){let g=n.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");g&&s.push(w(t,e,"next_action",g,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(n)&&s.push(w(t,e,"blocker",n,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(n)&&s.push(w(t,e,"warning",n,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(n)&&s.push(w(t,e,"decision",n,{confidence:.9})),s}function Be(t,e){if(e.length===0)return[];let r=[],n=new Set;function s(i){n.has(i.id)||(n.add(i.id),r.push(i))}for(let i of e){if(i.type==="decision"){let a=[];_(i.data,a);for(let c of a)s(w(t,i,"decision",c,{confidence:1}))}if(i.type==="todo"){let a=[];_(i.data,a);for(let c of a)s(w(t,i,"task",c,{status:G(c),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let a of["filePath","path","file"]){let c=i.data[a];typeof c=="string"&&c&&s(w(t,i,"file",c,{confidence:1}))}if(i.type==="test"){let a=[];_(i.data,a);for(let c of a)s(w(t,i,"test",c,{confidence:1}))}let u=[];_(i.data,u);for(let a of u)for(let c of a.split(/\n+/u))for(let d of gr(t,i,c))s(d)}let o=e[e.length-1];return s(w(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),r}function De(t){return String(t).padStart(12,"0")}var Q=class{constructor(e){this.storage=e}storage;async write(e,r){if(r.length===0)return null;let n=Math.min(...r.map(c=>c.sequence)),s=Math.max(...r.map(c=>c.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:n,lastSequence:s,observations:r},i=JSON.stringify(o,null,2)+`
|
|
6
|
+
`,u=v(r.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${De(n)}-${De(s)}-${u}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,i,"application/json"),a}};import{join as Ke}from"node:path";import{mkdirSync as hr}from"node:fs";function yr(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function $(t,e=20){let r=[],n=new Set;for(let s of t.slice().reverse()){let o=yr(s);if(!(!o||n.has(o))&&(n.add(o),r.push(s),r.length>=e))break}return r.reverse()}function Sr(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 qe(t,e){let r=e.status??t?.status??"pending",n=r;t&&(t.status==="completed"&&r!=="completed"?n="completed":r==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(n=t.status));let s=t&&Sr(e)?t.title:e.text;return{id:t?.id??v(e.key).slice(0,24),title:s,status:n,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 vr(t,e){let r=`projects/${t.id}/work/observations/`,n=await e.list(r),s=[];for(let o of n.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 X(t,e){let n=(await vr(t,e)).flatMap(f=>f.observations).sort((f,b)=>{let we=f.occurredAt.localeCompare(b.occurredAt);if(we!==0)return we;let be=f.sequence-b.sequence;return be!==0?be:f.id.localeCompare(b.id)}),s=new Map,o=new Map,i,u,a,c=[],d=[],p=[],g=[],l=[],y=[];for(let f of n)switch(f.kind){case"goal":i=f.text;break;case"plan":u=f.text;break;case"phase":s.set(f.key,qe(s.get(f.key),f));break;case"task":o.set(f.key,qe(o.get(f.key),f));break;case"decision":c.push(f.text);break;case"blocker":d.push(f.text);break;case"warning":p.push(f.text);break;case"next_action":g.push(f.text);break;case"file":l.push(f.text);break;case"test":y.push(f.text);break;case"session":a={agent:f.agent,nativeSessionId:f.nativeSessionId,sessionKey:f.sessionKey,updatedAt:f.occurredAt};break}let h=Array.from(s.values()).sort((f,b)=>(f.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),m=Array.from(o.values()).sort((f,b)=>(f.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),S=h.find(f=>f.status==="in_progress")??h.find(f=>f.status==="blocked")??h.find(f=>f.status==="pending"),k=m.find(f=>f.status==="in_progress")??m.find(f=>f.status==="blocked")??m.find(f=>f.status==="pending"),M=$([...g,...k?[k.title]:[],...!k&&S?[S.title]:[],...m.filter(f=>f.status==="pending").slice(0,5).map(f=>f.title)],8),T=$([...d,...h.filter(f=>f.status==="blocked").map(f=>f.title),...m.filter(f=>f.status==="blocked").map(f=>f.title)],20),E={version:1,projectId:t.id,projectName:t.name,goal:i,plan:u,phases:h,tasks:m,decisions:$(c,20),blockers:T,warnings:$(p,20),nextActions:M,filesTouched:$(l,30),tests:$(y,20),currentPhase:S,currentTask:k,progress:{phasesTotal:h.length,phasesCompleted:h.filter(f=>f.status==="completed").length,tasksTotal:m.length,tasksCompleted:m.filter(f=>f.status==="completed").length,blocked:h.filter(f=>f.status==="blocked").length+m.filter(f=>f.status==="blocked").length},lastSession:a,updatedAt:n.length?n[n.length-1].occurredAt:new Date().toISOString()},R=Ke(t.rootPath,".toolnet","work");return hr(R,{recursive:!0}),x(Ke(R,"current.json"),E),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(E,null,2)+`
|
|
7
|
+
`,"application/json"),E}async function Z(t,e){let r=await e.getText(`projects/${t.id}/work/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}import{closeSync as jr,existsSync as kr,openSync as wr,readSync as br,statSync as xr}from"node:fs";function Ir(t,e){if(!kr(t))return{events:[],nextOffset:e};let r=xr(t).size,n=Number.isFinite(e)?Math.max(0,e):0;if(n>r&&(n=0),n===r)return{events:[],nextOffset:r};let s=r-n,o=Buffer.alloc(s),i=wr(t,"r");try{br(i,o,0,s,n)}finally{jr(i)}let u=o.toString("utf8"),a=u.lastIndexOf(`
|
|
8
8
|
`);if(a<0)return{events:[],nextOffset:n};let c=u.slice(0,a+1);return{events:c.split(`
|
|
9
|
-
`).filter(Boolean).flatMap(p=>{try{return[JSON.parse(p)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(c,"utf8")}}var
|
|
9
|
+
`).filter(Boolean).flatMap(p=>{try{return[JSON.parse(p)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(c,"utf8")}}var ee=class{constructor(e){this.options=e;this.journal=new Q(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),r=Number(e.sourceCursors["work.continuity.offset"]??0),n=Ir(this.options.wal.eventsFile,Number.isFinite(r)?r:0);if(n.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:n.nextOffset};let s=Be(this.options.identity,n.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await X(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",n.nextOffset),{scannedEvents:n.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:n.nextOffset}}};import{mkdirSync as Cr}from"node:fs";import{join as me}from"node:path";import{existsSync as Ue,mkdirSync as Pr,readFileSync as Or,statSync as Je,writeFileSync as Er}from"node:fs";import{dirname as Ar,join as Nr}from"node:path";var Ve=64*1024,Mr=`# ToolNet Project Operating Manual
|
|
10
10
|
|
|
11
11
|
This file contains persistent instructions for AI agents working on this project.
|
|
12
12
|
|
|
@@ -49,30 +49,30 @@ Things an AI agent should always remember.
|
|
|
49
49
|
<!--
|
|
50
50
|
- [advisory] Prefer small focused files.
|
|
51
51
|
-->
|
|
52
|
-
`;function
|
|
52
|
+
`;function te(t){return Nr(t.rootPath,".toolnet","PROJECT.md")}function Rr(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function Tr(t){let e=[],r=new Set,n=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=n.exec(t);){let o=s[1].toLowerCase(),i=Rr(s[2]);if(!i)continue;let u=`${o}:${i.toLowerCase()}`;r.has(u)||(r.add(u),e.push({id:v(u).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function _r(t){let e=te(t);return Ue(e)||(Pr(Ar(e),{recursive:!0}),Er(e,Mr,{encoding:"utf8",mode:384})),e}function re(t,e=!1){let r=e?_r(t):te(t);if(!Ue(r))return null;if(Je(r).size>Ve)throw new Error(`PROJECT.md exceeds ${Ve} bytes`);let s=Or(r,"utf8");return{path:r,content:s,digest:v(s),rules:Tr(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(Je(r).mtimeMs).toISOString()}}function $r(t){return{goal:t.goal,plan:t.plan,phases:t.phases.map(e=>({id:e.id,title:e.title,status:e.status,order:e.order})),tasks:t.tasks.map(e=>({id:e.id,title:e.title,status:e.status,order:e.order})),decisions:t.decisions,blockers:t.blockers,warnings:t.warnings,nextActions:t.nextActions,filesTouched:t.filesTouched,tests:t.tests}}function Lr(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 ne=class{constructor(e){this.options=e}options;async capture(e,r){let n=await Z(this.options.project,this.options.storage);if(n||(n=await X(this.options.project,this.options.storage)),!Lr(n))return null;let s=re(this.options.project,!1),o=s?s.rules.filter(g=>g.mode==="enforce").map(g=>g.text):[],i=v(JSON.stringify($r(n))),u=v([this.options.project.id,this.options.identity.sessionKey,i].join("|")).slice(0,24),a=new Date().toISOString(),c={version:1,id:u,projectId:this.options.project.id,projectName:this.options.project.name,createdAt:a,reason:e,sourceSession:{agent:this.options.identity.agent,nativeSessionId:this.options.identity.nativeSessionId,sessionKey:this.options.identity.sessionKey,sequence:r},goal:n.goal,plan:n.plan,progress:n.progress,currentPhase:n.currentPhase,currentTask:n.currentTask,incompletePhases:n.phases.filter(g=>g.status!=="completed"&&g.status!=="cancelled"),incompleteTasks:n.tasks.filter(g=>g.status!=="completed"&&g.status!=="cancelled"),nextActions:n.nextActions.slice(0,10),blockers:n.blockers.slice(0,10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:[...o,...n.warnings].slice(0,20),filesTouched:n.filesTouched.slice(-20),tests:n.tests.slice(-15),stateDigest:i},d=`projects/${this.options.project.id}/work/handoffs/${u}.json`;await this.options.storage.exists(d)||await this.options.storage.put(d,JSON.stringify(c,null,2)+`
|
|
53
53
|
`,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(c,null,2)+`
|
|
54
|
-
`,"application/json");let p=
|
|
55
|
-
`,"application/json"),l}async function
|
|
56
|
-
`);if(
|
|
54
|
+
`,"application/json");let p=me(this.options.project.rootPath,".toolnet","work","handoffs");return Cr(p,{recursive:!0}),x(me(p,`${u}.json`),c),x(me(this.options.project.rootPath,".toolnet","work","handoff-latest.json"),c),c}};async function He(t,e){let r=await e.getText(`projects/${t.id}/work/handoff-latest.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}import{mkdirSync as zr}from"node:fs";import{join as Ye}from"node:path";function Wr(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function Fr(t,e){if(!e)return!0;let r=t.evidence.occurredAt.localeCompare(e.evidence.occurredAt);return r!==0?r>0:t.evidence.sessionKey===e.evidence.sessionKey?t.evidence.sequence>=e.evidence.sequence:t.confidence>=e.confidence}function A(t,e){return Fr(e,t)?e:t}function N(t,e=30){let r=new Set,n=[];for(let s of t){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||r.has(o)||(r.add(o),n.push(s))}return n.slice(-e)}async function Br(t,e){let r=`projects/${t.id}/work/semantic/observations/`,n=await e.list(r),s=[];for(let o of n.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 Dr(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function Ge(t,e){let n=(await Br(t,e)).flatMap(h=>h.observations).sort((h,m)=>{let S=h.evidence.occurredAt.localeCompare(m.evidence.occurredAt);return S!==0?S:h.evidence.sessionKey===m.evidence.sessionKey?h.evidence.sequence-m.evidence.sequence:h.id.localeCompare(m.id)}),s,o,i,u,a,c=new Map,d=[],p=[],g=[];for(let h of n){let m=Wr(h);if(h.scope==="phase"&&h.scopeKey){let S=c.get(h.scopeKey)??Dr(h);switch(h.kind){case"phase_objective":S.objective=A(S.objective,m);break;case"phase_why":S.why=A(S.why,m);break;case"phase_deliverable":S.deliverable=A(S.deliverable,m);break;case"acceptance_criterion":S.acceptanceCriteria.push(m);break;case"dependency":S.dependencies.push(m);break;case"open_question":S.openQuestions.push(m);break;case"constraint":S.constraints.push(m);break;case"note":S.notes.push(m);break}c.set(S.key,S);continue}switch(h.kind){case"mission":s=A(s,m);break;case"objective":o=A(o,m);break;case"why":i=A(i,m);break;case"desired_outcome":u=A(u,m);break;case"plan_rationale":a=A(a,m);break;case"open_question":d.push(m);break;case"constraint":p.push(m);break;case"note":g.push(m);break}}for(let h of c.values())h.acceptanceCriteria=N(h.acceptanceCriteria,20),h.dependencies=N(h.dependencies,15),h.openQuestions=N(h.openQuestions,15),h.constraints=N(h.constraints,15),h.notes=N(h.notes,20);let l={version:1,projectId:t.id,projectName:t.name,mission:s,activeObjective:o,why:i,desiredOutcome:u,planRationale:a,phases:Array.from(c.values()).sort((h,m)=>h.order-m.order),openQuestions:N(d,20),constraints:N(p,20),notes:N(g,20),updatedAt:n.length?n[n.length-1].evidence.occurredAt:new Date().toISOString()},y=Ye(t.rootPath,".toolnet","work");return zr(y,{recursive:!0}),x(Ye(y,"semantic-current.json"),l),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(l,null,2)+`
|
|
55
|
+
`,"application/json"),l}async function Qe(t,e){let r=await e.getText(`projects/${t.id}/work/semantic/current.json`);if(!r)return null;try{return JSON.parse(r)}catch{return null}}function ge(t){if(!t)return 0;let e=Array.from(t).length,r=t.trim().split(/\s+/u).filter(Boolean).length;return Math.ceil(Math.max(e/3.5,r*1.3))}function j(t,e){let r=t.replace(/\s+/g," ").trim();return r.length<=e?r:r.slice(0,Math.max(0,e-1)).trimEnd()+"\u2026"}function Kr(t){let e=[],r=!1;for(let n of t.split(/\r?\n/u)){let s=n.trim();if(s.includes("<!--")&&(r=!0),r){s.includes("-->")&&(r=!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(j(s,280)),e.length>=16))break}return e}function qr(t){let e=[],r=[];for(let n of t.split(/\\r?\\n/u)){let s=n.trim(),o=s.toLowerCase(),u=["- [enforce]","* [enforce]","- [advisory]","* [advisory]"].find(c=>o.startsWith(c));if(!u)continue;let a=s.slice(u.length).trim();a&&(u.includes("enforce")?e.push(a):r.push(a))}return{enforce:e,advisory:r}}function Jr(t,e){let r=[];for(let n of t){let s=[...r,n].join(`
|
|
56
|
+
`);if(ge(s)<=e){r.push(n);continue}let o=ge(r.join(`
|
|
57
57
|
`)),i=Math.max(0,e-o);if(i>=16){let u=Math.floor(i*3.2),a=j(n,u);a&&r.push(a)}break}return r.join(`
|
|
58
|
-
`).trim()}async function
|
|
59
|
-
`,"application/json"),u}};import{closeSync as
|
|
58
|
+
`).trim()}async function Xe(t){let e=Math.max(256,Math.min(2e3,t.maxTokens??1e3)),r=re(t.project,!1),n=r?.content??"";n||(n=await t.storage.getText(`projects/${t.project.id}/project/manual.md`)??"");let s=qr(n),o=r?r.rules.filter(l=>l.mode==="enforce").map(l=>l.text):s.enforce,i=r?r.rules.filter(l=>l.mode==="advisory").map(l=>l.text):s.advisory,u=n?Kr(n):[],a=await Z(t.project,t.storage),c=await Qe(t.project,t.storage),d=await He(t.project,t.storage),p=[];if(p.push("[TOOLNET PROJECT CONTEXT]"),p.push(`Project: ${t.project.name}`),p.push("Continue existing project state. Do not restart completed work unless evidence shows it is necessary."),n&&p.push(`Full operating manual: ${te(t.project)}`),o.length){p.push("","PROJECT RULES \u2014 MUST FOLLOW");for(let l of o.slice(0,24))p.push(`- [ENFORCE] ${j(l,240)}`)}if(i.length){p.push("","PROJECT PREFERENCES");for(let l of i.slice(0,10))p.push(`- ${j(l,220)}`)}if(c&&(c.mission&&p.push("","MISSION",j(c.mission.value,420)),c.activeObjective&&p.push("","CURRENT OBJECTIVE",j(c.activeObjective.value,420)),c.why&&p.push("","WHY THIS WORK MATTERS",j(c.why.value,420)),c.desiredOutcome&&p.push("","DESIRED OUTCOME",j(c.desiredOutcome.value,420)),c.planRationale&&p.push("","WHY THIS APPROACH",j(c.planRationale.value,420))),a){if(p.push("","ACTIVE WORK"),a.goal&&p.push(`Goal: ${j(a.goal,320)}`),a.plan&&p.push(`Plan: ${j(a.plan,320)}`),p.push(`Progress: phases ${a.progress.phasesCompleted}/${a.progress.phasesTotal}; tasks ${a.progress.tasksCompleted}/${a.progress.tasksTotal}; blocked ${a.progress.blocked}`),a.currentPhase&&p.push(`Current phase: ${a.currentPhase.title} [${a.currentPhase.status}]`),a.currentPhase&&c){let l=c.phases.find(y=>y.order===a.currentPhase?.order);l&&(l.objective&&p.push(`Phase objective: ${j(l.objective.value,340)}`),l.why?p.push(`Why this phase: ${j(l.why.value,340)}`):p.push("Why this phase: not explicitly recorded. Inspect existing implementation before assuming intent."),l.deliverable&&p.push(`Deliverable: ${j(l.deliverable.value,340)}`),l.dependencies.length&&p.push(`Depends on: ${l.dependencies.slice(0,4).map(y=>j(y.value,180)).join("; ")}`),l.acceptanceCriteria.length&&(p.push("","DEFINITION OF DONE"),l.acceptanceCriteria.slice(0,6).forEach(y=>{p.push(`- ${j(y.value,260)}`)})),l.openQuestions.length&&(p.push("","OPEN QUESTIONS FOR CURRENT PHASE"),l.openQuestions.slice(0,4).forEach(y=>{p.push(`- ${j(y.value,260)}`)})))}a.currentTask&&p.push(`Current task: ${a.currentTask.title} [${a.currentTask.status}]`),a.nextActions.length&&(p.push("","NEXT ACTIONS"),a.nextActions.slice(0,6).forEach((l,y)=>{p.push(`${y+1}. ${j(l,260)}`)})),a.blockers.length&&(p.push("","BLOCKERS"),a.blockers.slice(0,5).forEach(l=>{p.push(`- ${j(l,260)}`)})),a.warnings.length&&(p.push("","ATTENTION"),a.warnings.slice(-5).forEach(l=>{p.push(`- ${j(l,260)}`)})),a.decisions.length&&(p.push("","RECENT DECISIONS"),a.decisions.slice(-5).forEach(l=>{p.push(`- ${j(l,260)}`)})),a.lastSession&&p.push("",`Last work session: ${a.lastSession.agent} / ${a.lastSession.nativeSessionId}`)}if(c&&c.openQuestions.length&&(p.push("","UNRESOLVED QUESTIONS"),c.openQuestions.slice(0,5).forEach(l=>{p.push(`- ${j(l.value,260)}`)})),d&&p.push(`Latest handoff: ${d.reason} / ${d.sourceSession.agent}`),u.length){p.push("","OPERATING NOTES");for(let l of u)p.push(`- ${l}`)}p.push("","Before changing anything: verify the current repository state and continue from the active phase/task above.");let g=Jr(p,e);return{version:1,projectId:t.project.id,projectName:t.project.name,text:g,estimatedTokens:ge(g),maxTokens:e,hasManual:!!n,hasWorkState:!!a,hasHandoff:!!d,generatedAt:new Date().toISOString()}}var Vr=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function L(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function he(t,e,r=0){if(!(r>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let n of t.slice(0,50))he(n,e,r+1);return}if(!(!t||typeof t!="object"))for(let[n,s]of Object.entries(t))(Vr.has(n)||["data","payload","parts","messages"].includes(n))&&he(s,e,r+1)}}function I(t,e,r,n,s,o=.95){let i=L(n);return{version:1,id:v([t.projectId,r,s.type,s.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:r,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 O(t,e){let r=t.toLowerCase();for(let n of e){let s=n.toLowerCase();if(r.startsWith(`${s}:`)||r.startsWith(`${s} -`)||r.startsWith(`${s} \u2014`))return L(t.slice(n.length+1))}return null}function Ur(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function Hr(t){return L(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function Ze(t,e){let r=[],n=new Set;function s(o){!o.value||o.value.length<3||n.has(o.id)||(n.add(o.id),r.push(o))}for(let o of e){let i=[];he(o.data,i);for(let u of i){let a={type:"project"},c=null;for(let d of u.split(/\r?\n/u)){let p=L(d);if(!p){c=null;continue}let g=p.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(g){let b=Number(g[1]);a={type:"phase",key:`phase:${b}`,order:b,title:L(g[2]??"")},c=null;continue}let l=p.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(l){let b=Number(l[1]);a={type:"task",key:`task:${b}`,order:b,title:L(l[2]??"")},c=null;continue}let y=O(p,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(y){s(I(t,o,"mission",y,{type:"project"},.99)),c=null;continue}let h=O(p,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(h){s(I(t,o,a.type==="phase"?"phase_objective":"objective",h,a,.98)),c=null;continue}let m=O(p,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(m){s(I(t,o,a.type==="phase"?"phase_why":"why",m,a,.98)),c=null;continue}let S=O(p,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(S){s(I(t,o,"desired_outcome",S,{type:"project"},.98)),c=null;continue}let k=O(p,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(k){s(I(t,o,"plan_rationale",k,{type:"project"},.98)),c=null;continue}let M=O(p,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(M){s(I(t,o,"phase_deliverable",M,a,.97)),c=null;continue}let T=O(p,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(T){s(I(t,o,"acceptance_criterion",T,a,.98)),c="acceptance_criterion";continue}let E=O(p,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(E){s(I(t,o,"dependency",E,a,.97)),c="dependency";continue}let R=O(p,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(R){s(I(t,o,"open_question",R,a,.95)),c="open_question";continue}let f=O(p,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(f){s(I(t,o,"constraint",f,a,.97)),c="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(p)){c="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(p)){c="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(p)){c="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(p)){c="constraint";continue}if(c&&Ur(d)){s(I(t,o,c,Hr(d),a,.96));continue}c=null}}}return r}function et(t){return String(t).padStart(12,"0")}var se=class{constructor(e){this.storage=e}storage;async write(e,r){if(r.length===0)return null;let n=Math.min(...r.map(a=>a.evidence.sequence)),s=Math.max(...r.map(a=>a.evidence.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:n,lastSequence:s,createdAt:new Date().toISOString(),observations:r},i=v(r.map(a=>a.id).sort().join("|")).slice(0,16),u=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${et(n)}-${et(s)}-${i}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,JSON.stringify(o,null,2)+`
|
|
59
|
+
`,"application/json"),u}};import{closeSync as Yr,existsSync as Gr,openSync as Qr,readSync as Xr,statSync as Zr}from"node:fs";function en(t,e){if(!Gr(t))return{events:[],nextOffset:e};let r=Zr(t).size,n=Number.isFinite(e)?Math.max(0,e):0;if(n>r&&(n=0),n===r)return{events:[],nextOffset:r};let s=Buffer.alloc(r-n),o=Qr(t,"r");try{Xr(o,s,0,s.length,n)}finally{Yr(o)}let i=s.toString("utf8"),u=i.lastIndexOf(`
|
|
60
60
|
`);if(u<0)return{events:[],nextOffset:n};let a=i.slice(0,u+1);return{events:a.split(`
|
|
61
|
-
`).filter(Boolean).flatMap(c=>{try{return[JSON.parse(c)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(a,"utf8")}}var
|
|
61
|
+
`).filter(Boolean).flatMap(c=>{try{return[JSON.parse(c)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(a,"utf8")}}var oe=class{constructor(e){this.options=e;this.journal=new se(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),r=Number(e.sourceCursors["work.semantic.offset"]??0),n=en(this.options.wal.eventsFile,Number.isFinite(r)?r:0);if(n.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:n.nextOffset};let s=Ze(this.options.identity,n.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Ge(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",n.nextOffset),{scannedEvents:n.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:n.nextOffset}}};import{existsSync as tn,mkdirSync as rn,readFileSync as nn,writeFileSync as sn}from"node:fs";import{dirname as on,join as tt}from"node:path";function rt(t){return tt(t.rootPath,".toolnet","context","startup.md")}function an(t){return tt(t.rootPath,".toolnet","context","startup.json")}function nt(t,e){let r=rt(t);rn(on(r),{recursive:!0}),sn(r,e.text.endsWith(`
|
|
62
62
|
`)?e.text:e.text+`
|
|
63
|
-
`,{encoding:"utf8",mode:384}),x(
|
|
63
|
+
`,{encoding:"utf8",mode:384}),x(an(t),e)}async function ye(t,e,r=900){let n=await Xe({project:t,storage:e,maxTokens:r}),s={version:1,projectId:t.id,projectName:t.name,text:n.text,digest:v(n.text),estimatedTokens:n.estimatedTokens,generatedAt:new Date().toISOString()};return nt(t,s),await e.put(`projects/${t.id}/context/startup.md`,s.text+`
|
|
64
64
|
`,"text/markdown"),await e.put(`projects/${t.id}/context/startup.json`,JSON.stringify(s,null,2)+`
|
|
65
|
-
`,"application/json"),s}async function
|
|
65
|
+
`,"application/json"),s}async function st(t,e,r=900){try{let s=await e.getText(`projects/${t.id}/context/startup.md`);if(s&&s.trim()){let o=s.trim(),i={version:1,projectId:t.id,projectName:t.name,text:o,digest:v(o),estimatedTokens:Math.ceil(o.length/3.5),generatedAt:new Date().toISOString()};return nt(t,i),i}}catch{}let n=rt(t);if(tn(n))try{let s=nn(n,"utf8").trim();if(s)return{version:1,projectId:t.id,projectName:t.name,text:s,digest:v(s),estimatedTokens:Math.ceil(s.length/3.5),generatedAt:new Date().toISOString()}}catch{}try{return await ye(t,e,r)}catch{return null}}import{existsSync as cn,mkdirSync as un,readFileSync as pn}from"node:fs";import{homedir as ln}from"node:os";import{dirname as dn,join as ot}from"node:path";function fn(t,e,r){let n=r??ot(ln(),".config","toolnet-memory","injections","agy");return ot(n,`${t.id}-${e}.json`)}function mn(t){if(!cn(t))return null;try{return JSON.parse(pn(t,"utf8"))}catch{return null}}async function it(t){let e=t.now??Date.now(),r=t.resumeAfterMs??360*60*1e3,n=fn(t.project,t.conversationId,t.markerDirectory),s=mn(n),o=s?Date.parse(s.injectedAt):0,i=o?e-o:Number.POSITIVE_INFINITY;if(s&&i<6e4)return{};let u=t.invocationNum===0,a=i>=r;if(s&&!u&&!a)return{};let c=await st(t.project,t.storage,900);return c?.text?(un(dn(n),{recursive:!0}),x(n,{digest:c.digest,injectedAt:new Date(e).toISOString()}),{injectSteps:[{userMessage:c.text}]}):{}}import{existsSync as gn}from"node:fs";import{dirname as hn,join as yn,parse as Sn,resolve as vn}from"node:path";function at(t){for(let e of t){let r=vn(e),n=Sn(r).root;for(;;){if(gn(yn(r,".toolnet","project.json")))return new J().detect(r);if(r===n)break;let s=hn(r);if(s===r)break;r=s}}return null}import{homedir as wt}from"node:os";import{join as ss,resolve as os}from"node:path";import{join as jn}from"node:path";function ct(t,e){let r=t.trim(),n=r.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=v(r).slice(0,12);if(!n||n==="."||n==="..")return`${e}--${s}`;let o=n.slice(0,100);return o===r&&r.length<=100?o:`${o.slice(0,85)}--${s}`}function ut(t,e,r){let n=e.trim(),s=r.trim();if(!n)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=ct(n.toLowerCase(),"agent"),i=ct(s,"session");return{projectId:t.id,projectName:t.name,projectRoot:t.rootPath,agent:n,nativeSessionId:s,sessionKey:`${n}:${s}`,remotePrefix:["projects",t.id,"sessions",o,i].join("/"),localDirectory:jn(t.rootPath,".toolnet","sessions",o,i)}}function pt(t){return String(t).padStart(12,"0")}var ie=class{constructor(e,r=100,n=512*1024){this.storage=e;this.maxEventsPerChunk=r;this.maxChunkBytes=n;if(r<1)throw new Error("maxEventsPerChunk must be positive");if(n<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let r=await this.storage.getText(e);return r?JSON.parse(r):null}async putJson(e,r){await this.storage.put(e,JSON.stringify(r,null,2)+`
|
|
66
66
|
`,"application/json")}async scan(e){let r=`${e.remotePrefix}/events/`,n=await this.storage.list(r),s=[],o=0;for(let i of n){let u=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!u)continue;let a=Number(u[1]),c=Number(u[2]);!Number.isFinite(a)||!Number.isFinite(c)||(s.push({key:i.key,start:a,end:c}),o=Math.max(o,c))}return s.sort((i,u)=>i.start-u.start),{chunks:s,maxSequence:o}}split(e){let r=[],n=[],s=0;for(let o of e){let i=Buffer.byteLength(JSON.stringify(o)+`
|
|
67
|
-
`,"utf8");n.length>0&&(n.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(r.push(n),n=[],s=0),n.push(o),s+=i}return n.length>0&&r.push(n),r}async loadManifest(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let r=await this.scan(e);return{maxSequence:r.maxSequence,chunkCount:r.chunks.length}}async append(e,r,n,s={}){let o=await this.loadManifest(e),i=await this.scan(e),u=r.filter(m=>m.sequence>i.maxSequence),a=0;for(let m of this.split(u)){let S=m[0],
|
|
67
|
+
`,"utf8");n.length>0&&(n.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(r.push(n),n=[],s=0),n.push(o),s+=i}return n.length>0&&r.push(n),r}async loadManifest(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let r=await this.scan(e);return{maxSequence:r.maxSequence,chunkCount:r.chunks.length}}async append(e,r,n,s={}){let o=await this.loadManifest(e),i=await this.scan(e),u=r.filter(m=>m.sequence>i.maxSequence),a=0;for(let m of this.split(u)){let S=m[0],k=m[m.length-1],M=m.map(R=>JSON.stringify(R)).join(`
|
|
68
68
|
`)+`
|
|
69
|
-
`,
|
|
69
|
+
`,T=v(M).slice(0,16),E=[e.remotePrefix,"events",`${pt(S.sequence)}-${pt(k.sequence)}-${T}.jsonl`].join("/");await this.storage.exists(E)||await this.storage.put(E,M,"application/x-ndjson"),a+=m.length}let c=await this.scan(e),d=r[r.length-1],p=o?.status??"active";d?.type==="session_end"||d?.type==="session_idle"?p="idle":d?.type==="error"?p="error":r.length>0&&(p="active");let g=new Date().toISOString(),l=r[0],y={version:1,projectId:e.projectId,projectName:e.projectName,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,status:p,createdAt:o?.createdAt??l?.timestamp??g,updatedAt:d?.timestamp??g,firstEventAt:o?.firstEventAt??l?.timestamp,lastEventAt:d?.timestamp??o?.lastEventAt,eventCount:c.maxSequence,chunkCount:c.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(y.title=s.title??o?.title);let h={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,lastLocalSequence:r.length>0?r[r.length-1].sequence:c.maxSequence,lastRemoteSequence:c.maxSequence,sourceCursors:n,updatedAt:g};return await this.putJson(`${e.remotePrefix}/cursor.json`,h),await this.putJson(`${e.remotePrefix}/session.json`,y),{uploadedEvents:a,lastRemoteSequence:c.maxSequence,eventCount:y.eventCount,chunkCount:y.chunkCount,status:p}}};import{closeSync as Se,existsSync as kn,fsyncSync as wn,mkdirSync as bn,openSync as ve,readSync as xn,rmSync as lt,statSync as dt,writeSync as In}from"node:fs";import{join as je}from"node:path";var Pn=12e4,On=80,En=2e3;function An(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var ae=class{constructor(e){this.identity=e;bn(e.localDirectory,{recursive:!0}),this.eventsFile=je(e.localDirectory,"events.jsonl"),this.stateFile=je(e.localDirectory,"state.json"),this.lockFile=je(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 ze(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){x(this.stateFile,e)}acquireLock(){for(let e=0;e<On;e+=1)try{return ve(this.lockFile,"wx",384)}catch(r){if(r.code!=="EEXIST")throw r;try{if(Date.now()-dt(this.lockFile).mtimeMs>Pn){lt(this.lockFile,{force:!0});continue}}catch{}An(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let r=this.acquireLock();try{return e()}finally{Se(r),lt(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let r=this.loadStateUnsafe(),n=new Set(r.recentEventIds),s=r.lastSequence,o=[];for(let p of e){let g=p.timestamp??new Date().toISOString(),l=p.data??{},y=p.provenance?.rawDigest??v(Le(l)),h=p.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,p.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,p.type,g,y].join("|"),m=v(h).slice(0,32);if(n.has(m))continue;s+=1;let S={version:1,id:m,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,type:p.type,timestamp:g,data:l,provenance:{...p.provenance,rawDigest:y}};p.role!==void 0&&(S.role=p.role),p.sourceEventId!==void 0&&(S.sourceEventId=p.sourceEventId),p.sourceSequence!==void 0&&(S.sourceSequence=p.sourceSequence),o.push(S),n.add(m)}if(o.length===0)return[];let i=o.map(p=>JSON.stringify(p)).join(`
|
|
70
70
|
`)+`
|
|
71
|
-
`,u=
|
|
72
|
-
`).filter(Boolean).map(c=>JSON.parse(c)),startOffset:n,endOffset:r}})}markRemote(e,r){this.withLock(()=>{let n=this.loadStateUnsafe();this.saveStateUnsafe({...n,lastRemoteSequence:Math.max(n.lastRemoteSequence,e),remoteByteOffset:Math.max(n.remoteByteOffset,r),updatedAt:new Date().toISOString()})})}setSourceCursor(e,r){this.withLock(()=>{let n=this.loadStateUnsafe();this.saveStateUnsafe({...n,sourceCursors:{...n.sourceCursors,[e]:String(r)},updatedAt:new Date().toISOString()})})}};import{closeSync as
|
|
73
|
-
`,a=v(n.map(
|
|
71
|
+
`,u=ve(this.eventsFile,"a",384);try{In(u,i,null,"utf8"),wn(u)}finally{Se(u)}let a=o[o.length-1],c="active";a.type==="session_end"||a.type==="session_idle"?c="idle":a.type==="error"&&(c="error");let d=Array.from(n).slice(-En);return this.saveStateUnsafe({...r,status:c,updatedAt:a.timestamp,lastSequence:a.sequence,recentEventIds:d}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!kn(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let r=dt(this.eventsFile).size,n=Math.min(e.remoteByteOffset,r);if(r<=n)return{events:[],startOffset:n,endOffset:r};let s=r-n,o=Buffer.alloc(s),i=ve(this.eventsFile,"r");try{xn(i,o,0,s,n)}finally{Se(i)}return{events:o.toString("utf8").split(`
|
|
72
|
+
`).filter(Boolean).map(c=>JSON.parse(c)),startOffset:n,endOffset:r}})}markRemote(e,r){this.withLock(()=>{let n=this.loadStateUnsafe();this.saveStateUnsafe({...n,lastRemoteSequence:Math.max(n.lastRemoteSequence,e),remoteByteOffset:Math.max(n.remoteByteOffset,r),updatedAt:new Date().toISOString()})})}setSourceCursor(e,r){this.withLock(()=>{let n=this.loadStateUnsafe();this.saveStateUnsafe({...n,sourceCursors:{...n.sourceCursors,[e]:String(r)},updatedAt:new Date().toISOString()})})}};import{closeSync as Jn,existsSync as Vn,openSync as Un,readSync as Hn,statSync as Yn}from"node:fs";function ft(t,e){let r=e.toLowerCase();return r.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||r.includes("tuy\u1EC7t \u0111\u1ED1i")||r.includes("must not")||r.includes("never ")?"critical":t==="rule"||t==="decision"?"high":t==="todo"||r.includes("error")||r.includes("failed")||r.includes("exception")?"normal":"temporary"}var yt=[/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],Nn=[/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],Mn=[/\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],Rn=[/\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],Tn=[/đã 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],mt=[/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],_n=[/\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],Cn=[/đườ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],$n=[/\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],gt=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Ln=new Set(["payload","data","content","message","messages","parts","summary"]);function P(t,e){return e.some(r=>r.test(t))}function St(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function zn(t){return St(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Wn(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 ke(t,e,r,n=0){if(!(n>6)){if(typeof t=="string"){(!e||gt.has(e))&&r.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))ke(s,e,r,n+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(gt.has(s)||Ln.has(s))&&ke(o,s,r,n+1)}}function Fn(t){let e=[];ke(t.data,void 0,e);let r=[],n=new Set;for(let s of e)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=St(o);if(Wn(i)&&!n.has(i)&&(n.add(i),r.push(i),r.length>=50))return r}return r}function ht(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function Bn(t,e,r){if(r.type==="decision")return{kind:"decision",confidence:1};if(r.type==="todo")return{kind:"todo",confidence:1};let n=e==="user"||r.type==="user_prompt",s=e==="assistant"||r.type==="assistant_message";return n&&P(t,yt)?{kind:"rule",confidence:.98}:n&&P(t,Nn)?{kind:"rule",confidence:.92}:P(t,Mn)?{kind:P(t,mt)?"architecture":"decision",confidence:n?.93:.86}:n&&P(t,Rn)?{kind:"todo",confidence:.87}:P(t,mt)&&P(t,_n)?{kind:"architecture",confidence:n?.88:.82}:s&&P(t,Tn)?{kind:"fix",confidence:.8}:n&&P(t,Cn)&&P(t,$n)?{kind:"context",confidence:.79}:null}function Dn(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Kn(t,e,r){return t==="rule"&&P(r,yt)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":ft(e,r)}function vt(t,e){let r=[],n=new Set,s=new Map;for(let o of e){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,u=ht(o);i&&u&&s.set(i,u)}for(let o of e){let i=ht(o),u=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&u&&(i=s.get(u)??"");for(let a of Fn(o)){let c=Bn(a,i,o);if(!c||c.confidence<.75)continue;let d=Dn(c.kind),p=zn(a),g=v([t.projectId,c.kind,p].join("|"));if(n.has(g))continue;n.add(g);let l=o.provenance.sourcePath?[o.provenance.sourcePath]:[],y=o.sourceEventId?[o.sourceEventId]:[];r.push({version:1,fingerprint:g,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:c.kind,type:d,content:a,confidence:c.confidence,importance:Kn(c.kind,d,a),tags:[d],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[o.id],sourceEventIds:y,sourcePaths:l,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return r}function jt(t){return String(t).padStart(12,"0")}function qn(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var ce=class{constructor(e){this.storage=e}storage;async write(e,r,n){if(n.length===0||r.length===0)return null;let s=Math.min(...r.map(d=>d.sequence)),o=Math.max(...r.map(d=>d.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:n.length,candidates:n},u=JSON.stringify(i,null,2)+`
|
|
73
|
+
`,a=v(n.map(d=>d.fingerprint).sort().join("|")).slice(0,16),c=[qn(e),"batches",`${jt(s)}-${jt(o)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,u,"application/json"),c}};function Gn(t,e){if(!Vn(t))return{events:[],nextOffset:e};let r=Yn(t).size,n=Number.isFinite(e)?Math.max(0,e):0;if(n>r&&(n=0),n===r)return{events:[],nextOffset:r};let s=r-n,o=Buffer.alloc(s),i=Un(t,"r");try{Hn(i,o,0,s,n)}finally{Jn(i)}let u=o.toString("utf8"),a=u.lastIndexOf(`
|
|
74
74
|
`);if(a<0)return{events:[],nextOffset:n};let c=u.slice(0,a+1);return{events:c.split(`
|
|
75
|
-
`).filter(Boolean).flatMap(p=>{try{return[JSON.parse(p)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(c,"utf8")}}var
|
|
76
|
-
`);if(c<0)return{events:[],nextOffset:s,reset:n};let
|
|
75
|
+
`).filter(Boolean).flatMap(p=>{try{return[JSON.parse(p)]}catch{return[]}}),nextOffset:n+Buffer.byteLength(c,"utf8")}}var ue=class{constructor(e){this.options=e;this.journal=new ce(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),r=Number(e.sourceCursors["memory.learner.offset"]??0),n=Number.isFinite(r)?r:0,s=Gn(this.options.wal.eventsFile,n);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=vt(this.options.identity,s.events),i=!1;return o.length>0&&(i=!!await this.journal.write(this.options.identity,s.events,o)),this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:o.length,journalWritten:i,nextOffset:s.nextOffset}}};var pe=class{identity;wal;remote;sanitizer=new F;learner;continuity;semantic;handoff;title;metadata;constructor(e){this.identity=ut(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new ae(this.identity),this.remote=new ie(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new ue({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new ee({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new oe({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new ne({project:e.project,storage:e.storage,identity:this.identity})}sanitizeEvent(e){let r=e.provenance?{...e.provenance,metadata:this.sanitizer.sanitizeValue(e.provenance.metadata)}:void 0;return{...e,data:this.sanitizer.sanitizeValue(e.data??{}),provenance:r}}start(e={}){let r=this.wal.loadState();return this.record({type:r.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(r=>this.sanitizeEvent(r)))}setSourceCursor(e,r){this.wal.setSourceCursor(e,r)}async flush(){let e=this.wal.readPending(),r=this.wal.loadState(),n=await this.remote.append(this.identity,e.events,r.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 n}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 Qn,openSync as Xn,closeSync as Zn,readSync as es,statSync as ts}from"node:fs";function rs(t){let e=typeof t.role=="string"?t.role:"",r=typeof t.type=="string"?t.type.toLowerCase():"";return e==="user"||r.includes("user")?"user_prompt":e==="assistant"||r.includes("assistant")||r.includes("model")?"assistant_message":r.includes("tool")||"toolCall"in t||"tool_call"in t?"tool_call":r.includes("error")?"error":"message"}function ns(t){let e=[t.timestamp,t.createdAt,t.time,t.created_at];for(let r of e){if(typeof r=="string"){let n=new Date(r);if(!Number.isNaN(n.getTime()))return n.toISOString()}if(typeof r=="number"){let n=r;n<1e11&&(n*=1e3);let s=new Date(n);if(!Number.isNaN(s.getTime()))return s.toISOString()}}return new Date().toISOString()}function kt(t,e={offset:0}){if(!Qn(t))return{events:[],nextOffset:e.offset,reset:!1};let r=ts(t).size,n=e.offset>r,s=n?0:e.offset;if(s===r)return{events:[],nextOffset:r,reset:n};let o=r-s,i=Buffer.alloc(o),u=Xn(t,"r");try{es(u,i,0,o,s)}finally{Zn(u)}let a=i.toString("utf8"),c=a.lastIndexOf(`
|
|
76
|
+
`);if(c<0)return{events:[],nextOffset:s,reset:n};let d=a.slice(0,c+1),p=Buffer.byteLength(d,"utf8"),g=[],l=0;for(let y of d.split(`
|
|
77
77
|
`)){if(!y)continue;let h=Buffer.byteLength(y+`
|
|
78
|
-
`,"utf8"),m=s+l;l+=h;let S;try{S=JSON.parse(y)}catch{g.push({type:"custom",sourceEventId:`transcript:${m}`,sourceSequence:m,data:{format:"raw-line",content:y},provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:m}});continue}let
|
|
78
|
+
`,"utf8"),m=s+l;l+=h;let S;try{S=JSON.parse(y)}catch{g.push({type:"custom",sourceEventId:`transcript:${m}`,sourceSequence:m,data:{format:"raw-line",content:y},provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:m}});continue}let k=S&&typeof S=="object"&&!Array.isArray(S)?S:{value:S};g.push({type:rs(k),timestamp:ns(k),role:typeof k.role=="string"?k.role:void 0,sourceEventId:`transcript:${m}`,sourceSequence:m,data:k,provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:m}})}return{events:g,nextOffset:s+p,reset:n}}function is(t){return t==="~"?wt():t.startsWith("~/")?ss(wt(),t.slice(2)):t}async function bt(t){let e=t.conversationId.trim();if(!e)throw new Error("Agy conversationId is required");let r=os(is(t.transcriptPath)),n=new pe({project:t.project,storage:t.storage,agent:"agy",nativeSessionId:e,metadata:{source:"antigravity-hook",transcriptPath:r,workspacePaths:t.workspacePaths??[],artifactDirectoryPath:t.artifactDirectoryPath,modelName:t.modelName}}),s=n.status(),o=s.sourceCursors["agy.transcript.offset"],i=o?Number(o):0,u=kt(r,{offset:Number.isFinite(i)?i:0}),a=[];s.lastSequence===0&&a.push({type:"session_start",sourceEventId:`agy:${e}:start`,data:{workspacePaths:t.workspacePaths??[],transcriptPath:r,modelName:t.modelName},provenance:{source:"antigravity-hook",sourcePath:r}}),u.reset&&a.push({type:"custom",sourceEventId:`agy:${e}:transcript-reset:${u.nextOffset}`,data:{event:"transcript_reset",transcriptPath:r},provenance:{source:"agy-transcript",sourcePath:r}}),a.push(...u.events),t.phase==="stop"&&(t.error&&a.push({type:"error",sourceEventId:["agy",e,"stop-error",t.terminationReason??"",u.nextOffset].join(":"),data:{error:t.error,terminationReason:t.terminationReason,fullyIdle:t.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),t.fullyIdle&&a.push({type:"session_idle",sourceEventId:["agy",e,"idle",u.nextOffset].join(":"),data:{terminationReason:t.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let c=n.recordMany(a);n.setSourceCursor("agy.transcript.offset",u.nextOffset),t.phase&&n.setSourceCursor("agy.last.phase",t.phase);let d=await n.flush();return{conversationId:e,imported:c.length,eventCount:d.eventCount,chunkCount:d.chunkCount,status:d.status,transcriptOffset:u.nextOffset,reset:u.reset}}async function as(){let t="";for await(let e of process.stdin)t+=e.toString();if(!t.trim())return{};try{return JSON.parse(t)}catch{return{}}}function D(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}function cs(t){let e=typeof t.common=="object"&&t.common!==null?t.common:{},r=typeof t.pre_invocation_hook_args=="object"&&t.pre_invocation_hook_args!==null?t.pre_invocation_hook_args:{},n=typeof t.post_invocation_hook_args=="object"&&t.post_invocation_hook_args!==null?t.post_invocation_hook_args:{},s=typeof t.stop_hook_args=="object"&&t.stop_hook_args!==null?t.stop_hook_args:{},o=(typeof e.conversation_id=="string"?e.conversation_id:"")||(typeof t.conversationId=="string"?t.conversationId:"")||(typeof t.conversation_id=="string"?t.conversation_id:""),i=(typeof e.transcript_path=="string"?e.transcript_path:"")||(typeof t.transcriptPath=="string"?t.transcriptPath:"")||(typeof t.transcript_path=="string"?t.transcript_path:""),u=D(e.workspace_paths).length>0?D(e.workspace_paths):D(t.workspacePaths).length>0?D(t.workspacePaths):D(t.workspace_paths),a=typeof r.invocation_num=="number"?r.invocation_num:typeof t.invocationNum=="number"?t.invocationNum:typeof t.invocation_num=="number"?t.invocation_num:void 0,c=(typeof e.artifact_directory_path=="string"?e.artifact_directory_path:"")||(typeof t.artifactDirectoryPath=="string"?t.artifactDirectoryPath:"")||(typeof t.artifact_directory_path=="string"?t.artifact_directory_path:"")||void 0,d=(typeof e.model_name=="string"?e.model_name:"")||(typeof t.modelName=="string"?t.modelName:"")||(typeof t.model_name=="string"?t.model_name:"")||void 0,p=s.fully_idle===!0||t.fullyIdle===!0||t.fully_idle===!0,g=(typeof s.termination_reason=="string"?s.termination_reason:"")||(typeof t.terminationReason=="string"?t.terminationReason:"")||(typeof t.termination_reason=="string"?t.termination_reason:"")||void 0,l=(typeof s.error=="string"&&s.error?s.error:"")||(typeof t.error=="string"&&t.error?t.error:"")||void 0;return{conversationId:o,transcriptPath:i,workspacePaths:u,invocationNum:a,artifactDirectoryPath:c,modelName:d,fullyIdle:p,terminationReason:g,error:l}}async function us(){let t=process.argv[2]??"post",e=await as(),r=cs(e),n=r.conversationId,s=r.transcriptPath,o=r.workspacePaths,i=at(o),u={};if(i&&n)try{let a=xe(),c=_e(Re({provider:a.storage.provider,huggingface:a.storage.huggingface,localRoot:a.storage.localRoot}),{attempts:2}),d=new Y(c,i.id,i.name,i.remote??i.name);if(s)try{await bt({project:i,storage:d,conversationId:n,transcriptPath:s,workspacePaths:o,artifactDirectoryPath:r.artifactDirectoryPath,modelName:r.modelName,phase:t,fullyIdle:r.fullyIdle,terminationReason:r.terminationReason,error:r.error})}catch{}if(t==="pre")try{u=await it({project:i,storage:d,conversationId:n,invocationNum:r.invocationNum})}catch{u={}}if(t==="stop")try{await ye(i,d,900)}catch{}}catch{}if(t==="stop"){process.stdout.write(JSON.stringify({decision:"stop"}));return}process.stdout.write(JSON.stringify(u))}us().catch(()=>{process.argv[2]==="stop"?process.stdout.write('{"decision":"stop"}'):process.stdout.write("{}"),process.exitCode=0});export{cs as normalizeAgyInput};
|