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