toolnet-memory 0.3.10 → 0.3.12
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/README.md +432 -163
- package/bin/toolnet-memory +5 -0
- package/bundle/agy-hook.js +38 -38
- package/bundle/agy.js +23 -23
- package/bundle/api.js +19 -16
- package/bundle/auto-integrate.js +84 -31
- package/bundle/claude-hook.js +9 -9
- package/bundle/codex.js +28 -28
- package/bundle/context-runtime.js +4 -4
- package/bundle/context.js +12 -12
- package/bundle/continuity-certify.js +16 -13
- package/bundle/copilot-hook.js +66 -66
- package/bundle/copilot.js +23 -27
- package/bundle/cursor-hook.js +66 -66
- package/bundle/cursor.js +24 -27
- package/bundle/grok-hook.js +46 -46
- package/bundle/grok.js +6 -7
- package/bundle/help-cli.js +4 -4
- package/bundle/init.js +92 -39
- package/bundle/integration-status.js +55 -0
- package/bundle/kiro-hook.js +14 -14
- package/bundle/mcp.js +21 -18
- package/bundle/opencode.js +27 -27
- package/bundle/setup.js +90 -37
- package/bundle/status-cli.js +4 -4
- package/package.json +12 -2
package/bundle/grok-hook.js
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import*as
|
|
2
|
-
`),a=Math.max(o,i);return a>r*.7?s.slice(0,a+1):s}import{createHash as
|
|
3
|
-
`)}function
|
|
4
|
-
|
|
5
|
-
`,{encoding:"utf8",mode:384})
|
|
1
|
+
import*as te from"fs";import*as H from"path";function ws(e){return e?Math.ceil(e.length/3.5):0}function Jt(e,t){if(!e)return"";if(ws(e)<=t)return e;let r=Math.floor(t*3.5),s=e.slice(0,r),o=s.lastIndexOf("."),i=s.lastIndexOf(`
|
|
2
|
+
`),a=Math.max(o,i);return a>r*.7?s.slice(0,a+1):s}import{createHash as vs}from"node:crypto";import{chmodSync as Vt,existsSync as bs,mkdirSync as xs,readFileSync as js,renameSync as Is,writeFileSync as Bt}from"node:fs";import{dirname as Gt,join as Ae}from"node:path";var mt="toolnet.context-offload.v1",As="toolnet.context-offload-asset.v1",Cs=256,Ps=new Set(["tool_call","tool_result","file_read","file_write","file_edit","command","test","artifact"]);function Ut(e){return Ae(e,".toolnet","offload")}function Ms(e){return Ae(Ut(e),"assets")}function Yt(e){return Ae(Ut(e),"graph.json")}function Xt(e){xs(e,{recursive:!0,mode:448});try{Vt(e,448)}catch{}}function Es(e,t){Xt(Gt(e));let n=`${e}.${process.pid}.${Date.now()}.tmp`;Bt(n,t,{encoding:"utf8",mode:384}),Is(n,e);try{Vt(e,384)}catch{}}function pt(e){return Array.isArray(e)?e.map(pt):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,pt(n)])):e}function Ts(e){return vs("sha256").update(JSON.stringify(pt(e)),"utf8").digest("hex")}function dt(){return{schema:mt,version:1,updatedAt:new Date(0).toISOString(),nodes:[]}}function Os(e){let t=Yt(e);if(!bs(t))return dt();try{let n=JSON.parse(js(t,"utf8"));return n.schema!==mt||n.version!==1||!Array.isArray(n.nodes)?dt():n}catch{return dt()}}function Rs(e,t){Es(Yt(e),JSON.stringify(t,null,2)+`
|
|
3
|
+
`)}function Ns(e,t=260){if(typeof e!="string")return null;let n=e.replace(/\s+/gu," ").trim();return n?n.slice(0,t):null}function _s(e){let t=[...e.provenance.files??[],e.provenance.sourcePath],n=[];for(let r of t){let s=Ns(r);if(!(!s||n.includes(s))&&(n.push(s),n.length===3))break}return n}function Ks(e){return`${e.agent}:${e.sourceEventId??e.id}`.replace(/\s+/gu," ").trim().slice(0,120)}function $s(e,t){Xt(Gt(e));try{return Bt(e,t,{encoding:"utf8",flag:"wx",mode:384}),!0}catch(n){if(n.code==="EEXIST")return!1;throw n}}function Fs(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:mt,version:1,updatedAt:new Date().toISOString(),nodes:[...e.nodes.filter(s=>s.id!==t.id),r].slice(-Cs)}}function Qt(e,t){let n=Os(e),r=0,s=0,o=0,i=[];for(let a of t){if(!Ps.has(a.type))continue;r+=1;let c=Ts({type:a.type,data:a.data}),u={schema:As,version:1,assetId:c,event:{type:a.type,agent:a.agent,nativeSessionId:a.nativeSessionId,timestamp:a.timestamp,sourceEventId:a.sourceEventId,provenance:a.provenance,data:a.data}},f=JSON.stringify(u,null,2)+`
|
|
4
|
+
`;$s(Ae(Ms(e),`${c}.json`),f)?s+=1:o+=1,i.push(c),n=Fs(n,{id:c,kind:a.type,bytes:Buffer.byteLength(f,"utf8"),createdAt:a.timestamp,sourceRefs:[Ks(a)],files:_s(a)})}return r>0&&Rs(e,n),{eligible:r,written:s,deduped:o,graphNodes:n.nodes.length,assetIds:i}}import{existsSync as en,mkdirSync as Js,readFileSync as tn,renameSync as Vs,writeFileSync as Bs}from"node:fs";import{dirname as Gs,join as nn}from"node:path";import{createHash as Ws}from"node:crypto";import{dirname as Ls}from"node:path";import{mkdirSync as Ds,readFileSync as zs,renameSync as qs,writeFileSync as Hs}from"node:fs";function w(e){return Ws("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 Ce(e){return JSON.stringify(ft(e))}function Zt(e){try{return JSON.parse(zs(e,"utf8"))}catch{return null}}function O(e,t){Ds(Ls(e),{recursive:!0});let n=`${e}.${process.pid}.tmp`;Hs(n,JSON.stringify(t,null,2)+`
|
|
5
|
+
`,{encoding:"utf8",mode:384}),qs(n,e)}function rn(e){return nn(e.rootPath,".toolnet","context","handoff.md")}function sn(e){return nn(e.rootPath,".toolnet","context","handoff.json")}function on(e,t){Js(Gs(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;Bs(n,t.endsWith(`
|
|
6
6
|
`)?t:`${t}
|
|
7
|
-
`,{encoding:"utf8",mode:384}),
|
|
8
|
-
`)}function
|
|
9
|
-
`).trim();if(!n)return null;let r={version:1,projectId:e.id,projectName:e.name,text:n,digest:w(n),generatedAt:new Date().toISOString()};return
|
|
10
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function
|
|
11
|
-
`,{encoding:"utf8",mode:384}),eo(s,r)}function mn(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 Ee=class{detect(t=process.cwd()){let n=ue(t),r=ao(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>ft(Te(r,f))),i=io(n,o?r:void 0);if(i){let f=gt(i),m=co(f);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),pn(i,m)),mn(m,i)}let a=new Date().toISOString(),c=no(r),u={version:1,id:so(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return pn(r,u),mn(u,r)}};var uo=[{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}],Oe=class{scan(t){let n=[];for(let r of uo){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 B=class{scanner=new Oe;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 Ro}from"node:os";import{join as No}from"node:path";import{DeleteObjectCommand as lo,GetObjectCommand as po,HeadObjectCommand as mo,ListObjectsV2Command as fo,PutObjectCommand as go,S3Client as yo}from"@aws-sdk/client-s3";import{getSignedUrl as ho}from"@aws-sdk/s3-request-presigner";var Re=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new yo({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 go({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await ho(this.client,new po({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 mo({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 lo({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new fo({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 yn,mkdir as So,readFile as ko,readdir as wo,rm as vo,stat as hn,writeFile as bo}from"node:fs/promises";import{dirname as xo,join as jo,relative as Sn,resolve as Ao}from"node:path";var le=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return Ao(this.root,n)}async put(t,n){let r=this.path(t);await So(xo(r),{recursive:!0}),await bo(r,n)}async get(t){try{return await ko(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 yn(this.path(t)),!0}catch{return!1}}async delete(t){await vo(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await yn(n)}catch{return r}let s=async i=>{let a=await wo(i,{withFileTypes:!0});for(let c of a){let u=jo(i,c.name);if(c.isDirectory()){await s(u);continue}let f=await hn(u);r.push({key:Sn(this.root,u),size:f.size,updatedAt:f.mtime.toISOString()})}},o=await hn(n);return o.isDirectory()?await s(n):r.push({key:Sn(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as Io,GetObjectCommand as Co,HeadObjectCommand as Po,ListObjectsV2Command as Mo,PutObjectCommand as Eo,S3Client as To}from"@aws-sdk/client-s3";import{getSignedUrl as Oo}from"@aws-sdk/s3-request-presigner";var de=class{name;client;bucket;constructor(t){this.name=t.name??"s3",this.bucket=t.bucket,this.client=new To({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 Eo({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await Oo(this.client,new Co({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 Po({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 Io({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new Mo({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 yt(e,t){return console.warn(t),new le(e)}function kn(e){let t=e.localRoot??No(Ro(),".toolnet-memory","storage");if(e.provider==="r2"){let n=e.r2;return n?.accountId&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new de({name:"r2",endpoint:`https://${n.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:n.bucket,forcePathStyle:!0,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):yt(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 de({name:"s3",endpoint:n.endpoint,region:n.region??"us-east-1",bucket:n.bucket,forcePathStyle:n.forcePathStyle??!1,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):yt(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 Re({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):yt(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new le(t)}function _o(e){return new Promise(t=>setTimeout(t,e))}async function wn(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,s=t.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(o=a,i>=n)break;let c=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await _o(c+u)}throw o}var Ko=new Set(["put","get","getText","delete","list"]);function vn(e,t={}){return new Proxy(e,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:Ko.has(r)?(...o)=>wn(()=>Promise.resolve(s.apply(n,o)),t):s.bind(n)}})}function bn(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 xn(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 Ne=class{constructor(t,n,r,s){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=bn(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let t=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(t);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(o,null,2)+`
|
|
12
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=
|
|
13
|
-
`,{encoding:"utf8",mode:384}),
|
|
14
|
-
`)}function
|
|
7
|
+
`,{encoding:"utf8",mode:384}),Vs(n,e)}function Us(e,t){on(e,`${JSON.stringify(t,null,2)}
|
|
8
|
+
`)}function an(e,t){let n=t.replace(/\r\n/g,`
|
|
9
|
+
`).trim();if(!n)return null;let r={version:1,projectId:e.id,projectName:e.name,text:n,digest:w(n),generatedAt:new Date().toISOString()};return on(rn(e),n),Us(sn(e),r),r}function cn(e){let t=rn(e);if(!en(t))return null;try{let n=tn(t,"utf8").trim();if(!n)return null;let r=new Date(0).toISOString(),s=sn(e);if(en(s))try{let o=JSON.parse(tn(s,"utf8"));typeof o.generatedAt=="string"&&(r=o.generatedAt)}catch{}return{version:1,projectId:e.id,projectName:e.name,text:n,digest:w(n),generatedAt:r}}catch{return null}}function un(e){let t=H.resolve(e),n=H.parse(t).root;for(;t!==n;){let r=H.join(t,".toolnet");if(te.existsSync(r)&&te.statSync(r).isDirectory())return t;t=H.dirname(t)}return null}function ln(e){return e.replace(/\\/g,"/").toLowerCase()}function gt(e,t,n=0){if(!(n>6||t.length>=250)){if(typeof e=="string"){t.push(e);return}if(Array.isArray(e)){for(let r of e)if(gt(r,t,n+1),t.length>=250)break;return}if(e&&typeof e=="object"){for(let r of Object.values(e))if(gt(r,t,n+1),t.length>=250)break}}}function Ys(e){let t=ln(e);if(t.includes(".toolnet/sessions/")||t.endsWith(".toolnet/sessions")||t.includes(".gemini/antigravity-cli/brain/")||t.endsWith(".gemini/antigravity-cli/brain")||t.includes("/transcript.jsonl")||t.endsWith("transcript.jsonl")||t.includes(".toolnet/")&&(t.endsWith("/events.jsonl")||t.endsWith("/state.json")||t.includes("/sessions/")))return!0;let n=process.env.CURSOR_TRANSCRIPT_PATH;return!!(n&&ln(n)===t)}function dn(e){let t=[];return gt(e,t),t.find(Ys)?{blocked:!0,reason:"ToolNet continuity guard: do not read or reconstruct previous work from raw ToolNet/agent session history. Use the injected ToolNet handoff first; if it is insufficient, invoke the MCP tool memory_agent_ask directly. Then verify normal repository/git source truth."}:{blocked:!1}}function Pe(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function pn(e,t=process.env){return Pe(t.TOOLNET_HOOK_EVENT)??Pe(e.hookEventName)??Pe(e.hook_event_name)??Pe(t.GROK_HOOK_EVENT)??""}function mn(e){return dn(e.toolInput??e.tool_input??e)}function fn(e){return{decision:"deny",reason:e}}import{existsSync as yu}from"node:fs";import{join as hu}from"node:path";import{existsSync as Xs,readFileSync as Qs}from"node:fs";import{homedir as Zs}from"node:os";import{join as eo}from"node:path";function to(e){let t=e.trim();return t.length>=2&&t.startsWith('"')&&t.endsWith('"')?(t=t.slice(1,-1),t.replace(/\\n/g,`
|
|
10
|
+
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function no(){let e=process.env.TOOLNET_GLOBAL_ENV??eo(Zs(),".config","toolnet-memory",".env");if(!Xs(e))return;let t=Qs(e,"utf8");for(let n of t.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=to(r.slice(s+1)))}}no();function 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 Me(){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 ro}from"node:crypto";import{existsSync as yt,mkdirSync as so,readFileSync as oo,renameSync as io,writeFileSync as ao}from"node:fs";import{basename as co,dirname as Ee,join as Oe,parse as hn,resolve as le}from"node:path";var Sn=".toolnet",uo="project.json";function lo(e){return ro("sha256").update(e).digest("hex").slice(0,16)}function ht(e){return Oe(e,Sn,uo)}function po(e){return yt(ht(e))}function mo(e,t){let n=le(e),r=hn(n).root;for(;;){if(po(n))return n;if(n===r||t&&n===le(t))break;let s=Ee(n);if(s===n)break;n=s}return null}function fo(e){let t=le(e),n=hn(t).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>yt(Oe(t,o))))return t;if(t===n)break;let s=Ee(t);if(s===t)break;t=s}return le(e)}function go(e){let t;try{t=JSON.parse(oo(e,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${e}: ${s instanceof Error?s.message:String(s)}`)}if(!t||typeof t!="object")throw new Error(`Invalid ToolNet project manifest: ${e}`);let n=t;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${e}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${e}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:Ee(Ee(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 gn(e,t){let n=Oe(e,Sn);so(n,{recursive:!0});let r=ht(e),s=`${r}.tmp-${process.pid}`;ao(s,JSON.stringify(t,null,2)+`
|
|
11
|
+
`,{encoding:"utf8",mode:384}),io(s,r)}function yn(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 Te=class{detect(t=process.cwd()){let n=le(t),r=fo(n),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(f=>yt(Oe(r,f))),i=mo(n,o?r:void 0);if(i){let f=ht(i),m=go(f);return m.rootPath!==i&&(m.rootPath=i,m.updatedAt=new Date().toISOString(),gn(i,m)),yn(m,i)}let a=new Date().toISOString(),c=co(r),u={version:1,id:lo(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return gn(r,u),yn(u,r)}};var yo=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],Re=class{scan(t){let n=[];for(let r of yo){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of t.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(t){return this.scan(t).length>0}};var G=class{scanner=new Re;sanitize(t){let n=t,r=this.scanner.scan(t),s=new Set;for(let o of r)s.add(o.type),n=n.split(o.value).join(`[REDACTED:${o.type}]`);return{text:n,redacted:r.length,secretTypes:[...s]}}sanitizeValue(t){if(typeof t=="string")return this.sanitize(t).text;if(Array.isArray(t))return t.map(n=>this.sanitizeValue(n));if(t&&typeof t=="object"){let n={};for(let[r,s]of Object.entries(t)){let o=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");o.includes("password")||o.includes("passwd")||o==="pwd"||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")||o.includes("apikey")||o.includes("accesskey")||o.includes("privatekey")||o.includes("clientsecret")||o.includes("credential")?n[r]="[REDACTED]":n[r]=this.sanitizeValue(s)}return n}return t}};import{homedir as Wo}from"node:os";import{join as Lo}from"node:path";import{DeleteObjectCommand as ho,GetObjectCommand as So,HeadObjectCommand as ko,ListObjectsV2Command as wo,PutObjectCommand as vo,S3Client as bo}from"@aws-sdk/client-s3";import{getSignedUrl as xo}from"@aws-sdk/s3-request-presigner";var Ne=class{name="huggingface";client;bucket;constructor(t){this.bucket=t.bucket,this.client=new bo({region:"us-east-1",endpoint:`https://s3.hf.co/${t.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}})}async put(t,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new vo({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await xo(this.client,new So({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await this.client.send(new ko({Bucket:this.bucket,Key:t})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(t){await this.client.send(new ho({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new wo({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 kn,mkdir as jo,readFile as Io,readdir as Ao,rm as Co,stat as wn,writeFile as Po}from"node:fs/promises";import{dirname as Mo,join as Eo,relative as vn,resolve as To}from"node:path";var de=class{constructor(t){this.root=t}root;name="local";path(t){let n=t.replace(/^\/+/,"");return To(this.root,n)}async put(t,n){let r=this.path(t);await jo(Mo(r),{recursive:!0}),await Po(r,n)}async get(t){try{return await Io(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 kn(this.path(t)),!0}catch{return!1}}async delete(t){await Co(this.path(t),{force:!0})}async list(t=""){let n=this.path(t),r=[];try{await kn(n)}catch{return r}let s=async i=>{let a=await Ao(i,{withFileTypes:!0});for(let c of a){let u=Eo(i,c.name);if(c.isDirectory()){await s(u);continue}let f=await wn(u);r.push({key:vn(this.root,u),size:f.size,updatedAt:f.mtime.toISOString()})}},o=await wn(n);return o.isDirectory()?await s(n):r.push({key:vn(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as Oo,GetObjectCommand as Ro,HeadObjectCommand as No,ListObjectsV2Command as _o,PutObjectCommand as Ko,S3Client as $o}from"@aws-sdk/client-s3";import{getSignedUrl as Fo}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 $o({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 Ko({Bucket:this.bucket,Key:t,Body:s,ContentType:r}))}async get(t){let n=await Fo(this.client,new Ro({Bucket:this.bucket,Key:t}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(t){let n=await this.get(t);return n?Buffer.from(n).toString("utf8"):null}async exists(t){try{return await this.client.send(new No({Bucket:this.bucket,Key:t})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(t){await this.client.send(new Oo({Bucket:this.bucket,Key:t}))}async list(t=""){let n=[],r;do{let s=await this.client.send(new _o({Bucket:this.bucket,Prefix:t||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};function St(e,t){return console.warn(t),new de(e)}function bn(e){let t=e.localRoot??Lo(Wo(),".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}):St(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}):St(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 Ne({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):St(t,"[storage] Hugging Face credentials missing. Using local fallback.")}return new de(t)}function Do(e){return new Promise(t=>setTimeout(t,e))}async function xn(e,t={}){let n=Math.max(1,t.attempts??3),r=t.baseDelayMs??150,s=t.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await e()}catch(a){if(o=a,i>=n)break;let c=Math.min(s,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Do(c+u)}throw o}var zo=new Set(["put","get","getText","delete","list"]);function jn(e,t={}){return new Proxy(e,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:zo.has(r)?(...o)=>xn(()=>Promise.resolve(s.apply(n,o)),t):s.bind(n)}})}function In(e){let t=e.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!t||t==="."||t==="..")throw new Error("Invalid project storage folder");return t}function An(e){let t=e.replace(/^\/+/,"");if(t.startsWith("memories/"))return"memory/records/"+t.slice(9);if(t.startsWith("vectors/"))return"memory/vectors/"+t.slice(8);if(t.startsWith("graph/"))return"code/graph/"+t.slice(6);let n=t.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=t.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=t.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=t.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=t.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=t.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:t))}var _e=class{constructor(t,n,r,s){this.provider=t;this.name=t.name,this.projectId=n,this.projectName=r,this.folder=In(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let t=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(t);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${t}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(t,JSON.stringify(o,null,2)+`
|
|
12
|
+
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(t){if(t=An(t),t===this.sourcePrefix)return this.targetPrefix;if(t.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+t.slice(this.sourcePrefix.length);if(t===this.targetPrefix||t.startsWith(`${this.targetPrefix}/`))return t;if(t.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${t}`].join(" "));return t}async put(t,n,r){return await this.ensureRegistered(),this.provider.put(this.key(t),n,r)}async get(t){return await this.ensureRegistered(),this.provider.get(this.key(t))}async getText(t){return await this.ensureRegistered(),this.provider.getText(this.key(t))}async delete(t){return await this.ensureRegistered(),this.provider.delete(this.key(t))}async exists(t){return await this.ensureRegistered(),this.provider.exists(this.key(t))}async list(t){return await this.ensureRegistered(),this.provider.list(this.key(t))}};import{existsSync as Qo,readFileSync as Zo}from"node:fs";import{join as ei}from"node:path";import{existsSync as qo,mkdirSync as Ho,readFileSync as Jo,renameSync as Vo,writeFileSync as Bo}from"node:fs";import{dirname as Go,join as Uo}from"node:path";function Cn(e){return Uo(e.rootPath,".toolnet","context","session-origin.json")}function Yo(e,t){Ho(Go(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;Bo(n,`${JSON.stringify(t,null,2)}
|
|
13
|
+
`,{encoding:"utf8",mode:384}),Vo(n,e)}function Ke(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 Pn(e,t){let n=Ke(t.observations,"file"),r=Ke(t.observations,"next_action"),s=Ke(t.observations,"blocker"),o=Ke(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 Yo(Cn(e),i),i}function Xo(e){let t=Cn(e);if(!qo(t))return null;try{let n=JSON.parse(Jo(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function Mn(e){let t=Xo(e);if(!t)return null;let n=["Previous session:",`- Agent: ${t.agent}`,`- Session: ${t.nativeSessionId}`];return t.currentRequest&&n.push(`- Current request: ${t.currentRequest}`),t.currentActivity&&n.push(`- Current activity: ${t.currentActivity}`),t.currentPhase&&n.push(`- Current phase: ${t.currentPhase}`),t.currentTask&&n.push(`- Current task: ${t.currentTask}`),t.lastTouchedFile&&n.push(`- Last touched file: ${t.lastTouchedFile}`),t.latestBlocker&&n.push(`- Blocker: ${t.latestBlocker}`),t.latestNextAction&&n.push(`- Next action: ${t.latestNextAction}`),t.latestDecision&&n.push(`- Important decision: ${t.latestDecision}`),n.join(`
|
|
14
|
+
`)}function ti(e){let t=ei(e.rootPath,".toolnet","current.md");if(!Qo(t))return null;try{return Zo(t,"utf8").trim()}catch{return null}}function ni(e,t){let n=t.replace(/\r\n/g,`
|
|
15
15
|
`).trim(),r=2400,s=n.length>r?`${n.slice(0,r)}
|
|
16
16
|
|
|
17
|
-
[Current work truncated for fast handoff]`:n,o=
|
|
18
|
-
`)}function
|
|
17
|
+
[Current work truncated for fast handoff]`:n,o=Mn(e);return["# ToolNet Fast Handoff","",`Project: ${e.name}`,"",...o?[o,""]:[],s,"","---","","Continuation rule:","- Continue unfinished work; do not redo completed steps.","- Query ToolNet Memory only when deeper history is needed."].join(`
|
|
18
|
+
`)}function En(e){let t=ti(e);if(t===null)return{updated:!1,reason:"missing-current",chars:0};if(!t.trim())return{updated:!1,reason:"empty-current",chars:0};let n=ni(e,t);return cn(e)?.text.trim()===n.trim()?{updated:!1,reason:"unchanged",chars:n.length}:(an(e,n),{updated:!0,reason:"updated",chars:n.length})}import{join as ri}from"node:path";function Tn(e,t){let n=e.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=w(n).slice(0,12);if(!r||r==="."||r==="..")return`${t}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function $e(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=Tn(r.toLowerCase(),"agent"),i=Tn(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:ri(e.rootPath,".toolnet","sessions",o,i)}}function On(e){return String(e).padStart(12,"0")}var Fe=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)+`
|
|
19
19
|
`,"application/json")}async scan(t){let n=`${t.remotePrefix}/events/`,r=await this.storage.list(n),s=[],o=0;for(let i of r){let a=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!a)continue;let c=Number(a[1]),u=Number(a[2]);!Number.isFinite(c)||!Number.isFinite(u)||(s.push({key:i.key,start:c,end:u}),o=Math.max(o,u))}return s.sort((i,a)=>i.start-a.start),{chunks:s,maxSequence:o}}split(t){let n=[],r=[],s=0;for(let o of t){let i=Buffer.byteLength(JSON.stringify(o)+`
|
|
20
|
-
`,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(n.push(r),r=[],s=0),r.push(o),s+=i}return r.length>0&&n.push(r),n}async loadManifest(t){return this.getJson(`${t.remotePrefix}/session.json`)}async loadCursor(t){return this.getJson(`${t.remotePrefix}/cursor.json`)}async recover(t){let n=await this.scan(t);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(t,n,r,s={}){let o=await this.loadManifest(t),i=await this.scan(t),a=n.filter(y=>y.sequence>i.maxSequence),c=0;for(let y of this.split(a)){let h=y[0],k=y[y.length-1],
|
|
20
|
+
`,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(n.push(r),r=[],s=0),r.push(o),s+=i}return r.length>0&&n.push(r),n}async loadManifest(t){return this.getJson(`${t.remotePrefix}/session.json`)}async loadCursor(t){return this.getJson(`${t.remotePrefix}/cursor.json`)}async recover(t){let n=await this.scan(t);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(t,n,r,s={}){let o=await this.loadManifest(t),i=await this.scan(t),a=n.filter(y=>y.sequence>i.maxSequence),c=0;for(let y of this.split(a)){let h=y[0],k=y[y.length-1],M=y.map(T=>JSON.stringify(T)).join(`
|
|
21
21
|
`)+`
|
|
22
|
-
`,
|
|
22
|
+
`,E=w(M).slice(0,16),P=[t.remotePrefix,"events",`${On(h.sequence)}-${On(k.sequence)}-${E}.jsonl`].join("/");await this.storage.exists(P)||await this.storage.put(P,M,"application/x-ndjson"),c+=y.length}let u=await this.scan(t),f=n[n.length-1],m=o?.status??"active";f?.type==="session_end"||f?.type==="session_idle"?m="idle":f?.type==="error"?m="error":n.length>0&&(m="active");let d=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:m,createdAt:o?.createdAt??l?.timestamp??d,updatedAt:f?.timestamp??d,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 S={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:u.maxSequence,lastRemoteSequence:u.maxSequence,sourceCursors:r,updatedAt:d};return await this.putJson(`${t.remotePrefix}/cursor.json`,S),await this.putJson(`${t.remotePrefix}/session.json`,g),{uploadedEvents:c,lastRemoteSequence:u.maxSequence,eventCount:g.eventCount,chunkCount:g.chunkCount,status:m}}};import{closeSync as wt,existsSync as ui,fsyncSync as li,mkdirSync as di,openSync as vt,readSync as pi,rmSync as Nn,statSync as _n,writeSync as mi}from"node:fs";import{join as bt}from"node:path";var si=new Set(["thinking","reasoning","reasoningcontent","chainofthought","cot","analysistext","internalreasoning","modelthinking"]),oi=new Set(["reasoning","thinking","chain_of_thought","chain-of-thought","internal_reasoning","internal-reasoning"]);function ii(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,"")}function ai(e){for(let t of["type","kind"]){let n=e[t];if(typeof n=="string"){let r=n.toLowerCase();if(oi.has(r))return n}}return null}function kt(e,t=0){if(t>12)return"[ToolNet nested value omitted]";if(Array.isArray(e))return e.map(o=>kt(o,t+1));if(!e||typeof e!="object")return e;let n=e,r=ai(n);if(r)return{type:r,omitted:"[private reasoning omitted]"};let s={};for(let[o,i]of Object.entries(n))si.has(ii(o))||(s[o]=kt(i,t+1));return s}function ci(e){if(!e)return new Date().toISOString();let t=new Date(e);return Number.isNaN(t.getTime())?new Date().toISOString():t.toISOString()}function U(e){return e?.trim()||void 0}function Rn(e,t={}){let n={...e.provenance??{}},r=U(e.source)??U(t.source)??U(n.source);return{...e,timestamp:ci(e.timestamp),source:r,turnId:U(e.turnId)??U(t.turnId),cwd:U(e.cwd)??U(t.cwd),data:kt(e.data??{}),provenance:n}}var fi=12e4,gi=80,yi=2e3;function hi(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}var ne=class{constructor(t,n={}){this.identity=t;this.eventContext=n;di(t.localDirectory,{recursive:!0}),this.eventsFile=bt(t.localDirectory,"events.jsonl"),this.stateFile=bt(t.localDirectory,"state.json"),this.lockFile=bt(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){O(this.stateFile,t)}acquireLock(){for(let t=0;t<gi;t+=1)try{return vt(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-_n(this.lockFile).mtimeMs>fi){Nn(this.lockFile,{force:!0});continue}}catch{}hi(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(t){let n=this.acquireLock();try{return t()}finally{wt(n),Nn(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 m of t){let d=Rn(m,this.eventContext),l=d.timestamp??new Date().toISOString(),g=d.data??{},S=d.provenance?.rawDigest??w(Ce(g)),y=d.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,d.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,d.type,l,S].join("|"),h=w(y).slice(0,32);if(r.has(h))continue;s+=1;let k={version:1,id:h,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,sessionId:this.identity.nativeSessionId,type:d.type,timestamp:l,source:d.source??d.provenance?.source??this.identity.agent,data:g,provenance:{...d.provenance,rawDigest:S}};d.role!==void 0&&(k.role=d.role),d.turnId!==void 0&&(k.turnId=d.turnId),d.cwd!==void 0&&(k.cwd=d.cwd),d.sourceEventId!==void 0&&(k.sourceEventId=d.sourceEventId),d.sourceSequence!==void 0&&(k.sourceSequence=d.sourceSequence),o.push(k),r.add(h)}if(o.length===0)return[];let i=o.map(m=>JSON.stringify(m)).join(`
|
|
23
23
|
`)+`
|
|
24
|
-
`,a=
|
|
25
|
-
`).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
|
|
26
|
-
`)}function
|
|
27
|
-
`).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let f=u.toLowerCase().replace(/\s+/g," ");if(r.has(f))continue;r.add(f);let m="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)?m="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?m="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?m="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?m="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?m="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?m="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(m="file");let d=
|
|
24
|
+
`,a=vt(this.eventsFile,"a",384);try{mi(a,i,null,"utf8"),li(a)}finally{wt(a)}let c=o[o.length-1],u="active";c.type==="session_end"||c.type==="session_idle"?u="idle":c.type==="error"&&(u="error");let f=Array.from(r).slice(-yi);return this.saveStateUnsafe({...n,status:u,updatedAt:c.timestamp,lastLocalEventAt:c.timestamp,lastSequence:c.sequence,recentEventIds:f}),o})}readPending(){return this.withLock(()=>{let t=this.loadStateUnsafe();if(!ui(this.eventsFile))return{events:[],startOffset:t.remoteByteOffset,endOffset:t.remoteByteOffset};let n=_n(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=vt(this.eventsFile,"r");try{pi(i,o,0,s,r)}finally{wt(i)}return{events:o.toString("utf8").split(`
|
|
25
|
+
`).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 za,existsSync as qa,openSync as Ha,readSync as Ja,statSync as Va}from"node:fs";function Kn(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 Ln=[/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],Si=[/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],ki=[/\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],wi=[/\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],vi=[/đã 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],$n=[/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],bi=[/\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],xi=[/đườ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],ji=[/\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],Fn=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Ii=new Set(["payload","data","content","message","messages","parts","summary"]);function R(e,t){return t.some(n=>n.test(e))}function Dn(e){return e.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function Ai(e){return Dn(e).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function Ci(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 xt(e,t,n,r=0){if(!(r>6)){if(typeof e=="string"){(!t||Fn.has(t))&&n.push(e);return}if(Array.isArray(e)){for(let s of e.slice(0,50))xt(s,t,n,r+1);return}if(!(!e||typeof e!="object"))for(let[s,o]of Object.entries(e))(Fn.has(s)||Ii.has(s))&&xt(o,s,n,r+1)}}function Pi(e){let t=[];xt(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=Dn(o);if(Ci(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function Wn(e){return(e.role??(typeof e.data.role=="string"?e.data.role:"")).toLowerCase()}function Mi(e,t,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=t==="user"||n.type==="user_prompt",s=t==="assistant"||n.type==="assistant_message";return r&&R(e,Ln)?{kind:"rule",confidence:.98}:r&&R(e,Si)?{kind:"rule",confidence:.92}:R(e,ki)?{kind:R(e,$n)?"architecture":"decision",confidence:r?.93:.86}:r&&R(e,wi)?{kind:"todo",confidence:.87}:R(e,$n)&&R(e,bi)?{kind:"architecture",confidence:r?.88:.82}:s&&R(e,vi)?{kind:"fix",confidence:.8}:r&&R(e,xi)&&R(e,ji)?{kind:"context",confidence:.79}:null}function Ei(e){switch(e){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Ti(e,t,n){return e==="rule"&&R(n,Ln)?"critical":e==="architecture"||e==="decision"||e==="rule"?"high":e==="fix"||e==="context"?"normal":Kn(t,n)}function zn(e,t){let n=[],r=new Set,s=new Map;for(let o of t){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,a=Wn(o);i&&a&&s.set(i,a)}for(let o of t){let i=Wn(o),a=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&a&&(i=s.get(a)??"");for(let c of Pi(o)){let u=Mi(c,i,o);if(!u||u.confidence<.75)continue;let f=Ei(u.kind),m=Ai(c),d=w([e.projectId,u.kind,m].join("|"));if(r.has(d))continue;r.add(d);let l=o.provenance.sourcePath?[o.provenance.sourcePath]:[],g=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:d,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,kind:u.kind,type:f,content:c,confidence:u.confidence,importance:Ti(u.kind,f,c),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 Oi}from"node:crypto";var Ri=["project-knowledge","implementation","continuation","session-context"],Ni={"project-knowledge":"Project knowledge",implementation:"Implementation state",continuation:"Work continuation","session-context":"Session context"};function jt(e){return Oi("sha256").update(e).digest("hex")}function We(e,t){return`${e}:${jt(t).slice(0,24)}`}function _i(e){try{return jt(JSON.stringify(e))}catch{return jt(String(e))}}function Y(e){let t=new Set,n=[];for(let r of e){let s=r?.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function Hn(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 Ki(e){return e==="rule"||e==="architecture"?"project-knowledge":e==="decision"||e==="fix"?"implementation":e==="todo"?"continuation":"session-context"}function qn(e){return e.length===0?0:e.reduce((t,n)=>t+n,0)/e.length}function $i(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=>Hn(t.content)).join(" | ")}function Fi(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=>Hn(t.content)).join(`
|
|
26
|
+
`)}function Jn(e,t){let n=e.slice().sort((d,l)=>d.sequence-l.sequence||d.timestamp.localeCompare(l.timestamp)||d.id.localeCompare(l.id)),r=n.map(d=>({id:We("raw",[d.projectId,d.agent,d.nativeSessionId,d.id,String(d.sequence)].join("|")),level:"raw",eventId:d.id,sourceEventId:d.sourceEventId,sequence:d.sequence,type:d.type,role:d.role,timestamp:d.timestamp,sourcePath:d.provenance.sourcePath,payloadDigest:_i(d.data)})),s=new Map,o=new Map;n.forEach((d,l)=>{let g=r[l];g&&(s.set(d.id,g.id),d.sourceEventId&&o.set(d.sourceEventId,g.id))});let i=t.map(d=>{let l=Y([...d.provenance.eventIds.map(g=>s.get(g)),...d.provenance.sourceEventIds.map(g=>o.get(g))]);return{id:We("fact",d.fingerprint),level:"fact",fingerprint:d.fingerprint,kind:d.kind,type:d.type,content:d.content,knowledgeClass:d.knowledgeClass,importanceScore:d.importanceScore,confidence:d.confidence,tags:Y([...d.tags,"level:fact",`class:${d.knowledgeClass}`,`kind:${d.kind}`]),rawIds:l,sourcePaths:Y(d.provenance.sourcePaths)}}),a=new Map;for(let d of i){let l=Ki(d.kind),g=a.get(l)??[];g.push(d),a.set(l,g)}let c=[];for(let d of Ri){let l=a.get(d);if(!l?.length)continue;let g=l.slice().sort((y,h)=>h.importanceScore-y.importanceScore||h.confidence-y.confidence||y.id.localeCompare(h.id)),S=g.map(y=>y.id);c.push({id:We("scene",`${d}|${S.join("|")}`),level:"scene",kind:d,title:Ni[d],summary:$i(g),factIds:S,importanceScore:Math.max(...g.map(y=>y.importanceScore)),confidence:qn(g.map(y=>y.confidence)),tags:Y(["level:scene",`scene:${d}`,...g.flatMap(y=>y.tags)]),sourcePaths:Y(g.flatMap(y=>y.sourcePaths))})}let u=new Map(i.map(d=>[d.id,d])),f=[];for(let d of c){let g=d.factIds.map(h=>u.get(h)).filter(h=>!!h).filter(h=>(h.knowledgeClass==="permanent"||h.knowledgeClass==="task")&&h.importanceScore>=.55);if(g.length===0)continue;let S=g.some(h=>h.knowledgeClass==="permanent")?"permanent":"task",y=Fi(g);f.push({id:We("knowledge",`${d.id}|${S}|${g.map(h=>h.id).join("|")}`),level:"knowledge",knowledgeClass:S,title:d.title,content:y,sceneIds:[d.id],factIds:g.map(h=>h.id),importanceScore:Math.max(...g.map(h=>h.importanceScore)),confidence:qn(g.map(h=>h.confidence)),tags:Y(["level:knowledge",`class:${S}`,`scene:${d.kind}`,...g.flatMap(h=>h.tags)]),sourcePaths:Y(g.flatMap(h=>h.sourcePaths))})}let m=[];for(let d of i)for(let l of d.rawIds)m.push({from:l,to:d.id,type:"supports"});for(let d of c)for(let l of d.factIds)m.push({from:l,to:d.id,type:"belongs_to"});for(let d of f)for(let l of d.sceneIds)m.push({from:l,to:d.id,type:"promotes_to"});return{schema:"toolnet.memory-hierarchy.v1",version:1,raw:r,facts:i,scenes:c,knowledge:f,links:m,stats:{raw:r.length,facts:i.length,scenes:c.length,knowledge:f.length,links:m.length}}}function me(){let e=Me(),t=process.env.TOOLNET_SESSION_SAVE||"summary",n=process.env.TOOLNET_RAW_TRANSCRIPT==="on"||t==="archive"||t==="full",r=process.env.TOOLNET_MEMORY_PROMOTION||"conservative",s=parseFloat(process.env.TOOLNET_PROMOTE_MIN_SCORE||"0.65"),o=parseInt(process.env.TOOLNET_SESSION_SUMMARY_MAX_TOKENS||"700",10),i=parseInt(process.env.TOOLNET_DURABLE_MEMORY_MAX_ITEMS_PER_SESSION||"10",10),a=n,c=process.env.TOOLNET_RAW_TRANSCRIPT_REMOTE==="on"||t==="full";return{sessionSave:t,rawTranscript:n,memoryPromotion:r,promoteMinScore:s,sessionSummaryMaxTokens:o,durableMemoryMaxItemsPerSession:i,archiveLocal:a,archiveRemote:c}}function Vn(e){return(e||me()).durableMemoryMaxItemsPerSession}function Bn(e){return(e||me()).sessionSummaryMaxTokens}var Gn=new G;function Un(e){let t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{let r=JSON.parse(t);return JSON.stringify(Gn.sanitizeValue(r))}catch{}let n=Gn.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 Wi(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 Li(e,t){let n=[],r=new Set;for(let i of e){let a=i.split(`
|
|
27
|
+
`).filter(c=>c.trim());for(let c of a){let u=c.trim();if(u.length<15)continue;let f=u.toLowerCase().replace(/\s+/g," ");if(r.has(f))continue;r.add(f);let m="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)?m="rule":/\b(fix|fixed|bug|issue|error|lỗi)\b/i.test(u)?m="fix":/\b(blocker|blocked|stuck|cannot|không thể)\b/i.test(u)?m="blocker":/\b(next|todo|action|task|cần làm)\b/i.test(u)?m="next_action":/\b(deploy|release|publish|ship)\b/i.test(u)?m="deploy":/\b(architecture|design|structure|pattern)\b/i.test(u)?m="architecture":/\.(ts|js|py|go|rs|java|cpp|c|h)\b/i.test(u)&&(m="file");let d=Wi(u,m);if(d<.3)continue;let l=Un(u);n.push({category:m,text:l,importance:d,sourceSessionId:t})}}let s=me(),o=Vn(s);return n.sort((i,a)=>a.importance-i.importance).slice(0,o)}function Di(e){let t=me(),n=Bn(t),o=e.join(`
|
|
28
28
|
|
|
29
29
|
`).split(`
|
|
30
|
-
`).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>
|
|
31
|
-
`);return
|
|
30
|
+
`).filter(i=>{let a=i.trim();return a.length>20&&!a.startsWith("npm")&&!a.startsWith("\u2713")&&!a.startsWith("Error:")}).slice(0,20).map(i=>Un(i)).join(`
|
|
31
|
+
`);return Jt(o,n)}function Yn(e,t){let r=(Array.isArray(e)?e:e.split(`
|
|
32
32
|
|
|
33
|
-
`).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=Ni(r,t),o=s.filter(l=>l.category==="decision").map(l=>l.text),i=s.filter(l=>l.category==="rule").map(l=>l.text),a=s.filter(l=>l.category==="file").map(l=>l.text),c=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),m=s.filter(l=>l.category==="deploy").map(l=>l.text);return{summary:_i(r),decisions:o,projectRules:i,filesChanged:a,bugsFixed:c,commands:m,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 Ki(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 $i(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Wi(e){let t=$i(e.importance);return Math.max(0,Math.min(1,t*.75+e.confidence*.25))}function Fi(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 Li(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 zi(e){let t=Fi(e),n=Wi(e),r=Li(e.content);return{...e,knowledgeClass:t,importanceScore:n,retrievalTerms:r,tags:H([...e.tags,"level:fact",`class:${t}`,`kind:${e.kind}`])}}function Di(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 qi(e,t,n){let r=Bn(Di(t),e.nativeSessionId),s=n.filter(u=>u.kind==="todo").map(u=>u.content),o=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=H([...s,...r.nextActions]),c=H([...r.nextActions,...s]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:H(r.decisions),files:H([...r.filesChanged,...o]),todos:a,completed:H(r.bugsFixed),blockers:H(r.blockers),nextActions:c,architecture:H(i)}}}function Fe(e,t){let n=Ki(t),r=Fn(e,n).map(zi),s=r.filter(f=>f.knowledgeClass!=="transient").sort((f,m)=>m.importanceScore-f.importanceScore),{summary:o,state:i}=qi(e,n,s),a=s.map(f=>({fingerprint:f.fingerprint,kind:f.kind,knowledgeClass:f.knowledgeClass,importanceScore:f.importanceScore,content:f.content,terms:f.retrievalTerms})),c=Dn(n,s),u=f=>r.filter(m=>m.knowledgeClass===f).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:a,hierarchy:c,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}import{createHash as Xi}from"node:crypto";import{existsSync as Qi,readdirSync as Zi,readFileSync as ea}from"node:fs";import{basename as ta,join as lr}from"node:path";import{randomUUID as Yn}from"node:crypto";var j=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function me(e){let t=new Set,n=[];for(let r of e){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function X(e){let t=e.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!t)throw new j("Invalid Wiki slug",400);return t}function Gn(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(X(r))}return me(t)}function Hi(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function Un(e){return{id:`revision-${Yn()}`,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 Y(e){return structuredClone(e)}var Le=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:me(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 Y([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=X(t),s=n.pages.find(o=>o.slug===r||o.id===t);if(!s)throw new j(`Wiki page not found: ${t}`,404);return Y(s)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),s=t.content.trim();if(!r)throw new j("Wiki title is required",400);let o=X(t.slug??r);if(n.pages.some(c=>c.slug===o))throw new j(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${Yn()}`,slug:o,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:s,tags:me(t.tags??[]),links:Gn(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(Un(a)),Y(a)})}async updatePage(t,n){return this.mutate(r=>{let s=X(t),o=r.pages.find(i=>i.slug===s||i.id===t);if(!o)throw new j(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new j("Wiki title is required",400);o.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?o.summary=i:delete o.summary}return n.content!==void 0&&(o.content=n.content.trim(),o.links=Gn(o.content)),n.tags!==void 0&&(o.tags=me(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(Un(o)),Y(o)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return Y(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 Y(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=me(Hi(t));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),f=a.summary?.toLowerCase()??"",m=a.content.toLowerCase(),d=a.tags.map(g=>g.toLowerCase()),l=0;for(let g of s)u===g&&(l+=12),c===g&&(l+=10),c.includes(g)&&(l+=6),u.includes(g)&&(l+=5),d.some(S=>S===g)?l+=5:d.some(S=>S.includes(g))&&(l+=3),f.includes(g)&&(l+=2),m.includes(g)&&(l+=1);l>0&&i.push({page:Y(a),score:l})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var Xn="wiki/state.v1.json";function Vi(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function Ji(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(Xn);if(!t){let n=Vi(this.project);return await this.save(n),n}return Ji(t,this.project)}async save(t){await this.storage.put(Xn,JSON.stringify(t,null,2),"application/json")}};import{createHash as Bi,randomUUID as Qn}from"node:crypto";var Zn="wiki/governance.v1.json",rr="toolnet.knowledge-governance.v1",er=500,fe={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function Gi(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function xt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function tr(e){return Bi("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function Ui(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 Yi(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),Gi(t)}function nr(e){let t=new Date().toISOString();return{schema:rr,version:1,projectId:e,policy:{...fe},reviews:[],audit:[],createdAt:t,updatedAt:t}}function sr(e){let t=e.autoApproveThreshold??fe.autoApproveThreshold,n=e.criticalApproveThreshold??fe.criticalApproveThreshold,r=e.staleAfterDays??fe.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new j("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new j("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new j("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var De=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(Zn);if(!t){let n=nr(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==rr||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:sr(n.policy??fe)}}catch{let n=nr(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(Zn,JSON.stringify(t,null,2),"application/json")}},qe=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:Qn(),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>er&&(t.audit=t.audit.slice(-er))}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=sr({...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=Yi(t),o=xt(t.title),i=n.filter(f=>f.slug!==t.slug&&xt(f.title)===o&&tr(f.content)!==tr(t.content)).map(f=>f.slug),a=Ui(t),c=[];s<r.policy.autoApproveThreshold&&c.push(`confidence:${s.toFixed(2)}`),a&&s<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||a&&s<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(s=>{let o=s.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(o?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(o)};if(o?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(o)};if(!r.requiresReview)return this.audit(s,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(o?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(o)};let i=new Date().toISOString(),a={id:Qn(),sourceKey:t.sourceKey,sourceType:t.sourceType,slug:t.slug,marker:t.marker,digest:t.digest,title:t.title,...t.summary?{summary:t.summary}:{},content:t.content,tags:[...new Set([...t.tags,t.marker])],confidence:r.confidence,risk:r.risk,reasons:[...r.reasons],conflicts:[...r.conflicts],status:"pending",createdAt:i,updatedAt:i};return s.reviews.push(a),this.audit(s,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(t,n){await this.mutate(r=>{let s=r.reviews.find(o=>o.sourceKey===t&&o.digest===n&&o.status==="approved");s&&(s.appliedAt=new Date().toISOString(),s.updatedAt=s.appliedAt,this.audit(r,"knowledge:applied",s.reviewedBy??"system",{reviewId:s.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async s=>{let o=s.reviews.find(u=>u.id===t);if(!o)throw new j(`Governance review not found: ${t}`,404);if(o.status!=="pending")throw new j("Governance review is already resolved",409);let i=new Date().toISOString();if(o.reviewedAt=i,o.reviewedBy=n.principal,o.updatedAt=i,n.note?.trim()&&(o.reviewNote=n.note.trim()),n.action==="reject")return o.status="rejected",this.audit(s,"knowledge:rejected",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o);if(n.action==="supersede")return o.status="superseded",n.targetReviewId&&(o.supersededBy=n.targetReviewId),this.audit(s,"knowledge:superseded",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(o);if(n.action==="merge"){if(!n.targetReviewId)throw new j("targetReviewId is required for merge",400);let u=s.reviews.find(f=>f.id===n.targetReviewId);if(!u)throw new j("Merge target review not found",404);return o.status="superseded",o.mergedInto=u.id,this.audit(s,"knowledge:merged",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let c=(await r.listPages()).find(u=>u.slug===o.slug);if(c&&!c.tags.includes(o.marker))throw new j(`Wiki page '${o.slug}' is manually managed`,409);return c?await r.updatePage(o.slug,{title:o.title,summary:o.summary??"",content:o.content,tags:o.tags}):await r.createPage({slug:o.slug,title:o.title,...o.summary?{summary:o.summary}:{},content:o.content,tags:o.tags}),o.appliedAt=i,this.audit(s,"knowledge:approved",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),s=Date.now(),o=n.policy.staleAfterDays*864e5,i=r.map(f=>{let m=s-Date.parse(f.updatedAt);return{slug:f.slug,title:f.title,updatedAt:f.updatedAt,ageDays:Math.max(0,Math.floor(m/864e5)),stale:Number.isFinite(m)&&m>o}}).filter(f=>f.stale).map(({stale:f,...m})=>m),a=new Map;for(let f of r){let m=xt(f.title),d=a.get(m)??[];d.push(f),a.set(m,d)}let c=[...a.entries()].filter(([,f])=>f.length>1).map(([f,m])=>({title:f,pages:m.map(d=>d.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(m=>m.startsWith("toolnet-auto-"))).length,manualPages:r.filter(f=>!f.tags.some(m=>m.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,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 dr="wiki/automation.v1.json",pr="toolnet.wiki-automation.v1",It=8e3,or=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function ye(e){return Xi("sha256").update(JSON.stringify(e)).digest("hex")}function ge(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function ir(e){return Array.isArray(e)?e:[]}function mr(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function jt(e){return Array.isArray(e)?e.map(mr).filter(t=>!!t):[]}function _(e,t){for(let n of t){let r=mr(e[n]);if(r)return r}}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 He(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(or.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=>He(i,t+1,n));let s=ge(e);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();or.has(c)||o.push(...He(a,t+1,i))}return o}function ar(e){let n=he(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>He(e[s],0,s)));return(n.length>0?n:he(He(e))).join(`
|
|
33
|
+
`).filter(l=>l.trim())).map(l=>typeof l=="string"?l:JSON.stringify(l)).filter(l=>l.trim()),s=Li(r,t),o=s.filter(l=>l.category==="decision").map(l=>l.text),i=s.filter(l=>l.category==="rule").map(l=>l.text),a=s.filter(l=>l.category==="file").map(l=>l.text),c=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),m=s.filter(l=>l.category==="deploy").map(l=>l.text);return{summary:Di(r),decisions:o,projectRules:i,filesChanged:a,bugsFixed:c,commands:m,blockers:u,nextActions:f,durableFacts:s}}function J(e){let t=new Set,n=[];for(let r of e){let s=r?.replace(/\s+/g," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function zi(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 qi(e){switch(e){case"critical":return 1;case"high":return .85;case"normal":return .6;case"temporary":return .25}}function Hi(e){let t=qi(e.importance);return Math.max(0,Math.min(1,t*.75+e.confidence*.25))}function Ji(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 Vi(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 Bi(e){let t=Ji(e),n=Hi(e),r=Vi(e.content);return{...e,knowledgeClass:t,importanceScore:n,retrievalTerms:r,tags:J([...e.tags,"level:fact",`class:${t}`,`kind:${e.kind}`])}}function Gi(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 Ui(e,t,n){let r=Yn(Gi(t),e.nativeSessionId),s=n.filter(u=>u.kind==="todo").map(u=>u.content),o=n.flatMap(u=>u.provenance.sourcePaths),i=n.filter(u=>u.kind==="architecture").map(u=>u.content),a=J([...s,...r.nextActions]),c=J([...r.nextActions,...s]);return{summary:r.summary,state:{task:c[0]??a[0],decisions:J(r.decisions),files:J([...r.filesChanged,...o]),todos:a,completed:J(r.bugsFixed),blockers:J(r.blockers),nextActions:c,architecture:J(i)}}}function Le(e,t){let n=zi(t),r=zn(e,n).map(Bi),s=r.filter(f=>f.knowledgeClass!=="transient").sort((f,m)=>m.importanceScore-f.importanceScore),{summary:o,state:i}=Ui(e,n,s),a=s.map(f=>({fingerprint:f.fingerprint,kind:f.kind,knowledgeClass:f.knowledgeClass,importanceScore:f.importanceScore,content:f.content,terms:f.retrievalTerms})),c=Jn(n,s),u=f=>r.filter(m=>m.knowledgeClass===f).length;return{version:2,normalizedEvents:n,summary:o,state:i,candidates:s,retrievalIndex:a,hierarchy:c,stats:{inputEvents:t.length,normalizedEvents:n.length,extractedCandidates:r.length,persistedCandidates:s.length,permanent:u("permanent"),task:u("task"),session:u("session"),transient:u("transient")}}}import{createHash as ra}from"node:crypto";import{existsSync as sa,readdirSync as oa,readFileSync as ia}from"node:fs";import{basename as aa,join as mr}from"node:path";import{randomUUID as Zn}from"node:crypto";var j=class extends Error{constructor(n,r){super(n);this.statusCode=r}statusCode};function fe(e){let t=new Set,n=[];for(let r of e){let s=r.replace(/\s+/gu," ").trim();if(!s)continue;let o=s.normalize("NFKC").toLowerCase();t.has(o)||(t.add(o),n.push(s))}return n}function Q(e){let t=e.normalize("NFKD").replace(/[\u0300-\u036f]/gu,"").toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,120);if(!t)throw new j("Invalid Wiki slug",400);return t}function Xn(e){let t=[];for(let n of e.matchAll(/\[\[([^\[\]]+)\]\]/gu)){let r=n[1]?.trim();r&&t.push(Q(r))}return fe(t)}function Yi(e){return e.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}_-]+/u).map(t=>t.trim()).filter(t=>t.length>=2)}function Qn(e){return{id:`revision-${Zn()}`,pageId:e.id,slug:e.slug,revision:e.revision,title:e.title,...e.summary?{summary:e.summary}:{},content:e.content,tags:[...e.tags],links:[...e.links],createdAt:e.updatedAt}}function X(e){return structuredClone(e)}var De=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:fe(t.pages.flatMap(r=>r.tags)).sort((r,s)=>r.localeCompare(s)),links:t.pages.reduce((r,s)=>r+s.links.length,0),orphanPages:t.pages.filter(r=>r.links.length===0&&!n.has(r.slug)).length,automatedPages:t.pages.filter(r=>r.tags.some(s=>s.startsWith("toolnet-auto-"))).length,updatedAt:t.updatedAt}}async listPages(){let t=await this.ensureState();return X([...t.pages].sort((n,r)=>n.title.localeCompare(r.title)))}async getPage(t){let n=await this.ensureState(),r=Q(t),s=n.pages.find(o=>o.slug===r||o.id===t);if(!s)throw new j(`Wiki page not found: ${t}`,404);return X(s)}async createPage(t){return this.mutate(n=>{let r=t.title.trim(),s=t.content.trim();if(!r)throw new j("Wiki title is required",400);let o=Q(t.slug??r);if(n.pages.some(c=>c.slug===o))throw new j(`Wiki page already exists: ${o}`,409);let i=new Date().toISOString(),a={id:`wiki-${Zn()}`,slug:o,title:r,...t.summary?.trim()?{summary:t.summary.trim()}:{},content:s,tags:fe(t.tags??[]),links:Xn(s),revision:1,createdAt:i,updatedAt:i};return n.pages.push(a),n.revisions.push(Qn(a)),X(a)})}async updatePage(t,n){return this.mutate(r=>{let s=Q(t),o=r.pages.find(i=>i.slug===s||i.id===t);if(!o)throw new j(`Wiki page not found: ${t}`,404);if(n.title!==void 0){let i=n.title.trim();if(!i)throw new j("Wiki title is required",400);o.title=i}if(n.summary!==void 0){let i=n.summary.trim();i?o.summary=i:delete o.summary}return n.content!==void 0&&(o.content=n.content.trim(),o.links=Xn(o.content)),n.tags!==void 0&&(o.tags=fe(n.tags)),o.revision+=1,o.updatedAt=new Date().toISOString(),r.revisions.push(Qn(o)),X(o)})}async history(t){let n=await this.getPage(t),r=await this.ensureState();return X(r.revisions.filter(s=>s.pageId===n.id).sort((s,o)=>o.revision-s.revision))}async backlinks(t){let n=await this.getPage(t),r=await this.ensureState();return X(r.pages.filter(s=>s.links.includes(n.slug)).sort((s,o)=>s.title.localeCompare(o.title)))}async search(t,n=10){let r=await this.ensureState(),s=fe(Yi(t));if(s.length===0)return[];let o=Math.max(1,Math.min(20,Math.floor(n))),i=[];for(let a of r.pages){let c=a.title.toLowerCase(),u=a.slug.toLowerCase(),f=a.summary?.toLowerCase()??"",m=a.content.toLowerCase(),d=a.tags.map(g=>g.toLowerCase()),l=0;for(let g of s)u===g&&(l+=12),c===g&&(l+=10),c.includes(g)&&(l+=6),u.includes(g)&&(l+=5),d.some(S=>S===g)?l+=5:d.some(S=>S.includes(g))&&(l+=3),f.includes(g)&&(l+=2),m.includes(g)&&(l+=1);l>0&&i.push({page:X(a),score:l})}return i.sort((a,c)=>c.score-a.score||c.page.updatedAt.localeCompare(a.page.updatedAt)).slice(0,o)}};var er="wiki/state.v1.json";function Xi(e){let t=new Date().toISOString();return{schema:"toolnet.wiki.v1",version:1,projectId:e.id,pages:[],revisions:[],createdAt:t,updatedAt:t}}function Qi(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(er);if(!t){let n=Xi(this.project);return await this.save(n),n}return Qi(t,this.project)}async save(t){await this.storage.put(er,JSON.stringify(t,null,2),"application/json")}};import{createHash as Zi,randomUUID as tr}from"node:crypto";var nr="wiki/governance.v1.json",ir="toolnet.knowledge-governance.v1",rr=500,ge={autoApproveThreshold:.86,criticalApproveThreshold:.94,staleAfterDays:90};function ea(e,t=0,n=1){return Math.max(t,Math.min(n,e))}function It(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/gu," ").trim()}function sr(e){return Zi("sha256").update(e.normalize("NFKC").replace(/\s+/gu," ").trim()).digest("hex")}function ta(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 na(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),ea(t)}function or(e){let t=new Date().toISOString();return{schema:ir,version:1,projectId:e,policy:{...ge},reviews:[],audit:[],createdAt:t,updatedAt:t}}function ar(e){let t=e.autoApproveThreshold??ge.autoApproveThreshold,n=e.criticalApproveThreshold??ge.criticalApproveThreshold,r=e.staleAfterDays??ge.staleAfterDays;if(!Number.isFinite(t)||t<.5||t>1)throw new j("Invalid autoApproveThreshold",400);if(!Number.isFinite(n)||n<.5||n>1)throw new j("Invalid criticalApproveThreshold",400);if(!Number.isInteger(r)||r<1||r>3650)throw new j("Invalid staleAfterDays",400);return{autoApproveThreshold:t,criticalApproveThreshold:n,staleAfterDays:r}}var qe=class{constructor(t,n){this.storage=t;this.project=n}storage;project;async load(){let t=await this.storage.getText(nr);if(!t){let n=or(this.project.id);return await this.save(n),n}try{let n=JSON.parse(t);if(n.schema!==ir||n.version!==1||n.projectId!==this.project.id||!Array.isArray(n.reviews)||!Array.isArray(n.audit))throw new Error("invalid");return{...n,policy:ar(n.policy??ge)}}catch{let n=or(this.project.id);return await this.save(n),n}}async save(t){await this.storage.put(nr,JSON.stringify(t,null,2),"application/json")}},He=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>rr&&(t.audit=t.audit.slice(-rr))}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=ar({...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=na(t),o=It(t.title),i=n.filter(f=>f.slug!==t.slug&&It(f.title)===o&&sr(f.content)!==sr(t.content)).map(f=>f.slug),a=ta(t),c=[];s<r.policy.autoApproveThreshold&&c.push(`confidence:${s.toFixed(2)}`),a&&s<r.policy.criticalApproveThreshold&&c.push("critical-knowledge"),i.length>0&&c.push("conflicting-knowledge");let u=i.length>0?"conflict":a?"critical":"normal";return{confidence:s,risk:u,requiresReview:i.length>0||s<r.policy.autoApproveThreshold||a&&s<r.policy.criticalApproveThreshold,reasons:c,conflicts:i}}async gate(t,n){let r=await this.assess(t,n);return this.mutate(s=>{let o=s.reviews.find(c=>c.sourceKey===t.sourceKey&&c.digest===t.digest);if(o?.status==="approved")return{allowed:!0,mode:"review-approved",assessment:r,review:structuredClone(o)};if(o?.status==="rejected")return{allowed:!1,mode:"rejected",assessment:r,review:structuredClone(o)};if(!r.requiresReview)return this.audit(s,"knowledge:auto-approved","system",{sourceKey:t.sourceKey,metadata:{confidence:r.confidence,risk:r.risk}}),{allowed:!0,mode:"auto-approved",assessment:r};if(o?.status==="pending")return{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(o)};let i=new Date().toISOString(),a={id: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(a),this.audit(s,"knowledge:review-requested","system",{reviewId:a.id,sourceKey:a.sourceKey,metadata:{confidence:a.confidence,risk:a.risk}}),{allowed:!1,mode:"pending-review",assessment:r,review:structuredClone(a)}})}async markApplied(t,n){await this.mutate(r=>{let s=r.reviews.find(o=>o.sourceKey===t&&o.digest===n&&o.status==="approved");s&&(s.appliedAt=new Date().toISOString(),s.updatedAt=s.appliedAt,this.audit(r,"knowledge:applied",s.reviewedBy??"system",{reviewId:s.id,sourceKey:t}))})}async decide(t,n,r){return this.mutate(async s=>{let o=s.reviews.find(u=>u.id===t);if(!o)throw new j(`Governance review not found: ${t}`,404);if(o.status!=="pending")throw new j("Governance review is already resolved",409);let i=new Date().toISOString();if(o.reviewedAt=i,o.reviewedBy=n.principal,o.updatedAt=i,n.note?.trim()&&(o.reviewNote=n.note.trim()),n.action==="reject")return o.status="rejected",this.audit(s,"knowledge:rejected",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o);if(n.action==="supersede")return o.status="superseded",n.targetReviewId&&(o.supersededBy=n.targetReviewId),this.audit(s,"knowledge:superseded",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:n.targetReviewId}}),structuredClone(o);if(n.action==="merge"){if(!n.targetReviewId)throw new j("targetReviewId is required for merge",400);let u=s.reviews.find(f=>f.id===n.targetReviewId);if(!u)throw new j("Merge target review not found",404);return o.status="superseded",o.mergedInto=u.id,this.audit(s,"knowledge:merged",n.principal,{reviewId:t,sourceKey:o.sourceKey,metadata:{targetReviewId:u.id}}),structuredClone(o)}o.status="approved";let c=(await r.listPages()).find(u=>u.slug===o.slug);if(c&&!c.tags.includes(o.marker))throw new j(`Wiki page '${o.slug}' is manually managed`,409);return c?await r.updatePage(o.slug,{title:o.title,summary:o.summary??"",content:o.content,tags:o.tags}):await r.createPage({slug:o.slug,title:o.title,...o.summary?{summary:o.summary}:{},content:o.content,tags:o.tags}),o.appliedAt=i,this.audit(s,"knowledge:approved",n.principal,{reviewId:t,sourceKey:o.sourceKey}),structuredClone(o)})}async quality(t){let n=await this.ensureState(),r=await t.listPages(),s=Date.now(),o=n.policy.staleAfterDays*864e5,i=r.map(f=>{let m=s-Date.parse(f.updatedAt);return{slug:f.slug,title:f.title,updatedAt:f.updatedAt,ageDays:Math.max(0,Math.floor(m/864e5)),stale:Number.isFinite(m)&&m>o}}).filter(f=>f.stale).map(({stale:f,...m})=>m),a=new Map;for(let f of r){let m=It(f.title),d=a.get(m)??[];d.push(f),a.set(m,d)}let c=[...a.entries()].filter(([,f])=>f.length>1).map(([f,m])=>({title:f,pages:m.map(d=>d.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(m=>m.startsWith("toolnet-auto-"))).length,manualPages:r.filter(f=>!f.tags.some(m=>m.startsWith("toolnet-auto-"))).length,stalePages:i,duplicateTitles:c,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 fr="wiki/automation.v1.json",gr="toolnet.wiki-automation.v1",Pt=8e3,cr=new Set(["raw","rawtext","raw_text","rawtranscript","raw_transcript","transcript","messages","message","payload","prompt","response","assistantmessage","assistant_message","userprompt","user_prompt"]);function he(e){return ra("sha256").update(JSON.stringify(e)).digest("hex")}function ye(e){if(!(!e||typeof e!="object"||Array.isArray(e)))return e}function ur(e){return Array.isArray(e)?e:[]}function yr(e){return typeof e!="string"?void 0:e.replace(/\s+/gu," ").trim()||void 0}function At(e){return Array.isArray(e)?e.map(yr).filter(t=>!!t):[]}function K(e,t){for(let n of t){let r=yr(e[n]);if(r)return r}}function Se(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 Je(e,t=0,n=""){if(t>3)return[];let r=n.replace(/[^a-z0-9]/giu,"").toLowerCase();if(cr.has(r))return[];if(typeof e=="string"){let i=e.replace(/\s+/gu," ").trim();return i.length<8?[]:[i]}if(Array.isArray(e))return e.flatMap(i=>Je(i,t+1,n));let s=ye(e);if(!s)return[];let o=[];for(let[i,a]of Object.entries(s)){let c=i.replace(/[^a-z0-9]/giu,"").toLowerCase();cr.has(c)||o.push(...Je(a,t+1,i))}return o}function lr(e){let n=Se(["content","summary","text","value","statement","description","decision","task","knowledge","context","outcome","reason","rationale"].flatMap(s=>Je(e[s],0,s)));return(n.length>0?n:Se(Je(e))).join(`
|
|
34
34
|
|
|
35
|
-
`).slice(0,
|
|
35
|
+
`).slice(0,Pt)}function dr(e,t){return K(e,["id","key","fingerprint","knowledgeId","sceneId"])??t}function pr(e,t){return K(e,["title","name","topic","label","task","kind","type"])??t}function ca(e){return(K(e,["knowledgeClass","class","classification","scope"])??"").toLowerCase()}function ua(e){return(K(e,["kind","sceneKind","type"])??"").toLowerCase()}function la(e){let t=ye(e);if(!t)return[];let n=[],r=ur(t.knowledge);for(let[o,i]of r.entries()){let a=ye(i);if(!a)continue;let c=ca(a);if(c==="session"||c==="transient")continue;let u=lr(a);if(u.length<20)continue;let f=dr(a,he(a).slice(0,16)),m=pr(a,`Durable Memory ${o+1}`);n.push({sourceKey:`memory:${f}`,sourceType:"memory",title:m,summary:K(a,["summary","description"]),content:u,tags:Se(["toolnet","auto","memory",...c?[c]:[]])})}let s=ur(t.scenes);for(let[o,i]of s.entries()){let a=ye(i);if(!a)continue;let c=ua(a);if(c==="session-context")continue;let u=lr(a);if(u.length<20)continue;let f=dr(a,he(a).slice(0,16)),m=pr(a,`Knowledge Scene ${o+1}`);n.push({sourceKey:`scene:${f}`,sourceType:"scene",title:m,summary:K(a,["summary","description"]),content:u,tags:Se(["toolnet","auto","scene",...c?[c]:[]])})}return n}function da(e){return mr(e,".toolnet","memory","skills")}function pa(e){let t=da(e);if(!sa(t))return{candidates:[],failed:0};let n=[],r=0,s=oa(t).filter(o=>o.endsWith(".json")).sort();for(let o of s)try{let i=JSON.parse(ia(mr(t,o),"utf8")),a=ye(i);if(!a||a.schema!=="toolnet.skill-memory.v1")continue;let c=K(a,["id","fingerprint"])??aa(o,".json"),u=K(a,["task"])??"",f=K(a,["title"])||u||`Reusable Skill ${c.slice(0,8)}`,m=K(a,["summary"])??void 0,d=At(a.steps),l=At(a.verification),g=At(a.files),S=[];u&&S.push(`## Task
|
|
36
36
|
${u}`),m&&S.push(`## Summary
|
|
37
37
|
${m}`),d.length>0&&S.push(`## Procedure
|
|
38
38
|
${d.map((h,k)=>`${k+1}. ${h}`).join(`
|
|
@@ -42,23 +42,23 @@ ${l.map(h=>`- ${h}`).join(`
|
|
|
42
42
|
${g.map(h=>`- \`${h}\``).join(`
|
|
43
43
|
`)}`);let y=S.join(`
|
|
44
44
|
|
|
45
|
-
`).slice(0,
|
|
46
|
-
`).slice(0,
|
|
47
|
-
`,{encoding:"utf8",mode:384}),
|
|
48
|
-
`,c=w(r.map(f=>f.fingerprint).sort().join("|")).slice(0,16),u=[
|
|
49
|
-
`,"application/json"),c}};function
|
|
45
|
+
`).slice(0,Pt);if(y.length<20)continue;n.push({sourceKey:`skill:${c}`,sourceType:"skill",title:f,summary:m,content:y,tags:["toolnet","auto","skill","sop"]})}catch{r+=1}return{candidates:n,failed:r}}function Ct(e){let t=new Date().toISOString();return{schema:gr,version:1,projectId:e,entries:[],createdAt:t,updatedAt:t}}async function ma(e,t){let n=await e.getText(fr);if(!n)return Ct(t);try{let r=JSON.parse(n);return r.schema!==gr||r.version!==1||r.projectId!==t||!Array.isArray(r.entries)?Ct(t):r}catch{return Ct(t)}}async function fa(e,t){await e.put(fr,JSON.stringify(t,null,2),"application/json")}function ga(e){return`toolnet-auto-${he(e).slice(0,12)}`}function ya(e){let t=Q(e.title).slice(0,72),n=he(e.sourceKey).slice(0,10);return Q(`auto-${e.sourceType}-${t}-${n}`)}function ha(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(`
|
|
46
|
+
`).slice(0,Pt)}function Sa(e){return he({sourceType:e.sourceType,title:e.title,summary:e.summary,content:e.content,tags:e.tags})}function ka(e,t){return e.tags.includes(t)}async function hr(e){let t=la(e.hierarchy),n=pa(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 De(new ze(e.storage,e.project));await i.initialize();let a=new He(new qe(e.storage,e.project));await a.initialize();let c=await ma(e.storage,e.project.id),u=await i.listPages(),f=new Map(u.map(l=>[l.slug,l])),m=new Map(c.entries.map(l=>[l.sourceKey,l]));for(let l of s)try{let g=ga(l.sourceKey),S=Sa(l),y=m.get(l.sourceKey),h=y?.slug??ya(l),k=f.get(h);if(k&&!ka(k,g)){o.skipped+=1;continue}let M=Se([...l.tags,g]),E=ha(l),P=await a.gate({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,marker:g,digest:S,title:l.title,...l.summary?{summary:l.summary}:{},content:E,tags:M},[...f.values()]);if(!P.allowed){P.mode==="pending-review"?o.reviewPending+=1:o.skipped+=1;continue}P.mode==="auto-approved"?o.autoApproved+=1:P.mode==="review-approved"&&(o.reviewApproved+=1),k?y?.digest!==S?(k=await i.updatePage(h,{title:l.title,summary:l.summary??"",content:E,tags:M}),f.set(k.slug,k),o.updated+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:k.slug,action:"updated"})):(o.unchanged+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,action:"unchanged"})):(k=await i.createPage({slug:h,title:l.title,summary:l.summary,content:E,tags:M}),f.set(k.slug,k),o.created+=1,o.pages.push({sourceKey:l.sourceKey,sourceType:l.sourceType,slug:k.slug,action:"created"}));let T=new Date().toISOString(),x={sourceKey:l.sourceKey,sourceType:l.sourceType,slug:h,digest:S,marker:g,updatedAt:T},v=c.entries.findIndex(L=>L.sourceKey===l.sourceKey);v>=0?c.entries[v]=x:c.entries.push(x),m.set(l.sourceKey,x),await a.markApplied(l.sourceKey,S)}catch(g){if(g instanceof j&&g.statusCode===409){o.skipped+=1;continue}o.failed+=1}let d=new Date().toISOString();return c.updatedAt=d,c.lastRunAt=d,c.entries.sort((l,g)=>l.sourceKey.localeCompare(g.sourceKey)),await fa(e.storage,c),o}import{createHash as wa}from"node:crypto";import{chmodSync as kr,existsSync as va,mkdirSync as ba,readFileSync as cm,readdirSync as um,renameSync as xa,statSync as lm,writeFileSync as ja}from"node:fs";import{join as wr}from"node:path";var Ia="toolnet.skill-memory.v1",Sr=5,Aa=16,Ca=24,Pa=32;function Ma(e){return wa("sha256").update(e).digest("hex")}function we(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 Mt(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 Ea(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&&Mt(Ea(e),t)||void 0}function ve(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim())return r}}function vr(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 br(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(br(t,["passed","pass","success","succeeded","ok"])===!1)return!0;let r=vr(t,["exitCode","exit_code","code","statusCode"]);if(r!==void 0&&r!==0)return!0;let s=ve(t,["status","result","outcome"]);return!!(s&&/\b(fail(?:ed)?|error|broken|cancelled)\b/iu.test(s))}function ke(e){let t=e.data??{};if(xr(e))return!1;if(br(t,["passed","pass","success","succeeded","ok"])===!0||vr(t,["exitCode","exit_code","code","statusCode"])===0)return!0;let s=ve(t,["status","result","outcome"]);return s&&/\b(pass(?:ed)?|success(?:ful)?|succeeded|ok|green|complete(?:d)?)\b/iu.test(s)?!0:e.type==="commit"||e.type==="deploy"}function jr(e){let t=e.data??{},n=ve(t,["path","file","filePath","filename","target"]);if(n)return z(n,260);let r=e.provenance?.files;return z(r?.[0],260)}function Et(e){return z(ve(e.data??{},["command","cmd","script"]),420)}function re(e){return z(ve(e.data??{},["name","test","suite","title","message","text","result","status"]),300)}function Ta(e){let t=[];for(let n of[...e].sort((r,s)=>r.sequence-s.sequence))if(ke(n)){if(n.type==="test"){let r=re(n)??Et(n)??"Tests passed";t.push(`Test passed: ${r}`);continue}if(n.type==="commit"){let r=re(n);t.push(r?`Commit: ${r}`:"Commit completed");continue}if(n.type==="deploy"){let r=re(n);t.push(r?`Deploy: ${r}`:"Deployment completed")}}return we(t,10)}function Oa(e,t){let n=[];for(let r of[...e].sort((s,o)=>s.sequence-o.sequence))switch(r.type){case"file_write":case"file_edit":{let s=jr(r);s&&n.push(`Update ${s}`);break}case"command":{if(xr(r))break;let s=Et(r);s&&n.push(`Run: ${s}`);break}case"test":{if(!ke(r))break;let s=re(r)??Et(r)??"project tests";n.push(`Verify: ${s}`);break}case"commit":{if(!ke(r))break;let s=re(r);n.push(s?`Commit: ${s}`:"Commit verified changes");break}case"deploy":{if(!ke(r))break;let s=re(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 we(n,Aa)}function Ra(e,t){let n=[...t.files];for(let r of e){let s=jr(r);s&&n.push(s);for(let o of r.provenance?.files??[]){let i=z(o,260);i&&n.push(i)}}return we(n,Ca)}function Na(e){return we(e.filter(t=>["file_write","file_edit","command","test","commit","deploy"].includes(t.type)).map(t=>t.id),Pa)}function _a(e){return e.map(n=>n.timestamp).filter(Boolean).sort().at(-1)??new Date(0).toISOString()}function Ir(e,t,n){if(t.length===0)return[];let r=Ta(t),s=we(n.completed.map(g=>z(g,280)??""),Sr);if(!(s.length>0||t.some(g=>["test","commit","deploy"].includes(g.type)&&ke(g))))return[];let i=z(n.task,280)??z(n.nextActions[0],280),a=s.length>0?s:i?[i]:[];if(a.length===0)return[];let c=Oa(t,n);if(c.length===0)return[];let u=Ra(t,n),f=Na(t),m=Math.min(...t.map(g=>g.sequence)),d=Math.max(...t.map(g=>g.sequence)),l=_a(t);return a.slice(0,Sr).map(g=>{let S=[`Reusable procedure learned from successful task: ${g}.`,u.length>0?`Files: ${u.slice(0,6).join(", ")}.`:"",r.length>0?`Verification: ${r.slice(0,4).join("; ")}.`:""].filter(Boolean),y=JSON.stringify({projectId:e.projectId,task:g,steps:c,verification:r,files:u}),h=Ma(y);return{schema:Ia,version:1,id:`skill-${h.slice(0,24)}`,fingerprint:h,projectId:e.projectId,title:Mt(`SOP: ${g}`,180),task:g,summary:Mt(S.join(" "),900),steps:c,verification:r,files:u,source:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:m,lastSequence:d,eventIds:f},createdAt:l}})}function Ka(e){return wr(e.rootPath,".toolnet","memory","skills")}function $a(e){let t=Ka(e);return ba(t,{recursive:!0,mode:448}),kr(t,448),t}function Ar(e,t){if(t.length===0)return{written:0,deduped:0,files:[]};let n=$a(e),r=0,s=0,o=[];for(let i of t){if(i.projectId!==e.id)throw new Error(`Skill project mismatch: ${i.projectId} != ${e.id}`);let a=wr(n,`${i.id}.json`);if(o.push(a),va(a)){s+=1;continue}let c=`${a}.${process.pid}.${Date.now()}.tmp`;ja(c,JSON.stringify(i,null,2)+`
|
|
47
|
+
`,{encoding:"utf8",mode:384}),xa(c,a),kr(a,384),r+=1}return{written:r,deduped:s,files:o}}function Cr(e){return String(e).padStart(12,"0")}function Fa(e){return e.remotePrefix.replace("/sessions/","/memory/learned/")}var Ve=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},a=JSON.stringify(i,null,2)+`
|
|
48
|
+
`,c=w(r.map(f=>f.fingerprint).sort().join("|")).slice(0,16),u=[Fa(t),"batches",`${Cr(s)}-${Cr(o)}-${c}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,a,"application/json"),u}};import{createHash as Wa}from"node:crypto";function Pr(e){return String(e).padStart(12,"0")}function La(e){return Wa("sha256").update(e).digest("hex")}function Da(e){return e.remotePrefix.replace("/sessions/","/memory/hierarchy/")}var Be=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},a=La([...r.facts.map(u=>u.id),...r.knowledge.map(u=>u.id)].sort().join("|")).slice(0,16),c=[Da(t),"batches",`${Pr(s)}-${Pr(o)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,`${JSON.stringify(i,null,2)}
|
|
49
|
+
`,"application/json"),c}};function Ba(e,t){if(!qa(e))return{events:[],nextOffset:t};let n=Va(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=Ha(e,"r");try{Ja(i,o,0,s,r)}finally{za(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
|
|
50
50
|
`);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
|
|
51
|
-
`).filter(Boolean).flatMap(m=>{try{return[JSON.parse(m)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var
|
|
52
|
-
`))))}function
|
|
53
|
-
`).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
|
|
54
|
-
`,a=w(n.map(u=>u.id).sort().join("|")).slice(0,16),c=[`projects/${t.projectId}`,"work","observations",t.agent,t.nativeSessionId,`${
|
|
55
|
-
`,"application/json"),
|
|
51
|
+
`).filter(Boolean).flatMap(m=>{try{return[JSON.parse(m)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Ge=class{constructor(t){this.options=t;this.journal=new Ve(t.storage),this.hierarchyJournal=new Be(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=Ba(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Le(this.options.identity,s.events),i=o.candidates,a=!1;i.length>0&&(a=!!await this.journal.write(this.options.identity,s.events,i));let c=!1;o.hierarchy.facts.length>0&&(c=!!await this.hierarchyJournal.write(this.options.identity,s.events,o.hierarchy));let u=Ir(this.options.identity,s.events,o.state),f=Ar(this.options.project,u);this.options.wal.setSourceCursor("memory.pipeline.version",2),this.options.wal.setSourceCursor("memory.pipeline.normalized_events",o.stats.normalizedEvents),this.options.wal.setSourceCursor("memory.pipeline.persisted",o.stats.persistedCandidates),this.options.wal.setSourceCursor("memory.pipeline.permanent",o.stats.permanent),this.options.wal.setSourceCursor("memory.pipeline.task",o.stats.task),this.options.wal.setSourceCursor("memory.pipeline.session",o.stats.session),this.options.wal.setSourceCursor("memory.pipeline.transient",o.stats.transient),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.version",o.hierarchy.version),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.raw",o.hierarchy.stats.raw),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.facts",o.hierarchy.stats.facts),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.scenes",o.hierarchy.stats.scenes),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.knowledge",o.hierarchy.stats.knowledge),this.options.wal.setSourceCursor("memory.pipeline.hierarchy.journal_written",c?1:0),this.options.wal.setSourceCursor("memory.skill.assets",u.length),this.options.wal.setSourceCursor("memory.skill.written",f.written),this.options.wal.setSourceCursor("memory.skill.deduped",f.deduped);try{let m=Qt(this.options.project.rootPath,s.events);this.options.wal.setSourceCursor("memory.context_offload.eligible",m.eligible),this.options.wal.setSourceCursor("memory.context_offload.written",m.written),this.options.wal.setSourceCursor("memory.context_offload.deduped",m.deduped),this.options.wal.setSourceCursor("memory.context_offload.graph_nodes",m.graphNodes),this.options.wal.setSourceCursor("memory.context_offload.failed",0)}catch{this.options.wal.setSourceCursor("memory.context_offload.failed",1)}try{let m=await hr({project:this.options.project,storage:this.options.storage,hierarchy:o.hierarchy});this.options.wal.setSourceCursor("memory.wiki_automation.scanned",m.scanned),this.options.wal.setSourceCursor("memory.wiki_automation.eligible",m.eligible),this.options.wal.setSourceCursor("memory.wiki_automation.created",m.created),this.options.wal.setSourceCursor("memory.wiki_automation.updated",m.updated),this.options.wal.setSourceCursor("memory.wiki_automation.unchanged",m.unchanged),this.options.wal.setSourceCursor("memory.wiki_automation.skipped",m.skipped),this.options.wal.setSourceCursor("memory.wiki_automation.failed",m.failed),this.options.wal.setSourceCursor("memory.wiki_automation.review_pending",m.reviewPending),this.options.wal.setSourceCursor("memory.wiki_automation.auto_approved",m.autoApproved),this.options.wal.setSourceCursor("memory.wiki_automation.review_approved",m.reviewApproved)}catch{this.options.wal.setSourceCursor("memory.wiki_automation.failed",1)}return this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:i.length,journalWritten:a,nextOffset:s.nextOffset}}};import{closeSync as dc,existsSync as pc,openSync as mc,readSync as fc,statSync as gc}from"node:fs";function Mr(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function xe(e){return e.toLowerCase().replace(/[^a-z0-9]/gu,"")}function be(e,t,n=0){if(n>8)return;if(Array.isArray(e)){for(let s of e.slice(0,50))be(s,t,n+1);return}let r=Mr(e);if(r)for(let[s,o]of Object.entries(r))t(s,o,r),be(o,t,n+1)}function se(e,t){let n=[];return be(e,(r,s)=>{t.has(xe(r))&&typeof s=="string"&&s.trim()&&n.push(s.trim())}),n}function Ga(e){let t=e.trim();if(!t.startsWith("{"))return null;try{return Mr(JSON.parse(t))}catch{return null}}function Ua(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 be(t,(r,s,o)=>{if(n)return;let i=xe(r);if(["tool","toolname"].includes(i)&&typeof s=="string"){n=s.trim().toLowerCase();return}if(i!=="name"||typeof s!="string")return;let a=typeof o.type=="string"?o.type.toLowerCase():"";(a.includes("tool")||a.includes("function")||a.includes("command"))&&(n=s.trim().toLowerCase())}),n}function Ya(e){let t=se(e.data,new Set(["command","cmd","script"])),n=se(e.data,new Set(["arguments","args"]));for(let r of n){let s=Ga(r);if(s)for(let o of se(s,new Set(["command","cmd","script"])))t.push(o)}return Array.from(new Set(t.map(r=>r.trim()).filter(Boolean)))}function Xa(e){let t=se(e.data,new Set(["filepath","file_path","filename","file","path","target"].map(xe)));return Array.from(new Set(t.map(n=>n.trim()).filter(n=>n.length>0&&n.length<1e3&&!n.includes(`
|
|
52
|
+
`))))}function Qa(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 Za(e){let t=se(e.data,new Set(["patch","diff","arguments","input"].map(xe))),n=[];for(let r of t){let s=[{regex:/^\*\*\* Update File:\s*(.+)$/gimu,action:"modified"},{regex:/^\*\*\* Add File:\s*(.+)$/gimu,action:"created"},{regex:/^\*\*\* Delete File:\s*(.+)$/gimu,action:"deleted"}];for(let o of s)for(let i of r.matchAll(o.regex)){let a=i[1]?.trim();a&&n.push({kind:"file",text:a,fileAction:o.action,confidence:.99})}}return n}function ec(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 tc(e){let t=null;return be(e,(n,r)=>{if(t===null&&["exitcode","code"].includes(xe(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 nc(e){return se(e,new Set(["status","state","result","output","outputsummary","message","text"]))}function rc(e){let t=tc(e.data);if(t!==null)return t===0?"passed":"failed";let n=nc(e.data).join(`
|
|
53
|
+
`).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 sc(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 Er(e){let t=[],n=Ua(e),r=Qa(e,n);if(r)for(let s of Xa(e))t.push({kind:"file",text:s,fileAction:r,confidence:e.type==="file_edit"||e.type==="file_write"?1:.96});t.push(...Za(e));for(let s of Ya(e)){t.push({kind:"command",text:s,confidence:.98});let o=ec(s);o&&t.push({kind:"test",text:s,checkKind:o,checkStatus:rc(e),confidence:.98})}return sc(t)}var oc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function ee(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Or(e){return ee(e).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function Z(e,t,n=0){if(!(n>6)){if(typeof e=="string"){t.push(e);return}if(Array.isArray(e)){for(let r of e.slice(0,50))Z(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(oc.has(r)||["data","payload","parts","messages"].includes(r))&&Z(s,t,n+1)}}function Ue(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 Tr(e){let t=ee(e);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(t)}function I(e,t,n,r,s={}){let o=ee(r),i=s.key??Or(o);return{version:1,id:w([e.projectId,n,i,t.id,o,s.status??"",s.fileAction??"",s.checkKind??"",s.checkStatus??"",s.order??""].join("|")).slice(0,32),projectId:e.projectId,kind:n,key:i,text:o,status:s.status,fileAction:s.fileAction,checkKind:s.checkKind,checkStatus:s.checkStatus,order:s.order,confidence:s.confidence??.85,occurredAt:t.timestamp,sequence:t.sequence,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId}}function ic(e,t,n){let r=ee(n);if(r.length<5||r.length>1200)return[];let s=[],o=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(I(e,t,"goal",i[1],{confidence:.97}));let a=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);a?.[1]&&s.push(I(e,t,"plan",a[1],{confidence:.95}));let c=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,u;for(;!o&&(u=c.exec(r));){let d=Number(u[1]),l=ee(u[2]??""),g=l&&!Tr(l)?`Phase ${d} - ${l}`:`Phase ${d}`;s.push(I(e,t,"phase",g,{key:`phase:${d}`,order:d,status:Ue(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":Ue(f[2]),confidence:.96}));let m=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(m?.[2]){let d=m[1]?Number(m[1]):void 0,l=ee(m[2]),g=Tr(l);s.push(I(e,t,"task",g&&d!==void 0?`TODO ${d}`:l,{key:d!==void 0?`task:${d}`:Or(l),order:d,status:Ue(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 d=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");d&&s.push(I(e,t,"next_action",d,{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 Ye(e,t){if(t.length===0)return[];let n=[],r=new Set;function s(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of t){if(i.type==="user_prompt"||i.role==="user"){let c=[];Z(i.data,c);let u=c.map(f=>ee(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 c of Er(i))s(I(e,i,c.kind,c.text,{fileAction:c.fileAction,checkKind:c.checkKind,checkStatus:c.checkStatus,status:c.kind==="test"?c.checkStatus==="passed"?"completed":c.checkStatus==="failed"?"blocked":c.checkStatus==="running"?"in_progress":"pending":void 0,confidence:c.confidence}));if(i.type==="decision"){let c=[];Z(i.data,c);for(let u of c)s(I(e,i,"decision",u,{confidence:1}))}if(i.type==="todo"){let c=[];Z(i.data,c);for(let u of c)s(I(e,i,"task",u,{status:Ue(u),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let c of["filePath","path","file"]){let u=i.data[c];typeof u=="string"&&u&&s(I(e,i,"file",u,{fileAction:"modified",confidence:1}))}if(i.type==="test"){let c=[];Z(i.data,c);for(let u of c)s(I(e,i,"test",u,{confidence:1}))}let a=[];Z(i.data,a);for(let c of a)for(let u of c.split(/\n+/u))for(let f of ic(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 Rr(e){return String(e).padStart(12,"0")}var Xe=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)+`
|
|
54
|
+
`,a=w(n.map(u=>u.id).sort().join("|")).slice(0,16),c=[`projects/${t.projectId}`,"work","observations",t.agent,t.nativeSessionId,`${Rr(r)}-${Rr(s)}-${a}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,i,"application/json"),c}};import{join as Nr}from"node:path";import{mkdirSync as ac}from"node:fs";function Kr(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=Kr(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=t))break}return n.reverse()}function cc(e,t=20){let n=new Map;for(let r of e){let s=`${r.kind}|${Kr(r.command)}`;n.delete(s),n.set(s,r)}return Array.from(n.values()).slice(-t)}function uc(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 _r(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&&uc(t)?e.title:t.text;return{id:e?.id??w(t.key).slice(0,24),title:s,status:r,order:t.order??e?.order,confidence:Math.max(t.confidence,e?.confidence??0),updatedAt:t.occurredAt,updatedBy:{agent:t.agent,nativeSessionId:t.nativeSessionId,eventId:t.eventId}}}async function lc(e,t){let n=`projects/${e.id}/work/observations/`,r=await t.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}async function Qe(e,t){let r=(await lc(e,t)).flatMap(p=>p.observations).sort((p,b)=>{let q=p.occurredAt.localeCompare(b.occurredAt);if(q!==0)return q;let Ht=p.sequence-b.sequence;return Ht!==0?Ht:p.id.localeCompare(b.id)}),s=new Map,o=new Map,i,a,c,u,f,m=[],d=[],l=[],g=[],S=[],y=new Map,h=[],k=[],M=[],E=[],P=[],T=[];for(let p of r)switch(p.kind){case"request":i=p.text;break;case"activity":a=p.text;break;case"goal":c=p.text;break;case"plan":u=p.text;break;case"phase":s.set(p.key,_r(s.get(p.key),p));break;case"task":o.set(p.key,_r(o.get(p.key),p));break;case"decision":m.push(p.text);break;case"blocker":d.push(p.text);break;case"warning":l.push(p.text);break;case"next_action":g.push(p.text);break;case"file":{S.push(p.text);let b=p.fileAction??"active";y.delete(p.text),y.set(p.text,b),b==="modified"?h.push(p.text):b==="created"?k.push(p.text):b==="deleted"&&M.push(p.text);break}case"command":E.push(p.text);break;case"test":P.push(p.text),p.checkKind&&T.push({kind:p.checkKind,command:p.text,status:p.checkStatus??"unknown",updatedAt:p.occurredAt,agent:p.agent,nativeSessionId:p.nativeSessionId});break;case"session":f={agent:p.agent,nativeSessionId:p.nativeSessionId,sessionKey:p.sessionKey,updatedAt:p.occurredAt};break}let x=Array.from(s.values()).sort((p,b)=>(p.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),v=Array.from(o.values()).sort((p,b)=>(p.order??Number.MAX_SAFE_INTEGER)-(b.order??Number.MAX_SAFE_INTEGER)),L=x.find(p=>p.status==="in_progress")??x.find(p=>p.status==="blocked")??x.find(p=>p.status==="pending"),D=v.find(p=>p.status==="in_progress")??v.find(p=>p.status==="blocked")??v.find(p=>p.status==="pending"),ut=$([...g,...D?[D.title]:[],...!D&&L?[L.title]:[],...v.filter(p=>p.status==="pending").slice(0,5).map(p=>p.title)],8),lt=$([...d,...x.filter(p=>p.status==="blocked").map(p=>p.title),...v.filter(p=>p.status==="blocked").map(p=>p.title)],20),ie={version:1,projectId:e.id,projectName:e.name,currentRequest:i,currentActivity:a,goal:c,plan:u,phases:x,tasks:v,decisions:$(m,20),blockers:lt,warnings:$(l,20),nextActions:ut,filesTouched:$(S,30),activeFiles:Array.from(y.entries()).filter(([,p])=>p!=="deleted").map(([p])=>p).slice(-5),modifiedFiles:$(h,30),createdFiles:$(k,30),deletedFiles:$(M,30),commands:$(E,20),tests:$(P,20),checks:cc(T,20),currentPhase:L,currentTask:D,progress:{phasesTotal:x.length,phasesCompleted:x.filter(p=>p.status==="completed").length,tasksTotal:v.length,tasksCompleted:v.filter(p=>p.status==="completed").length,blocked:x.filter(p=>p.status==="blocked").length+v.filter(p=>p.status==="blocked").length},lastSession:f,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},ae=Nr(e.rootPath,".toolnet","work");return ac(ae,{recursive:!0}),O(Nr(ae,"current.json"),ie),await t.put(`projects/${e.id}/work/current.json`,JSON.stringify(ie,null,2)+`
|
|
55
|
+
`,"application/json"),ie}async function $r(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}}function yc(e,t){if(!pc(e))return{events:[],nextOffset:t};let n=gc(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=mc(e,"r");try{fc(i,o,0,s,r)}finally{dc(i)}let a=o.toString("utf8"),c=a.lastIndexOf(`
|
|
56
56
|
`);if(c<0)return{events:[],nextOffset:r};let u=a.slice(0,c+1);return{events:u.split(`
|
|
57
|
-
`).filter(Boolean).flatMap(m=>{try{return[JSON.parse(m)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var
|
|
58
|
-
`,"application/json"),a}};import{mkdirSync as
|
|
59
|
-
`,"application/json"),l}function
|
|
57
|
+
`).filter(Boolean).flatMap(m=>{try{return[JSON.parse(m)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var Ze=class{constructor(t){this.options=t;this.journal=new Xe(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.continuity.offset"]??0),r=yc(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=Ye(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Qe(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{closeSync as Ic,existsSync as Ac,openSync as Cc,readSync as Pc,statSync as Mc}from"node:fs";var hc=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function oe(e){return e.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Tt(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))Tt(r,t,n+1);return}if(!(!e||typeof e!="object"))for(let[r,s]of Object.entries(e))(hc.has(r)||["data","payload","parts","messages"].includes(r))&&Tt(s,t,n+1)}}function N(e,t,n,r,s,o=.95){let i=oe(r);return{version:1,id:w([e.projectId,n,s.type,s.key??"",i.toLowerCase(),t.id].join("|")).slice(0,32),projectId:e.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,eventId:t.id,sourceEventId:t.sourceEventId,sequence:t.sequence,occurredAt:t.timestamp}}}function 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 oe(e.slice(r.length+1))}return null}function Sc(e){let t=e.trimStart();return t.startsWith("- ")||t.startsWith("* ")||/^\d+[.)]\s+/u.test(t)}function kc(e){return oe(e.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function Fr(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=[];Tt(o.data,i);for(let a of i){let c={type:"project"},u=null;for(let f of a.split(/\r?\n/u)){let m=oe(f);if(!m){u=null;continue}let d=m.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(d){let v=Number(d[1]);c={type:"phase",key:`phase:${v}`,order:v,title:oe(d[2]??"")},u=null;continue}let l=m.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(l){let v=Number(l[1]);c={type:"task",key:`task:${v}`,order:v,title:oe(l[2]??"")},u=null;continue}let g=F(m,["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 S=F(m,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(S){s(N(e,o,c.type==="phase"?"phase_objective":"objective",S,c,.98)),u=null;continue}let y=F(m,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(y){s(N(e,o,c.type==="phase"?"phase_why":"why",y,c,.98)),u=null;continue}let h=F(m,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(h){s(N(e,o,"desired_outcome",h,{type:"project"},.98)),u=null;continue}let k=F(m,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(k){s(N(e,o,"plan_rationale",k,{type:"project"},.98)),u=null;continue}let M=F(m,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(M){s(N(e,o,"phase_deliverable",M,c,.97)),u=null;continue}let E=F(m,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(E){s(N(e,o,"acceptance_criterion",E,c,.98)),u="acceptance_criterion";continue}let P=F(m,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(P){s(N(e,o,"dependency",P,c,.97)),u="dependency";continue}let T=F(m,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(T){s(N(e,o,"open_question",T,c,.95)),u="open_question";continue}let x=F(m,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(x){s(N(e,o,"constraint",x,c,.97)),u="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(m)){u="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(m)){u="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(m)){u="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(m)){u="constraint";continue}if(u&&Sc(f)){s(N(e,o,u,kc(f),c,.96));continue}u=null}}}return n}function Wr(e){return String(e).padStart(12,"0")}var et=class{constructor(t){this.storage=t}storage;async write(t,n){if(n.length===0)return null;let r=Math.min(...n.map(c=>c.evidence.sequence)),s=Math.max(...n.map(c=>c.evidence.sequence)),o={version:1,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=w(n.map(c=>c.id).sort().join("|")).slice(0,16),a=[`projects/${t.projectId}`,"work","semantic","observations",t.agent,t.nativeSessionId,`${Wr(r)}-${Wr(s)}-${i}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,JSON.stringify(o,null,2)+`
|
|
58
|
+
`,"application/json"),a}};import{mkdirSync as wc}from"node:fs";import{join as Lr}from"node:path";function vc(e){return{value:e.value,confidence:e.confidence,evidence:e.evidence}}function bc(e,t){if(!t)return!0;let n=e.evidence.occurredAt.localeCompare(t.evidence.occurredAt);return n!==0?n>0:e.evidence.sessionKey===t.evidence.sessionKey?e.evidence.sequence>=t.evidence.sequence:e.confidence>=t.confidence}function V(e,t){return bc(t,e)?t:e}function B(e,t=30){let n=new Set,r=[];for(let s of e){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-t)}async function xc(e,t){let n=`projects/${e.id}/work/semantic/observations/`,r=await t.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,a)=>i.key.localeCompare(a.key))){let i=await t.getText(o.key);if(i)try{let a=JSON.parse(i);a.version===1&&Array.isArray(a.observations)&&s.push(a)}catch{}}return s}function jc(e){return{key:e.scopeKey??`phase:${e.scopeOrder??0}`,order:e.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function Dr(e,t){let r=(await xc(e,t)).flatMap(S=>S.observations).sort((S,y)=>{let h=S.evidence.occurredAt.localeCompare(y.evidence.occurredAt);return h!==0?h:S.evidence.sessionKey===y.evidence.sessionKey?S.evidence.sequence-y.evidence.sequence:S.id.localeCompare(y.id)}),s,o,i,a,c,u=new Map,f=[],m=[],d=[];for(let S of r){let y=vc(S);if(S.scope==="phase"&&S.scopeKey){let h=u.get(S.scopeKey)??jc(S);switch(S.kind){case"phase_objective":h.objective=V(h.objective,y);break;case"phase_why":h.why=V(h.why,y);break;case"phase_deliverable":h.deliverable=V(h.deliverable,y);break;case"acceptance_criterion":h.acceptanceCriteria.push(y);break;case"dependency":h.dependencies.push(y);break;case"open_question":h.openQuestions.push(y);break;case"constraint":h.constraints.push(y);break;case"note":h.notes.push(y);break}u.set(h.key,h);continue}switch(S.kind){case"mission":s=V(s,y);break;case"objective":o=V(o,y);break;case"why":i=V(i,y);break;case"desired_outcome":a=V(a,y);break;case"plan_rationale":c=V(c,y);break;case"open_question":f.push(y);break;case"constraint":m.push(y);break;case"note":d.push(y);break}}for(let S of u.values())S.acceptanceCriteria=B(S.acceptanceCriteria,20),S.dependencies=B(S.dependencies,15),S.openQuestions=B(S.openQuestions,15),S.constraints=B(S.constraints,15),S.notes=B(S.notes,20);let l={version:1,projectId:e.id,projectName:e.name,mission:s,activeObjective:o,why:i,desiredOutcome:a,planRationale:c,phases:Array.from(u.values()).sort((S,y)=>S.order-y.order),openQuestions:B(f,20),constraints:B(m,20),notes:B(d,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},g=Lr(e.rootPath,".toolnet","work");return wc(g,{recursive:!0}),O(Lr(g,"semantic-current.json"),l),await t.put(`projects/${e.id}/work/semantic/current.json`,JSON.stringify(l,null,2)+`
|
|
59
|
+
`,"application/json"),l}function Ec(e,t){if(!Ac(e))return{events:[],nextOffset:t};let n=Mc(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=Cc(e,"r");try{Pc(o,s,0,s.length,r)}finally{Ic(o)}let i=s.toString("utf8"),a=i.lastIndexOf(`
|
|
60
60
|
`);if(a<0)return{events:[],nextOffset:r};let c=i.slice(0,a+1);return{events:c.split(`
|
|
61
|
-
`).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var
|
|
61
|
+
`).filter(Boolean).flatMap(u=>{try{return[JSON.parse(u)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(c,"utf8")}}var tt=class{constructor(t){this.options=t;this.journal=new et(t.storage)}options;journal;async learnNew(){let t=this.options.wal.loadState(),n=Number(t.sourceCursors["work.semantic.offset"]??0),r=Ec(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=Fr(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Dr(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 Zc,mkdirSync as eu}from"node:fs";import{join as Rt}from"node:path";import{existsSync as Hr,mkdirSync as Tc,readFileSync as Oc,statSync as zr,writeFileSync as Rc}from"node:fs";import{dirname as Nc,join as _c}from"node:path";var qr=64*1024,Kc=`# ToolNet Project Operating Manual
|
|
62
62
|
|
|
63
63
|
This file contains persistent instructions for AI agents working on this project.
|
|
64
64
|
|
|
@@ -101,14 +101,14 @@ Things an AI agent should always remember.
|
|
|
101
101
|
<!--
|
|
102
102
|
- [advisory] Prefer small focused files.
|
|
103
103
|
-->
|
|
104
|
-
`;function
|
|
105
|
-
`,{encoding:"utf8",mode:384})
|
|
106
|
-
`).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function
|
|
104
|
+
`;function Jr(e){return _c(e.rootPath,".toolnet","PROJECT.md")}function $c(e){return e.normalize("NFKC").replace(/\s+/g," ").trim()}function Fc(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=$c(s[2]);if(!i)continue;let a=`${o}:${i.toLowerCase()}`;n.has(a)||(n.add(a),t.push({id:w(a).slice(0,24),mode:o,text:i,source:"manual"}))}return t}function Wc(e){let t=Jr(e);return Hr(t)||(Tc(Nc(t),{recursive:!0}),Rc(t,Kc,{encoding:"utf8",mode:384})),t}function Vr(e,t=!1){let n=t?Wc(e):Jr(e);if(!Hr(n))return null;if(zr(n).size>qr)throw new Error(`PROJECT.md exceeds ${qr} bytes`);let s=Oc(n,"utf8");return{path:n,content:s,digest:w(s),rules:Fc(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(zr(n).mtimeMs).toISOString()}}import{existsSync as Lc,mkdirSync as Dc,readFileSync as zc,renameSync as qc,writeFileSync as Hc}from"node:fs";import{dirname as Jc,join as Vc}from"node:path";function Bc(e,t){Dc(Jc(e),{recursive:!0});let n=`${e}.tmp-${process.pid}-${Date.now()}`;Hc(n,`${JSON.stringify(t,null,2)}
|
|
105
|
+
`,{encoding:"utf8",mode:384}),qc(n,e)}function Qr(e){return Vc(e.rootPath,".toolnet","work","current.json")}function Ot(e){let t=Qr(e);if(!Lc(t))return null;try{let n=JSON.parse(zc(t,"utf8"));return n.version!==1||n.projectId!==e.id?null:n}catch{return null}}function nt(e){return e.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(e,t,n){let r=[],s=new Set;for(let o of[...e,...t].reverse()){let i=nt(o);if(!(!i||s.has(i))&&(s.add(i),r.push(o),r.length>=n))break}return r.reverse()}function Gc(e,t,n=20){let r=new Map;for(let s of[...e,...t]){let o=`${s.kind}|${nt(s.command)}`;r.delete(o),r.set(o,s)}return Array.from(r.values()).slice(-n)}function Uc(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 Br(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&&Uc(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 Gr(e){let t=new Map;for(let n of e){let r=n.order!==void 0?`order:${n.order}`:nt(n.title);t.set(r,n)}return t}function Ur(e){return e.order!==void 0?`order:${e.order}`:nt(e.key||e.text)}function Yr(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 Xr(e){return e.find(t=>t.status==="in_progress")??e.find(t=>t.status==="blocked")??e.find(t=>t.status==="pending")}function Zr(e,t){let n=Ot(e),r=Gr(n?.phases??[]),s=Gr(n?.tasks??[]),o=n?.currentRequest,i=n?.currentActivity,a=n?.goal,c=n?.plan,u=n?.lastSession,f=[],m=[],d=[],l=[],g=[],S=[...n?.activeFiles??[]],y=[],h=[],k=[],M=[],E=[],P=[],T=[...t].sort((p,b)=>{let q=p.occurredAt.localeCompare(b.occurredAt);return q!==0?q:p.sequence-b.sequence});for(let p of T)switch(p.kind){case"request":o=p.text;break;case"activity":i=p.text;break;case"goal":a=p.text;break;case"plan":c=p.text;break;case"phase":{let b=Ur(p);r.set(b,Br(r.get(b),p));break}case"task":{let b=Ur(p);s.set(b,Br(s.get(b),p));break}case"decision":f.push(p.text);break;case"blocker":m.push(p.text);break;case"warning":d.push(p.text);break;case"next_action":l.push(p.text);break;case"file":{g.push(p.text);let b=p.fileAction??"active",q=S.indexOf(p.text);q>=0&&S.splice(q,1),b!=="deleted"&&S.push(p.text),b==="modified"?y.push(p.text):b==="created"?h.push(p.text):b==="deleted"&&k.push(p.text);break}case"command":M.push(p.text);break;case"test":E.push(p.text),p.checkKind&&P.push({kind:p.checkKind,command:p.text,status:p.checkStatus??"unknown",updatedAt:p.occurredAt,agent:p.agent,nativeSessionId:p.nativeSessionId});break;case"session":u={agent:p.agent,nativeSessionId:p.nativeSessionId,sessionKey:p.sessionKey,updatedAt:p.occurredAt};break}let x=Yr(r.values()),v=Yr(s.values()),L=Xr(x),D=Xr(v),ut=_(n?.nextActions??[],[...l,...D?[D.title]:[],...!D&&L?[L.title]:[],...v.filter(p=>p.status==="pending").slice(0,5).map(p=>p.title)],8),lt=_(n?.blockers??[],[...m,...x.filter(p=>p.status==="blocked").map(p=>p.title),...v.filter(p=>p.status==="blocked").map(p=>p.title)],20),ie=T.length>0?T[T.length-1].occurredAt:n?.updatedAt??new Date().toISOString(),ae={version:1,projectId:e.id,projectName:e.name,currentRequest:o,currentActivity:i,goal:a,plan:c,phases:x,tasks:v,decisions:_(n?.decisions??[],f,20),blockers:lt,warnings:_(n?.warnings??[],d,20),nextActions:ut,filesTouched:_(n?.filesTouched??[],g,30),activeFiles:_([],S,5),modifiedFiles:_(n?.modifiedFiles??[],y,30),createdFiles:_(n?.createdFiles??[],h,30),deletedFiles:_(n?.deletedFiles??[],k,30),commands:_(n?.commands??[],M,20),tests:_(n?.tests??[],E,20),checks:Gc(n?.checks??[],P,20),currentPhase:L,currentTask:D,progress:{phasesTotal:x.length,phasesCompleted:x.filter(p=>p.status==="completed").length,tasksTotal:v.length,tasksCompleted:v.filter(p=>p.status==="completed").length,blocked:x.filter(p=>p.status==="blocked").length+v.filter(p=>p.status==="blocked").length},lastSession:u,updatedAt:ie};return Bc(Qr(e),ae),ae}function A(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 es(e){if(e)return{id:e.id,title:e.title,status:e.status}}function Yc(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(`
|
|
106
|
+
`).toLowerCase();return/(?:failed|failing|failure|error|✗|❌)/u.test(r)?"failing":/(?:passed|passing|green|success|✓|✅)/u.test(r)?"passing":"unknown"}function Xc(e){return w(JSON.stringify(e))}function Qc(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 A(t,30)}function ts(e){let{project:t,identity:n,state:r}=e,s=r.activeFiles?.at(-1)??r.filesTouched.at(-1),o=r.phases.filter(k=>k.status==="completed").map(k=>k.title),i=r.tasks.filter(k=>k.status==="completed").map(k=>k.title),a=r.phases.filter(k=>k.status!=="completed"&&k.status!=="cancelled").map(k=>k.title),c=r.tasks.filter(k=>k.status!=="completed"&&k.status!=="cancelled").map(k=>k.title),u=new Set(r.tasks.filter(k=>k.status==="completed").map(k=>k.title.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),f=A(r.nextActions.filter(k=>!u.has(k.normalize("NFKC").toLowerCase().replace(/\s+/gu," ").trim())),10),m=A([...c,...f],15),d=A(r.tests.slice().reverse(),10),l=A([...(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:es(r.currentPhase),task:es(r.currentTask),file:s},completed:{phases:A(o,20),tasks:A(i,30)},remaining:{phases:A(a,20),tasks:A(c,30),todos:m},nextAction:f[0],blockers:A(r.blockers.slice().reverse(),10),decisions:A(r.decisions.slice().reverse(),10),files:{current:s,recent:l,active:A(r.activeFiles??[],10),modified:A(r.modifiedFiles??[],20),created:A(r.createdFiles??[],20),deleted:A(r.deletedFiles??[],20)},tests:{status:Yc(r.tests,r.checks),recent:d,checks:(r.checks??[]).slice(-10).map(k=>({kind:k.kind,status:k.status,command:k.command}))},evidence:{commands:A((r.commands??[]).slice().reverse(),20),references:Qc([r.currentRequest,r.currentActivity,r.goal,r.plan,...r.decisions,...r.blockers,...r.warnings,...r.nextActions,...r.filesTouched,...r.commands??[],...r.tests,...(r.checks??[]).map(k=>k.command)])},attention:A(e.attention??[],20),progress:r.progress},{capturedAt:S,source:y,...h}=g;return{...g,stateDigest:Xc(h)}}function tu(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 ns(e,t,n,r,s){if(!tu(n))return null;let o=Vr(e,!1),a=[...o?o.rules.filter(m=>m.mode==="enforce").map(m=>m.text):[],...n.warnings].slice(0,20),c=ts({project:e,identity:t,state:n,reason:r,sequence:s,attention:a}),u=c.stateDigest;return{version:1,id:w([e.id,t.sessionKey,u].join("|")).slice(0,24),projectId:e.id,projectName:e.name,createdAt:new Date().toISOString(),reason:r,sourceSession:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,sequence:s},currentRequest:n.currentRequest,currentActivity:n.currentActivity,goal:n.goal,plan:n.plan,progress:n.progress,currentPhase:n.currentPhase,currentTask:n.currentTask,incompletePhases:n.phases.filter(m=>m.status!=="completed"&&m.status!=="cancelled"),incompleteTasks:n.tasks.filter(m=>m.status!=="completed"&&m.status!=="cancelled"),nextActions:c.remaining.todos.slice(0,10),blockers:n.blockers.slice(-10),decisions:n.decisions.slice(-10),warnings:n.warnings.slice(-10),attention:a,filesTouched:n.filesTouched.slice(-20),activeFiles:n.activeFiles?.slice(-10),modifiedFiles:n.modifiedFiles?.slice(-20),createdFiles:n.createdFiles?.slice(-20),deletedFiles:n.deletedFiles?.slice(-20),tests:n.tests.slice(-15),checks:n.checks?.slice(-10),stateDigest:u,continuity:c}}function rs(e,t){let n=Rt(e.rootPath,".toolnet","work","handoffs");eu(n,{recursive:!0});let r=Rt(n,`${t.id}.json`);Zc(r)||O(r,t),O(Rt(e.rootPath,".toolnet","work","handoff-latest.json"),t)}function ss(e){let t=ns(e.project,e.identity,e.state,e.reason,e.sequence);return t?(rs(e.project,t),t):null}var rt=class{constructor(t){this.options=t}options;async capture(t,n){let r=Ot(this.options.project);r||(r=await $r(this.options.project,this.options.storage)),r||(r=await Qe(this.options.project,this.options.storage));let s=ns(this.options.project,this.options.identity,r,t,n);if(!s)return null;rs(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)+`
|
|
107
107
|
`,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(s,null,2)+`
|
|
108
|
-
`,"application/json"),s}};import{existsSync as
|
|
109
|
-
`)}function
|
|
108
|
+
`,"application/json"),s}};import{existsSync as nu,readFileSync as ru,writeFileSync as su}from"node:fs";import{join as ou}from"node:path";var is="<!-- TOOLNET:STABLE-WORK:BEGIN -->",Nt="<!-- TOOLNET:STABLE-WORK:END -->";function _t(e){switch(e.status){case"completed":return"[x]";case"in_progress":return"[~]";case"blocked":return"[!]";case"cancelled":return"[-]";default:return"[ ]"}}function W(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${n}`)]:[]}function os(e,t){return t.length?["",`${e}:`,...t.map(n=>`- ${_t(n)} ${n.title}`)]:[]}function iu(e){let t=[is,"# 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:",`${_t(e.currentPhase)} ${e.currentPhase.title}`),e.currentTask&&t.push("","Current task:",`${_t(e.currentTask)} ${e.currentTask.title}`),t.push(...os("Phases",e.phases)),t.push(...os("TODO / Tasks",e.tasks)),t.push(...W("Next actions",e.nextActions)),t.push(...W("Blockers",e.blockers)),t.push(...W("Important decisions",e.decisions)),t.push(...W("Active files",e.activeFiles??[])),t.push(...W("Modified files",e.modifiedFiles??[])),t.push(...W("Created files",e.createdFiles??[])),t.push(...W("Deleted files",e.deletedFiles??[])),t.push(...W("Files touched",e.filesTouched)),t.push(...W("Recent commands",e.commands??[])),t.push(...W("Checks",(e.checks??[]).map(n=>`[${n.status}] ${n.kind}: ${n.command}`))),t.push("","Progress:",`- Phases: ${e.progress.phasesCompleted}/${e.progress.phasesTotal}`,`- Tasks: ${e.progress.tasksCompleted}/${e.progress.tasksTotal}`,`- Blocked: ${e.progress.blocked}`,"","Continuation:","- Resume current unfinished task.","- Never redo completed TODO/Phase unless explicitly requested.","- Ask ToolNet Memory for deeper history only when necessary.",Nt),t.join(`
|
|
109
|
+
`)}function as(e,t){let n=ou(e.rootPath,".toolnet","current.md"),r="";if(nu(n))try{r=ru(n,"utf8")}catch{r=""}r=r.replace(/<!-- TOOLNET:AUTO-CURRENT:BEGIN -->[\s\S]*?<!-- TOOLNET:AUTO-CURRENT:END -->/gu,"");let s=iu(t),o=r.indexOf(is),i=r.indexOf(Nt),a;o>=0&&i>=o?a=[r.slice(0,o).trimEnd(),s,r.slice(i+Nt.length).trimStart()].filter(Boolean).join(`
|
|
110
110
|
|
|
111
111
|
`):a=r.trim()?`${r.trim()}
|
|
112
112
|
|
|
113
|
-
${s}`:s,
|
|
114
|
-
`,{encoding:"utf8",mode:384})}import{existsSync as os,mkdirSync as eu,readFileSync as tu}from"node:fs";import{join as Nt}from"node:path";function is(e){return Nt(e.rootPath,".toolnet","memory","checkpoints")}function as(e){return Nt(is(e),"latest.json")}function nu(e){let t=as(e);if(!os(t))return null;try{let n=JSON.parse(tu(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function ru(e){return["rule","architecture","decision","fix"].includes(e)}function su(e,t){return t.length===0?[]:Fe(e,t).candidates.filter(r=>ru(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 ou(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 iu(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 cs(e,t,n,r){let s=nu(e),o=ou(s?.durableFacts??[],su(t,n)),i=n.at(-1)?.sequence??s?.source.sequence??0,a=r.phases.filter(y=>y.status==="completed").map(y=>y.title),c=r.tasks.filter(y=>y.status==="completed").map(y=>y.title),u=r.phases.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),f=r.tasks.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),m={work:iu(r),durableFacts:o.map(y=>y.fingerprint).sort()},d=w(JSON.stringify(m)).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:a,tasks:c},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:d},g=is(e);eu(g,{recursive:!0,mode:448});let S=Nt(g,`${d}.json`);return os(S)||T(S,l),T(as(e),l),l}function rt(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=Ue(t,n);if(r.length===0)return{updated:!1,observations:0};let s=Yr(e,r);ss(e,s),An(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:s});try{cs(e,t,n,s)}catch{}try{ts({project:e,identity:t,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var st=class{identity;wal;remote;sanitizer=new B;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=Ke(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new te(this.identity,t.eventContext),this.remote=new $e(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new Be({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new Qe({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new et({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new nt({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{rt(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)}};var ot=4e3,_t=20,Kt=30,us=4,$t=20;function Wt(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function it(e,t=0){if(t>=us)return typeof e=="string"?e.length>ot?`${e.slice(0,ot)}\u2026`:e:Array.isArray(e)?`[array:${e.length}]`:Wt(e)?`[object:${Object.keys(e).length}]`:e;if(typeof e=="string")return e.length>ot?`${e.slice(0,ot)}\u2026`:e;if(Array.isArray(e)){let n=e.slice(0,_t).map(r=>it(r,t+1));return e.length>_t&&n.push(`[+${e.length-_t} items]`),n}if(Wt(e)){let n={},r=Object.entries(e);for(let[s,o]of r.slice(0,Kt))n[s]=it(o,t+1);return r.length>Kt&&(n.__truncatedKeys=r.length-Kt),n}return e}function Ft(e,t,n=0){if(!(n>us||t.size>=$t)){if(Array.isArray(e)){for(let r of e)if(Ft(r,t,n+1),t.size>=$t)break;return}if(Wt(e))for(let[r,s]of Object.entries(e)){let o=r.toLowerCase().replace(/[^a-z]/g,"");if((o==="path"||o==="filepath"||o==="filename")&&typeof s=="string"&&s.trim()&&t.add(s.trim()),Ft(s,t,n+1),t.size>=$t)break}}}function xe(e){try{return w(Ie(e)).slice(0,20)}catch{return w(String(e)).slice(0,20)}}function au(e){if(typeof e=="number"&&Number.isFinite(e)){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}if(typeof e=="string"&&e.trim()){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}return new Date().toISOString()}function cu(e,t){let n=(e??"").toLowerCase();return n==="read"||n==="view"||n.includes("read_file")||n.includes("list_dir")||n.includes("listdir")||n.includes("grep")||n.includes("glob")||n.includes("search")?null:t.length>0&&(n.includes("edit")||n.includes("patch")||n.includes("replace"))?"file_edit":t.length>0&&(n.includes("write")||n.includes("create")||n.includes("delete"))?"file_write":n.includes("bash")||n.includes("shell")||n.includes("terminal")||n.includes("command")||n.includes("execute")?"command":"tool_result"}function Lt(e,t){let r={timestamp:au(e.timestamp),cwd:e.cwd,source:e.agent,provenance:{source:`${e.agent}-hook`}};if(e.event==="SessionStart")return[{...r,type:"session_start",sourceEventId:`${e.agent}:${e.sessionId}:start`,data:{sessionId:e.sessionId,cwd:e.cwd}}];if(e.event==="UserPromptSubmit"){let s=e.prompt?.trim();return s?[{...r,type:"user_prompt",role:"user",sourceEventId:`${e.agent}:${e.sessionId}:prompt:`+xe(s),data:{content:s}}]:[]}if(e.event==="PostToolUse"){let s=new Set;Ft(e.toolInput,s);let o=[...s],i=cu(e.toolName,o);if(!i)return[];let a=it(e.toolInput),c=it(e.toolResponse);return[{...r,type:i,sourceEventId:[e.agent,e.sessionId,"tool",xe({toolName:e.toolName,input:a,response:c})].join(":"),data:{tool:e.toolName,input:a,response:c,files:o},provenance:{source:`${e.agent}-hook`,files:o.length>0?o:void 0}}]}if(e.event==="AssistantMessage"){let s=e.assistantResponse?.trim();return s?[{...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+xe(s),data:{content:s}}]:[]}if(e.event==="Stop"){let s=[],o=e.assistantResponse?.trim();return o&&s.push({...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+xe(o),data:{content:o}}),s.push({...r,type:"session_idle",sourceEventId:`${e.agent}:${e.sessionId}:idle:`+xe({sessionId:e.sessionId,response:o??""}),data:{sessionId:e.sessionId}}),s}return[]}function du(e){let t=on(e);if(!t||!uu(lu(t,".toolnet","project.json")))return null;try{return new Ee().detect(t)}catch{return null}}function pu(e,t){let n=Lt(t,e);if(n.length===0)return 0;let r=Ke(e,t.agent,t.sessionId),o=new te(r,{source:t.agent,cwd:t.cwd}).append(n);return rt(e,r,o),o.length}async function mu(e,t,n,r){let s=Pe(),o=vn(kn({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),{attempts:2}),i=new Ne(o,e.id,e.name,e.remote??e.name);await new st({project:e,storage:i,agent:t,nativeSessionId:n,metadata:{source:`${t}-hook`},eventContext:{source:t,cwd:r}}).flush()}async function ls(e,t={}){if(!e.cwd||!e.sessionId)return{active:!1,captured:0,flushed:!1};let n=du(e.cwd);if(!n)return{active:!1,captured:0,flushed:!1};let r=0;try{r=pu(n,e)}catch(o){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:0,flushed:!1,error:o instanceof Error?o.message:String(o)}}if(e.event==="PostToolUse"||e.event==="AssistantMessage"||e.event==="Stop")try{Cn(n)}catch{}if(e.event!=="Stop")return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1};let s=t.flushSession??mu;try{return await s(n,e.agent,e.sessionId,e.cwd),{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!0}}catch(o){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1,error:o instanceof Error?o.message:String(o)}}}function ds(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function je(...e){for(let t of e){let n=ds(t);if(n)return n}}function fu(e){switch(ds(e)){case"SessionStart":case"sessionStart":case"session_start":return"SessionStart";case"UserPromptSubmit":case"userPromptSubmit":case"user_prompt_submit":return"UserPromptSubmit";case"PostToolUse":case"postToolUse":case"post_tool_use":return"PostToolUse";case"Stop":case"stop":return"Stop";default:return null}}function ps(e,t=process.env){let n=fu(t.TOOLNET_HOOK_EVENT??e.hookEventName??e.hook_event_name);if(!n)return null;let r=je(e.sessionId,e.session_id,t.GROK_SESSION_ID),s=je(e.cwd,e.workspaceRoot,t.GROK_WORKSPACE_ROOT,t.CLAUDE_PROJECT_DIR);return!r||!s?null:{agent:"grok",event:n,sessionId:r,cwd:s,timestamp:typeof e.timestamp=="string"||typeof e.timestamp=="number"?e.timestamp:void 0,prompt:je(e.prompt),toolName:je(e.toolName,e.tool_name),toolInput:e.toolInput??e.tool_input,toolResponse:e.toolResult??e.tool_result??e.toolResponse,assistantResponse:je(e.response,e.assistantResponse,e.lastAssistantMessage)}}async function ms(e,t={},n=process.env){let r=ps(e,n);return r?ls(r,t):{active:!1,captured:0,flushed:!1}}async function gu(){let e="";for await(let t of process.stdin)e+=t.toString();if(!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}async function yu(){let e=await gu(),t=un(e);if(t==="PreToolUse"||t==="preToolUse"||t==="pre_tool_use"){let n=ln(e);n.blocked&&process.stdout.write(JSON.stringify(dn(n.reason??"ToolNet continuity guard blocked this tool.")));return}await ms(e)}yu().catch(()=>{process.exitCode=0});
|
|
113
|
+
${s}`:s,su(n,`${a.trim()}
|
|
114
|
+
`,{encoding:"utf8",mode:384})}import{existsSync as cs,mkdirSync as au,readFileSync as cu}from"node:fs";import{join as Kt}from"node:path";function us(e){return Kt(e.rootPath,".toolnet","memory","checkpoints")}function ls(e){return Kt(us(e),"latest.json")}function uu(e){let t=ls(e);if(!cs(t))return null;try{let n=JSON.parse(cu(t,"utf8"));return n.schema!=="toolnet.memory.checkpoint.v1"||n.project.id!==e.id?null:n}catch{return null}}function lu(e){return["rule","architecture","decision","fix"].includes(e)}function du(e,t){return t.length===0?[]:Le(e,t).candidates.filter(r=>lu(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 pu(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 mu(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 ds(e,t,n,r){let s=uu(e),o=pu(s?.durableFacts??[],du(t,n)),i=n.at(-1)?.sequence??s?.source.sequence??0,a=r.phases.filter(y=>y.status==="completed").map(y=>y.title),c=r.tasks.filter(y=>y.status==="completed").map(y=>y.title),u=r.phases.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),f=r.tasks.filter(y=>y.status!=="completed"&&y.status!=="cancelled").map(y=>y.title),m={work:mu(r),durableFacts:o.map(y=>y.fingerprint).sort()},d=w(JSON.stringify(m)).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:a,tasks:c},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:d},g=us(e);au(g,{recursive:!0,mode:448});let S=Kt(g,`${d}.json`);return cs(S)||O(S,l),O(ls(e),l),l}function st(e,t,n){if(process.env.TOOLNET_LOCAL_CHECKPOINT==="0"||n.length===0)return{updated:!1,observations:0};let r=Ye(t,n);if(r.length===0)return{updated:!1,observations:0};let s=Zr(e,r);as(e,s),Pn(e,{agent:t.agent,nativeSessionId:t.nativeSessionId,observations:r,workState:s});try{ds(e,t,n,s)}catch{}try{ss({project:e,identity:t,state:s,reason:"continuous-checkpoint",sequence:n.at(-1)?.sequence??0})}catch{}return{updated:!0,observations:r.length}}var ot=class{identity;wal;remote;sanitizer=new G;learner;continuity;semantic;handoff;project;title;metadata;constructor(t){this.project=t.project,this.identity=$e(t.project,t.agent,t.nativeSessionId),this.title=t.title,this.metadata=this.sanitizer.sanitizeValue(t.metadata??{}),this.wal=new ne(this.identity,t.eventContext),this.remote=new Fe(t.storage,t.maxEventsPerChunk??100,t.maxChunkBytes??512*1024),this.learner=new Ge({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.continuity=new Ze({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.semantic=new tt({project:t.project,storage:t.storage,identity:this.identity,wal:this.wal}),this.handoff=new rt({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{st(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)}};var it=4e3,$t=20,Ft=30,ps=4,Wt=20;function Lt(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function at(e,t=0){if(t>=ps)return typeof e=="string"?e.length>it?`${e.slice(0,it)}\u2026`:e:Array.isArray(e)?`[array:${e.length}]`:Lt(e)?`[object:${Object.keys(e).length}]`:e;if(typeof e=="string")return e.length>it?`${e.slice(0,it)}\u2026`:e;if(Array.isArray(e)){let n=e.slice(0,$t).map(r=>at(r,t+1));return e.length>$t&&n.push(`[+${e.length-$t} items]`),n}if(Lt(e)){let n={},r=Object.entries(e);for(let[s,o]of r.slice(0,Ft))n[s]=at(o,t+1);return r.length>Ft&&(n.__truncatedKeys=r.length-Ft),n}return e}function Dt(e,t,n=0){if(!(n>ps||t.size>=Wt)){if(Array.isArray(e)){for(let r of e)if(Dt(r,t,n+1),t.size>=Wt)break;return}if(Lt(e))for(let[r,s]of Object.entries(e)){let o=r.toLowerCase().replace(/[^a-z]/g,"");if((o==="path"||o==="filepath"||o==="filename")&&typeof s=="string"&&s.trim()&&t.add(s.trim()),Dt(s,t,n+1),t.size>=Wt)break}}}function je(e){try{return w(Ce(e)).slice(0,20)}catch{return w(String(e)).slice(0,20)}}function fu(e){if(typeof e=="number"&&Number.isFinite(e)){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}if(typeof e=="string"&&e.trim()){let t=new Date(e);if(!Number.isNaN(t.getTime()))return t.toISOString()}return new Date().toISOString()}function gu(e,t){let n=(e??"").toLowerCase();return n==="read"||n==="view"||n.includes("read_file")||n.includes("list_dir")||n.includes("listdir")||n.includes("grep")||n.includes("glob")||n.includes("search")?null:t.length>0&&(n.includes("edit")||n.includes("patch")||n.includes("replace"))?"file_edit":t.length>0&&(n.includes("write")||n.includes("create")||n.includes("delete"))?"file_write":n.includes("bash")||n.includes("shell")||n.includes("terminal")||n.includes("command")||n.includes("execute")?"command":"tool_result"}function zt(e,t){let r={timestamp:fu(e.timestamp),cwd:e.cwd,source:e.agent,provenance:{source:`${e.agent}-hook`}};if(e.event==="SessionStart")return[{...r,type:"session_start",sourceEventId:`${e.agent}:${e.sessionId}:start`,data:{sessionId:e.sessionId,cwd:e.cwd}}];if(e.event==="UserPromptSubmit"){let s=e.prompt?.trim();return s?[{...r,type:"user_prompt",role:"user",sourceEventId:`${e.agent}:${e.sessionId}:prompt:`+je(s),data:{content:s}}]:[]}if(e.event==="PostToolUse"){let s=new Set;Dt(e.toolInput,s);let o=[...s],i=gu(e.toolName,o);if(!i)return[];let a=at(e.toolInput),c=at(e.toolResponse);return[{...r,type:i,sourceEventId:[e.agent,e.sessionId,"tool",je({toolName:e.toolName,input:a,response:c})].join(":"),data:{tool:e.toolName,input:a,response:c,files:o},provenance:{source:`${e.agent}-hook`,files:o.length>0?o:void 0}}]}if(e.event==="AssistantMessage"){let s=e.assistantResponse?.trim();return s?[{...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+je(s),data:{content:s}}]:[]}if(e.event==="Stop"){let s=[],o=e.assistantResponse?.trim();return o&&s.push({...r,type:"assistant_message",role:"assistant",sourceEventId:`${e.agent}:${e.sessionId}:assistant:`+je(o),data:{content:o}}),s.push({...r,type:"session_idle",sourceEventId:`${e.agent}:${e.sessionId}:idle:`+je({sessionId:e.sessionId,response:o??""}),data:{sessionId:e.sessionId}}),s}return[]}function Su(e){let t=un(e);if(!t||!yu(hu(t,".toolnet","project.json")))return null;try{return new Te().detect(t)}catch{return null}}function ku(e,t){let n=zt(t,e);if(n.length===0)return 0;let r=$e(e,t.agent,t.sessionId),o=new ne(r,{source:t.agent,cwd:t.cwd}).append(n);return st(e,r,o),o.length}async function wu(e,t,n,r){let s=Me(),o=jn(bn({provider:s.storage.provider,huggingface:s.storage.huggingface,localRoot:s.storage.localRoot}),{attempts:2}),i=new _e(o,e.id,e.name,e.remote??e.name);await new ot({project:e,storage:i,agent:t,nativeSessionId:n,metadata:{source:`${t}-hook`},eventContext:{source:t,cwd:r}}).flush()}async function ms(e,t={}){if(!e.cwd||!e.sessionId)return{active:!1,captured:0,flushed:!1};let n=Su(e.cwd);if(!n)return{active:!1,captured:0,flushed:!1};let r=0;try{r=ku(n,e)}catch(o){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:0,flushed:!1,error:o instanceof Error?o.message:String(o)}}if(e.event==="PostToolUse"||e.event==="AssistantMessage"||e.event==="Stop")try{En(n)}catch{}if(e.event!=="Stop")return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1};let s=t.flushSession??wu;try{return await s(n,e.agent,e.sessionId,e.cwd),{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!0}}catch(o){return{active:!0,projectRoot:n.rootPath,sessionId:e.sessionId,captured:r,flushed:!1,error:o instanceof Error?o.message:String(o)}}}function fs(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function Ie(...e){for(let t of e){let n=fs(t);if(n)return n}}function vu(e){switch(fs(e)){case"SessionStart":case"sessionStart":case"session_start":return"SessionStart";case"UserPromptSubmit":case"userPromptSubmit":case"user_prompt_submit":return"UserPromptSubmit";case"PostToolUse":case"postToolUse":case"post_tool_use":return"PostToolUse";case"Stop":case"stop":return"Stop";default:return null}}function gs(e,t=process.env){let n=vu(t.TOOLNET_HOOK_EVENT??e.hookEventName??e.hook_event_name);if(!n)return null;let r=Ie(e.sessionId,e.session_id,t.GROK_SESSION_ID),s=Ie(e.cwd,e.workspaceRoot,t.GROK_WORKSPACE_ROOT,t.CLAUDE_PROJECT_DIR);return!r||!s?null:{agent:"grok",event:n,sessionId:r,cwd:s,timestamp:typeof e.timestamp=="string"||typeof e.timestamp=="number"?e.timestamp:void 0,prompt:Ie(e.prompt),toolName:Ie(e.toolName,e.tool_name),toolInput:e.toolInput??e.tool_input,toolResponse:e.toolResult??e.tool_result??e.toolResponse,assistantResponse:Ie(e.response,e.assistantResponse,e.lastAssistantMessage)}}async function ys(e,t={},n=process.env){let r=gs(e,n);return r?ms(r,t):{active:!1,captured:0,flushed:!1}}import{createHash as bu}from"node:crypto";import{closeSync as xu,existsSync as ju,mkdirSync as Iu,openSync as Au,readFileSync as Cu,rmSync as Pu,statSync as hs,writeFileSync as Mu}from"node:fs";import{tmpdir as Eu}from"node:os";import{join as Ss}from"node:path";function C(e){return typeof e=="string"&&e.trim()?e.trim():void 0}function qt(e){if(Array.isArray(e))return e.map(qt);if(e&&typeof e=="object"){let t=e;return Object.fromEntries(Object.keys(t).sort().map(n=>[n,qt(t[n])]))}return e}function ct(e){return C(e.sessionId)??C(e.session_id)??C(e.conversation_id)??C(e.conversationId)??"unknown-session"}function Tu(e){return C(e.toolUseId)??C(e.tool_use_id)??C(e.toolCallId)??C(e.tool_call_id)??C(e.callId)??C(e.call_id)??C(e.generation_id)??C(e.generationId)}function Ou(e){return C(e.prompt)??C(e.userPrompt)??C(e.user_prompt)??C(e.originalPrompt)??C(e.original_prompt)}function Ru(e){let t=e.timestamp;return typeof t=="string"||typeof t=="number"?String(t):void 0}function Nu(e){let t=Tu(e.input),n=Ou(e.input),r=Ru(e.input),s=t?{agent:e.agent,event:e.event,session:ct(e.input),nativeId:t}:n?{agent:e.agent,event:e.event,session:ct(e.input),prompt:n,timestamp:r}:{agent:e.agent,event:e.event,session:ct(e.input),input:qt(e.input)};return bu("sha256").update(JSON.stringify(s)).digest("hex")}function _u(e){return e.directory??Ss(Eu(),"toolnet-memory-hook-dedupe")}function Ku(e){try{let t=JSON.parse(Cu(e,"utf8"));return typeof t.createdAt=="number"?t.createdAt:hs(e).mtimeMs}catch{try{return hs(e).mtimeMs}catch{return}}}function $u(e,t,n){let r=Ku(e);return r===void 0||t-r>n}function ks(e){let t=e.ttlMs??1e4,n=e.nowMs??Date.now(),r=_u(e),s=Nu(e),o=Ss(r,`${s}.json`);Iu(r,{recursive:!0,mode:448});for(let i=0;i<2;i+=1)try{let a=Au(o,"wx",384);try{Mu(a,JSON.stringify({createdAt:n,agent:e.agent,event:e.event,sessionId:ct(e.input)}),"utf8")}finally{xu(a)}return{duplicate:!1,key:s,file:o}}catch(a){if((a&&typeof a=="object"&&"code"in a?String(a.code):"")!=="EEXIST")throw a;if(i===0&&ju(o)&&$u(o,n,t)){Pu(o,{force:!0});continue}return{duplicate:!0,key:s,file:o}}return{duplicate:!0,key:s,file:o}}async function Fu(){let e="";for await(let t of process.stdin)e+=t.toString();if(!e.trim())return{};try{return JSON.parse(e)}catch{return{}}}async function Wu(){let e=await Fu(),t=pn(e);if(t==="PreToolUse"||t==="preToolUse"||t==="pre_tool_use"){let n=mn(e);n.blocked&&process.stdout.write(JSON.stringify(fn(n.reason??"ToolNet continuity guard blocked this tool.")));return}t&&ks({agent:"grok",event:t,input:e,directory:process.env.TOOLNET_HOOK_DEDUPE_DIR}).duplicate||await ys(e)}Wu().catch(()=>{process.exitCode=0});
|