toolnet-memory 0.3.9 → 0.3.10

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.
@@ -1,4 +1,4 @@
1
- import{existsSync as Ie,readFileSync as _e}from"node:fs";import{homedir as Pe}from"node:os";import{join as we}from"node:path";function Me(t){let e=t.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
2
- `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function Re(){let t=process.env.TOOLNET_GLOBAL_ENV??we(Pe(),".config","toolnet-memory",".env");if(!Ie(t))return;let e=_e(t,"utf8");for(let r of e.split(/\r?\n/)){let n=r.trim();if(!n||n.startsWith("#"))continue;n.startsWith("export ")&&(n=n.slice(7));let s=n.indexOf("=");if(s<=0)continue;let i=n.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(i)&&process.env[i]===void 0&&(process.env[i]=Me(n.slice(s+1)))}}Re();function S(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function A(t,e){if(!t)return e;let r=Number(t);return Number.isFinite(r)?r:e}function V(){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:A(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:A(process.env.MEMORY_RERANK_TOP,10),finalContext:A(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:A(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:A(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as je}from"node:crypto";import{existsSync as N,mkdirSync as Te,readFileSync as De,renameSync as Le,writeFileSync as Ne}from"node:fs";import{basename as Ke,dirname as _,join as w,parse as W,resolve as E}from"node:path";var J=".toolnet",Ue="project.json";function Fe(t){return je("sha256").update(t).digest("hex").slice(0,16)}function K(t){return w(t,J,Ue)}function $e(t){return N(K(t))}function Be(t,e){let r=E(t),n=W(r).root;for(;;){if($e(r))return r;if(r===n||e&&r===E(e))break;let s=_(r);if(s===r)break;r=s}return null}function Ge(t){let e=E(t),r=W(e).root,n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(n.some(i=>N(w(e,i))))return e;if(e===r)break;let s=_(e);if(s===e)break;e=s}return E(t)}function He(t){let e;try{e=JSON.parse(De(t,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${t}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${t}`);let r=e;if(typeof r.id!="string"||!r.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof r.name!="string"||!r.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let n=new Date().toISOString();return{version:1,id:r.id,name:r.name,remote:typeof r.remote=="string"&&r.remote.trim()?r.remote:r.name,rootPath:typeof r.rootPath=="string"?r.rootPath:_(_(t)),createdAt:typeof r.createdAt=="string"?r.createdAt:n,updatedAt:typeof r.updatedAt=="string"?r.updatedAt:n,graphVersion:typeof r.graphVersion=="number"?r.graphVersion:0,memoryVersion:typeof r.memoryVersion=="number"?r.memoryVersion:0,metadata:r.metadata&&typeof r.metadata=="object"?r.metadata:void 0}}function Y(t,e){let r=w(t,J);Te(r,{recursive:!0});let n=K(t),s=`${n}.tmp-${process.pid}`;Ne(s,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),Le(s,n)}function z(t,e){return{id:t.id,name:t.name,remote:t.remote,rootPath:e,createdAt:t.createdAt,updatedAt:t.updatedAt,graphVersion:t.graphVersion,memoryVersion:t.memoryVersion,metadata:t.metadata}}var P=class{detect(e=process.cwd()){let r=E(e),n=Ge(r),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(m=>N(w(n,m))),a=Be(r,i?n:void 0);if(a){let m=K(a),l=He(m);return l.rootPath!==a&&(l.rootPath=a,l.updatedAt=new Date().toISOString(),Y(a,l)),z(l,a)}let u=new Date().toISOString(),d=Ke(n),p={version:1,id:Fe(n),name:d,remote:d,rootPath:n,createdAt:u,updatedAt:u,graphVersion:0,memoryVersion:0};return Y(n,p),z(p,n)}};var q=[{id:"openai-compatible",label:"OpenAI-compatible",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"alibaba",label:"Alibaba / DashScope",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"openrouter",label:"OpenRouter",defaultBaseUrl:"https://openrouter.ai/api/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"groq",label:"Groq",defaultBaseUrl:"https://api.groq.com/openai/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"deepseek",label:"DeepSeek",defaultBaseUrl:"https://api.deepseek.com",defaultModel:"deepseek-v4-flash",requiresApiKey:!0,transport:"openai-compatible"},{id:"nvidia",label:"NVIDIA NIM",defaultBaseUrl:"https://integrate.api.nvidia.com/v1",defaultModel:"deepseek-ai/deepseek-v4-pro",requiresApiKey:!0,transport:"openai-compatible"},{id:"gemini",label:"Gemini",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta",requiresApiKey:!0,transport:"gemini"},{id:"huggingface",label:"Hugging Face",defaultBaseUrl:"https://router.huggingface.co/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"ollama",label:"Ollama / Local",defaultBaseUrl:"http://127.0.0.1:11434/v1",requiresApiKey:!1,transport:"openai-compatible"},{id:"custom",label:"Custom endpoint",requiresApiKey:!1,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"cloudflare",label:"Cloudflare Workers AI",requiresApiKey:!0,requiresAccountId:!0,transport:"cloudflare"}];function M(t){let e=q.find(r=>r.id===t);if(!e)throw new Error(`Unsupported AI provider: ${t}`);return e}function R(t){return q.some(e=>e.id===t)}function o(t){return process.env[t]?.trim()||void 0}function c(...t){return t.find(e=>!!e?.trim())}function Q(){if(o("GROQ_API_KEY"))return"groq";if(o("DEEPSEEK_API_KEY"))return"deepseek";if(o("NVIDIA_API_KEY")||o("NVIDIA_NIM_API_KEY"))return"nvidia";if(o("OPENROUTER_API_KEY"))return"openrouter";if(o("ALIBABA_API_KEY")||o("DASHSCOPE_API_KEY"))return"alibaba";if(o("GEMINI_API_KEY")||o("GOOGLE_API_KEY"))return"gemini";if(o("CLOUDFLARE_API_TOKEN")&&o("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(o("HF_TOKEN"))return"huggingface";if(o("OLLAMA_MODEL")||o("OLLAMA_BASE_URL"))return"ollama"}function Ve(){let t=o("TOOLNET_LLM_PROVIDER");return t&&R(t)?t:Q()??"openai-compatible"}function U(t){let e=M(t);switch(t){case"alibaba":return{provider:t,apiKey:c(o("ALIBABA_API_KEY"),o("DASHSCOPE_API_KEY")),baseUrl:c(o("ALIBABA_BASE_URL"),o("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:c(o("ALIBABA_MODEL"),o("DASHSCOPE_MODEL"))};case"openrouter":return{provider:t,apiKey:o("OPENROUTER_API_KEY"),baseUrl:c(o("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:o("OPENROUTER_MODEL")};case"groq":return{provider:t,apiKey:o("GROQ_API_KEY"),baseUrl:c(o("GROQ_BASE_URL"),e.defaultBaseUrl),model:o("GROQ_MODEL")};case"deepseek":return{provider:t,apiKey:o("DEEPSEEK_API_KEY"),baseUrl:c(o("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:c(o("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:t,apiKey:c(o("NVIDIA_API_KEY"),o("NVIDIA_NIM_API_KEY")),baseUrl:c(o("NVIDIA_BASE_URL"),o("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:c(o("NVIDIA_MODEL"),o("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:t,apiKey:c(o("GEMINI_API_KEY"),o("GOOGLE_API_KEY")),baseUrl:c(o("GEMINI_BASE_URL"),e.defaultBaseUrl),model:o("GEMINI_MODEL")};case"huggingface":return{provider:t,apiKey:o("HF_TOKEN"),baseUrl:c(o("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:c(o("HF_LLM_MODEL"),o("HF_MODEL"))};case"ollama":return{provider:t,apiKey:o("OLLAMA_API_KEY"),baseUrl:c(o("OLLAMA_BASE_URL"),e.defaultBaseUrl),model:o("OLLAMA_MODEL")};case"cloudflare":return{provider:t,accountId:o("CLOUDFLARE_ACCOUNT_ID"),apiKey:o("CLOUDFLARE_API_TOKEN"),baseUrl:o("CLOUDFLARE_AI_BASE_URL"),model:o("CLOUDFLARE_MODEL")};case"custom":return{provider:t,apiKey:o("CUSTOM_AI_API_KEY"),baseUrl:o("CUSTOM_AI_BASE_URL"),model:o("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:c(o("OPENAI_API_KEY"),o("MODEL_API_KEY")),baseUrl:c(o("OPENAI_BASE_URL"),o("MODEL_BASE_URL")),model:c(o("OPENAI_MODEL"),o("MODEL_NAME"))}}}function Ye(){let t=o("TOOLNET_LLM_PROVIDER"),e=t&&R(t)?t:Ve(),r=M(e),n=U(e);return{provider:e,apiKey:c(o("TOOLNET_LLM_API_KEY"),n.apiKey),baseUrl:c(o("TOOLNET_LLM_BASE_URL"),n.baseUrl,r.defaultBaseUrl),model:c(o("TOOLNET_LLM_MODEL"),n.model,r.defaultModel),accountId:c(o("TOOLNET_LLM_ACCOUNT_ID"),n.accountId)}}function ze(){let t=o("TOOLNET_EMBEDDING_PROVIDER");return t==="local"?"local":t&&R(t)?t:o("HF_TOKEN")||o("HF_EMBEDDING_MODEL")?"huggingface":"local"}function We(){let t=ze();if(t==="local")return{provider:"local",model:c(o("TOOLNET_EMBEDDING_MODEL"),o("LOCAL_EMBEDDING_MODEL"))};let e=M(t),r,n,s,i;switch(t){case"huggingface":r=o("HF_TOKEN"),n=o("HF_INFERENCE_BASE_URL"),s=o("HF_EMBEDDING_MODEL");break;case"openai-compatible":r=o("OPENAI_API_KEY"),n=o("OPENAI_BASE_URL"),s=o("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":r=o("CLOUDFLARE_API_TOKEN"),n=o("CLOUDFLARE_AI_BASE_URL"),s=o("CLOUDFLARE_EMBEDDING_MODEL"),i=o("CLOUDFLARE_ACCOUNT_ID");break;default:r=U(t).apiKey,n=U(t).baseUrl,s=o(`${t.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let a=c(o("TOOLNET_EMBEDDING_ACCOUNT_ID"),i),u=c(o("TOOLNET_EMBEDDING_BASE_URL"),n,e.defaultBaseUrl),d=t==="cloudflare"&&!u&&a?`https://api.cloudflare.com/client/v4/accounts/${a}/ai/v1`:u;return{provider:t,apiKey:c(o("TOOLNET_EMBEDDING_API_KEY"),r),baseUrl:d,model:c(o("TOOLNET_EMBEDDING_MODEL"),s),accountId:a}}function Z(){let t=Ye(),e=We();return{llm:t,embedding:e,legacy:{llm:!o("TOOLNET_LLM_PROVIDER")&&!!Q(),embedding:!o("TOOLNET_EMBEDDING_PROVIDER")&&!!(o("HF_TOKEN")||o("HF_EMBEDDING_MODEL"))}}}import{homedir as ht}from"node:os";import{join as St}from"node:path";import{DeleteObjectCommand as Je,GetObjectCommand as qe,HeadObjectCommand as Qe,ListObjectsV2Command as Ze,PutObjectCommand as Xe,S3Client as et}from"@aws-sdk/client-s3";import{getSignedUrl as tt}from"@aws-sdk/s3-request-presigner";var j=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new et({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,r,n="application/octet-stream"){let s=typeof r=="string"?Buffer.from(r,"utf8"):r;await this.client.send(new Xe({Bucket:this.bucket,Key:e,Body:s,ContentType:n}))}async get(e){let r=await tt(this.client,new qe({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(r,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`HF download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await this.client.send(new Qe({Bucket:this.bucket,Key:e})),!0}catch(r){if(typeof r=="object"&&r!==null&&"$metadata"in r&&r.$metadata?.httpStatusCode===404)return!1;throw r}}async delete(e){await this.client.send(new Je({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],n;do{let s=await this.client.send(new Ze({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let i of s.Contents??[])i.Key&&r.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});n=s.IsTruncated?s.NextContinuationToken:void 0}while(n);return r}};import{access as X,mkdir as rt,readFile as nt,readdir as ot,rm as st,stat as ee,writeFile as it}from"node:fs/promises";import{dirname as at,join as ct,relative as te,resolve as lt}from"node:path";var b=class{constructor(e){this.root=e}root;name="local";path(e){let r=e.replace(/^\/+/,"");return lt(this.root,r)}async put(e,r){let n=this.path(e);await rt(at(n),{recursive:!0}),await it(n,r)}async get(e){try{return await nt(this.path(e))}catch(r){if(typeof r=="object"&&r!==null&&"code"in r&&r.code==="ENOENT")return null;throw r}}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await X(this.path(e)),!0}catch{return!1}}async delete(e){await st(this.path(e),{force:!0})}async list(e=""){let r=this.path(e),n=[];try{await X(r)}catch{return n}let s=async a=>{let u=await ot(a,{withFileTypes:!0});for(let d of u){let p=ct(a,d.name);if(d.isDirectory()){await s(p);continue}let m=await ee(p);n.push({key:te(this.root,p),size:m.size,updatedAt:m.mtime.toISOString()})}},i=await ee(r);return i.isDirectory()?await s(r):n.push({key:te(this.root,r),size:i.size,updatedAt:i.mtime.toISOString()}),n}};import{DeleteObjectCommand as ut,GetObjectCommand as dt,HeadObjectCommand as pt,ListObjectsV2Command as gt,PutObjectCommand as mt,S3Client as ft}from"@aws-sdk/client-s3";import{getSignedUrl as yt}from"@aws-sdk/s3-request-presigner";var k=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new ft({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,r,n="application/octet-stream"){let s=typeof r=="string"?Buffer.from(r,"utf8"):r;await this.client.send(new mt({Bucket:this.bucket,Key:e,Body:s,ContentType:n}))}async get(e){let r=await yt(this.client,new dt({Bucket:this.bucket,Key:e}),{expiresIn:60}),n=await fetch(r,{redirect:"follow"});if(n.status===404)return null;if(!n.ok)throw new Error(`${this.name} download failed: ${n.status} ${n.statusText}`);return new Uint8Array(await n.arrayBuffer())}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await this.client.send(new pt({Bucket:this.bucket,Key:e})),!0}catch(r){if(typeof r=="object"&&r!==null&&"$metadata"in r&&r.$metadata?.httpStatusCode===404)return!1;throw r}}async delete(e){await this.client.send(new ut({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],n;do{let s=await this.client.send(new gt({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:n}));for(let i of s.Contents??[])i.Key&&r.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});n=s.IsTruncated?s.NextContinuationToken:void 0}while(n);return r}};function F(t,e){return console.warn(e),new b(t)}function re(t){let e=t.localRoot??St(ht(),".toolnet-memory","storage");if(t.provider==="r2"){let r=t.r2;return r?.accountId&&r.bucket&&r.accessKeyId&&r.secretAccessKey?new k({name:"r2",endpoint:`https://${r.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:r.bucket,forcePathStyle:!0,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):F(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let r=t.s3;return r?.bucket&&r.accessKeyId&&r.secretAccessKey?new k({name:"s3",endpoint:r.endpoint,region:r.region??"us-east-1",bucket:r.bucket,forcePathStyle:r.forcePathStyle??!1,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):F(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let r=t.huggingface;return r?.namespace&&r.bucket&&r.accessKeyId&&r.secretAccessKey?new j({namespace:r.namespace,bucket:r.bucket,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):F(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new b(e)}function At(t){return new Promise(e=>setTimeout(e,t))}async function ne(t,e={}){let r=Math.max(1,e.attempts??3),n=e.baseDelayMs??150,s=e.maxDelayMs??2e3,i;for(let a=1;a<=r;a++)try{return await t()}catch(u){if(i=u,a>=r)break;let d=Math.min(s,n*2**(a-1)),p=Math.floor(Math.random()*Math.max(1,d*.2));await At(d+p)}throw i}var Et=new Set(["put","get","getText","delete","list"]);function oe(t,e={}){return new Proxy(t,{get(r,n){let s=Reflect.get(r,n,r);return typeof s!="function"?s:Et.has(n)?(...i)=>ne(()=>Promise.resolve(s.apply(r,i)),e):s.bind(r)}})}function se(t){let e=t.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function ie(t){let e=t.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let r=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var T=class{constructor(e,r,n,s){this.provider=e;this.name=e.name,this.projectId=r,this.projectName=n,this.folder=se(s??n),this.sourcePrefix=`projects/${r}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,r=new Date().toISOString(),n=r,s=await this.provider.getText(e);if(s){let a;try{a=JSON.parse(s)}catch(u){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${u instanceof Error?u.message:String(u)}`)}if(typeof a.id=="string"&&a.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${a.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof a.createdAt=="string"&&(n=a.createdAt)}let i={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:n,updatedAt:r};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=ie(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,r,n){return await this.ensureRegistered(),this.provider.put(this.key(e),r,n)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{existsSync as ue,readFileSync as Ct,readdirSync as ce}from"node:fs";import{join as D}from"node:path";import{existsSync as bt,mkdirSync as so,readFileSync as kt,renameSync as io,writeFileSync as ao}from"node:fs";import{dirname as lo,join as vt}from"node:path";function Ot(t){return vt(t.rootPath,".toolnet","work","current.json")}function ae(t){let e=Ot(t);if(!bt(e))return null;try{let r=JSON.parse(kt(e,"utf8"));return r.version!==1||r.projectId!==t.id?null:r}catch{return null}}function de(t){if(!ue(t))return null;try{return JSON.parse(Ct(t,"utf8"))}catch{return null}}function xt(t){let e=D(t.rootPath,".toolnet","sessions");if(!ue(e))return[];let r=[];for(let n of ce(e,{withFileTypes:!0})){if(!n.isDirectory())continue;let s=D(e,n.name);for(let i of ce(s,{withFileTypes:!0})){if(!i.isDirectory())continue;let a=de(D(s,i.name,"state.json"));!a||a.version!==1||a.projectId!==t.id||r.push(a)}}return r}function le(t){return t.filter(e=>!!e).sort().at(-1)}function It(t){let e=de(D(t.rootPath,".toolnet","runtime","opencode-status.json"));return!e||e.projectRoot&&e.projectRoot!==t.rootPath?null:e}function pe(t){let e=xt(t),n=[...e].sort((l,g)=>(l.lastLocalEventAt??l.updatedAt).localeCompare(g.lastLocalEventAt??g.updatedAt)).at(-1),s=Array.from(new Set(e.map(l=>l.agent))).sort(),i=e.reduce((l,g)=>l+Math.max(0,g.lastSequence-g.lastRemoteSequence),0),a=It(t),u=a?.state==="capture-failed",d=a?.state==="sync-failed",p;u?p="degraded":i>0||d?p="pending":e.length>0?p="healthy":p="unknown";let m=ae(t);return{ok:p!=="degraded",agents:s,sessions:e.length,latestAgent:n?.agent,latestSessionId:n?.nativeSessionId,lastCaptureAt:le(e.map(l=>l.lastLocalEventAt??l.updatedAt)),lastFlushAt:le(e.map(l=>l.lastRemoteAt)),pendingWal:i,currentTask:m?.currentTask?.title,currentFile:m?.activeFiles?.at(-1)??m?.filesTouched.at(-1),syncHealth:p,opencode:a?{state:a.state,reason:a.reason,timestamp:a.timestamp,error:a.error}:void 0}}import{existsSync as Nt}from"node:fs";import{homedir as Kt}from"node:os";import{join as Ut}from"node:path";import{spawnSync as Ft}from"node:child_process";import{homedir as _t}from"node:os";import{join as $}from"node:path";function ge(t={}){return $(t.home??_t(),".gemini")}function Pt(t={}){return $(ge(t),"config")}function wt(t={}){return $(ge(t),"antigravity-cli")}function me(t={}){return[wt(t),Pt(t)]}import{homedir as Mt}from"node:os";import{join as fe}from"node:path";function ye(t={}){let e=t.xdgConfigHome??process.env.XDG_CONFIG_HOME?.trim();return e?fe(e,"opencode"):fe(t.home??Mt(),".config","opencode")}import{homedir as Rt}from"node:os";import{join as jt}from"node:path";function he(t={}){return jt(t.home??Rt(),".claude")}import{homedir as Tt}from"node:os";import{join as v}from"node:path";function B(t={}){return t.kiroHome??process.env.KIRO_HOME??v(t.home??Tt(),".kiro")}function Dt(t={}){return v(B(t),"settings")}function Se(t={}){return v(Dt(t),"mcp.json")}function Lt(t={}){return v(B(t),"hooks")}function Ae(t={}){return v(Lt(t),"toolnet-memory.json")}function Ee(t={}){return[B(t)]}function $t(t){return Ft("sh",["-lc",`command -v ${JSON.stringify(t)} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}function O(t){let e=t.commandExists(t.command),r=t.configPaths.filter(i=>Nt(i)),n=r.length>0,s=[];e&&s.push(`command:${t.command}`);for(let i of r)s.push(`config:${i}`);return{agent:t.agent,detected:e||n,commandDetected:e,configDetected:n,evidence:s}}function be(t={}){let e=t.home??Kt(),r=t.commandExists??$t,n=t.codexHome??process.env.CODEX_HOME??Ut(e,".codex");return[O({agent:"agy",command:"agy",commandExists:r,configPaths:me({home:e})}),O({agent:"opencode",command:"opencode",commandExists:r,configPaths:[ye({home:e,xdgConfigHome:t.xdgConfigHome})]}),O({agent:"claude",command:"claude",commandExists:r,configPaths:[he({home:e})]}),O({agent:"kiro",command:"kiro-cli",commandExists:r,configPaths:Ee({home:e,kiroHome:t.kiroHome})}),O({agent:"codex",command:"codex",commandExists:r,configPaths:[n]})]}import{existsSync as G,readFileSync as Bt}from"node:fs";var Gt="ToolNet Memory - ",Ht=["SessionStart","UserPromptSubmit","PreToolUse","PostToolUse","Stop"];function y(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function ke(t){if(!G(t))return{};let e;try{e=JSON.parse(Bt(t,"utf8"))}catch(r){return{error:r instanceof Error?r.message:String(r)}}return y(e)?{value:e}:{error:"root must be a JSON object"}}function Vt(t){if(!t||!y(t.mcpServers))return!1;let e=t.mcpServers["toolnet-memory"];return y(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 Yt(t){if(!(!y(t)||!y(t.action)))return typeof t.action.command=="string"?t.action.command:void 0}function zt(t){if(!t||t.version!=="v1"||!Array.isArray(t.hooks))return[];let e=new Set;for(let r of t.hooks){if(!y(r)||typeof r.name!="string"||!r.name.startsWith(Gt))continue;let n=Yt(r);!n||!n.includes("session:kiro-hook")||r.enabled!==!1&&typeof r.trigger=="string"&&e.add(r.trigger)}return[...e]}function ve(t={}){let e=t.configFile??Se(),r=t.hooksFile??Ae(),n=ke(e),s=ke(r),i=!n.error&&Vt(n.value),a=s.error?[]:zt(s.value),u=Ht.every(g=>a.includes(g)),d=[];n.error&&d.push(`MCP config: ${n.error}`),s.error&&d.push(`Hooks config: ${s.error}`);let p=i&&u,m=G(e)||G(r),l=d.length>0?"invalid":p?"ready":m?"partial":"not-installed";return{installed:p,state:l,mcp:{configured:i,configFile:e,error:n.error},hooks:{configured:u,hooksFile:r,triggers:a,error:s.error},errors:d}}var Wt={spinner:["\xB7","\u2722","\u2733","\u2736","\u273B","\u273D"],barFilled:"\u2588",barEmpty:"\u2591",phaseDone:"\u25C6",phaseActive:"\u25C7",rail:"\u2502",branch:"\u251C",corner:"\u2514",dash:"\u2014"},Jt={spinner:[".","*","+","x","*","+"],barFilled:"#",barEmpty:"-",phaseDone:"[OK]",phaseActive:"[>>]",rail:"|",branch:"|",corner:"\\",dash:"-"};function qt(){if(process.env.TOOLNET_ASCII==="1")return!1;if(process.env.TOOLNET_UNICODE==="1")return!0;if(process.platform==="win32"){let t=process.env.TERM_PROGRAM,e=process.env.WT_SESSION,r=process.env.VSCODE_PID,n=process.env.ConEmuPID;return!!(e||r||n||t==="vscode")}return process.env.TERM!=="linux"}var H;function Oe(){return H||(H=qt()?Wt:Jt),H}var h={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 Qt(t){return t.noColor||process.env.NO_COLOR?!1:t.tty??process.stdout.isTTY??!1}function C(t,e,r){return Qt(r)?`${e}${t}${h.reset}`:t}function L(t,e){return C(t,h.dim,e)}function Zt(t,e){return C(t,h.bold,e)}function Xt(t,e){return C(t,h.cyan,e)}function er(t,e){return C(t,h.red,e)}function tr(t,e){return C(t,h.white,e)}function Ce(t,e,r){let n=Oe(),s=e?` ${L(`v${e}`,r)}`:"";return`${Xt(n.phaseDone,r)} ${t}${s}`}function x(t,e){return Zt(t,e)}function f(t,e,r,n){let s=" ".repeat(Math.max(0,r-t.length));return` ${L(t,n)}${s} ${tr(e,n)}`}function xe(t){return er("\u2717",t)}function rr(t){return{tty:t.tty,noColor:t.noColor}}async function nr(t){let e=rr(t);console.log(""),console.log(Ce("ToolNet Status",void 0,e)),console.log("");try{let r=new P().detect(),n=V(),s=Z();console.log(x("PROJECT",e)),console.log(f("Name",r.name,8,e));let i=oe(re({provider:n.storage.provider,r2:n.storage.r2,s3:n.storage.s3,huggingface:n.storage.huggingface,localRoot:n.storage.localRoot}),{attempts:3}),a=new T(i,r.id,r.name,r.remote??r.name),u="unknown",d="unknown";try{u=await a.exists(`${r.id}/memory.json`)?"ready":"not initialized"}catch{u="error"}try{d=await a.exists(`${r.id}/code-graph.json`)?"ready":"not built"}catch{d="error"}console.log(f("Memory",u,8,e)),console.log(f("Index",d,8,e)),console.log(""),console.log(x("AI",e)),console.log(f("Provider",s.llm.provider,8,e)),console.log(f("Model",s.llm.model??"not set",8,e)),console.log("");let p=be(),m=p.filter(g=>g.detected).map(g=>g.agent);if(m.length>0){if(console.log(x("INTEGRATIONS",e)),console.log(f("Detected",m.join(", "),8,e)),p.find(I=>I.agent==="kiro")?.detected){let I=ve();console.log(f("Kiro",I.installed?"ready":I.state,8,e))}console.log("")}let l=pe(r);if(l.agents.length>0){console.log(x("SERVICE",e));let g=l.syncHealth==="healthy"?"running":l.syncHealth==="degraded"?"degraded":"stopped";console.log(f("Daemon",g,8,e)),console.log("")}}catch(r){console.log(xe(e)+" Failed to get status"),console.log(""),console.log(L(` ${r instanceof Error?r.message:String(r)}`,e)),console.log(""),process.exitCode=1}}async function or(){let t=process.argv.slice(2),e={tty:process.stdout.isTTY,noColor:process.env.NO_COLOR!==void 0||t.includes("--no-color")};await nr(e)}or().catch(t=>{console.error(""),console.error(t instanceof Error?t.message:String(t)),console.error(""),process.exitCode=1});
1
+ import{existsSync as Re,readFileSync as je}from"node:fs";import{homedir as De}from"node:os";import{join as Te}from"node:path";function Le(t){let e=t.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
2
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function Ne(){let t=process.env.TOOLNET_GLOBAL_ENV??Te(De(),".config","toolnet-memory",".env");if(!Re(t))return;let e=je(t,"utf8");for(let r of e.split(/\r?\n/)){let o=r.trim();if(!o||o.startsWith("#"))continue;o.startsWith("export ")&&(o=o.slice(7));let i=o.indexOf("=");if(i<=0)continue;let s=o.slice(0,i).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=Le(o.slice(i+1)))}}Ne();function C(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function k(t,e){if(!t)return e;let r=Number(t);return Number.isFinite(r)?r:e}function V(){return{memory:{autoCapture:C(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:C(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:C(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:C(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:k(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:k(process.env.MEMORY_RERANK_TOP,10),finalContext:k(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:k(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:C(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:k(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Ke}from"node:crypto";import{existsSync as N,mkdirSync as Ue,readFileSync as Fe,renameSync as $e,writeFileSync as Be}from"node:fs";import{basename as He,dirname as P,join as M,parse as W,resolve as A}from"node:path";var J=".toolnet",Ge="project.json";function Ve(t){return Ke("sha256").update(t).digest("hex").slice(0,16)}function K(t){return M(t,J,Ge)}function Ye(t){return N(K(t))}function ze(t,e){let r=A(t),o=W(r).root;for(;;){if(Ye(r))return r;if(r===o||e&&r===A(e))break;let i=P(r);if(i===r)break;r=i}return null}function We(t){let e=A(t),r=W(e).root,o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(o.some(s=>N(M(e,s))))return e;if(e===r)break;let i=P(e);if(i===e)break;e=i}return A(t)}function Je(t){let e;try{e=JSON.parse(Fe(t,"utf8"))}catch(i){throw new Error(`Invalid ToolNet project manifest: ${t}: ${i instanceof Error?i.message:String(i)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${t}`);let r=e;if(typeof r.id!="string"||!r.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof r.name!="string"||!r.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let o=new Date().toISOString();return{version:1,id:r.id,name:r.name,remote:typeof r.remote=="string"&&r.remote.trim()?r.remote:r.name,rootPath:typeof r.rootPath=="string"?r.rootPath:P(P(t)),createdAt:typeof r.createdAt=="string"?r.createdAt:o,updatedAt:typeof r.updatedAt=="string"?r.updatedAt:o,graphVersion:typeof r.graphVersion=="number"?r.graphVersion:0,memoryVersion:typeof r.memoryVersion=="number"?r.memoryVersion:0,metadata:r.metadata&&typeof r.metadata=="object"?r.metadata:void 0}}function Y(t,e){let r=M(t,J);Ue(r,{recursive:!0});let o=K(t),i=`${o}.tmp-${process.pid}`;Be(i,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),$e(i,o)}function z(t,e){return{id:t.id,name:t.name,remote:t.remote,rootPath:e,createdAt:t.createdAt,updatedAt:t.updatedAt,graphVersion:t.graphVersion,memoryVersion:t.memoryVersion,metadata:t.metadata}}var _=class{detect(e=process.cwd()){let r=A(e),o=We(r),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(m=>N(M(o,m))),a=ze(r,s?o:void 0);if(a){let m=K(a),u=Je(m);return u.rootPath!==a&&(u.rootPath=a,u.updatedAt=new Date().toISOString(),Y(a,u)),z(u,a)}let l=new Date().toISOString(),p=He(o),d={version:1,id:Ve(o),name:p,remote:p,rootPath:o,createdAt:l,updatedAt:l,graphVersion:0,memoryVersion:0};return Y(o,d),z(d,o)}};var q=[{id:"openai-compatible",label:"OpenAI-compatible",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"alibaba",label:"Alibaba / DashScope",requiresApiKey:!0,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"openrouter",label:"OpenRouter",defaultBaseUrl:"https://openrouter.ai/api/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"groq",label:"Groq",defaultBaseUrl:"https://api.groq.com/openai/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"deepseek",label:"DeepSeek",defaultBaseUrl:"https://api.deepseek.com",defaultModel:"deepseek-v4-flash",requiresApiKey:!0,transport:"openai-compatible"},{id:"nvidia",label:"NVIDIA NIM",defaultBaseUrl:"https://integrate.api.nvidia.com/v1",defaultModel:"deepseek-ai/deepseek-v4-pro",requiresApiKey:!0,transport:"openai-compatible"},{id:"gemini",label:"Gemini",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta",requiresApiKey:!0,transport:"gemini"},{id:"huggingface",label:"Hugging Face",defaultBaseUrl:"https://router.huggingface.co/v1",requiresApiKey:!0,transport:"openai-compatible"},{id:"ollama",label:"Ollama / Local",defaultBaseUrl:"http://127.0.0.1:11434/v1",requiresApiKey:!1,transport:"openai-compatible"},{id:"custom",label:"Custom endpoint",requiresApiKey:!1,requiresBaseUrl:!0,transport:"openai-compatible"},{id:"cloudflare",label:"Cloudflare Workers AI",requiresApiKey:!0,requiresAccountId:!0,transport:"cloudflare"}];function w(t){let e=q.find(r=>r.id===t);if(!e)throw new Error(`Unsupported AI provider: ${t}`);return e}function R(t){return q.some(e=>e.id===t)}function n(t){return process.env[t]?.trim()||void 0}function c(...t){return t.find(e=>!!e?.trim())}function Q(){if(n("GROQ_API_KEY"))return"groq";if(n("DEEPSEEK_API_KEY"))return"deepseek";if(n("NVIDIA_API_KEY")||n("NVIDIA_NIM_API_KEY"))return"nvidia";if(n("OPENROUTER_API_KEY"))return"openrouter";if(n("ALIBABA_API_KEY")||n("DASHSCOPE_API_KEY"))return"alibaba";if(n("GEMINI_API_KEY")||n("GOOGLE_API_KEY"))return"gemini";if(n("CLOUDFLARE_API_TOKEN")&&n("CLOUDFLARE_ACCOUNT_ID"))return"cloudflare";if(n("HF_TOKEN"))return"huggingface";if(n("OLLAMA_MODEL")||n("OLLAMA_BASE_URL"))return"ollama"}function qe(){let t=n("TOOLNET_LLM_PROVIDER");return t&&R(t)?t:Q()??"openai-compatible"}function U(t){let e=w(t);switch(t){case"alibaba":return{provider:t,apiKey:c(n("ALIBABA_API_KEY"),n("DASHSCOPE_API_KEY")),baseUrl:c(n("ALIBABA_BASE_URL"),n("DASHSCOPE_BASE_URL"),e.defaultBaseUrl),model:c(n("ALIBABA_MODEL"),n("DASHSCOPE_MODEL"))};case"openrouter":return{provider:t,apiKey:n("OPENROUTER_API_KEY"),baseUrl:c(n("OPENROUTER_BASE_URL"),e.defaultBaseUrl),model:n("OPENROUTER_MODEL")};case"groq":return{provider:t,apiKey:n("GROQ_API_KEY"),baseUrl:c(n("GROQ_BASE_URL"),e.defaultBaseUrl),model:n("GROQ_MODEL")};case"deepseek":return{provider:t,apiKey:n("DEEPSEEK_API_KEY"),baseUrl:c(n("DEEPSEEK_BASE_URL"),e.defaultBaseUrl),model:c(n("DEEPSEEK_MODEL"),e.defaultModel)};case"nvidia":return{provider:t,apiKey:c(n("NVIDIA_API_KEY"),n("NVIDIA_NIM_API_KEY")),baseUrl:c(n("NVIDIA_BASE_URL"),n("NVIDIA_NIM_BASE_URL"),e.defaultBaseUrl),model:c(n("NVIDIA_MODEL"),n("NVIDIA_NIM_MODEL"),e.defaultModel)};case"gemini":return{provider:t,apiKey:c(n("GEMINI_API_KEY"),n("GOOGLE_API_KEY")),baseUrl:c(n("GEMINI_BASE_URL"),e.defaultBaseUrl),model:n("GEMINI_MODEL")};case"huggingface":return{provider:t,apiKey:n("HF_TOKEN"),baseUrl:c(n("HF_INFERENCE_BASE_URL"),e.defaultBaseUrl),model:c(n("HF_LLM_MODEL"),n("HF_MODEL"))};case"ollama":return{provider:t,apiKey:n("OLLAMA_API_KEY"),baseUrl:c(n("OLLAMA_BASE_URL"),e.defaultBaseUrl),model:n("OLLAMA_MODEL")};case"cloudflare":return{provider:t,accountId:n("CLOUDFLARE_ACCOUNT_ID"),apiKey:n("CLOUDFLARE_API_TOKEN"),baseUrl:n("CLOUDFLARE_AI_BASE_URL"),model:n("CLOUDFLARE_MODEL")};case"custom":return{provider:t,apiKey:n("CUSTOM_AI_API_KEY"),baseUrl:n("CUSTOM_AI_BASE_URL"),model:n("CUSTOM_AI_MODEL")};default:return{provider:"openai-compatible",apiKey:c(n("OPENAI_API_KEY"),n("MODEL_API_KEY")),baseUrl:c(n("OPENAI_BASE_URL"),n("MODEL_BASE_URL")),model:c(n("OPENAI_MODEL"),n("MODEL_NAME"))}}}function Qe(){let t=n("TOOLNET_LLM_PROVIDER"),e=t&&R(t)?t:qe(),r=w(e),o=U(e);return{provider:e,apiKey:c(n("TOOLNET_LLM_API_KEY"),o.apiKey),baseUrl:c(n("TOOLNET_LLM_BASE_URL"),o.baseUrl,r.defaultBaseUrl),model:c(n("TOOLNET_LLM_MODEL"),o.model,r.defaultModel),accountId:c(n("TOOLNET_LLM_ACCOUNT_ID"),o.accountId)}}function Ze(){let t=n("TOOLNET_EMBEDDING_PROVIDER");return t==="local"?"local":t&&R(t)?t:n("HF_TOKEN")||n("HF_EMBEDDING_MODEL")?"huggingface":"local"}function Xe(){let t=Ze();if(t==="local")return{provider:"local",model:c(n("TOOLNET_EMBEDDING_MODEL"),n("LOCAL_EMBEDDING_MODEL"))};let e=w(t),r,o,i,s;switch(t){case"huggingface":r=n("HF_TOKEN"),o=n("HF_INFERENCE_BASE_URL"),i=n("HF_EMBEDDING_MODEL");break;case"openai-compatible":r=n("OPENAI_API_KEY"),o=n("OPENAI_BASE_URL"),i=n("OPENAI_EMBEDDING_MODEL");break;case"cloudflare":r=n("CLOUDFLARE_API_TOKEN"),o=n("CLOUDFLARE_AI_BASE_URL"),i=n("CLOUDFLARE_EMBEDDING_MODEL"),s=n("CLOUDFLARE_ACCOUNT_ID");break;default:r=U(t).apiKey,o=U(t).baseUrl,i=n(`${t.toUpperCase().replace(/-/g,"_")}_EMBEDDING_MODEL`)}let a=c(n("TOOLNET_EMBEDDING_ACCOUNT_ID"),s),l=c(n("TOOLNET_EMBEDDING_BASE_URL"),o,e.defaultBaseUrl),p=t==="cloudflare"&&!l&&a?`https://api.cloudflare.com/client/v4/accounts/${a}/ai/v1`:l;return{provider:t,apiKey:c(n("TOOLNET_EMBEDDING_API_KEY"),r),baseUrl:p,model:c(n("TOOLNET_EMBEDDING_MODEL"),i),accountId:a}}function Z(){let t=Qe(),e=Xe();return{llm:t,embedding:e,legacy:{llm:!n("TOOLNET_LLM_PROVIDER")&&!!Q(),embedding:!n("TOOLNET_EMBEDDING_PROVIDER")&&!!(n("HF_TOKEN")||n("HF_EMBEDDING_MODEL"))}}}import{homedir as Ot}from"node:os";import{join as Et}from"node:path";import{DeleteObjectCommand as et,GetObjectCommand as tt,HeadObjectCommand as rt,ListObjectsV2Command as ot,PutObjectCommand as nt,S3Client as it}from"@aws-sdk/client-s3";import{getSignedUrl as st}from"@aws-sdk/s3-request-presigner";var j=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new it({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,r,o="application/octet-stream"){let i=typeof r=="string"?Buffer.from(r,"utf8"):r;await this.client.send(new nt({Bucket:this.bucket,Key:e,Body:i,ContentType:o}))}async get(e){let r=await st(this.client,new tt({Bucket:this.bucket,Key:e}),{expiresIn:60}),o=await fetch(r,{redirect:"follow"});if(o.status===404)return null;if(!o.ok)throw new Error(`HF download failed: ${o.status} ${o.statusText}`);return new Uint8Array(await o.arrayBuffer())}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await this.client.send(new rt({Bucket:this.bucket,Key:e})),!0}catch(r){if(typeof r=="object"&&r!==null&&"$metadata"in r&&r.$metadata?.httpStatusCode===404)return!1;throw r}}async delete(e){await this.client.send(new et({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],o;do{let i=await this.client.send(new ot({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let s of i.Contents??[])s.Key&&r.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});o=i.IsTruncated?i.NextContinuationToken:void 0}while(o);return r}};import{access as X,mkdir as at,readFile as ct,readdir as ut,rm as lt,stat as ee,writeFile as pt}from"node:fs/promises";import{dirname as dt,join as gt,relative as te,resolve as mt}from"node:path";var O=class{constructor(e){this.root=e}root;name="local";path(e){let r=e.replace(/^\/+/,"");return mt(this.root,r)}async put(e,r){let o=this.path(e);await at(dt(o),{recursive:!0}),await pt(o,r)}async get(e){try{return await ct(this.path(e))}catch(r){if(typeof r=="object"&&r!==null&&"code"in r&&r.code==="ENOENT")return null;throw r}}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await X(this.path(e)),!0}catch{return!1}}async delete(e){await lt(this.path(e),{force:!0})}async list(e=""){let r=this.path(e),o=[];try{await X(r)}catch{return o}let i=async a=>{let l=await ut(a,{withFileTypes:!0});for(let p of l){let d=gt(a,p.name);if(p.isDirectory()){await i(d);continue}let m=await ee(d);o.push({key:te(this.root,d),size:m.size,updatedAt:m.mtime.toISOString()})}},s=await ee(r);return s.isDirectory()?await i(r):o.push({key:te(this.root,r),size:s.size,updatedAt:s.mtime.toISOString()}),o}};import{DeleteObjectCommand as ft,GetObjectCommand as yt,HeadObjectCommand as ht,ListObjectsV2Command as St,PutObjectCommand as Ct,S3Client as kt}from"@aws-sdk/client-s3";import{getSignedUrl as At}from"@aws-sdk/s3-request-presigner";var E=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new kt({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,r,o="application/octet-stream"){let i=typeof r=="string"?Buffer.from(r,"utf8"):r;await this.client.send(new Ct({Bucket:this.bucket,Key:e,Body:i,ContentType:o}))}async get(e){let r=await At(this.client,new yt({Bucket:this.bucket,Key:e}),{expiresIn:60}),o=await fetch(r,{redirect:"follow"});if(o.status===404)return null;if(!o.ok)throw new Error(`${this.name} download failed: ${o.status} ${o.statusText}`);return new Uint8Array(await o.arrayBuffer())}async getText(e){let r=await this.get(e);return r?Buffer.from(r).toString("utf8"):null}async exists(e){try{return await this.client.send(new ht({Bucket:this.bucket,Key:e})),!0}catch(r){if(typeof r=="object"&&r!==null&&"$metadata"in r&&r.$metadata?.httpStatusCode===404)return!1;throw r}}async delete(e){await this.client.send(new ft({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],o;do{let i=await this.client.send(new St({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let s of i.Contents??[])s.Key&&r.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});o=i.IsTruncated?i.NextContinuationToken:void 0}while(o);return r}};function F(t,e){return console.warn(e),new O(t)}function re(t){let e=t.localRoot??Et(Ot(),".toolnet-memory","storage");if(t.provider==="r2"){let r=t.r2;return r?.accountId&&r.bucket&&r.accessKeyId&&r.secretAccessKey?new E({name:"r2",endpoint:`https://${r.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:r.bucket,forcePathStyle:!0,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):F(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(t.provider==="s3"){let r=t.s3;return r?.bucket&&r.accessKeyId&&r.secretAccessKey?new E({name:"s3",endpoint:r.endpoint,region:r.region??"us-east-1",bucket:r.bucket,forcePathStyle:r.forcePathStyle??!1,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):F(e,"[storage] S3 credentials missing. Using local fallback.")}if(t.provider==="huggingface"){let r=t.huggingface;return r?.namespace&&r.bucket&&r.accessKeyId&&r.secretAccessKey?new j({namespace:r.namespace,bucket:r.bucket,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):F(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new O(e)}function bt(t){return new Promise(e=>setTimeout(e,t))}async function oe(t,e={}){let r=Math.max(1,e.attempts??3),o=e.baseDelayMs??150,i=e.maxDelayMs??2e3,s;for(let a=1;a<=r;a++)try{return await t()}catch(l){if(s=l,a>=r)break;let p=Math.min(i,o*2**(a-1)),d=Math.floor(Math.random()*Math.max(1,p*.2));await bt(p+d)}throw s}var xt=new Set(["put","get","getText","delete","list"]);function ne(t,e={}){return new Proxy(t,{get(r,o){let i=Reflect.get(r,o,r);return typeof i!="function"?i:xt.has(o)?(...s)=>oe(()=>Promise.resolve(i.apply(r,s)),e):i.bind(r)}})}function ie(t){let e=t.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function se(t){let e=t.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let r=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(o)return`${o[1]}memory/records/${o[2]}`;if(o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),o)return`${o[1]}memory/vectors/${o[2]}`;if(o=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),o)return`${o[1]}code/graph/${o[2]}`;let i=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return i?`${i[1]}memory/records/${i[2]}`:(i=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),i?`${i[1]}memory/vectors/${i[2]}`:(i=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),i?`${i[1]}code/graph/${i[2]}`:e))}var D=class{constructor(e,r,o,i){this.provider=e;this.name=e.name,this.projectId=r,this.projectName=o,this.folder=ie(i??o),this.sourcePrefix=`projects/${r}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,r=new Date().toISOString(),o=r,i=await this.provider.getText(e);if(i){let a;try{a=JSON.parse(i)}catch(l){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${l instanceof Error?l.message:String(l)}`)}if(typeof a.id=="string"&&a.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${a.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof a.createdAt=="string"&&(o=a.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:o,updatedAt:r};await this.provider.put(e,JSON.stringify(s,null,2)+`
4
+ `,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=se(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,r,o){return await this.ensureRegistered(),this.provider.put(this.key(e),r,o)}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 le,readFileSync as Mt,readdirSync as ce}from"node:fs";import{join as T}from"node:path";import{existsSync as vt,mkdirSync as Cn,readFileSync as It,renameSync as kn,writeFileSync as An}from"node:fs";import{dirname as En,join as Pt}from"node:path";function _t(t){return Pt(t.rootPath,".toolnet","work","current.json")}function ae(t){let e=_t(t);if(!vt(e))return null;try{let r=JSON.parse(It(e,"utf8"));return r.version!==1||r.projectId!==t.id?null:r}catch{return null}}function pe(t){if(!le(t))return null;try{return JSON.parse(Mt(t,"utf8"))}catch{return null}}function wt(t){let e=T(t.rootPath,".toolnet","sessions");if(!le(e))return[];let r=[];for(let o of ce(e,{withFileTypes:!0})){if(!o.isDirectory())continue;let i=T(e,o.name);for(let s of ce(i,{withFileTypes:!0})){if(!s.isDirectory())continue;let a=pe(T(i,s.name,"state.json"));!a||a.version!==1||a.projectId!==t.id||r.push(a)}}return r}function ue(t){return t.filter(e=>!!e).sort().at(-1)}function Rt(t){let e=pe(T(t.rootPath,".toolnet","runtime","opencode-status.json"));return!e||e.projectRoot&&e.projectRoot!==t.rootPath?null:e}function de(t){let e=wt(t),o=[...e].sort((u,g)=>(u.lastLocalEventAt??u.updatedAt).localeCompare(g.lastLocalEventAt??g.updatedAt)).at(-1),i=Array.from(new Set(e.map(u=>u.agent))).sort(),s=e.reduce((u,g)=>u+Math.max(0,g.lastSequence-g.lastRemoteSequence),0),a=Rt(t),l=a?.state==="capture-failed",p=a?.state==="sync-failed",d;l?d="degraded":s>0||p?d="pending":e.length>0?d="healthy":d="unknown";let m=ae(t);return{ok:d!=="degraded",agents:i,sessions:e.length,latestAgent:o?.agent,latestSessionId:o?.nativeSessionId,lastCaptureAt:ue(e.map(u=>u.lastLocalEventAt??u.updatedAt)),lastFlushAt:ue(e.map(u=>u.lastRemoteAt)),pendingWal:s,currentTask:m?.currentTask?.title,currentFile:m?.activeFiles?.at(-1)??m?.filesTouched.at(-1),syncHealth:d,opencode:a?{state:a.state,reason:a.reason,timestamp:a.timestamp,error:a.error}:void 0}}import{existsSync as qt}from"node:fs";import{homedir as Qt}from"node:os";import{join as Zt}from"node:path";import{spawnSync as Xt}from"node:child_process";import{homedir as jt}from"node:os";import{join as $}from"node:path";function ge(t={}){return $(t.home??jt(),".gemini")}function Dt(t={}){return $(ge(t),"config")}function Tt(t={}){return $(ge(t),"antigravity-cli")}function me(t={}){return[Tt(t),Dt(t)]}import{homedir as Lt}from"node:os";import{join as fe}from"node:path";function ye(t={}){let e=t.xdgConfigHome??process.env.XDG_CONFIG_HOME?.trim();return e?fe(e,"opencode"):fe(t.home??Lt(),".config","opencode")}import{homedir as Nt}from"node:os";import{join as Kt}from"node:path";function he(t={}){return Kt(t.home??Nt(),".claude")}import{homedir as Ut}from"node:os";import{join as b}from"node:path";function B(t={}){return t.kiroHome??process.env.KIRO_HOME??b(t.home??Ut(),".kiro")}function Ft(t={}){return b(B(t),"settings")}function Se(t={}){return b(Ft(t),"mcp.json")}function $t(t={}){return b(B(t),"hooks")}function Ce(t={}){return b($t(t),"toolnet-memory.json")}function ke(t={}){return[B(t)]}import{homedir as Bt}from"node:os";import{join as Ae}from"node:path";function Oe(t={}){return t.cursorHome??Ae(t.home??Bt(),".cursor")}function Ht(t={}){return t.cursorConfigDir??process.env.CURSOR_CONFIG_DIR??(t.xdgConfigHome??process.env.XDG_CONFIG_HOME?Ae(t.xdgConfigHome??process.env.XDG_CONFIG_HOME,"cursor"):void 0)??Oe(t)}function Ee(t={}){return Array.from(new Set([Oe(t),Ht(t)]))}import{homedir as Gt}from"node:os";import{join as Vt}from"node:path";function Yt(t={}){return t.copilotHome??process.env.COPILOT_HOME??Vt(t.home??Gt(),".copilot")}function be(t={}){return[Yt(t)]}import{homedir as zt}from"node:os";import{join as Wt}from"node:path";function Jt(t={}){return t.grokHome??process.env.GROK_HOME??Wt(t.home??zt(),".grok")}function xe(t={}){return[Jt(t)]}function er(t){return Xt("sh",["-lc",`command -v ${JSON.stringify(t)} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}function y(t){let e=t.commandExists(t.command),r=t.configPaths.filter(s=>qt(s)),o=r.length>0,i=[];e&&i.push(`command:${t.command}`);for(let s of r)i.push(`config:${s}`);return{agent:t.agent,detected:e||o,commandDetected:e,configDetected:o,evidence:i}}function ve(t={}){let e=t.home??Qt(),r=t.commandExists??er,o=t.codexHome??process.env.CODEX_HOME??Zt(e,".codex");return[y({agent:"agy",command:"agy",commandExists:r,configPaths:me({home:e})}),y({agent:"opencode",command:"opencode",commandExists:r,configPaths:[ye({home:e,xdgConfigHome:t.xdgConfigHome})]}),y({agent:"claude",command:"claude",commandExists:r,configPaths:[he({home:e})]}),y({agent:"kiro",command:"kiro-cli",commandExists:r,configPaths:ke({home:e,kiroHome:t.kiroHome})}),y({agent:"cursor",command:"agent",commandExists:r,configPaths:Ee({home:e,cursorHome:t.cursorHome,cursorConfigDir:t.cursorConfigDir,xdgConfigHome:t.xdgConfigHome})}),y({agent:"copilot",command:"copilot",commandExists:r,configPaths:be({home:e,copilotHome:t.copilotHome})}),y({agent:"grok",command:"grok",commandExists:r,configPaths:xe({home:e,grokHome:t.grokHome})}),y({agent:"codex",command:"codex",commandExists:r,configPaths:[o]})]}import{existsSync as H,readFileSync as tr}from"node:fs";var rr="ToolNet Memory - ",or=["SessionStart","UserPromptSubmit","PreToolUse","PostToolUse","Stop"];function h(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Ie(t){if(!H(t))return{};let e;try{e=JSON.parse(tr(t,"utf8"))}catch(r){return{error:r instanceof Error?r.message:String(r)}}return h(e)?{value:e}:{error:"root must be a JSON object"}}function nr(t){if(!t||!h(t.mcpServers))return!1;let e=t.mcpServers["toolnet-memory"];return h(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 ir(t){if(!(!h(t)||!h(t.action)))return typeof t.action.command=="string"?t.action.command:void 0}function sr(t){if(!t||t.version!=="v1"||!Array.isArray(t.hooks))return[];let e=new Set;for(let r of t.hooks){if(!h(r)||typeof r.name!="string"||!r.name.startsWith(rr))continue;let o=ir(r);!o||!o.includes("session:kiro-hook")||r.enabled!==!1&&typeof r.trigger=="string"&&e.add(r.trigger)}return[...e]}function Pe(t={}){let e=t.configFile??Se(),r=t.hooksFile??Ce(),o=Ie(e),i=Ie(r),s=!o.error&&nr(o.value),a=i.error?[]:sr(i.value),l=or.every(g=>a.includes(g)),p=[];o.error&&p.push(`MCP config: ${o.error}`),i.error&&p.push(`Hooks config: ${i.error}`);let d=s&&l,m=H(e)||H(r),u=p.length>0?"invalid":d?"ready":m?"partial":"not-installed";return{installed:d,state:u,mcp:{configured:s,configFile:e,error:o.error},hooks:{configured:l,hooksFile:r,triggers:a,error:i.error},errors:p}}var ar={spinner:["\xB7","\u2722","\u2733","\u2736","\u273B","\u273D"],barFilled:"\u2588",barEmpty:"\u2591",phaseDone:"\u25C6",phaseActive:"\u25C7",rail:"\u2502",branch:"\u251C",corner:"\u2514",dash:"\u2014"},cr={spinner:[".","*","+","x","*","+"],barFilled:"#",barEmpty:"-",phaseDone:"[OK]",phaseActive:"[>>]",rail:"|",branch:"|",corner:"\\",dash:"-"};function ur(){if(process.env.TOOLNET_ASCII==="1")return!1;if(process.env.TOOLNET_UNICODE==="1")return!0;if(process.platform==="win32"){let t=process.env.TERM_PROGRAM,e=process.env.WT_SESSION,r=process.env.VSCODE_PID,o=process.env.ConEmuPID;return!!(e||r||o||t==="vscode")}return process.env.TERM!=="linux"}var G;function _e(){return G||(G=ur()?ar:cr),G}var S={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 lr(t){return t.noColor||process.env.NO_COLOR?!1:t.tty??process.stdout.isTTY??!1}function x(t,e,r){return lr(r)?`${e}${t}${S.reset}`:t}function L(t,e){return x(t,S.dim,e)}function pr(t,e){return x(t,S.bold,e)}function dr(t,e){return x(t,S.cyan,e)}function gr(t,e){return x(t,S.red,e)}function mr(t,e){return x(t,S.white,e)}function Me(t,e,r){let o=_e(),i=e?` ${L(`v${e}`,r)}`:"";return`${dr(o.phaseDone,r)} ${t}${i}`}function v(t,e){return pr(t,e)}function f(t,e,r,o){let i=" ".repeat(Math.max(0,r-t.length));return` ${L(t,o)}${i} ${mr(e,o)}`}function we(t){return gr("\u2717",t)}function fr(t){return{tty:t.tty,noColor:t.noColor}}async function yr(t){let e=fr(t);console.log(""),console.log(Me("ToolNet Status",void 0,e)),console.log("");try{let r=new _().detect(),o=V(),i=Z();console.log(v("PROJECT",e)),console.log(f("Name",r.name,8,e));let s=ne(re({provider:o.storage.provider,r2:o.storage.r2,s3:o.storage.s3,huggingface:o.storage.huggingface,localRoot:o.storage.localRoot}),{attempts:3}),a=new D(s,r.id,r.name,r.remote??r.name),l="unknown",p="unknown";try{l=await a.exists(`${r.id}/memory.json`)?"ready":"not initialized"}catch{l="error"}try{p=await a.exists(`${r.id}/code-graph.json`)?"ready":"not built"}catch{p="error"}console.log(f("Memory",l,8,e)),console.log(f("Index",p,8,e)),console.log(""),console.log(v("AI",e)),console.log(f("Provider",i.llm.provider,8,e)),console.log(f("Model",i.llm.model??"not set",8,e)),console.log("");let d=ve(),m=d.filter(g=>g.detected).map(g=>g.agent);if(m.length>0){if(console.log(v("INTEGRATIONS",e)),console.log(f("Detected",m.join(", "),8,e)),d.find(I=>I.agent==="kiro")?.detected){let I=Pe();console.log(f("Kiro",I.installed?"ready":I.state,8,e))}console.log("")}let u=de(r);if(u.agents.length>0){console.log(v("SERVICE",e));let g=u.syncHealth==="healthy"?"running":u.syncHealth==="degraded"?"degraded":"stopped";console.log(f("Daemon",g,8,e)),console.log("")}}catch(r){console.log(we(e)+" Failed to get status"),console.log(""),console.log(L(` ${r instanceof Error?r.message:String(r)}`,e)),console.log(""),process.exitCode=1}}async function hr(){let t=process.argv.slice(2),e={tty:process.stdout.isTTY,noColor:process.env.NO_COLOR!==void 0||t.includes("--no-color")};await yr(e)}hr().catch(t=>{console.error(""),console.error(t instanceof Error?t.message:String(t)),console.error(""),process.exitCode=1});
package/bundle/update.js CHANGED
@@ -1,4 +1,5 @@
1
- import v from"node:fs";import c from"node:path";import{fileURLToPath as b}from"node:url";import{spawn as $}from"node:child_process";var m=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],i={clear:"\r\x1B[2K",cyan:"\x1B[36m",green:"\x1B[32m",red:"\x1B[31m",yellow:"\x1B[33m",amber:"\x1B[38;5;214m",dim:"\x1B[2m",reset:"\x1B[0m"};function p(t,e=16){let o=Math.max(1,e-4+1),r=t%o;return"\u2500".repeat(r)+"\u2501".repeat(4)+"\u2500".repeat(Math.max(0,e-r-4))}function f(t){let e=Date.now()-t;return e<1e3?`${e}ms`:e<1e4?`${(e/1e3).toFixed(1)}s`:`${Math.round(e/1e3)}s`}var d=class{stream;enabled;interactive;color;intervalMs;display;label;frame=0;startedAt=0;timer;active=!1;constructor(e,s={}){this.label=e,this.stream=s.stream??process.stderr,this.enabled=s.enabled??!0,this.interactive=s.interactive??this.stream.isTTY===!0,this.color=s.color??(this.interactive&&process.env.NO_COLOR===void 0),this.intervalMs=Math.max(40,s.intervalMs??80),this.display=s.display??"spinner"}start(){return!this.enabled||this.active?this:(this.active=!0,this.startedAt=Date.now(),this.interactive?(this.render(),this.timer=setInterval(()=>{this.frame=(this.frame+1)%1e4,this.render()},this.intervalMs),this.timer.unref?.(),this):(this.stream.write(`\u2192 ${this.label}
2
- `),this))}update(e){return this.label=e,this.enabled&&this.active&&this.interactive&&this.render(),this}succeed(e){this.finish("\u2713",e??this.label,i.green)}fail(e){this.finish("\u2717",e??this.label,i.red)}warn(e){this.finish("!",e??this.label,i.yellow)}stop(){this.active&&(this.timer&&(clearInterval(this.timer),this.timer=void 0),this.enabled&&this.interactive&&this.stream.write(i.clear),this.active=!1)}render(){if(!this.enabled||!this.active||!this.interactive)return;let e=m[this.frame%m.length],s=this.display==="bar"?this.color?`${i.amber}${p(this.frame)}${i.reset}`:p(this.frame):this.color?`${i.cyan}${e}${i.reset}`:e,o=f(this.startedAt),r=this.color?`${i.dim}${o}${i.reset}`:o;this.stream.write(`${i.clear}${s} ${this.label} ${r}`)}finish(e,s,o){if(!this.enabled){this.active=!1;return}this.startedAt||(this.startedAt=Date.now()),this.timer&&(clearInterval(this.timer),this.timer=void 0);let r=f(this.startedAt),a=this.color?`${o}${e}${i.reset}`:e,l=this.color?`${i.dim}${r}${i.reset}`:r;this.interactive?this.stream.write(`${i.clear}${a} ${s} ${l}
3
- `):this.stream.write(`${a} ${s} (${r})
4
- `),this.active=!1}};var h="toolnet-memory";function g(t,e){return new Promise((s,o)=>{let r=$(t,e,{stdio:["ignore","pipe","pipe"],env:process.env}),a="",l="";r.stdout?.setEncoding("utf8"),r.stderr?.setEncoding("utf8"),r.stdout?.on("data",n=>{a+=n}),r.stderr?.on("data",n=>{l+=n}),r.once("error",o),r.once("close",n=>{s({status:n??1,stdout:a,stderr:l})})})}function y(){let t=c.dirname(b(import.meta.url));return c.resolve(t,"..")}function w(t){try{let e=JSON.parse(v.readFileSync(c.join(t,"package.json"),"utf8"));return String(e.version??"unknown")}catch{return"unknown"}}function x(t){let e=`${c.sep}lib${c.sep}node_modules${c.sep}${h}`;return t.endsWith(e)?t.slice(0,-e.length)||c.parse(t).root:null}async function C(){let t=y(),e=w(t);console.log(""),console.log("\u25C7 ToolNet Memory Update"),console.log(""),console.log("\u2502");let s=new d("Checking npm registry",{stream:process.stdout,display:"bar",intervalMs:180}).start(),o;try{o=await g("npm",["view",`${h}@latest`,"version","--silent"])}catch(u){throw s.fail("Unable to reach npm registry"),u}if(o.status!==0){s.fail("Unable to check latest version"),o.stderr.trim()&&console.error(o.stderr.trim()),process.exitCode=1;return}let r=o.stdout.trim();if(s.succeed("Checking registry \u2014 done"),console.log("\u2502"),console.log(`\u25C6 Current v${e}`),console.log(`\u25C6 Latest v${r}`),console.log("\u2502"),e===r){console.log("\u2514 \u25C6 Already up to date"),console.log("");return}let a=x(t);if(!a){console.log("This appears to be a development checkout."),console.log(""),console.log("Self-update is disabled for source checkouts."),console.log(""),console.log("For the published CLI, install/update with:"),console.log(" npm install -g toolnet-memory@latest"),console.log(""),process.exitCode=1;return}let l=new d("Downloading & installing",{stream:process.stdout,display:"bar",intervalMs:180}).start(),n;try{n=await g("npm",["install","-g","--prefix",a,`${h}@${r}`,"--no-fund","--no-audit","--loglevel=error"])}catch(u){throw l.fail("ToolNet Memory update failed"),u}if(n.status!==0){l.fail("ToolNet Memory update failed"),n.stderr.trim()&&(console.error(""),console.error(n.stderr.trim())),console.error(""),console.error("Retry with:"),console.error(` npm install -g ${h}@${r}`),console.error(""),process.exitCode=n.status||1;return}l.succeed("Downloading & installing \u2014 done"),console.log("\u2502"),console.log(`\u2514 \u25C6 Updated to v${r}`),console.log("")}C().catch(t=>{console.error(""),console.error(t instanceof Error?t.message:String(t)),console.error(""),process.exitCode=1});
1
+ import I from"node:fs";import p from"node:path";import{fileURLToPath as _}from"node:url";import{spawn as N}from"node:child_process";function v(){if(process.argv.includes("--no-color"))return!1;if(process.argv.includes("--color"))return!0;let e=process.env.NO_COLOR;if(e!==void 0&&e!=="")return!1;let t=process.env.FORCE_COLOR;if(t!==void 0&&t!=="")return t!=="0"&&t.toLowerCase()!=="false";if(process.stdout.isTTY===!0&&process.env.TERM!=="dumb")return!0;let r=process.env.CI;return r!==void 0&&r!==""}var o={reset:"\x1B[0m",amber:"\x1B[38;5;214m",green:"\x1B[32m",red:"\x1B[31m",dim:"\x1B[2m",bold:"\x1B[1m"},k=50,U=68;function m(e,t,r){return Math.min(r,Math.max(t,e))}function $(e){let t=Math.max(0,e);return t<1e4?`${(t/1e3).toFixed(1)}s`:`${Math.round(t/1e3)}s`}function M(e){return e.replace(/\x1b\[[0-9;]*m/g,"").length}function L(e,t){if(M(e)<=t)return e;let r=e.replace(/\x1b\[[0-9;]*m/g,"");return t<=1?r.slice(0,t):`${r.slice(0,Math.max(0,t-1))}\u2026`}function R(e,t){let r=L(e,t),n=Math.max(0,t-M(r));return`${r}${" ".repeat(n)}`}function a(e,t,r){return r?`${t}${e}${o.reset}`:e}function u(e,t){let r=t-4;return`\u2502 ${R(e,r)} \u2502`}function F(e){return`\u251C${"\u2500".repeat(e-2)}\u2524`}function A(e,t){let r=" ToolNet Memory Update ",n=a(r,`${o.bold}${o.amber}`,t),s=Math.max(0,e-r.length-2);return`\u250C${n}${"\u2500".repeat(s)}\u2510`}function D(e){return`\u2514${"\u2500".repeat(e-2)}\u2518`}function E(e,t){return e.failed?a(e.status,o.red,t):e.completed?a(e.status,o.green,t):a(e.status,o.amber,t)}function O(e,t,r){let n=t-4,s=m(Math.round(e.percent),0,100),l=$(e.elapsedMs),i=`${s}%`,c=1+i.length+2+l.length,d=Math.max(12,n-c-2),g=m(Math.round(d*s/100),0,d),b="\u2588".repeat(g),P="\u2591".repeat(d-g),w=e.completed?a(b,o.green,r):a(b,o.amber,r),T=a(P,o.dim,r),y=e.completed?a(i,o.green,r):a(i,o.amber,r),C=a(l,o.dim,r);return u(`[${w}${T}] ${y} ${C}`,t)}function V(e,t=80,r={}){let n=m(t-2,k,U),s=r.color??!1,l=e.latest==="checking\u2026"?e.latest:`v${e.latest}`,i=`Step ${e.step}/${e.totalSteps} ${e.label}`,c=e.completed?a(i,o.green,s):a(i,o.amber,s),d=a(`ETA: ${$(e.etaMs)}`,o.dim,s);return[A(n,s),u(`Current : v${e.current}`,n),u(`Latest : ${l}`,n),u(`Status : ${E(e,s)}`,n),F(n),u(c,n),O(e,n,s),u(d,n),D(n)].join(`
2
+ `)}var f=class{stream;interactive;color;totalSteps=4;current;latest="checking\u2026";status="Preparing...";step=1;label="Checking registry";percent=0;etaMs=0;completed=!1;failed=!1;operationStartedAt=Date.now();stepStartedAt=Date.now();fromPercent=0;toPercent=0;estimatedMs=1;timer;renderedLines=0;constructor(t,r={}){this.current=t,this.stream=r.stream??process.stdout,this.interactive=r.interactive??this.stream.isTTY===!0,this.color=r.color??(this.interactive&&v())}setLatest(t){this.latest=t,this.draw()}startStep(t){this.stopTimer(),this.step=t.step,this.label=t.label,this.status=t.status??"Updating...",this.fromPercent=m(t.fromPercent,0,100),this.toPercent=m(t.toPercent,this.fromPercent,100),this.percent=this.fromPercent,this.estimatedMs=Math.max(250,t.estimatedMs),this.stepStartedAt=Date.now(),this.etaMs=this.estimatedMs,this.completed=!1,this.failed=!1,this.draw(),!(!this.interactive||this.fromPercent>=this.toPercent)&&(this.timer=setInterval(()=>{this.tick()},100),this.timer.unref?.())}completeStep(t){this.stopTimer(),this.percent=m(t,0,100),this.etaMs=0,this.draw()}succeed(t){this.stopTimer(),this.latest=t,this.status="Updated successfully",this.step=4,this.label="Complete",this.percent=100,this.etaMs=0,this.completed=!0,this.failed=!1,this.draw(!0)}alreadyUpToDate(){this.stopTimer(),this.status="Already up to date",this.step=4,this.label="Complete",this.percent=100,this.etaMs=0,this.completed=!0,this.failed=!1,this.draw(!0)}fail(t){this.stopTimer(),this.status=`Failed: ${t}`,this.etaMs=0,this.completed=!1,this.failed=!0,this.draw(!0)}tick(){let t=Date.now()-this.stepStartedAt,r=1-Math.exp(-t/(this.estimatedMs*.45)),n=Math.min(.96,r);this.percent=this.fromPercent+(this.toPercent-this.fromPercent)*n;let s=r>.02?t/r:this.estimatedMs;this.etaMs=Math.max(250,s-t),this.draw()}draw(t=!1){let r=V({current:this.current,latest:this.latest,status:this.status,step:this.step,totalSteps:this.totalSteps,label:this.label,percent:this.percent,elapsedMs:Date.now()-this.operationStartedAt,etaMs:this.etaMs,completed:this.completed,failed:this.failed},this.stream.columns??80,{color:this.color}),n=r.split(`
3
+ `);if(!this.interactive){(t||this.renderedLines===0)&&this.stream.write(`${r}
4
+ `),this.renderedLines=n.length;return}this.renderedLines>0&&this.stream.write(`\x1B[${this.renderedLines}A`);for(let s of n)this.stream.write(`\x1B[2K${s}
5
+ `);this.renderedLines=n.length}stopTimer(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}};var h="toolnet-memory";function x(e,t){return new Promise((r,n)=>{let s=N(e,t,{stdio:["ignore","pipe","pipe"],env:process.env}),l="",i="";s.stdout?.setEncoding("utf8"),s.stderr?.setEncoding("utf8"),s.stdout?.on("data",c=>{l+=c}),s.stderr?.on("data",c=>{i+=c}),s.once("error",n),s.once("close",c=>{r({status:c??1,stdout:l,stderr:i})})})}function W(){let e=p.dirname(_(import.meta.url));return p.resolve(e,"..")}function S(e){try{let t=JSON.parse(I.readFileSync(p.join(e,"package.json"),"utf8"));return String(t.version??"unknown")}catch{return"unknown"}}function j(e){let t=`${p.sep}lib${p.sep}node_modules${p.sep}${h}`;return e.endsWith(t)?e.slice(0,-t.length)||p.parse(e).root:null}async function Y(){let e=W(),t=S(e),r=new f(t);r.startStep({step:1,label:"Checking registry",fromPercent:0,toPercent:18,estimatedMs:2500,status:"Checking for updates..."});let n;try{n=await x("npm",["view",`${h}@latest`,"version","--silent"])}catch(d){throw r.fail("Unable to reach npm registry"),d}if(n.status!==0){r.fail("Unable to check latest version"),n.stderr.trim()&&console.error(n.stderr.trim()),process.exitCode=1;return}let s=n.stdout.trim();if(r.setLatest(s),r.completeStep(20),t===s){r.alreadyUpToDate();return}let l=j(e);if(!l){r.fail("Self-update unavailable in source checkout"),console.error(""),console.error("For a source checkout, update the published CLI with:"),console.error(` npm install -g ${h}@latest`),console.error(""),process.exitCode=1;return}r.startStep({step:2,label:"Downloading & installing package",fromPercent:20,toPercent:88,estimatedMs:15e3,status:"Updating..."});let i;try{i=await x("npm",["install","-g","--prefix",l,`${h}@${s}`,"--no-fund","--no-audit","--loglevel=error"])}catch(d){throw r.fail("Package installation failed"),d}if(i.status!==0){r.fail("Package installation failed"),i.stderr.trim()&&(console.error(""),console.error(i.stderr.trim())),console.error(""),console.error("Retry with:"),console.error(` npm install -g ${h}@${s}`),console.error(""),process.exitCode=i.status||1;return}r.completeStep(90),r.startStep({step:3,label:"Verifying installation",fromPercent:90,toPercent:98,estimatedMs:1200,status:"Verifying..."});let c=S(e);if(c!==s){r.fail(`Version verification failed (${c} != ${s})`),process.exitCode=1;return}r.completeStep(99),r.succeed(s)}Y().catch(e=>{console.error(""),console.error(e instanceof Error?e.message:String(e)),console.error(""),process.exitCode=1});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolnet-memory",
3
- "version": "0.3.9",
3
+ "version": "0.3.10",
4
4
  "description": "Persistent project memory, work continuity, and code intelligence for AI coding agents.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,7 +25,13 @@
25
25
  "antigravity",
26
26
  "code-intelligence",
27
27
  "kiro",
28
- "kiro-cli"
28
+ "kiro-cli",
29
+ "cursor",
30
+ "cursor-cli",
31
+ "github-copilot",
32
+ "copilot-cli",
33
+ "grok",
34
+ "grok-build"
29
35
  ],
30
36
  "scripts": {
31
37
  "dev": "tsx src/index.ts",
@@ -78,7 +84,14 @@
78
84
  "session:kiro-mcp:test": "vitest run tests/session/kiro-mcp-installer.test.ts",
79
85
  "session:kiro:test": "vitest run tests/session/kiro-event-mapper.test.ts tests/session/kiro-hook-installer.test.ts tests/session/kiro-runtime.test.ts",
80
86
  "session:kiro-continuity:test": "vitest run tests/session/kiro-continuity.test.ts",
81
- "session:kiro-integration:test": "vitest run tests/session/kiro-integration.test.ts tests/production/kiro-auto-integrate.test.ts"
87
+ "session:kiro-integration:test": "vitest run tests/session/kiro-integration.test.ts tests/production/kiro-auto-integrate.test.ts",
88
+ "session:cursor-mcp:test": "vitest run tests/session/cursor-mcp-installer.test.ts",
89
+ "session:copilot-mcp:test": "vitest run tests/session/copilot-mcp-installer.test.ts",
90
+ "session:grok-mcp:test": "vitest run tests/session/grok-mcp-installer.test.ts",
91
+ "session:new-agents:test": "vitest run tests/session/new-agent-event-mappers.test.ts tests/session/new-agent-hook-installers.test.ts tests/session/new-agent-runtime.test.ts",
92
+ "session:new-agents-continuity:test": "vitest run tests/session/new-agent-continuity.test.ts tests/session/new-agent-continuity-installers.test.ts",
93
+ "session:new-agents-integration:test": "vitest run tests/session/new-agent-integrations.test.ts tests/production/new-agent-auto-integrate.test.ts tests/production/new-agent-production-wiring.test.ts",
94
+ "release:certify:8": "vitest run tests/integration/cross-agent-continuity.test.ts tests/production/eight-agent-release-contract.test.ts"
82
95
  },
83
96
  "dependencies": {
84
97
  "@aws-sdk/client-s3": "^3.1102.0",