toolnet-memory 0.3.16 → 0.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/.env.example +74 -0
  2. package/.release-target +1 -1
  3. package/README.md +165 -7
  4. package/bin/toolnet-memory +12 -0
  5. package/bundle/agy-hook.js +59 -59
  6. package/bundle/agy.js +58 -58
  7. package/bundle/api.js +15 -15
  8. package/bundle/audit.js +2 -0
  9. package/bundle/background-refresh.js +7 -7
  10. package/bundle/code-capabilities.js +2 -0
  11. package/bundle/codex.js +63 -63
  12. package/bundle/context-runtime.js +41 -41
  13. package/bundle/context.js +15 -15
  14. package/bundle/copilot-hook.js +73 -73
  15. package/bundle/cursor-hook.js +73 -73
  16. package/bundle/docker-healthcheck.js +3 -0
  17. package/bundle/doctor.js +4 -4
  18. package/bundle/full-index.js +20 -19
  19. package/bundle/gc.js +5 -3
  20. package/bundle/graph-cli.js +1 -1
  21. package/bundle/graph-index.js +5 -4
  22. package/bundle/graph-ui.js +4 -3
  23. package/bundle/grok-hook.js +52 -52
  24. package/bundle/handoff-refresh.js +2 -2
  25. package/bundle/help-cli.js +4 -4
  26. package/bundle/impact.js +5 -4
  27. package/bundle/incremental.js +5 -5
  28. package/bundle/init.js +35 -35
  29. package/bundle/kiro-hook.js +74 -74
  30. package/bundle/learner.js +8 -6
  31. package/bundle/mcp.js +19 -17
  32. package/bundle/memory-agent.js +4 -4
  33. package/bundle/memory-query.js +3 -3
  34. package/bundle/opencode.js +73 -73
  35. package/bundle/project-manual.js +7 -7
  36. package/bundle/public/index.html +51 -2
  37. package/bundle/runtime.js +16 -13
  38. package/bundle/semantic.js +6 -5
  39. package/bundle/service.js +11 -6
  40. package/bundle/snapshot.js +6 -4
  41. package/bundle/status-cli.js +4 -4
  42. package/bundle/toolnet-cli.js +49 -49
  43. package/bundle/work-continuity.js +7 -7
  44. package/package.json +26 -2
  45. package/release-manifest.json +94 -5
@@ -1,4 +1,4 @@
1
- import{existsSync as qe,readFileSync as Ze}from"node:fs";import{homedir as Qe}from"node:os";import{join as Xe}from"node:path";function et(r){let e=r.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
2
- `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function tt(){let r=process.env.TOOLNET_GLOBAL_ENV??Xe(Qe(),".config","toolnet-memory",".env");if(!qe(r))return;let e=Ze(r,"utf8");for(let t of e.split(/\r?\n/)){let n=t.trim();if(!n||n.startsWith("#"))continue;n.startsWith("export ")&&(n=n.slice(7));let o=n.indexOf("=");if(o<=0)continue;let i=n.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)&&process.env[i]===void 0&&(process.env[i]=et(n.slice(o+1)))}}tt();function S(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function C(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function q(){return{memory:{autoCapture:S(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:S(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:S(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:S(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:C(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:C(process.env.MEMORY_RERANK_TOP,10),finalContext:C(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:C(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:S(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:C(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as at}from"node:crypto";import{existsSync as E,mkdirSync as ut,readFileSync as dt,renameSync as lt,writeFileSync as pt}from"node:fs";import{basename as mt,dirname as T,join as v,parse as oe,resolve as f}from"node:path";import{createHash as X}from"node:crypto";import{spawnSync as rt}from"node:child_process";var b="git-remote-v1",nt=new Set(["github.com","gitlab.com","bitbucket.org"]);function ee(r,e){let t=e.replaceAll("\\","/").replace(/^\/+/u,"").replace(/\/+$/u,"").replace(/\.git$/iu,"").replace(/\/+/gu,"/");return!t||t==="."||t===".."||t.split("/").some(n=>!n||n==="."||n==="..")?null:(nt.has(r)&&(t=t.toLowerCase()),t)}function ot(r){let e;try{e=new URL(r)}catch{return null}if(!["https:","http:","ssh:","git:"].includes(e.protocol))return null;let t=e.hostname.trim().toLowerCase();if(!t)return null;let n=e.protocol==="https:"&&e.port==="443"||e.protocol==="http:"&&e.port==="80"||e.protocol==="ssh:"&&e.port==="22",o=e.port&&!n?`${t}:${e.port}`:t,i=ee(t,e.pathname);return i?`${o}/${i}`:null}function it(r){let e=r.match(/^(?:[^@\s/:]+@)?([^:/\s]+):(.+)$/u);if(!e)return null;let t=e[1]?.trim().toLowerCase();if(!t||t.length===1)return null;let n=ee(t,e[2]??"");return n?`${t}/${n}`:null}function Z(r){let e=r.trim();return e?e.includes("://")?ot(e):it(e):null}function st(r){return X("sha256").update(`${b}:${r}`).digest("hex")}function te(r){return X("sha256").update(`toolnet-project:${b}:${r}`).digest("hex").slice(0,16)}function ct(r){return r.split("/").filter(Boolean).at(-1)?.trim()||null}function L(r,e){let t=rt("git",["-C",r,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return t.error||t.status!==0?null:t.stdout?.trim()||null}function Q(r,e){let t=ct(r);return t?{scheme:b,canonicalRemote:r,fingerprint:st(r),repositoryName:t,source:e}:null}function re(r){let e=L(r,["remote","get-url","origin"]);if(e){let o=Z(e);if(o)return Q(o,"origin")}let t=L(r,["remote"]);if(!t)return null;let n=new Set;for(let o of t.split(/\r?\n/u).map(i=>i.trim()).filter(Boolean)){let i=L(r,["remote","get-url",o]);if(!i)continue;let s=Z(i);s&&n.add(s)}return n.size!==1?null:Q([...n][0],"unique-remote")}var ie=".toolnet",gt="project.json";function ft(r){return at("sha256").update(r).digest("hex").slice(0,16)}function h(r){return v(r,ie,gt)}function se(r){return E(h(r))}function ne(r,e){let t=f(r),n=oe(t).root;for(;;){if(se(t))return t;if(t===n||e&&t===f(e))break;let o=T(t);if(o===t)break;t=o}return null}function G(r){let e=f(r),t=oe(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(i=>E(v(e,i))))return e;if(e===t)break;let o=T(e);if(o===e)break;e=o}return f(r)}function I(r){let e;try{e=JSON.parse(dt(r,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${r}: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${r}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${r}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${r}`);let n=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:T(T(r)),createdAt:typeof t.createdAt=="string"?t.createdAt:n,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:n,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function R(r,e){let t=v(r,ie);ut(t,{recursive:!0});let n=h(r),o=`${n}.tmp-${process.pid}`;pt(o,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),lt(o,n)}function g(r,e){return{id:r.id,name:r.name,remote:r.remote,rootPath:e,createdAt:r.createdAt,updatedAt:r.updatedAt,graphVersion:r.graphVersion,memoryVersion:r.memoryVersion,metadata:r.metadata}}function z(r){return{version:1,scheme:b,canonicalRemote:r.canonicalRemote,fingerprint:r.fingerprint,repositoryName:r.repositoryName}}function yt(r){let e=r.metadata?.toolnetIdentity;if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;return typeof t.fingerprint=="string"?t.fingerprint:null}var _=class{adopt(e,t){let n=G(f(e));if(!t.id.trim())throw new Error("PROJECT_ADOPTION_INVALID_ID");if(!t.name.trim())throw new Error("PROJECT_ADOPTION_INVALID_NAME");if(!t.remote.trim())throw new Error("PROJECT_ADOPTION_INVALID_REMOTE");if(se(n)){let c=I(h(n));if(c.id!==t.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${c.id}`,`requested=${t.id}`].join(" "));return g(c,n)}let o=new Date().toISOString(),i={...t.metadata};t.gitIdentity&&(i.toolnetIdentity=z(t.gitIdentity));let s={version:1,id:t.id.trim(),name:t.name.trim(),remote:t.remote.trim(),rootPath:n,createdAt:t.createdAt??o,updatedAt:o,graphVersion:t.graphVersion??0,memoryVersion:t.memoryVersion??0,metadata:Object.keys(i).length?i:void 0};return R(n,s),g(s,n)}recordGitIdentity(e,t,n={}){let o=this.requireExisting(e),i=h(o.rootPath),s=I(i),c=yt(s);if(c&&c!==t.fingerprint&&!n.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${c}`,`current=${t.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let u=s.metadata?.toolnetIdentity;return u&&typeof u=="object"&&!Array.isArray(u)&&u.fingerprint===t.fingerprint||(s.metadata={...s.metadata,toolnetIdentity:z(t)},s.updatedAt=new Date().toISOString(),R(o.rootPath,s)),g(s,o.rootPath)}findExisting(e=process.cwd()){let t=f(e),n=G(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(u=>E(v(n,u))),s=ne(t,i?n:void 0);if(!s)return null;let c=I(h(s));return g(c,s)}requireExisting(e=process.cwd()){let t=this.findExisting(e);if(!t)throw new Error("PROJECT_NOT_INITIALIZED");return t}detect(e=process.cwd()){let t=f(e),n=G(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(a=>E(v(n,a))),s=ne(t,i?n:void 0);if(s){let a=h(s),l=I(a);return l.rootPath!==s&&(l.rootPath=s,l.updatedAt=new Date().toISOString(),R(s,l)),g(l,s)}let c=new Date().toISOString(),u=mt(n),d=re(n),p={version:1,id:d?te(d.canonicalRemote):ft(n),name:u,remote:d?.repositoryName??u,rootPath:n,createdAt:c,updatedAt:c,graphVersion:0,memoryVersion:0,metadata:d?{toolnetIdentity:z(d)}:void 0};return R(n,p),g(p,n)}};var ht=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,confidence:"exact"},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g,confidence:"exact"},{type:"aws_access_key",regex:/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,confidence:"exact"},{type:"github_token",regex:/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{40,255})\b/g,confidence:"exact"},{type:"stripe_secret_key",regex:/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,confidence:"exact"},{type:"google_api_key",regex:/\bAIza[A-Za-z0-9_-]{30,}\b/g,confidence:"exact"},{type:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{16,}\b/g,confidence:"exact"},{type:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,confidence:"high"},{type:"jwt",regex:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,confidence:"exact"},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,confidence:"exact"},{type:"password_assignment",regex:/\b(?:password|passwd|pwd)\s*[:=]\s*["']?[^"' \t\r\n]{6,}["']?/gi,confidence:"high"},{type:"secret_assignment",regex:/\b(?:secret|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*["']?[^"' \t\r\n]{8,}["']?/gi,confidence:"high"},{type:"cookie",regex:/\b(?:cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi,confidence:"high"},{type:"url_credentials",regex:/\bhttps?:\/\/[^:/@\s]+:[^/@\s]{4,}@[^/\s]+/gi,confidence:"high"}],xt=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function ce(r){return r.normalize("NFKC").trim().toLowerCase()}function kt(r){if(r.length===0)return 0;let e=new Map;for(let n of r)e.set(n,(e.get(n)??0)+1);let t=0;for(let n of e.values()){let o=n/r.length;t-=o*Math.log2(o)}return t}function St(r){return/^[a-f0-9]{32}$/iu.test(r)||/^[a-f0-9]{40}$/iu.test(r)||/^[a-f0-9]{64}$/iu.test(r)}function Ct(r,e,t){let n=r.slice(Math.max(0,e-48),e),o=r.slice(t,Math.min(r.length,t+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${n} ${o}`)}function bt(r,e){return r.start<e.end&&e.start<r.end}function ae(r){return r.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var D=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let n=ce(t);n&&this.allowValues.add(n)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let i of ht){let s=new RegExp(i.regex.source,i.regex.flags);for(let c of e.matchAll(s))c.index===void 0||!c[0]||this.allowed(c[0])||t.push({type:i.type,value:c[0],start:c.index,end:c.index+c[0].length,confidence:i.confidence})}this.enableEntropyHeuristic&&t.push(...this.entropyMatches(e));let n=ae(t),o=[];for(let i of n)o.some(s=>bt(s,i))||o.push(i);return ae(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=ce(e);return xt.has(t)?!0:this.allowValues.has(t)}entropyMatches(e){let t=[],n=/[A-Za-z0-9_+/=-]{32,160}/g;for(let o of e.matchAll(n)){if(o.index===void 0||!o[0])continue;let i=o[0];this.allowed(i)||St(i)||!/[A-Za-z]/u.test(i)||!/[0-9]/u.test(i)||Ct(e,o.index,o.index+i.length)&&(kt(i)<3.7||t.push({type:"high_entropy_secret",value:i,start:o.index,end:o.index+i.length,confidence:"heuristic"}))}return t}};var N=class{scanner;constructor(e={}){this.scanner=new D(e)}sanitize(e){let t=this.scanner.scan(e);if(t.length===0)return{text:e,redacted:0,secretTypes:[]};let n=e,o=[...t].sort((s,c)=>c.start-s.start),i=new Set;for(let s of o)i.add(s.type),n=n.slice(0,s.start)+`[REDACTED:${s.type}]`+n.slice(s.end);return{text:n,redacted:t.length,secretTypes:[...i].sort()}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[n,o]of Object.entries(e)){let i=n.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(i.includes("password")||i.includes("passwd")||i==="pwd"||i.includes("secret")||i.includes("token")||i.includes("cookie")||i.includes("authorization")||i.includes("apikey")||i.includes("accesskey")||i.includes("privatekey")||i.includes("clientsecret")||i.includes("credential")){t[n]="[REDACTED]";continue}t[n]=this.sanitizeValue(o)}return t}return e}};var pn=new N;import{homedir as Ut}from"node:os";import{join as Bt}from"node:path";import{DeleteObjectCommand as wt,GetObjectCommand as Pt,HeadObjectCommand as jt,ListObjectsV2Command as Ot,PutObjectCommand as At,S3Client as Mt}from"@aws-sdk/client-s3";import{getSignedUrl as It}from"@aws-sdk/s3-request-presigner";var K=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Mt({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,n="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new At({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await It(this.client,new Pt({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(t,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`HF download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new jt({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new wt({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new Ot({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let i of o.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}};import{access as ue,mkdir as Rt,readFile as Et,readdir as Tt,rm as _t,stat as de,writeFile as Dt}from"node:fs/promises";import{dirname as Nt,join as Kt,relative as le,resolve as Ft}from"node:path";var w=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Ft(this.root,t)}async put(e,t){let n=this.path(e);await Rt(Nt(n),{recursive:!0}),await Dt(n,t)}async get(e){try{return await Et(this.path(e))}catch(t){if(typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT")return null;throw t}}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await ue(this.path(e)),!0}catch{return!1}}async delete(e){await _t(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),n=[];try{await ue(t)}catch{return n}let o=async s=>{let c=await Tt(s,{withFileTypes:!0});for(let u of c){let d=Kt(s,u.name);if(u.isDirectory()){await o(d);continue}let p=await de(d);n.push({key:le(this.root,d),size:p.size,updatedAt:p.mtime.toISOString()})}},i=await de(t);return i.isDirectory()?await o(t):n.push({key:le(this.root,t),size:i.size,updatedAt:i.mtime.toISOString()}),n}};import{DeleteObjectCommand as $t,GetObjectCommand as Ht,HeadObjectCommand as Lt,ListObjectsV2Command as Gt,PutObjectCommand as zt,S3Client as Wt}from"@aws-sdk/client-s3";import{getSignedUrl as Vt}from"@aws-sdk/s3-request-presigner";var P=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Wt({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,n="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new zt({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await Vt(this.client,new Ht({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(t,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`${this.name} download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new Lt({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new $t({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new Gt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let i of o.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}};function W(r,e){return console.warn(e),new w(r)}function pe(r){let e=r.localRoot??Bt(Ut(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new P({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):W(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(r.provider==="s3"){let t=r.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new P({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):W(e,"[storage] S3 credentials missing. Using local fallback.")}if(r.provider==="huggingface"){let t=r.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new K({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):W(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new w(e)}function Jt(r){return new Promise(e=>setTimeout(e,r))}async function me(r,e={}){let t=Math.max(1,e.attempts??3),n=e.baseDelayMs??150,o=e.maxDelayMs??2e3,i;for(let s=1;s<=t;s++)try{return await r()}catch(c){if(i=c,s>=t)break;let u=Math.min(o,n*2**(s-1)),d=Math.floor(Math.random()*Math.max(1,u*.2));await Jt(u+d)}throw i}var Yt=new Set(["put","get","getText","delete","list"]);function ge(r,e={}){return new Proxy(r,{get(t,n){let o=Reflect.get(t,n,t);return typeof o!="function"?o:Yt.has(n)?(...i)=>me(()=>Promise.resolve(o.apply(t,i)),e):o.bind(t)}})}function fe(r){let e=r.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function ye(r){let e=r.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let o=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:e))}var F=class{constructor(e,t,n,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=n,this.folder=fe(o??n),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),n=t,o=await this.provider.getText(e);if(o){let s;try{s=JSON.parse(o)}catch(c){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${c instanceof Error?c.message:String(c)}`)}if(typeof s.id=="string"&&s.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${s.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof s.createdAt=="string"&&(n=s.createdAt)}let i={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:n,updatedAt:t};await this.provider.put(e,JSON.stringify(i,null,2)+`
4
- `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=ye(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,n){return await this.ensureRegistered(),this.provider.put(this.key(e),t,n)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{existsSync as Ce,readFileSync as er,readdirSync as xe}from"node:fs";import{join as j}from"node:path";var Xo=new Int32Array(new SharedArrayBuffer(4));import{closeSync as oi,existsSync as qt,fsyncSync as ii,mkdirSync as si,openSync as ci,readFileSync as Zt,renameSync as ai,writeFileSync as ui}from"node:fs";import{dirname as li,join as Qt}from"node:path";function Xt(r){return Qt(r.rootPath,".toolnet","work","current.json")}function he(r){let e=Xt(r);if(!qt(e))return null;try{let t=JSON.parse(Zt(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}function be(r){if(!Ce(r))return null;try{return JSON.parse(er(r,"utf8"))}catch{return null}}function ke(r,e){if(!Ce(r))return[];let t=[];for(let n of xe(r,{withFileTypes:!0})){if(!n.isDirectory())continue;let o=j(r,n.name);for(let i of xe(o,{withFileTypes:!0})){if(!i.isDirectory())continue;let s=be(j(o,i.name,"state.json"));s&&s.version===1&&s.projectId===e.id&&t.push(s)}}return t}function tr(r){let e=j(r.rootPath,".toolnet","runtime","sources"),t=j(r.rootPath,".toolnet","sessions"),n=ke(e,r),o=ke(t,r),i=new Map;for(let s of o)i.set(`${s.agent}:${s.nativeSessionId}`,s);for(let s of n)i.set(`${s.agent}:${s.nativeSessionId}`,s);return Array.from(i.values())}function Se(r){return r.filter(e=>!!e).sort().at(-1)}function rr(r){let e=be(j(r.rootPath,".toolnet","runtime","opencode-status.json"));return!e||e.projectRoot&&e.projectRoot!==r.rootPath?null:e}function ve(r){let e=tr(r),n=[...e].sort((a,l)=>(a.lastLocalEventAt??a.updatedAt).localeCompare(l.lastLocalEventAt??l.updatedAt)).at(-1),o=Array.from(new Set(e.map(a=>a.agent))).sort(),i=e.reduce((a,l)=>a+Math.max(0,l.lastSequence-l.lastRemoteSequence),0),s=rr(r),c=s?.state==="capture-failed",u=s?.state==="sync-failed",d;c?d="degraded":i>0||u?d="pending":e.length>0?d="healthy":d="unknown";let p=he(r);return{ok:d!=="degraded",agents:o,sessions:e.length,latestAgent:n?.agent,latestSessionId:n?.nativeSessionId,lastCaptureAt:Se(e.map(a=>a.lastLocalEventAt??a.updatedAt)),lastFlushAt:Se(e.map(a=>a.lastRemoteAt)),pendingWal:i,currentTask:p?.currentTask?.title,currentFile:p?.activeFiles?.at(-1)??p?.filesTouched.at(-1),syncHealth:d,opencode:s?{state:s.state,reason:s.reason,timestamp:s.timestamp,error:s.error}:void 0}}import{existsSync as ze}from"node:fs";import{homedir as Pr}from"node:os";import{join as jr}from"node:path";import{spawnSync as Or}from"node:child_process";import{homedir as nr}from"node:os";import{join as O}from"node:path";function we(r={}){return O(r.home??nr(),".gemini")}function or(r={}){return O(we(r),"antigravity-cli")}function Pe(r={}){return O(we(r),"config")}function ir(r={}){return O(Pe(r),"mcp_config.json")}function sr(r={}){let e=r.cwd??process.cwd();return O(e,".agents","mcp_config.json")}function je(r={}){return[or(r),ir(r),Pe(r),sr(r)]}import{homedir as cr}from"node:os";import{join as Oe}from"node:path";function Ae(r={}){let e=process.env.OPENCODE_CONFIG_DIR?.trim();if(e)return e;let t=r.xdgConfigHome??process.env.XDG_CONFIG_HOME?.trim();return t?Oe(t,"opencode"):Oe(r.home??cr(),".config","opencode")}import{homedir as ar}from"node:os";import{join as ur}from"node:path";function Me(r={}){return ur(r.home??ar(),".claude")}import{homedir as dr}from"node:os";import{join as A}from"node:path";function V(r={}){return r.kiroHome??process.env.KIRO_HOME??A(r.home??dr(),".kiro")}function lr(r={}){return A(V(r),"settings")}function U(r={}){return A(lr(r),"mcp.json")}function pr(r={}){return A(V(r),"hooks")}function Ie(r={}){return A(pr(r),"toolnet-memory.json")}function Re(r={}){return[V(r),U(r)]}import{homedir as mr}from"node:os";import{join as Ee}from"node:path";function Te(r={}){return Ee(r.home??mr(),".toolnetcli")}function gr(r={}){return Ee(Te(r),"config.json")}function _e(r={}){let e=Te(r),t=gr(r);return[e,t]}import{homedir as fr}from"node:os";import{join as B}from"node:path";function De(r={}){if(r.kiloHome)return r.kiloHome;if(process.env.KILO_HOME)return process.env.KILO_HOME;let e=r.xdgConfigHome??process.env.XDG_CONFIG_HOME;return e?B(e,"kilo"):B(r.home??fr(),".config","kilo")}function yr(r={}){return B(De(r),"kilo.jsonc")}function Ne(r={}){let e=De(r),t=yr(r);return[e,t]}import{homedir as hr}from"node:os";import{join as Ke,resolve as Fi}from"node:path";function Fe(r={}){return r.cursorHome??Ke(r.home??hr(),".cursor")}function xr(r={}){return r.cursorConfigDir??process.env.CURSOR_CONFIG_DIR??(r.xdgConfigHome??process.env.XDG_CONFIG_HOME?Ke(r.xdgConfigHome??process.env.XDG_CONFIG_HOME,"cursor"):void 0)??Fe(r)}function $e(r={}){return Array.from(new Set([Fe(r),xr(r)]))}import{homedir as kr}from"node:os";import{join as Sr,resolve as Gi}from"node:path";function Cr(r={}){return r.copilotHome??process.env.COPILOT_HOME??Sr(r.home??kr(),".copilot")}function He(r={}){return[Cr(r)]}import{homedir as br}from"node:os";import{join as vr,resolve as Ui}from"node:path";function wr(r={}){return r.grokHome??process.env.GROK_HOME??vr(r.home??br(),".grok")}function Le(r={}){return[wr(r)]}function Ar(r){return Or("sh",["-lc",`command -v ${JSON.stringify(r)} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}function m(r){let e=r.commandExists(r.command),t=r.configPaths.filter(i=>ze(i)),n=t.length>0,o=[];e&&o.push(`command:${r.command}`);for(let i of t)o.push(`config:${i}`);return{agent:r.agent,detected:e||n,commandDetected:e,configDetected:n,evidence:o}}function Ge(r){let e=r.commands.filter(s=>r.commandExists(s)),t=r.configPaths.filter(s=>ze(s)),n=e.length>0,o=t.length>0,i=[...e.map(s=>`command:${s}`),...t.map(s=>`config:${s}`)];return{agent:r.agent,detected:n||o,commandDetected:n,configDetected:o,evidence:i}}function We(r={}){let e=r.home??Pr(),t=r.commandExists??Ar,n=r.codexHome??process.env.CODEX_HOME??jr(e,".codex");return[m({agent:"agy",command:"agy",commandExists:t,configPaths:je({home:e})}),m({agent:"opencode",command:"opencode",commandExists:t,configPaths:[Ae({home:e,xdgConfigHome:r.xdgConfigHome})]}),m({agent:"claude",command:"claude",commandExists:t,configPaths:[Me({home:e})]}),m({agent:"kiro",command:"kiro-cli",commandExists:t,configPaths:Re({home:e,kiroHome:r.kiroHome})}),Ge({agent:"cursor",commands:["agent","cursor-agent"],commandExists:t,configPaths:$e({home:e,cursorHome:r.cursorHome,cursorConfigDir:r.cursorConfigDir,xdgConfigHome:r.xdgConfigHome})}),m({agent:"copilot",command:"copilot",commandExists:t,configPaths:He({home:e,copilotHome:r.copilotHome})}),m({agent:"grok",command:"grok",commandExists:t,configPaths:Le({home:e,grokHome:r.grokHome})}),m({agent:"toolnet-cli",command:"toolnet",commandExists:t,configPaths:_e({home:e})}),Ge({agent:"kilo",commands:["kilo","kilo-code"],commandExists:t,configPaths:Ne({home:e,kiloHome:r.kiloHome})}),m({agent:"codex",command:"codex",commandExists:t,configPaths:[n]})]}import{existsSync as J,readFileSync as Mr}from"node:fs";var Ir="ToolNet Memory - ",Rr=["SessionStart","UserPromptSubmit","PreToolUse","PostToolUse","Stop"];function x(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function Ve(r){if(!J(r))return{};let e;try{e=JSON.parse(Mr(r,"utf8"))}catch(t){return{error:t instanceof Error?t.message:String(t)}}return x(e)?{value:e}:{error:"root must be a JSON object"}}function Er(r){if(!r||!x(r.mcpServers))return!1;let e=r.mcpServers["toolnet-memory"];return x(e)?typeof e.command=="string"&&e.command.trim().length>0&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp"&&e.disabled!==!0:!1}function Tr(r){if(!(!x(r)||!x(r.action)))return typeof r.action.command=="string"?r.action.command:void 0}function _r(r){if(!r||r.version!=="v1"||!Array.isArray(r.hooks))return[];let e=new Set;for(let t of r.hooks){if(!x(t)||typeof t.name!="string"||!t.name.startsWith(Ir))continue;let n=Tr(t);!n||!n.includes("session:kiro-hook")||t.enabled!==!1&&typeof t.trigger=="string"&&e.add(t.trigger)}return[...e]}function Ue(r={}){let e=r.configFile??U(),t=r.hooksFile??Ie(),n=Ve(e),o=Ve(t),i=!n.error&&Er(n.value),s=o.error?[]:_r(o.value),c=Rr.every(l=>s.includes(l)),u=[];n.error&&u.push(`MCP config: ${n.error}`),o.error&&u.push(`Hooks config: ${o.error}`);let d=i&&c,p=J(e)||J(t),a=u.length>0?"invalid":d?"ready":p?"partial":"not-installed";return{installed:d,state:a,mcp:{configured:i,configFile:e,error:n.error},hooks:{configured:c,hooksFile:t,triggers:s,error:o.error},errors:u}}var Dr={spinner:["\xB7","\u2722","\u2733","\u2736","\u273B","\u273D"],barFilled:"\u2588",barEmpty:"\u2591",phaseDone:"\u25C6",phaseActive:"\u25C7",rail:"\u2502",branch:"\u251C",corner:"\u2514",dash:"\u2014"},Nr={spinner:[".","*","+","x","*","+"],barFilled:"#",barEmpty:"-",phaseDone:"[OK]",phaseActive:"[>>]",rail:"|",branch:"|",corner:"\\",dash:"-"};function Kr(){if(process.env.TOOLNET_ASCII==="1")return!1;if(process.env.TOOLNET_UNICODE==="1")return!0;if(process.platform==="win32"){let r=process.env.TERM_PROGRAM,e=process.env.WT_SESSION,t=process.env.VSCODE_PID,n=process.env.ConEmuPID;return!!(e||t||n||r==="vscode")}return process.env.TERM!=="linux"}var Y;function Be(){return Y||(Y=Kr()?Dr:Nr),Y}var k={reset:"\x1B[0m",green:"\x1B[32m",cyan:"\x1B[36m",red:"\x1B[31m",yellow:"\x1B[33m",amber:"\x1B[38;5;214m",white:"\x1B[97m",dim:"\x1B[2m",bold:"\x1B[1m"};function Fr(r){return r.noColor||process.env.NO_COLOR?!1:r.tty??process.stdout.isTTY??!1}function M(r,e,t){return Fr(t)?`${e}${r}${k.reset}`:r}function $(r,e){return M(r,k.dim,e)}function $r(r,e){return M(r,k.bold,e)}function Hr(r,e){return M(r,k.cyan,e)}function Lr(r,e){return M(r,k.red,e)}function Gr(r,e){return M(r,k.white,e)}function Je(r,e,t){let n=Be(),o=e?` ${$(`v${e}`,t)}`:"";return`${Hr(n.phaseDone,t)} ${r}${o}`}function H(r,e){return $r(r,e)}function y(r,e,t,n){let o=" ".repeat(Math.max(0,t-r.length));return` ${$(r,n)}${o} ${Gr(e,n)}`}function Ye(r){return Lr("\u2717",r)}function zr(r){return{tty:r.tty,noColor:r.noColor}}async function Wr(r){let e=zr(r);console.log(""),console.log(Je("ToolNet Status",void 0,e)),console.log("");try{let t=new _().detect(),n=q();console.log(H("PROJECT",e)),console.log(y("Name",t.name,8,e));let o=ge(pe({provider:n.storage.provider,r2:n.storage.r2,s3:n.storage.s3,huggingface:n.storage.huggingface,localRoot:n.storage.localRoot}),{attempts:3}),i=new F(o,t.id,t.name,t.remote??t.name),s="unknown",c="unknown";try{s=await i.exists(`${t.id}/memory.json`)?"ready":"not initialized"}catch{s="error"}try{c=await i.exists(`${t.id}/code-graph.json`)?"ready":"not built"}catch{c="error"}console.log(y("Memory",s,8,e)),console.log(y("Index",c,8,e)),console.log("");let u=We(),d=u.filter(a=>a.detected).map(a=>a.agent);if(d.length>0){if(console.log(H("INTEGRATIONS",e)),console.log(y("Detected",d.join(", "),8,e)),u.find(l=>l.agent==="kiro")?.detected){let l=Ue();console.log(y("Kiro",l.installed?"ready":l.state,8,e))}console.log("")}let p=ve(t);if(p.agents.length>0){console.log(H("SERVICE",e));let a=p.syncHealth==="healthy"?"running":p.syncHealth==="degraded"?"degraded":"stopped";console.log(y("Daemon",a,8,e)),console.log("")}}catch(t){console.log(Ye(e)+" Failed to get status"),console.log(""),console.log($(` ${t instanceof Error?t.message:String(t)}`,e)),console.log(""),process.exitCode=1}}async function Vr(){let r=process.argv.slice(2),e={tty:process.stdout.isTTY,noColor:process.env.NO_COLOR!==void 0||r.includes("--no-color")};await Wr(e)}Vr().catch(r=>{console.error(""),console.error(r instanceof Error?r.message:String(r)),console.error(""),process.exitCode=1});
1
+ import{existsSync as yt,readFileSync as ht}from"node:fs";import{homedir as xt}from"node:os";import{join as kt}from"node:path";function St(r){let e=r.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
2
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function Ct(){let r=process.env.TOOLNET_GLOBAL_ENV??kt(xt(),".config","toolnet-memory",".env");if(!yt(r))return;let e=ht(r,"utf8");for(let t of e.split(/\r?\n/)){let n=t.trim();if(!n||n.startsWith("#"))continue;n.startsWith("export ")&&(n=n.slice(7));let o=n.indexOf("=");if(o<=0)continue;let i=n.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)&&process.env[i]===void 0&&(process.env[i]=St(n.slice(o+1)))}}Ct();function b(r,e){return r===void 0?e:["1","true","yes","on"].includes(r.toLowerCase())}function w(r,e){if(!r)return e;let t=Number(r);return Number.isFinite(t)?t:e}function se(){return{memory:{autoCapture:b(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:b(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:b(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:b(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:w(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:w(process.env.MEMORY_RERANK_TOP,10),finalContext:w(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:w(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:b(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:w(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Rt}from"node:crypto";import{existsSync as K,mkdirSync as At,readFileSync as jt,renameSync as It,writeFileSync as Mt}from"node:fs";import{basename as Tt,dirname as F,join as P,parse as me,resolve as y}from"node:path";import{createHash as ue}from"node:crypto";import{spawnSync as bt}from"node:child_process";var E="git-remote-v1",wt=new Set(["github.com","gitlab.com","bitbucket.org"]);function de(r,e){let t=e.replaceAll("\\","/").replace(/^\/+/u,"").replace(/\/+$/u,"").replace(/\.git$/iu,"").replace(/\/+/gu,"/");return!t||t==="."||t===".."||t.split("/").some(n=>!n||n==="."||n==="..")?null:(wt.has(r)&&(t=t.toLowerCase()),t)}function Et(r){let e;try{e=new URL(r)}catch{return null}if(!["https:","http:","ssh:","git:"].includes(e.protocol))return null;let t=e.hostname.trim().toLowerCase();if(!t)return null;let n=e.protocol==="https:"&&e.port==="443"||e.protocol==="http:"&&e.port==="80"||e.protocol==="ssh:"&&e.port==="22",o=e.port&&!n?`${t}:${e.port}`:t,i=de(t,e.pathname);return i?`${o}/${i}`:null}function Pt(r){let e=r.match(/^(?:[^@\s/:]+@)?([^:/\s]+):(.+)$/u);if(!e)return null;let t=e[1]?.trim().toLowerCase();if(!t||t.length===1)return null;let n=de(t,e[2]??"");return n?`${t}/${n}`:null}function ce(r){let e=r.trim();return e?e.includes("://")?Et(e):Pt(e):null}function vt(r){return ue("sha256").update(`${E}:${r}`).digest("hex")}function le(r){return ue("sha256").update(`toolnet-project:${E}:${r}`).digest("hex").slice(0,16)}function Ot(r){return r.split("/").filter(Boolean).at(-1)?.trim()||null}function W(r,e){let t=bt("git",["-C",r,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return t.error||t.status!==0?null:t.stdout?.trim()||null}function ae(r,e){let t=Ot(r);return t?{scheme:E,canonicalRemote:r,fingerprint:vt(r),repositoryName:t,source:e}:null}function pe(r){let e=W(r,["remote","get-url","origin"]);if(e){let o=ce(e);if(o)return ae(o,"origin")}let t=W(r,["remote"]);if(!t)return null;let n=new Set;for(let o of t.split(/\r?\n/u).map(i=>i.trim()).filter(Boolean)){let i=W(r,["remote","get-url",o]);if(!i)continue;let s=ce(i);s&&n.add(s)}return n.size!==1?null:ae([...n][0],"unique-remote")}var ge=".toolnet",_t="project.json";function Nt(r){return Rt("sha256").update(r).digest("hex").slice(0,16)}function k(r){return P(r,ge,_t)}function ye(r){return K(k(r))}function fe(r,e){let t=y(r),n=me(t).root;for(;;){if(ye(t))return t;if(t===n||e&&t===y(e))break;let o=F(t);if(o===t)break;t=o}return null}function Y(r){let e=y(r),t=me(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(i=>K(P(e,i))))return e;if(e===t)break;let o=F(e);if(o===e)break;e=o}return y(r)}function N(r){let e;try{e=JSON.parse(jt(r,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${r}: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${r}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${r}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${r}`);let n=new Date().toISOString();return{version:1,id:t.id,name:t.name,remote:typeof t.remote=="string"&&t.remote.trim()?t.remote:t.name,rootPath:typeof t.rootPath=="string"?t.rootPath:F(F(r)),createdAt:typeof t.createdAt=="string"?t.createdAt:n,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:n,graphVersion:typeof t.graphVersion=="number"?t.graphVersion:0,memoryVersion:typeof t.memoryVersion=="number"?t.memoryVersion:0,metadata:t.metadata&&typeof t.metadata=="object"?t.metadata:void 0}}function D(r,e){let t=P(r,ge);At(t,{recursive:!0});let n=k(r),o=`${n}.tmp-${process.pid}`;Mt(o,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),It(o,n)}function g(r,e){return{id:r.id,name:r.name,remote:r.remote,rootPath:e,createdAt:r.createdAt,updatedAt:r.updatedAt,graphVersion:r.graphVersion,memoryVersion:r.memoryVersion,metadata:r.metadata}}function B(r){return{version:1,scheme:E,canonicalRemote:r.canonicalRemote,fingerprint:r.fingerprint,repositoryName:r.repositoryName}}function Dt(r){let e=r.metadata?.toolnetIdentity;if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;return typeof t.fingerprint=="string"?t.fingerprint:null}var L=class{adopt(e,t){let n=Y(y(e));if(!t.id.trim())throw new Error("PROJECT_ADOPTION_INVALID_ID");if(!t.name.trim())throw new Error("PROJECT_ADOPTION_INVALID_NAME");if(!t.remote.trim())throw new Error("PROJECT_ADOPTION_INVALID_REMOTE");if(ye(n)){let c=N(k(n));if(c.id!==t.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${c.id}`,`requested=${t.id}`].join(" "));return g(c,n)}let o=new Date().toISOString(),i={...t.metadata};t.gitIdentity&&(i.toolnetIdentity=B(t.gitIdentity));let s={version:1,id:t.id.trim(),name:t.name.trim(),remote:t.remote.trim(),rootPath:n,createdAt:t.createdAt??o,updatedAt:o,graphVersion:t.graphVersion??0,memoryVersion:t.memoryVersion??0,metadata:Object.keys(i).length?i:void 0};return D(n,s),g(s,n)}recordGitIdentity(e,t,n={}){let o=this.requireExisting(e),i=k(o.rootPath),s=N(i),c=Dt(s);if(c&&c!==t.fingerprint&&!n.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${c}`,`current=${t.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let u=s.metadata?.toolnetIdentity;return u&&typeof u=="object"&&!Array.isArray(u)&&u.fingerprint===t.fingerprint||(s.metadata={...s.metadata,toolnetIdentity:B(t)},s.updatedAt=new Date().toISOString(),D(o.rootPath,s)),g(s,o.rootPath)}findExisting(e=process.cwd()){let t=y(e),n=Y(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(u=>K(P(n,u))),s=fe(t,i?n:void 0);if(!s)return null;let c=N(k(s));return g(c,s)}requireExisting(e=process.cwd()){let t=this.findExisting(e);if(!t)throw new Error("PROJECT_NOT_INITIALIZED");return t}detect(e=process.cwd()){let t=y(e),n=Y(t),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>K(P(n,d))),s=fe(t,i?n:void 0);if(s){let d=k(s),p=N(d);return p.rootPath!==s&&(p.rootPath=s,p.updatedAt=new Date().toISOString(),D(s,p)),g(p,s)}let c=new Date().toISOString(),u=Tt(n),a=pe(n),f={version:1,id:a?le(a.canonicalRemote):Nt(n),name:u,remote:a?.repositoryName??u,rootPath:n,createdAt:c,updatedAt:c,graphVersion:0,memoryVersion:0,metadata:a?{toolnetIdentity:B(a)}:void 0};return D(n,f),g(f,n)}};var Kt=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,confidence:"exact"},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g,confidence:"exact"},{type:"aws_access_key",regex:/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,confidence:"exact"},{type:"github_token",regex:/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{40,255})\b/g,confidence:"exact"},{type:"stripe_secret_key",regex:/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,confidence:"exact"},{type:"google_api_key",regex:/\bAIza[A-Za-z0-9_-]{30,}\b/g,confidence:"exact"},{type:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{16,}\b/g,confidence:"exact"},{type:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,confidence:"high"},{type:"jwt",regex:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,confidence:"exact"},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,confidence:"exact"},{type:"password_assignment",regex:/\b(?:password|passwd|pwd)\s*[:=]\s*["']?[^"' \t\r\n]{6,}["']?/gi,confidence:"high"},{type:"secret_assignment",regex:/\b(?:secret|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*["']?[^"' \t\r\n]{8,}["']?/gi,confidence:"high"},{type:"cookie",regex:/\b(?:cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi,confidence:"high"},{type:"url_credentials",regex:/\bhttps?:\/\/[^:/@\s]+:[^/@\s]{4,}@[^/\s]+/gi,confidence:"high"}],Ft=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function he(r){return r.normalize("NFKC").trim().toLowerCase()}function Lt(r){if(r.length===0)return 0;let e=new Map;for(let n of r)e.set(n,(e.get(n)??0)+1);let t=0;for(let n of e.values()){let o=n/r.length;t-=o*Math.log2(o)}return t}function $t(r){return/^[a-f0-9]{32}$/iu.test(r)||/^[a-f0-9]{40}$/iu.test(r)||/^[a-f0-9]{64}$/iu.test(r)}function Ht(r,e,t){let n=r.slice(Math.max(0,e-48),e),o=r.slice(t,Math.min(r.length,t+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${n} ${o}`)}function Gt(r,e){return r.start<e.end&&e.start<r.end}function xe(r){return r.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var $=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let n=he(t);n&&this.allowValues.add(n)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let i of Kt){let s=new RegExp(i.regex.source,i.regex.flags);for(let c of e.matchAll(s))c.index===void 0||!c[0]||this.allowed(c[0])||t.push({type:i.type,value:c[0],start:c.index,end:c.index+c[0].length,confidence:i.confidence})}this.enableEntropyHeuristic&&t.push(...this.entropyMatches(e));let n=xe(t),o=[];for(let i of n)o.some(s=>Gt(s,i))||o.push(i);return xe(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=he(e);return Ft.has(t)?!0:this.allowValues.has(t)}entropyMatches(e){let t=[],n=/[A-Za-z0-9_+/=-]{32,160}/g;for(let o of e.matchAll(n)){if(o.index===void 0||!o[0])continue;let i=o[0];this.allowed(i)||$t(i)||!/[A-Za-z]/u.test(i)||!/[0-9]/u.test(i)||Ht(e,o.index,o.index+i.length)&&(Lt(i)<3.7||t.push({type:"high_entropy_secret",value:i,start:o.index,end:o.index+i.length,confidence:"heuristic"}))}return t}};var H=class{scanner;constructor(e={}){this.scanner=new $(e)}sanitize(e){let t=this.scanner.scan(e);if(t.length===0)return{text:e,redacted:0,secretTypes:[]};let n=e,o=[...t].sort((s,c)=>c.start-s.start),i=new Set;for(let s of o)i.add(s.type),n=n.slice(0,s.start)+`[REDACTED:${s.type}]`+n.slice(s.end);return{text:n,redacted:t.length,secretTypes:[...i].sort()}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(t=>this.sanitizeValue(t));if(e&&typeof e=="object"){let t={};for(let[n,o]of Object.entries(e)){let i=n.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(i.includes("password")||i.includes("passwd")||i==="pwd"||i.includes("secret")||i.includes("token")||i.includes("cookie")||i.includes("authorization")||i.includes("apikey")||i.includes("accesskey")||i.includes("privatekey")||i.includes("clientsecret")||i.includes("credential")){t[n]="[REDACTED]";continue}t[n]=this.sanitizeValue(o)}return t}return e}};var $n=new H;import{homedir as Sr}from"node:os";import{join as Cr}from"node:path";import{DeleteObjectCommand as Vt,GetObjectCommand as zt,HeadObjectCommand as Wt,ListObjectsV2Command as Yt,PutObjectCommand as Bt,S3Client as Jt}from"@aws-sdk/client-s3";import{getSignedUrl as qt}from"@aws-sdk/s3-request-presigner";var G=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Jt({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,n="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Bt({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await qt(this.client,new zt({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(t,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`HF download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new Wt({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new Vt({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new Yt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let i of o.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}};import{access as ke,mkdir as Zt,readFile as Qt,readdir as Xt,rm as er,stat as Se,writeFile as tr}from"node:fs/promises";import{dirname as rr,join as nr,relative as Ce,resolve as or}from"node:path";var v=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return or(this.root,t)}async put(e,t){let n=this.path(e);await Zt(rr(n),{recursive:!0}),await tr(n,t)}async get(e){try{return await Qt(this.path(e))}catch(t){if(typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT")return null;throw t}}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await ke(this.path(e)),!0}catch{return!1}}async delete(e){await er(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),n=[];try{await ke(t)}catch{return n}let o=async s=>{let c=await Xt(s,{withFileTypes:!0});for(let u of c){let a=nr(s,u.name);if(u.isDirectory()){await o(a);continue}let f=await Se(a);n.push({key:Ce(this.root,a),size:f.size,updatedAt:f.mtime.toISOString()})}},i=await Se(t);return i.isDirectory()?await o(t):n.push({key:Ce(this.root,t),size:i.size,updatedAt:i.mtime.toISOString()}),n}};import{DeleteObjectCommand as ir,GetObjectCommand as sr,HeadObjectCommand as cr,ListObjectsV2Command as ar,PutObjectCommand as ur,S3Client as dr}from"@aws-sdk/client-s3";import{getSignedUrl as lr}from"@aws-sdk/s3-request-presigner";var O=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new dr({region:e.region??"us-east-1",endpoint:e.endpoint||void 0,forcePathStyle:e.forcePathStyle??!1,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,n="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new ur({Bucket:this.bucket,Key:e,Body:o,ContentType:n}))}async get(e){let t=await lr(this.client,new sr({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(t,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`${this.name} download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await this.client.send(new cr({Bucket:this.bucket,Key:e})),!0}catch(t){if(typeof t=="object"&&t!==null&&"$metadata"in t&&t.$metadata?.httpStatusCode===404)return!1;throw t}}async delete(e){await this.client.send(new ir({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],n;do{let o=await this.client.send(new ar({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let i of o.Contents??[])i.Key&&t.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});n=o.IsTruncated?o.NextContinuationToken:void 0}while(n);return t}};import{createCipheriv as pr,createDecipheriv as fr,createHash as mr,randomBytes as gr,timingSafeEqual as yr}from"node:crypto";import{readFileSync as hr}from"node:fs";var h=Buffer.from("TNMEME01","ascii"),we=1,R=8,A=12,J=16,Ee=h.length+1+R+A+J,xr="toolnet-memory:remote-encryption:v1:",Pe="aes-256-gcm",q=32,l=class extends Error{constructor(t,n){super(n);this.code=t;this.name="RemoteEncryptionError"}code};function kr(r){return r?["1","true","yes","on","enabled"].includes(r.trim().toLowerCase()):!1}function Z(r=process.env){return kr(r.TOOLNET_REMOTE_ENCRYPTION)}function be(r){let e=r.trim();if(!e)throw new l("REMOTE_ENCRYPTION_KEY_EMPTY","Remote encryption key is empty.");let t;if(e.startsWith("hex:")){let n=e.slice(4);if(!/^[0-9a-f]{64}$/iu.test(n))throw new l("REMOTE_ENCRYPTION_KEY_INVALID","hex: remote encryption key must contain exactly 64 hexadecimal characters.");t=Buffer.from(n,"hex")}else if(/^[0-9a-f]{64}$/iu.test(e))t=Buffer.from(e,"hex");else{let n=e.startsWith("base64:")?e.slice(7):e;if(!/^[A-Za-z0-9+/_-]+={0,2}$/u.test(n))throw new l("REMOTE_ENCRYPTION_KEY_INVALID","Remote encryption key must be 32 raw bytes encoded as hexadecimal or base64.");t=Buffer.from(n,n.includes("-")||n.includes("_")?"base64url":"base64")}if(t.length!==q)throw new l("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH",`Remote encryption key must decode to exactly ${q} bytes.`);return t}function ve(r=process.env){let e=r.TOOLNET_REMOTE_ENCRYPTION_KEY?.trim(),t=r.TOOLNET_REMOTE_ENCRYPTION_KEY_FILE?.trim();if(e&&t)throw new l("REMOTE_ENCRYPTION_KEY_AMBIGUOUS","Configure either TOOLNET_REMOTE_ENCRYPTION_KEY or TOOLNET_REMOTE_ENCRYPTION_KEY_FILE, not both.");if(e)return be(e);if(t){let n;try{n=hr(t,"utf8")}catch(o){throw new l("REMOTE_ENCRYPTION_KEY_FILE_READ_FAILED",[`Unable to read remote encryption key file: ${t}.`,o instanceof Error?o.message:String(o)].join(" "))}return be(n)}}function Oe(r){return mr("sha256").update(r).digest().subarray(0,R)}function Re(r){return Buffer.from(`${xr}${r}`,"utf8")}function Q(r){return r.byteLength<h.length?!1:Buffer.from(r).subarray(0,h.length).equals(h)}function Ae(r,e,t){if(t.byteLength!==q)throw new l("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH","AES-256-GCM requires a 32-byte key.");let n=typeof e=="string"?Buffer.from(e,"utf8"):Buffer.from(e),o=gr(A),i=pr(Pe,t,o);i.setAAD(Re(r));let s=Buffer.concat([i.update(n),i.final()]),c=i.getAuthTag(),u=Buffer.alloc(Ee),a=0;return h.copy(u,a),a+=h.length,u.writeUInt8(we,a),a+=1,Oe(t).copy(u,a),a+=R,o.copy(u,a),a+=A,c.copy(u,a),Buffer.concat([u,s])}function je(r,e,t){let n=Buffer.from(e);if(!Q(n))throw new l("REMOTE_ENCRYPTION_ENVELOPE_REQUIRED","Payload is not a ToolNet encrypted remote object.");if(n.length<Ee)throw new l("REMOTE_ENCRYPTION_ENVELOPE_TRUNCATED","Encrypted remote payload is truncated.");let o=h.length,i=n.readUInt8(o);if(o+=1,i!==we)throw new l("REMOTE_ENCRYPTION_VERSION_UNSUPPORTED",`Unsupported remote encryption envelope version: ${i}.`);let s=n.subarray(o,o+R);o+=R;let c=Oe(t);if(!yr(s,c))throw new l("REMOTE_ENCRYPTION_KEY_MISMATCH","Configured remote encryption key does not match this encrypted object.");let u=n.subarray(o,o+A);o+=A;let a=n.subarray(o,o+J);o+=J;let f=n.subarray(o),d=fr(Pe,t,u);d.setAAD(Re(r)),d.setAuthTag(a);try{return Buffer.concat([d.update(f),d.final()])}catch{throw new l("REMOTE_ENCRYPTION_AUTH_FAILED","Encrypted remote object failed AES-GCM authentication.")}}var X=class{constructor(e,t){this.inner=e;this.options=t;if(this.name=e.name,t.enabled&&!t.key)throw new l("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote client-side encryption is enabled but no encryption key is configured.")}inner;options;name;async put(e,t,n){if(!this.options.enabled){await this.inner.put(e,t,n);return}let o=this.options.key;if(!o)throw new l("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote encryption key is unavailable.");let i=Ae(e,t,o);await this.inner.put(e,i,"application/octet-stream")}async get(e){let t=await this.inner.get(e);if(!t)return null;if(!Q(t))return t;if(!this.options.enabled)throw new l("REMOTE_ENCRYPTION_REQUIRED",["Remote object is client-side encrypted.","Enable TOOLNET_REMOTE_ENCRYPTION and configure the matching key."].join(" "));let n=this.options.key;if(!n)throw new l("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote object is encrypted but no decryption key is configured.");return je(e,t,n)}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){return this.inner.exists(e)}async delete(e){await this.inner.delete(e)}async list(e=""){return this.inner.list(e)}};function Ie(r,e=process.env){if(r.name==="local")return Z(e)&&console.warn("[storage] Remote encryption requested but active storage provider is local; local data remains unchanged."),r;let t=Z(e),n=t?ve(e):void 0;return new X(r,{enabled:t,key:n})}function j(r){return Ie(r)}function ee(r,e){return console.warn(e),j(new v(r))}function Me(r){let e=r.localRoot??Cr(Sr(),".toolnet-memory","storage");if(r.provider==="r2"){let t=r.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?j(new O({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey})):ee(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(r.provider==="s3"){let t=r.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?j(new O({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey})):ee(e,"[storage] S3 credentials missing. Using local fallback.")}if(r.provider==="huggingface"){let t=r.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?j(new G({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey})):ee(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return j(new v(e))}function br(r){return new Promise(e=>setTimeout(e,r))}async function Te(r,e={}){let t=Math.max(1,e.attempts??3),n=e.baseDelayMs??150,o=e.maxDelayMs??2e3,i;for(let s=1;s<=t;s++)try{return await r()}catch(c){if(i=c,s>=t)break;let u=Math.min(o,n*2**(s-1)),a=Math.floor(Math.random()*Math.max(1,u*.2));await br(u+a)}throw i}var wr=new Set(["put","get","getText","delete","list"]);function _e(r,e={}){return new Proxy(r,{get(t,n){let o=Reflect.get(t,n,t);return typeof o!="function"?o:wr.has(n)?(...i)=>Te(()=>Promise.resolve(o.apply(t,i)),e):o.bind(t)}})}function Ne(r){let e=r.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function De(r){let e=r.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let t=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(t)return`${t[1]}memory/records/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),t)return`${t[1]}memory/vectors/${t[2]}`;if(t=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),t)return`${t[1]}code/graph/${t[2]}`;let n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let o=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return o?`${o[1]}memory/records/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),o?`${o[1]}memory/vectors/${o[2]}`:(o=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),o?`${o[1]}code/graph/${o[2]}`:e))}var U=class{constructor(e,t,n,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=n,this.folder=Ne(o??n),this.sourcePrefix=`projects/${t}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,t=new Date().toISOString(),n=t,o=await this.provider.getText(e);if(o){let s;try{s=JSON.parse(o)}catch(c){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${c instanceof Error?c.message:String(c)}`)}if(typeof s.id=="string"&&s.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${s.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof s.createdAt=="string"&&(n=s.createdAt)}let i={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:n,updatedAt:t};await this.provider.put(e,JSON.stringify(i,null,2)+`
4
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=De(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,t,n){return await this.ensureRegistered(),this.provider.put(this.key(e),t,n)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{existsSync as He,readFileSync as Rr,readdirSync as Fe}from"node:fs";import{join as I}from"node:path";var _i=new Int32Array(new SharedArrayBuffer(4));import{closeSync as Li,existsSync as Er,fsyncSync as $i,mkdirSync as Hi,openSync as Gi,readFileSync as Pr,renameSync as Ui,writeFileSync as Vi}from"node:fs";import{dirname as Wi,join as vr}from"node:path";function Or(r){return vr(r.rootPath,".toolnet","work","current.json")}function Ke(r){let e=Or(r);if(!Er(e))return null;try{let t=JSON.parse(Pr(e,"utf8"));return t.version!==1||t.projectId!==r.id?null:t}catch{return null}}function Ge(r){if(!He(r))return null;try{return JSON.parse(Rr(r,"utf8"))}catch{return null}}function Le(r,e){if(!He(r))return[];let t=[];for(let n of Fe(r,{withFileTypes:!0})){if(!n.isDirectory())continue;let o=I(r,n.name);for(let i of Fe(o,{withFileTypes:!0})){if(!i.isDirectory())continue;let s=Ge(I(o,i.name,"state.json"));s&&s.version===1&&s.projectId===e.id&&t.push(s)}}return t}function Ar(r){let e=I(r.rootPath,".toolnet","runtime","sources"),t=I(r.rootPath,".toolnet","sessions"),n=Le(e,r),o=Le(t,r),i=new Map;for(let s of o)i.set(`${s.agent}:${s.nativeSessionId}`,s);for(let s of n)i.set(`${s.agent}:${s.nativeSessionId}`,s);return Array.from(i.values())}function $e(r){return r.filter(e=>!!e).sort().at(-1)}function jr(r){let e=Ge(I(r.rootPath,".toolnet","runtime","opencode-status.json"));return!e||e.projectRoot&&e.projectRoot!==r.rootPath?null:e}function Ue(r){let e=Ar(r),n=[...e].sort((d,p)=>(d.lastLocalEventAt??d.updatedAt).localeCompare(p.lastLocalEventAt??p.updatedAt)).at(-1),o=Array.from(new Set(e.map(d=>d.agent))).sort(),i=e.reduce((d,p)=>d+Math.max(0,p.lastSequence-p.lastRemoteSequence),0),s=jr(r),c=s?.state==="capture-failed",u=s?.state==="sync-failed",a;c?a="degraded":i>0||u?a="pending":e.length>0?a="healthy":a="unknown";let f=Ke(r);return{ok:a!=="degraded",agents:o,sessions:e.length,latestAgent:n?.agent,latestSessionId:n?.nativeSessionId,lastCaptureAt:$e(e.map(d=>d.lastLocalEventAt??d.updatedAt)),lastFlushAt:$e(e.map(d=>d.lastRemoteAt)),pendingWal:i,currentTask:f?.currentTask?.title,currentFile:f?.activeFiles?.at(-1)??f?.filesTouched.at(-1),syncHealth:a,opencode:s?{state:s.state,reason:s.reason,timestamp:s.timestamp,error:s.error}:void 0}}import{existsSync as ut}from"node:fs";import{homedir as Xr}from"node:os";import{join as en}from"node:path";import{spawnSync as tn}from"node:child_process";import{homedir as Ir}from"node:os";import{join as M}from"node:path";function Ve(r={}){return M(r.home??Ir(),".gemini")}function Mr(r={}){return M(Ve(r),"antigravity-cli")}function ze(r={}){return M(Ve(r),"config")}function Tr(r={}){return M(ze(r),"mcp_config.json")}function _r(r={}){let e=r.cwd??process.cwd();return M(e,".agents","mcp_config.json")}function We(r={}){return[Mr(r),Tr(r),ze(r),_r(r)]}import{homedir as Nr}from"node:os";import{join as Ye}from"node:path";function Be(r={}){let e=process.env.OPENCODE_CONFIG_DIR?.trim();if(e)return e;let t=r.xdgConfigHome??process.env.XDG_CONFIG_HOME?.trim();return t?Ye(t,"opencode"):Ye(r.home??Nr(),".config","opencode")}import{homedir as Dr}from"node:os";import{join as Kr}from"node:path";function Je(r={}){return Kr(r.home??Dr(),".claude")}import{homedir as Fr}from"node:os";import{join as T}from"node:path";function te(r={}){return r.kiroHome??process.env.KIRO_HOME??T(r.home??Fr(),".kiro")}function Lr(r={}){return T(te(r),"settings")}function re(r={}){return T(Lr(r),"mcp.json")}function $r(r={}){return T(te(r),"hooks")}function qe(r={}){return T($r(r),"toolnet-memory.json")}function Ze(r={}){return[te(r),re(r)]}import{homedir as Hr}from"node:os";import{join as Qe}from"node:path";function Xe(r={}){return Qe(r.home??Hr(),".toolnetcli")}function Gr(r={}){return Qe(Xe(r),"config.json")}function et(r={}){let e=Xe(r),t=Gr(r);return[e,t]}import{homedir as Ur}from"node:os";import{join as ne}from"node:path";function tt(r={}){if(r.kiloHome)return r.kiloHome;if(process.env.KILO_HOME)return process.env.KILO_HOME;let e=r.xdgConfigHome??process.env.XDG_CONFIG_HOME;return e?ne(e,"kilo"):ne(r.home??Ur(),".config","kilo")}function Vr(r={}){return ne(tt(r),"kilo.jsonc")}function rt(r={}){let e=tt(r),t=Vr(r);return[e,t]}import{homedir as zr}from"node:os";import{join as nt,resolve as ks}from"node:path";function ot(r={}){return r.cursorHome??nt(r.home??zr(),".cursor")}function Wr(r={}){return r.cursorConfigDir??process.env.CURSOR_CONFIG_DIR??(r.xdgConfigHome??process.env.XDG_CONFIG_HOME?nt(r.xdgConfigHome??process.env.XDG_CONFIG_HOME,"cursor"):void 0)??ot(r)}function it(r={}){return Array.from(new Set([ot(r),Wr(r)]))}import{homedir as Yr}from"node:os";import{join as Br,resolve as ws}from"node:path";function Jr(r={}){return r.copilotHome??process.env.COPILOT_HOME??Br(r.home??Yr(),".copilot")}function st(r={}){return[Jr(r)]}import{homedir as qr}from"node:os";import{join as Zr,resolve as Os}from"node:path";function Qr(r={}){return r.grokHome??process.env.GROK_HOME??Zr(r.home??qr(),".grok")}function ct(r={}){return[Qr(r)]}function rn(r){return tn("sh",["-lc",`command -v ${JSON.stringify(r)} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}function m(r){let e=r.commandExists(r.command),t=r.configPaths.filter(i=>ut(i)),n=t.length>0,o=[];e&&o.push(`command:${r.command}`);for(let i of t)o.push(`config:${i}`);return{agent:r.agent,detected:e||n,commandDetected:e,configDetected:n,evidence:o}}function at(r){let e=r.commands.filter(s=>r.commandExists(s)),t=r.configPaths.filter(s=>ut(s)),n=e.length>0,o=t.length>0,i=[...e.map(s=>`command:${s}`),...t.map(s=>`config:${s}`)];return{agent:r.agent,detected:n||o,commandDetected:n,configDetected:o,evidence:i}}function dt(r={}){let e=r.home??Xr(),t=r.commandExists??rn,n=r.codexHome??process.env.CODEX_HOME??en(e,".codex");return[m({agent:"agy",command:"agy",commandExists:t,configPaths:We({home:e})}),m({agent:"opencode",command:"opencode",commandExists:t,configPaths:[Be({home:e,xdgConfigHome:r.xdgConfigHome})]}),m({agent:"claude",command:"claude",commandExists:t,configPaths:[Je({home:e})]}),m({agent:"kiro",command:"kiro-cli",commandExists:t,configPaths:Ze({home:e,kiroHome:r.kiroHome})}),at({agent:"cursor",commands:["agent","cursor-agent"],commandExists:t,configPaths:it({home:e,cursorHome:r.cursorHome,cursorConfigDir:r.cursorConfigDir,xdgConfigHome:r.xdgConfigHome})}),m({agent:"copilot",command:"copilot",commandExists:t,configPaths:st({home:e,copilotHome:r.copilotHome})}),m({agent:"grok",command:"grok",commandExists:t,configPaths:ct({home:e,grokHome:r.grokHome})}),m({agent:"toolnet-cli",command:"toolnet",commandExists:t,configPaths:et({home:e})}),at({agent:"kilo",commands:["kilo","kilo-code"],commandExists:t,configPaths:rt({home:e,kiloHome:r.kiloHome})}),m({agent:"codex",command:"codex",commandExists:t,configPaths:[n]})]}import{existsSync as oe,readFileSync as nn}from"node:fs";var on="ToolNet Memory - ",sn=["SessionStart","UserPromptSubmit","PreToolUse","PostToolUse","Stop"];function S(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function lt(r){if(!oe(r))return{};let e;try{e=JSON.parse(nn(r,"utf8"))}catch(t){return{error:t instanceof Error?t.message:String(t)}}return S(e)?{value:e}:{error:"root must be a JSON object"}}function cn(r){if(!r||!S(r.mcpServers))return!1;let e=r.mcpServers["toolnet-memory"];return S(e)?typeof e.command=="string"&&e.command.trim().length>0&&Array.isArray(e.args)&&e.args.length===1&&e.args[0]==="mcp"&&e.disabled!==!0:!1}function an(r){if(!(!S(r)||!S(r.action)))return typeof r.action.command=="string"?r.action.command:void 0}function un(r){if(!r||r.version!=="v1"||!Array.isArray(r.hooks))return[];let e=new Set;for(let t of r.hooks){if(!S(t)||typeof t.name!="string"||!t.name.startsWith(on))continue;let n=an(t);!n||!n.includes("session:kiro-hook")||t.enabled!==!1&&typeof t.trigger=="string"&&e.add(t.trigger)}return[...e]}function pt(r={}){let e=r.configFile??re(),t=r.hooksFile??qe(),n=lt(e),o=lt(t),i=!n.error&&cn(n.value),s=o.error?[]:un(o.value),c=sn.every(p=>s.includes(p)),u=[];n.error&&u.push(`MCP config: ${n.error}`),o.error&&u.push(`Hooks config: ${o.error}`);let a=i&&c,f=oe(e)||oe(t),d=u.length>0?"invalid":a?"ready":f?"partial":"not-installed";return{installed:a,state:d,mcp:{configured:i,configFile:e,error:n.error},hooks:{configured:c,hooksFile:t,triggers:s,error:o.error},errors:u}}var dn={spinner:["\xB7","\u2722","\u2733","\u2736","\u273B","\u273D"],barFilled:"\u2588",barEmpty:"\u2591",phaseDone:"\u25C6",phaseActive:"\u25C7",rail:"\u2502",branch:"\u251C",corner:"\u2514",dash:"\u2014"},ln={spinner:[".","*","+","x","*","+"],barFilled:"#",barEmpty:"-",phaseDone:"[OK]",phaseActive:"[>>]",rail:"|",branch:"|",corner:"\\",dash:"-"};function pn(){if(process.env.TOOLNET_ASCII==="1")return!1;if(process.env.TOOLNET_UNICODE==="1")return!0;if(process.platform==="win32"){let r=process.env.TERM_PROGRAM,e=process.env.WT_SESSION,t=process.env.VSCODE_PID,n=process.env.ConEmuPID;return!!(e||t||n||r==="vscode")}return process.env.TERM!=="linux"}var ie;function ft(){return ie||(ie=pn()?dn:ln),ie}var C={reset:"\x1B[0m",green:"\x1B[32m",cyan:"\x1B[36m",red:"\x1B[31m",yellow:"\x1B[33m",amber:"\x1B[38;5;214m",white:"\x1B[97m",dim:"\x1B[2m",bold:"\x1B[1m"};function fn(r){return r.noColor||process.env.NO_COLOR?!1:r.tty??process.stdout.isTTY??!1}function _(r,e,t){return fn(t)?`${e}${r}${C.reset}`:r}function V(r,e){return _(r,C.dim,e)}function mn(r,e){return _(r,C.bold,e)}function gn(r,e){return _(r,C.cyan,e)}function yn(r,e){return _(r,C.red,e)}function hn(r,e){return _(r,C.white,e)}function mt(r,e,t){let n=ft(),o=e?` ${V(`v${e}`,t)}`:"";return`${gn(n.phaseDone,t)} ${r}${o}`}function z(r,e){return mn(r,e)}function x(r,e,t,n){let o=" ".repeat(Math.max(0,t-r.length));return` ${V(r,n)}${o} ${hn(e,n)}`}function gt(r){return yn("\u2717",r)}function xn(r){return{tty:r.tty,noColor:r.noColor}}async function kn(r){let e=xn(r);console.log(""),console.log(mt("ToolNet Status",void 0,e)),console.log("");try{let t=new L().detect(),n=se();console.log(z("PROJECT",e)),console.log(x("Name",t.name,8,e));let o=_e(Me({provider:n.storage.provider,r2:n.storage.r2,s3:n.storage.s3,huggingface:n.storage.huggingface,localRoot:n.storage.localRoot}),{attempts:3}),i=new U(o,t.id,t.name,t.remote??t.name),s="unknown",c="unknown";try{s=await i.exists(`${t.id}/memory.json`)?"ready":"not initialized"}catch{s="error"}try{c=await i.exists(`${t.id}/code-graph.json`)?"ready":"not built"}catch{c="error"}console.log(x("Memory",s,8,e)),console.log(x("Index",c,8,e)),console.log("");let u=dt(),a=u.filter(d=>d.detected).map(d=>d.agent);if(a.length>0){if(console.log(z("INTEGRATIONS",e)),console.log(x("Detected",a.join(", "),8,e)),u.find(p=>p.agent==="kiro")?.detected){let p=pt();console.log(x("Kiro",p.installed?"ready":p.state,8,e))}console.log("")}let f=Ue(t);if(f.agents.length>0){console.log(z("SERVICE",e));let d=f.syncHealth==="healthy"?"running":f.syncHealth==="degraded"?"degraded":"stopped";console.log(x("Daemon",d,8,e)),console.log("")}}catch(t){console.log(gt(e)+" Failed to get status"),console.log(""),console.log(V(` ${t instanceof Error?t.message:String(t)}`,e)),console.log(""),process.exitCode=1}}async function Sn(){let r=process.argv.slice(2),e={tty:process.stdout.isTTY,noColor:process.env.NO_COLOR!==void 0||r.includes("--no-color")};await kn(e)}Sn().catch(r=>{console.error(""),console.error(r instanceof Error?r.message:String(r)),console.error(""),process.exitCode=1});