toolnet-memory 0.3.14 → 0.3.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +0 -1
- package/.release-target +1 -1
- package/README.md +182 -6
- package/bin/toolnet-memory +5 -0
- package/bundle/agy-hook.js +71 -71
- package/bundle/agy.js +65 -65
- package/bundle/api.js +15 -15
- package/bundle/auto-integrate.js +28 -28
- package/bundle/background-refresh.js +7 -7
- package/bundle/claude-hook.js +51 -50
- package/bundle/codex-context.js +29 -28
- package/bundle/codex.js +77 -77
- package/bundle/context-runtime.js +44 -43
- package/bundle/context.js +15 -15
- package/bundle/continuity-certify.js +13 -13
- package/bundle/copilot-hook.js +88 -86
- package/bundle/copilot.js +4 -4
- package/bundle/cursor-hook.js +88 -86
- package/bundle/cursor.js +4 -4
- package/bundle/doctor.js +4 -4
- package/bundle/full-index.js +21 -21
- package/bundle/gc.js +3 -0
- package/bundle/graph-index.js +4 -4
- package/bundle/graph-ui.js +3 -3
- package/bundle/grok-hook.js +64 -63
- package/bundle/grok.js +5 -5
- package/bundle/handoff-refresh.js +10 -10
- package/bundle/help-cli.js +3 -3
- package/bundle/impact.js +4 -4
- package/bundle/incremental.js +5 -4
- package/bundle/init.js +38 -37
- package/bundle/integration-status.js +4 -4
- package/bundle/kiro-hook.js +93 -92
- package/bundle/learner.js +6 -6
- package/bundle/mcp.js +17 -17
- package/bundle/memory-agent.js +7 -7
- package/bundle/memory-query.js +7 -7
- package/bundle/opencode.js +84 -84
- package/bundle/project-manual.js +7 -7
- package/bundle/recovery-certify.js +15 -15
- package/bundle/runtime.js +13 -12
- package/bundle/semantic.js +5 -5
- package/bundle/snapshot.js +4 -4
- package/bundle/status-cli.js +4 -4
- package/bundle/toolnet-cli.js +60 -60
- package/bundle/work-continuity.js +7 -7
- package/package.json +21 -3
- package/release-manifest.json +104 -3
package/bundle/semantic.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import"dotenv/config";import{existsSync as
|
|
2
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function
|
|
3
|
-
`,{encoding:"utf8",mode:384}),de(o,r)}function B(s,e){return{id:s.id,name:s.name,remote:s.remote,rootPath:e,createdAt:s.createdAt,updatedAt:s.updatedAt,graphVersion:s.graphVersion,memoryVersion:s.memoryVersion,metadata:s.metadata}}var R=class{detect(e=process.cwd()){let t=x(e),r=ye(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>_(T(r,d))),i=he(t,n?r:void 0);if(i){let d=F(i),u=Se(d);return u.rootPath!==i&&(u.rootPath=i,u.updatedAt=new Date().toISOString(),z(i,u)),B(u,i)}let a=new Date().toISOString(),p=ue(r),l={version:1,id:me(r),name:p,remote:p,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return z(r,l),B(l,r)}};var be=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],M=class{scan(e){let t=[];for(let r of be){let o=new RegExp(r.regex.source,r.regex.flags);for(let n of e.matchAll(o))t.push({type:r.type,value:n[0]})}return t}hasSecrets(e){return this.scan(e).length>0}};var E=class{scanner=new M;sanitize(e){let t=e,r=this.scanner.scan(e),o=new Set;for(let n of r)o.add(n.type),t=t.split(n.value).join(`[REDACTED:${n.type}]`);return{text:t,redacted:r.length,secretTypes:[...o]}}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[r,o]of Object.entries(e)){let n=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");n.includes("password")||n.includes("passwd")||n==="pwd"||n.includes("secret")||n.includes("token")||n.includes("cookie")||n.includes("authorization")||n.includes("apikey")||n.includes("accesskey")||n.includes("privatekey")||n.includes("clientsecret")||n.includes("credential")?t[r]="[REDACTED]":t[r]=this.sanitizeValue(o)}return t}return e}};import{homedir as ze}from"node:os";import{join as Be}from"node:path";import{DeleteObjectCommand as Ce,GetObjectCommand as xe,HeadObjectCommand as Ee,ListObjectsV2Command as we,PutObjectCommand as ve,S3Client as ke}from"@aws-sdk/client-s3";import{getSignedUrl as Pe}from"@aws-sdk/s3-request-presigner";var A=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new ke({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,r="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new ve({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Pe(this.client,new xe({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(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 Ee({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 Ce({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new we({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};import{access as H,mkdir as Re,readFile as Te,readdir as Me,rm as Ae,stat as V,writeFile as je}from"node:fs/promises";import{dirname as Le,join as Ne,relative as Y,resolve as Ie}from"node:path";var w=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return Ie(this.root,t)}async put(e,t){let r=this.path(e);await Re(Le(r),{recursive:!0}),await je(r,t)}async get(e){try{return await Te(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 H(this.path(e)),!0}catch{return!1}}async delete(e){await Ae(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await H(t)}catch{return r}let o=async i=>{let a=await Me(i,{withFileTypes:!0});for(let p of a){let l=Ne(i,p.name);if(p.isDirectory()){await o(l);continue}let d=await V(l);r.push({key:Y(this.root,l),size:d.size,updatedAt:d.mtime.toISOString()})}},n=await V(t);return n.isDirectory()?await o(t):r.push({key:Y(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};import{DeleteObjectCommand as Oe,GetObjectCommand as _e,HeadObjectCommand as Fe,ListObjectsV2Command as De,PutObjectCommand as $e,S3Client as Ge}from"@aws-sdk/client-s3";import{getSignedUrl as Ke}from"@aws-sdk/s3-request-presigner";var v=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Ge({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,r="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new $e({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Ke(this.client,new _e({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(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 Fe({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 Oe({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new De({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};function D(s,e){return console.warn(e),new w(s)}function J(s){let e=s.localRoot??Be(ze(),".toolnet-memory","storage");if(s.provider==="r2"){let t=s.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new v({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):D(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(s.provider==="s3"){let t=s.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new v({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):D(e,"[storage] S3 credentials missing. Using local fallback.")}if(s.provider==="huggingface"){let t=s.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new A({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):D(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new w(e)}var k=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var j=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","chunks","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};function q(s){let e=s.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 Q(s){let e=s.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 r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[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 L=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=q(o??r),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(),r=t,o=await this.provider.getText(e);if(o){let i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let n={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(n,null,2)+`
|
|
4
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=
|
|
5
|
-
`).trim();if(
|
|
1
|
+
import"dotenv/config";import{existsSync as Ce,readFileSync as Ee}from"node:fs";import{homedir as we}from"node:os";import{join as ve}from"node:path";function Re(n){let e=n.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 ke(){let n=process.env.TOOLNET_GLOBAL_ENV??ve(we(),".config","toolnet-memory",".env");if(!Ce(n))return;let e=Ee(n,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=Re(r.slice(s+1)))}}ke();function w(n,e){return n===void 0?e:["1","true","yes","on"].includes(n.toLowerCase())}function v(n,e){if(!n)return e;let t=Number(n);return Number.isFinite(t)?t:e}function Q(){return{memory:{autoCapture:w(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:w(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:w(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:w(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:v(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:v(process.env.MEMORY_RERANK_TOP,10),finalContext:v(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:v(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:w(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:v(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as Le}from"node:crypto";import{existsSync as N,mkdirSync as Ne,readFileSync as _e,renameSync as Oe,writeFileSync as Fe}from"node:fs";import{basename as De,dirname as _,join as k,parse as oe,resolve as x}from"node:path";import{createHash as ee}from"node:crypto";import{spawnSync as Pe}from"node:child_process";var R="git-remote-v1",Ae=new Set(["github.com","gitlab.com","bitbucket.org"]);function te(n,e){let t=e.replaceAll("\\","/").replace(/^\/+/u,"").replace(/\/+$/u,"").replace(/\.git$/iu,"").replace(/\/+/gu,"/");return!t||t==="."||t===".."||t.split("/").some(r=>!r||r==="."||r==="..")?null:(Ae.has(n)&&(t=t.toLowerCase()),t)}function Me(n){let e;try{e=new URL(n)}catch{return null}if(!["https:","http:","ssh:","git:"].includes(e.protocol))return null;let t=e.hostname.trim().toLowerCase();if(!t)return null;let r=e.protocol==="https:"&&e.port==="443"||e.protocol==="http:"&&e.port==="80"||e.protocol==="ssh:"&&e.port==="22",s=e.port&&!r?`${t}:${e.port}`:t,o=te(t,e.pathname);return o?`${s}/${o}`:null}function Te(n){let e=n.match(/^(?:[^@\s/:]+@)?([^:/\s]+):(.+)$/u);if(!e)return null;let t=e[1]?.trim().toLowerCase();if(!t||t.length===1)return null;let r=te(t,e[2]??"");return r?`${t}/${r}`:null}function Z(n){let e=n.trim();return e?e.includes("://")?Me(e):Te(e):null}function Ie(n){return ee("sha256").update(`${R}:${n}`).digest("hex")}function re(n){return ee("sha256").update(`toolnet-project:${R}:${n}`).digest("hex").slice(0,16)}function je(n){return n.split("/").filter(Boolean).at(-1)?.trim()||null}function W(n,e){let t=Pe("git",["-C",n,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return t.error||t.status!==0?null:t.stdout?.trim()||null}function X(n,e){let t=je(n);return t?{scheme:R,canonicalRemote:n,fingerprint:Ie(n),repositoryName:t,source:e}:null}function ne(n){let e=W(n,["remote","get-url","origin"]);if(e){let s=Z(e);if(s)return X(s,"origin")}let t=W(n,["remote"]);if(!t)return null;let r=new Set;for(let s of t.split(/\r?\n/u).map(o=>o.trim()).filter(Boolean)){let o=W(n,["remote","get-url",s]);if(!o)continue;let i=Z(o);i&&r.add(i)}return r.size!==1?null:X([...r][0],"unique-remote")}var ie=".toolnet",$e="project.json";function Ge(n){return Le("sha256").update(n).digest("hex").slice(0,16)}function C(n){return k(n,ie,$e)}function ae(n){return N(C(n))}function se(n,e){let t=x(n),r=oe(t).root;for(;;){if(ae(t))return t;if(t===r||e&&t===x(e))break;let s=_(t);if(s===t)break;t=s}return null}function U(n){let e=x(n),t=oe(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>N(k(e,o))))return e;if(e===t)break;let s=_(e);if(s===e)break;e=s}return x(n)}function j(n){let e;try{e=JSON.parse(_e(n,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${n}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${n}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${n}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${n}`);let r=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:_(_(n)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,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 L(n,e){let t=k(n,ie);Ne(t,{recursive:!0});let r=C(n),s=`${r}.tmp-${process.pid}`;Fe(s,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),Oe(s,r)}function b(n,e){return{id:n.id,name:n.name,remote:n.remote,rootPath:e,createdAt:n.createdAt,updatedAt:n.updatedAt,graphVersion:n.graphVersion,memoryVersion:n.memoryVersion,metadata:n.metadata}}function V(n){return{version:1,scheme:R,canonicalRemote:n.canonicalRemote,fingerprint:n.fingerprint,repositoryName:n.repositoryName}}function Ke(n){let e=n.metadata?.toolnetIdentity;if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;return typeof t.fingerprint=="string"?t.fingerprint:null}var O=class{adopt(e,t){let r=U(x(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(ae(r)){let a=j(C(r));if(a.id!==t.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${t.id}`].join(" "));return b(a,r)}let s=new Date().toISOString(),o={...t.metadata};t.gitIdentity&&(o.toolnetIdentity=V(t.gitIdentity));let i={version:1,id:t.id.trim(),name:t.name.trim(),remote:t.remote.trim(),rootPath:r,createdAt:t.createdAt??s,updatedAt:s,graphVersion:t.graphVersion??0,memoryVersion:t.memoryVersion??0,metadata:Object.keys(o).length?o:void 0};return L(r,i),b(i,r)}recordGitIdentity(e,t,r={}){let s=this.requireExisting(e),o=C(s.rootPath),i=j(o),a=Ke(i);if(a&&a!==t.fingerprint&&!r.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${a}`,`current=${t.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let c=i.metadata?.toolnetIdentity;return c&&typeof c=="object"&&!Array.isArray(c)&&c.fingerprint===t.fingerprint||(i.metadata={...i.metadata,toolnetIdentity:V(t)},i.updatedAt=new Date().toISOString(),L(s.rootPath,i)),b(i,s.rootPath)}findExisting(e=process.cwd()){let t=x(e),r=U(t),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>N(k(r,c))),i=se(t,o?r:void 0);if(!i)return null;let a=j(C(i));return b(a,i)}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=x(e),r=U(t),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(m=>N(k(r,m))),i=se(t,o?r:void 0);if(i){let m=C(i),f=j(m);return f.rootPath!==i&&(f.rootPath=i,f.updatedAt=new Date().toISOString(),L(i,f)),b(f,i)}let a=new Date().toISOString(),c=De(r),l=ne(r),p={version:1,id:l?re(l.canonicalRemote):Ge(r),name:c,remote:l?.repositoryName??c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:l?{toolnetIdentity:V(l)}:void 0};return L(r,p),b(p,r)}};var ze=[{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"}],Be=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function ce(n){return n.normalize("NFKC").trim().toLowerCase()}function He(n){if(n.length===0)return 0;let e=new Map;for(let r of n)e.set(r,(e.get(r)??0)+1);let t=0;for(let r of e.values()){let s=r/n.length;t-=s*Math.log2(s)}return t}function We(n){return/^[a-f0-9]{32}$/iu.test(n)||/^[a-f0-9]{40}$/iu.test(n)||/^[a-f0-9]{64}$/iu.test(n)}function Ue(n,e,t){let r=n.slice(Math.max(0,e-48),e),s=n.slice(t,Math.min(n.length,t+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${r} ${s}`)}function Ve(n,e){return n.start<e.end&&e.start<n.end}function le(n){return n.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var F=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let r=ce(t);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let o of ze){let i=new RegExp(o.regex.source,o.regex.flags);for(let a of e.matchAll(i))a.index===void 0||!a[0]||this.allowed(a[0])||t.push({type:o.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:o.confidence})}this.enableEntropyHeuristic&&t.push(...this.entropyMatches(e));let r=le(t),s=[];for(let o of r)s.some(i=>Ve(i,o))||s.push(o);return le(s)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=ce(e);return Be.has(t)?!0:this.allowValues.has(t)}entropyMatches(e){let t=[],r=/[A-Za-z0-9_+/=-]{32,160}/g;for(let s of e.matchAll(r)){if(s.index===void 0||!s[0])continue;let o=s[0];this.allowed(o)||We(o)||!/[A-Za-z]/u.test(o)||!/[0-9]/u.test(o)||Ue(e,s.index,s.index+o.length)&&(He(o)<3.7||t.push({type:"high_entropy_secret",value:o,start:s.index,end:s.index+o.length,confidence:"heuristic"}))}return t}};var E=class{scanner;constructor(e={}){this.scanner=new F(e)}sanitize(e){let t=this.scanner.scan(e);if(t.length===0)return{text:e,redacted:0,secretTypes:[]};let r=e,s=[...t].sort((i,a)=>a.start-i.start),o=new Set;for(let i of s)o.add(i.type),r=r.slice(0,i.start)+`[REDACTED:${i.type}]`+r.slice(i.end);return{text:r,redacted:t.length,secretTypes:[...o].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[r,s]of Object.entries(e)){let o=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(o.includes("password")||o.includes("passwd")||o==="pwd"||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")||o.includes("apikey")||o.includes("accesskey")||o.includes("privatekey")||o.includes("clientsecret")||o.includes("credential")){t[r]="[REDACTED]";continue}t[r]=this.sanitizeValue(s)}return t}return e}};var Jt=new E;import{homedir as ht}from"node:os";import{join as yt}from"node:path";import{DeleteObjectCommand as Ye,GetObjectCommand as qe,HeadObjectCommand as Je,ListObjectsV2Command as Qe,PutObjectCommand as Ze,S3Client as Xe}from"@aws-sdk/client-s3";import{getSignedUrl as et}from"@aws-sdk/s3-request-presigner";var D=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Xe({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,r="application/octet-stream"){let s=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Ze({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await et(this.client,new qe({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(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 Je({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 Ye({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new Qe({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&t.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};import{access as de,mkdir as tt,readFile as rt,readdir as nt,rm as st,stat as pe,writeFile as ot}from"node:fs/promises";import{dirname as it,join as at,relative as ue,resolve as ct}from"node:path";var P=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return ct(this.root,t)}async put(e,t){let r=this.path(e);await tt(it(r),{recursive:!0}),await ot(r,t)}async get(e){try{return await rt(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 de(this.path(e)),!0}catch{return!1}}async delete(e){await st(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await de(t)}catch{return r}let s=async i=>{let a=await nt(i,{withFileTypes:!0});for(let c of a){let l=at(i,c.name);if(c.isDirectory()){await s(l);continue}let p=await pe(l);r.push({key:ue(this.root,l),size:p.size,updatedAt:p.mtime.toISOString()})}},o=await pe(t);return o.isDirectory()?await s(t):r.push({key:ue(this.root,t),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as lt,GetObjectCommand as dt,HeadObjectCommand as pt,ListObjectsV2Command as ut,PutObjectCommand as mt,S3Client as ft}from"@aws-sdk/client-s3";import{getSignedUrl as gt}from"@aws-sdk/s3-request-presigner";var A=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,t,r="application/octet-stream"){let s=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new mt({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await gt(this.client,new dt({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(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 pt({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 lt({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new ut({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&t.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return t}};function Y(n,e){return console.warn(e),new P(n)}function me(n){let e=n.localRoot??yt(ht(),".toolnet-memory","storage");if(n.provider==="r2"){let t=n.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new A({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Y(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(n.provider==="s3"){let t=n.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new A({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Y(e,"[storage] S3 credentials missing. Using local fallback.")}if(n.provider==="huggingface"){let t=n.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new D({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):Y(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new P(e)}var M=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};var $=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"code","chunks","current.json"].join("/")}async load(e){let t=await this.storage.getText(this.key(e));return t?JSON.parse(t):null}async save(e){await this.storage.put(this.key(e.projectId),JSON.stringify(e),"application/json")}};function fe(n){let e=n.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 ge(n){let e=n.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 r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[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 G=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=fe(s??r),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(),r=t,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(o,null,2)+`
|
|
4
|
+
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=ge(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,r){return await this.ensureRegistered(),this.provider.put(this.key(e),t,r)}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))}};var zn=2*1024*1024;var T=class{symbols=new Map;edges=new Map;addSymbol(e){this.symbols.set(e.id,e)}addEdge(e){this.edges.set(e.id,e)}getSymbol(e){return this.symbols.get(e)}findByName(e,t){return[...this.symbols.values()].filter(r=>r.projectId===e&&(r.name===t||r.qualifiedName===t))}allSymbols(e){return[...this.symbols.values()].filter(t=>t.projectId===e)}allEdges(e){return[...this.edges.values()].filter(t=>t.projectId===e)}import(e,t){for(let r of e)this.addSymbol(r);for(let r of t)this.addEdge(r)}clearProject(e){for(let[t,r]of this.symbols)r.projectId===e&&this.symbols.delete(t);for(let[t,r]of this.edges)r.projectId===e&&this.edges.delete(t)}};import*as u from"typescript";import{execFile as Ct}from"node:child_process";import{promisify as Et}from"node:util";var ps=Et(Ct);import*as y from"typescript";import{createHash as vt}from"node:crypto";import{readFile as Rt}from"node:fs/promises";import{join as kt}from"node:path";function ye(n){return vt("sha256").update(n).digest("hex")}var K=class{sanitizer=new E;async build(e,t,r,s={}){let o=s.maxLines??80,i=s.overlapLines??10,a=new Map;for(let l of r){let p=a.get(l.filePath)??[];p.push(l),a.set(l.filePath,p)}let c=[];for(let[l,p]of a){let m;try{m=await Rt(kt(t,l),"utf8")}catch{continue}let f=m.split(/\r?\n/),S=p.filter(h=>h.type!=="file"&&typeof h.startLine=="number"&&typeof h.endLine=="number");if(S.length>0)for(let h of S)c.push(...this.chunkRange({projectId:e,filePath:l,lines:f,symbol:h,startLine:h.startLine,endLine:h.endLine,maxLines:o,overlapLines:i}));else c.push(...this.chunkRange({projectId:e,filePath:l,lines:f,startLine:1,endLine:Math.max(1,f.length),maxLines:o,overlapLines:i}))}return c}chunkRange(e){let{projectId:t,filePath:r,lines:s,symbol:o,maxLines:i}=e,a=Math.min(e.overlapLines,Math.max(0,i-1)),c=Math.max(1,e.startLine),l=Math.min(s.length,Math.max(c,e.endLine)),p=[],m=c,f=0;for(;m<=l;){let S=Math.min(l,m+i-1),h=s.slice(m-1,S).join(`
|
|
5
|
+
`).trim();if(h){let q=this.sanitizer.sanitize(h).text,J=ye(q),xe=[t,r,o?.id??"file",String(f),J].join(":");p.push({id:ye(xe).slice(0,32),projectId:t,filePath:r,symbolId:o?.id,symbolName:o?.qualifiedName??o?.name,symbolType:o?.type,startLine:m,endLine:S,content:q,contentHash:J})}if(S>=l)break;m=S-a+1,f++}return p}};import{DatabaseSync as Pt}from"node:sqlite";var z=class{constructor(e){this.projectId=e;this.db.exec("CREATE VIRTUAL TABLE code_fts USING fts5(id UNINDEXED, projectId UNINDEXED, filePath, symbol, content, tokenize='unicode61')")}projectId;db=new Pt(":memory:");chunks=new Map;get size(){return this.chunks.size}build(e){if(this.db.exec("DELETE FROM code_fts"),this.chunks.clear(),e.length===0)return 0;let t=this.db.prepare("INSERT INTO code_fts (id, projectId, filePath, symbol, content) VALUES (?, ?, ?, ?, ?)");this.db.exec("BEGIN");try{for(let r of e)this.chunks.set(r.id,r),t.run(r.id,this.projectId,r.filePath,r.symbolName??"",r.content);this.db.exec("COMMIT")}catch(r){throw this.db.exec("ROLLBACK"),r}return e.length}search(e,t=8){let r=this.toMatchQuery(e);if(!r)return[];let s=this.db.prepare("SELECT id, bm25(code_fts) AS rank FROM code_fts WHERE code_fts MATCH ? ORDER BY rank LIMIT ?").all(r,Math.max(t*4,20)),o=[];for(let i of s){let a=this.chunks.get(i.id);if(!a)continue;let c=1/(1+Math.abs(i.rank));o.push({chunk:a,score:c})}return o.slice(0,t)}toMatchQuery(e){let t=e.toLowerCase().normalize("NFKC").split(/[^\p{L}\p{N}]+/u).map(r=>r.trim()).filter(r=>r.length>0);return t.length===0?null:t.length===1?`"${t[0]}"`:`(${t.map(r=>`"${r}"`).join(" OR ")})`}close(){this.db.close()}};function Se(n,e){let t=n.toLowerCase().replaceAll("\\","/"),r=e.toLowerCase(),s=/\b(test|tests|spec|fixture|mock)\b/.test(r);return(t.startsWith("tests/")||t.includes("/tests/")||t.includes("__tests__")||/\.(test|spec)\.[^.]+$/.test(t))&&!s?.35:t.includes("/generated/")||t.includes(".generated.")?.25:1}var I="sqlite-fts5-bm25",B="lexical",At="Local Code Search \u2014 SQLite FTS5/BM25",be={engine:I,mode:B,displayName:At,semantic:!1,embedding:!1,vectorDatabase:!1,queryExpansion:!1,synonymExpansion:!1,networkRequired:!1,indexBackend:"sqlite-fts5",ranking:"bm25",compatibilityAliases:["SemanticCodeEngine","semantic_code_search","toolnet-memory semantic","semantic-index"]};var H=class{constructor(e){this.options=e;this.fts=new z(e.projectId)}options;fts;get searchContract(){return be}async initialize(e){let{projectId:t,rootPath:r,storage:s,graph:o}=this.options,i=new $(s),a=await new K().build(t,r,o.allSymbols(t)),c=await i.load(t),l=!c||c.chunks.length!==a.length||c.chunks.some(m=>!a.some(f=>f.id===m.id));l&&await i.save({version:1,projectId:t,updatedAt:new Date().toISOString(),chunks:a}),e?.({current:a.length,total:a.length,phase:"index",detail:I});let p=this.fts.build(a);return{chunks:a.length,documentsIndexed:p,indexSize:this.fts.size,engine:I,mode:B,embedding:!1,vectorDatabase:!1,savedChunks:l,vectorsLoaded:0,vectorsIndexed:p,vectorsRemoved:0,totalVectors:this.fts.size,savedVectors:l}}async search(e,t=8){let r=this.fts.search(e,t),s=[];for(let o of r){let i=o.chunk,a=Se(i.filePath,e),c=o.score,l=0,p=c*a;s.push({chunk:i,score:p,lexicalScore:c,vectorScore:l,engine:I,mode:B})}return s}size(){return this.fts.size}};import*as g from"typescript";import*as d from"typescript";var Po=new Set([d.SyntaxKind.EqualsToken,d.SyntaxKind.PlusEqualsToken,d.SyntaxKind.MinusEqualsToken,d.SyntaxKind.AsteriskEqualsToken,d.SyntaxKind.SlashEqualsToken,d.SyntaxKind.PercentEqualsToken,d.SyntaxKind.QuestionQuestionEqualsToken,d.SyntaxKind.AmpersandAmpersandEqualsToken,d.SyntaxKind.BarBarEqualsToken]);async function Tt(){let n=Q(),e=new O().detect(),t=me({provider:n.storage.provider,huggingface:n.storage.huggingface,localRoot:n.storage.localRoot}),r=new G(t,e.id,e.name,e.remote??e.name),s=new T,o=await new M(r).load(e.id);if(!o)throw new Error("Code graph missing. Run npm run code:index:test first.");s.import(o.symbols,o.edges);let i=new H({projectId:e.id,rootPath:e.rootPath,storage:r,graph:s}),a=await i.initialize(),c=process.argv.slice(2).join(" ")||"memory storage hugging face",l=await i.search(c,5);console.log({ok:!0,command:"semantic",legacyCommandName:!0,search:{engine:"sqlite-fts5-bm25",mode:"lexical",semantic:!1,embedding:!1,vectorDatabase:!1},query:c,...a,results:l.map(p=>({score:Number(p.score.toFixed(4)),file:p.chunk.filePath,symbol:p.chunk.symbolName,lines:`${p.chunk.startLine}-${p.chunk.endLine}`,preview:p.chunk.content.replace(/\s+/g," ").slice(0,140)}))})}Tt().catch(n=>{console.error(n),process.exit(1)});
|
package/bundle/snapshot.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import"dotenv/config";import{existsSync as
|
|
2
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function
|
|
3
|
-
`,{encoding:"utf8",mode:384}),Q(o,r)}function C(s,e){return{id:s.id,name:s.name,remote:s.remote,rootPath:e,createdAt:s.createdAt,updatedAt:s.updatedAt,graphVersion:s.graphVersion,memoryVersion:s.memoryVersion,metadata:s.metadata}}var v=class{detect(e=process.cwd()){let t=g(e),r=se(t),n=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>x(w(r,p))),i=re(t,n?r:void 0);if(i){let p=k(i),d=oe(p);return d.rootPath!==i&&(d.rootPath=i,d.updatedAt=new Date().toISOString(),A(i,d)),C(d,i)}let a=new Date().toISOString(),c=q(r),u={version:1,id:ee(r),name:c,remote:c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0};return A(r,u),C(u,r)}};import{homedir as Pe}from"node:os";import{join as Ae}from"node:path";import{DeleteObjectCommand as ne,GetObjectCommand as ie,HeadObjectCommand as ae,ListObjectsV2Command as ce,PutObjectCommand as ue,S3Client as pe}from"@aws-sdk/client-s3";import{getSignedUrl as de}from"@aws-sdk/s3-request-presigner";var j=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new pe({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,r="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new ue({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await de(this.client,new ie({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(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 ae({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 ne({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new ce({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};import{access as I,mkdir as le,readFile as me,readdir as fe,rm as ge,stat as O,writeFile as ye}from"node:fs/promises";import{dirname as he,join as Se,relative as _,resolve as ve}from"node:path";var y=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return ve(this.root,t)}async put(e,t){let r=this.path(e);await le(he(r),{recursive:!0}),await ye(r,t)}async get(e){try{return await me(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 I(this.path(e)),!0}catch{return!1}}async delete(e){await ge(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await I(t)}catch{return r}let o=async i=>{let a=await fe(i,{withFileTypes:!0});for(let c of a){let u=Se(i,c.name);if(c.isDirectory()){await o(u);continue}let p=await O(u);r.push({key:_(this.root,u),size:p.size,updatedAt:p.mtime.toISOString()})}},n=await O(t);return n.isDirectory()?await o(t):r.push({key:_(this.root,t),size:n.size,updatedAt:n.mtime.toISOString()}),r}};import{DeleteObjectCommand as we,GetObjectCommand as je,HeadObjectCommand as be,ListObjectsV2Command as xe,PutObjectCommand as ke,S3Client as Re}from"@aws-sdk/client-s3";import{getSignedUrl as Me}from"@aws-sdk/s3-request-presigner";var h=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Re({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,r="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new ke({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Me(this.client,new je({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(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 be({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 we({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new xe({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let n of o.Contents??[])n.Key&&t.push({key:n.Key,size:n.Size,updatedAt:n.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};function R(s,e){return console.warn(e),new y(s)}function $(s){let e=s.localRoot??Ae(Pe(),".toolnet-memory","storage");if(s.provider==="r2"){let t=s.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new h({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):R(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(s.provider==="s3"){let t=s.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new h({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):R(e,"[storage] S3 credentials missing. Using local fallback.")}if(s.provider==="huggingface"){let t=s.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new j({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):R(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new y(e)}function Ce(s){return new Promise(e=>setTimeout(e,s))}async function K(s,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,o=e.maxDelayMs??2e3,n;for(let i=1;i<=t;i++)try{return await s()}catch(a){if(n=a,i>=t)break;let c=Math.min(o,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await Ce(c+u)}throw n}var Ee=new Set(["put","get","getText","delete","list"]);function N(s,e={}){return new Proxy(s,{get(t,r){let o=Reflect.get(t,r,t);return typeof o!="function"?o:Ee.has(r)?(...n)=>K(()=>Promise.resolve(o.apply(t,n)),e):o.bind(t)}})}function D(s){let e=s.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 z(s){let e=s.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 r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[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 b=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=D(o??r),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(),r=t,o=await this.provider.getText(e);if(o){let i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let n={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};await this.provider.put(e,JSON.stringify(n,null,2)+`
|
|
4
|
-
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=
|
|
1
|
+
import"dotenv/config";import{existsSync as oe,readFileSync as se}from"node:fs";import{homedir as ie}from"node:os";import{join as ae}from"node:path";function ce(n){let e=n.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 ue(){let n=process.env.TOOLNET_GLOBAL_ENV??ae(ie(),".config","toolnet-memory",".env");if(!oe(n))return;let e=se(n,"utf8");for(let t of e.split(/\r?\n/)){let r=t.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let o=r.indexOf("=");if(o<=0)continue;let s=r.slice(0,o).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&process.env[s]===void 0&&(process.env[s]=ce(r.slice(o+1)))}}ue();function h(n,e){return n===void 0?e:["1","true","yes","on"].includes(n.toLowerCase())}function S(n,e){if(!n)return e;let t=Number(n);return Number.isFinite(t)?t:e}function K(){return{memory:{autoCapture:h(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:h(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:h(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:h(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:S(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:S(process.env.MEMORY_RERANK_TOP,10),finalContext:S(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:S(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:h(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:S(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as ye}from"node:crypto";import{existsSync as M,mkdirSync as he,readFileSync as Se,renameSync as ve,writeFileSync as xe}from"node:fs";import{basename as be,dirname as R,join as x,parse as G,resolve as m}from"node:path";import{createHash as L}from"node:crypto";import{spawnSync as de}from"node:child_process";var v="git-remote-v1",pe=new Set(["github.com","gitlab.com","bitbucket.org"]);function z(n,e){let t=e.replaceAll("\\","/").replace(/^\/+/u,"").replace(/\/+$/u,"").replace(/\.git$/iu,"").replace(/\/+/gu,"/");return!t||t==="."||t===".."||t.split("/").some(r=>!r||r==="."||r==="..")?null:(pe.has(n)&&(t=t.toLowerCase()),t)}function le(n){let e;try{e=new URL(n)}catch{return null}if(!["https:","http:","ssh:","git:"].includes(e.protocol))return null;let t=e.hostname.trim().toLowerCase();if(!t)return null;let r=e.protocol==="https:"&&e.port==="443"||e.protocol==="http:"&&e.port==="80"||e.protocol==="ssh:"&&e.port==="22",o=e.port&&!r?`${t}:${e.port}`:t,s=z(t,e.pathname);return s?`${o}/${s}`:null}function me(n){let e=n.match(/^(?:[^@\s/:]+@)?([^:/\s]+):(.+)$/u);if(!e)return null;let t=e[1]?.trim().toLowerCase();if(!t||t.length===1)return null;let r=z(t,e[2]??"");return r?`${t}/${r}`:null}function $(n){let e=n.trim();return e?e.includes("://")?le(e):me(e):null}function fe(n){return L("sha256").update(`${v}:${n}`).digest("hex")}function V(n){return L("sha256").update(`toolnet-project:${v}:${n}`).digest("hex").slice(0,16)}function ge(n){return n.split("/").filter(Boolean).at(-1)?.trim()||null}function T(n,e){let t=de("git",["-C",n,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return t.error||t.status!==0?null:t.stdout?.trim()||null}function D(n,e){let t=ge(n);return t?{scheme:v,canonicalRemote:n,fingerprint:fe(n),repositoryName:t,source:e}:null}function B(n){let e=T(n,["remote","get-url","origin"]);if(e){let o=$(e);if(o)return D(o,"origin")}let t=T(n,["remote"]);if(!t)return null;let r=new Set;for(let o of t.split(/\r?\n/u).map(s=>s.trim()).filter(Boolean)){let s=T(n,["remote","get-url",o]);if(!s)continue;let i=$(s);i&&r.add(i)}return r.size!==1?null:D([...r][0],"unique-remote")}var H=".toolnet",we="project.json";function je(n){return ye("sha256").update(n).digest("hex").slice(0,16)}function f(n){return x(n,H,we)}function J(n){return M(f(n))}function F(n,e){let t=m(n),r=G(t).root;for(;;){if(J(t))return t;if(t===r||e&&t===m(e))break;let o=R(t);if(o===t)break;t=o}return null}function _(n){let e=m(n),t=G(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>M(x(e,s))))return e;if(e===t)break;let o=R(e);if(o===e)break;e=o}return m(n)}function j(n){let e;try{e=JSON.parse(Se(n,"utf8"))}catch(o){throw new Error(`Invalid ToolNet project manifest: ${n}: ${o instanceof Error?o.message:String(o)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${n}`);let t=e;if(typeof t.id!="string"||!t.id.trim())throw new Error(`ToolNet project manifest is missing id: ${n}`);if(typeof t.name!="string"||!t.name.trim())throw new Error(`ToolNet project manifest is missing name: ${n}`);let r=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:R(R(n)),createdAt:typeof t.createdAt=="string"?t.createdAt:r,updatedAt:typeof t.updatedAt=="string"?t.updatedAt:r,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 k(n,e){let t=x(n,H);he(t,{recursive:!0});let r=f(n),o=`${r}.tmp-${process.pid}`;xe(o,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),ve(o,r)}function l(n,e){return{id:n.id,name:n.name,remote:n.remote,rootPath:e,createdAt:n.createdAt,updatedAt:n.updatedAt,graphVersion:n.graphVersion,memoryVersion:n.memoryVersion,metadata:n.metadata}}function O(n){return{version:1,scheme:v,canonicalRemote:n.canonicalRemote,fingerprint:n.fingerprint,repositoryName:n.repositoryName}}function ke(n){let e=n.metadata?.toolnetIdentity;if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e;return typeof t.fingerprint=="string"?t.fingerprint:null}var A=class{adopt(e,t){let r=_(m(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(J(r)){let a=j(f(r));if(a.id!==t.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${a.id}`,`requested=${t.id}`].join(" "));return l(a,r)}let o=new Date().toISOString(),s={...t.metadata};t.gitIdentity&&(s.toolnetIdentity=O(t.gitIdentity));let i={version:1,id:t.id.trim(),name:t.name.trim(),remote:t.remote.trim(),rootPath:r,createdAt:t.createdAt??o,updatedAt:o,graphVersion:t.graphVersion??0,memoryVersion:t.memoryVersion??0,metadata:Object.keys(s).length?s:void 0};return k(r,i),l(i,r)}recordGitIdentity(e,t,r={}){let o=this.requireExisting(e),s=f(o.rootPath),i=j(s),a=ke(i);if(a&&a!==t.fingerprint&&!r.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${a}`,`current=${t.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let c=i.metadata?.toolnetIdentity;return c&&typeof c=="object"&&!Array.isArray(c)&&c.fingerprint===t.fingerprint||(i.metadata={...i.metadata,toolnetIdentity:O(t)},i.updatedAt=new Date().toISOString(),k(o.rootPath,i)),l(i,o.rootPath)}findExisting(e=process.cwd()){let t=m(e),r=_(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(c=>M(x(r,c))),i=F(t,s?r:void 0);if(!i)return null;let a=j(f(i));return l(a,i)}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=m(e),r=_(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(y=>M(x(r,y))),i=F(t,s?r:void 0);if(i){let y=f(i),p=j(y);return p.rootPath!==i&&(p.rootPath=i,p.updatedAt=new Date().toISOString(),k(i,p)),l(p,i)}let a=new Date().toISOString(),c=be(r),u=B(r),d={version:1,id:u?V(u.canonicalRemote):je(r),name:c,remote:u?.repositoryName??c,rootPath:r,createdAt:a,updatedAt:a,graphVersion:0,memoryVersion:0,metadata:u?{toolnetIdentity:O(u)}:void 0};return k(r,d),l(d,r)}};var Me=[{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"}],Re=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function U(n){return n.normalize("NFKC").trim().toLowerCase()}function Ae(n){if(n.length===0)return 0;let e=new Map;for(let r of n)e.set(r,(e.get(r)??0)+1);let t=0;for(let r of e.values()){let o=r/n.length;t-=o*Math.log2(o)}return t}function Pe(n){return/^[a-f0-9]{32}$/iu.test(n)||/^[a-f0-9]{40}$/iu.test(n)||/^[a-f0-9]{64}$/iu.test(n)}function Ce(n,e,t){let r=n.slice(Math.max(0,e-48),e),o=n.slice(t,Math.min(n.length,t+16));return/\b(?:token|secret|key|credential|authorization|password|passwd|apikey|api_key|access[_-]?key)\b/iu.test(`${r} ${o}`)}function Ie(n,e){return n.start<e.end&&e.start<n.end}function Y(n){return n.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var P=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let r=U(t);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let s of Me){let i=new RegExp(s.regex.source,s.regex.flags);for(let a of e.matchAll(i))a.index===void 0||!a[0]||this.allowed(a[0])||t.push({type:s.type,value:a[0],start:a.index,end:a.index+a[0].length,confidence:s.confidence})}this.enableEntropyHeuristic&&t.push(...this.entropyMatches(e));let r=Y(t),o=[];for(let s of r)o.some(i=>Ie(i,s))||o.push(s);return Y(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=U(e);return Re.has(t)?!0:this.allowValues.has(t)}entropyMatches(e){let t=[],r=/[A-Za-z0-9_+/=-]{32,160}/g;for(let o of e.matchAll(r)){if(o.index===void 0||!o[0])continue;let s=o[0];this.allowed(s)||Pe(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||Ce(e,o.index,o.index+s.length)&&(Ae(s)<3.7||t.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return t}};var C=class{scanner;constructor(e={}){this.scanner=new P(e)}sanitize(e){let t=this.scanner.scan(e);if(t.length===0)return{text:e,redacted:0,secretTypes:[]};let r=e,o=[...t].sort((i,a)=>a.start-i.start),s=new Set;for(let i of o)s.add(i.type),r=r.slice(0,i.start)+`[REDACTED:${i.type}]`+r.slice(i.end);return{text:r,redacted:t.length,secretTypes:[...s].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[r,o]of Object.entries(e)){let s=r.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g,"");if(s.includes("password")||s.includes("passwd")||s==="pwd"||s.includes("secret")||s.includes("token")||s.includes("cookie")||s.includes("authorization")||s.includes("apikey")||s.includes("accesskey")||s.includes("privatekey")||s.includes("clientsecret")||s.includes("credential")){t[r]="[REDACTED]";continue}t[r]=this.sanitizeValue(o)}return t}return e}};var kt=new C;import{homedir as Xe}from"node:os";import{join as et}from"node:path";import{DeleteObjectCommand as Ee,GetObjectCommand as Te,HeadObjectCommand as _e,ListObjectsV2Command as Oe,PutObjectCommand as Ne,S3Client as Ke}from"@aws-sdk/client-s3";import{getSignedUrl as $e}from"@aws-sdk/s3-request-presigner";var I=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Ke({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,r="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Ne({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await $e(this.client,new Te({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(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 _e({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 Ee({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new Oe({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};import{access as W,mkdir as De,readFile as Le,readdir as ze,rm as Ve,stat as Z,writeFile as Be}from"node:fs/promises";import{dirname as Fe,join as Ge,relative as q,resolve as He}from"node:path";var b=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return He(this.root,t)}async put(e,t){let r=this.path(e);await De(Fe(r),{recursive:!0}),await Be(r,t)}async get(e){try{return await Le(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 W(this.path(e)),!0}catch{return!1}}async delete(e){await Ve(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await W(t)}catch{return r}let o=async i=>{let a=await ze(i,{withFileTypes:!0});for(let c of a){let u=Ge(i,c.name);if(c.isDirectory()){await o(u);continue}let d=await Z(u);r.push({key:q(this.root,u),size:d.size,updatedAt:d.mtime.toISOString()})}},s=await Z(t);return s.isDirectory()?await o(t):r.push({key:q(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as Je,GetObjectCommand as Ue,HeadObjectCommand as Ye,ListObjectsV2Command as We,PutObjectCommand as Ze,S3Client as qe}from"@aws-sdk/client-s3";import{getSignedUrl as Qe}from"@aws-sdk/s3-request-presigner";var w=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new qe({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,r="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Ze({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Qe(this.client,new Ue({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(t,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`${this.name} download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(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 Ye({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 Je({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new We({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let s of o.Contents??[])s.Key&&t.push({key:s.Key,size:s.Size,updatedAt:s.LastModified?.toISOString()});r=o.IsTruncated?o.NextContinuationToken:void 0}while(r);return t}};function N(n,e){return console.warn(e),new b(n)}function Q(n){let e=n.localRoot??et(Xe(),".toolnet-memory","storage");if(n.provider==="r2"){let t=n.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new w({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):N(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(n.provider==="s3"){let t=n.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?new w({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):N(e,"[storage] S3 credentials missing. Using local fallback.")}if(n.provider==="huggingface"){let t=n.huggingface;return t?.namespace&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new I({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):N(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new b(e)}function tt(n){return new Promise(e=>setTimeout(e,n))}async function X(n,e={}){let t=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,o=e.maxDelayMs??2e3,s;for(let i=1;i<=t;i++)try{return await n()}catch(a){if(s=a,i>=t)break;let c=Math.min(o,r*2**(i-1)),u=Math.floor(Math.random()*Math.max(1,c*.2));await tt(c+u)}throw s}var rt=new Set(["put","get","getText","delete","list"]);function ee(n,e={}){return new Proxy(n,{get(t,r){let o=Reflect.get(t,r,t);return typeof o!="function"?o:rt.has(r)?(...s)=>X(()=>Promise.resolve(o.apply(t,s)),e):o.bind(t)}})}function te(n){let e=n.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 re(n){let e=n.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 r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[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 E=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=te(o??r),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(),r=t,o=await this.provider.getText(e);if(o){let i;try{i=JSON.parse(o)}catch(a){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${a instanceof Error?a.message:String(a)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let s={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:t};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=re(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,r){return await this.ensureRegistered(),this.provider.put(this.key(e),t,r)}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))}};var nt=["memories/current.json","vectors/current.json","graph/current.json","graph/manifest.json","graph/resolution/current.json","code/chunks/current.json","code/vectors/current.json","code/architecture/current.json","code/architecture/entry-points.json","code/architecture/hotspots.json","code/architecture/layers.json","code/architecture/clusters.json","code/analysis/current.json","code/analysis/dead-code.json","code/analysis/dependencies.json","code/visualization/graph.json"],g=class{constructor(e){this.storage=e}storage;projectPrefix(e){return`projects/${e}`}snapshotPrefix(e,t){return[this.projectPrefix(e),"snapshots",t].join("/")}async create(e,t="automatic",r){let o=new Date().toISOString(),s=o.replace(/[:.]/g,"-"),i=this.projectPrefix(e),a=this.snapshotPrefix(e,s),c=[];for(let d of nt){let y=`${i}/${d}`,p=await this.storage.get(y);p&&(await this.storage.put(`${a}/${d}`,p,"application/json"),c.push(d))}if(c.length===0)return null;let u={version:1,id:s,projectId:e,createdAt:o,reason:t,objects:c,metadata:r};return await this.storage.put(`${a}/snapshot.json`,JSON.stringify(u,null,2),"application/json"),u}async list(e){let t=[this.projectPrefix(e),"snapshots"].join("/"),o=(await this.storage.list(t)).filter(i=>i.key.endsWith("/snapshot.json")),s=[];for(let i of o){let a=await this.storage.getText(i.key);if(a)try{s.push(JSON.parse(a))}catch{}}return s.sort((i,a)=>a.createdAt.localeCompare(i.createdAt))}async restore(e,t){let r=this.snapshotPrefix(e,t),o=await this.storage.getText(`${r}/snapshot.json`);if(!o)throw new Error(`Snapshot not found: ${t}`);let s=JSON.parse(o);if(s.projectId!==e)throw new Error("Snapshot project mismatch");let i=this.projectPrefix(e),a=[];for(let c of s.objects){let u=await this.storage.get(`${r}/${c}`);u&&(await this.storage.put(`${i}/${c}`,u,"application/json"),a.push(c))}return{restored:a}}async remove(e,t){let r=this.snapshotPrefix(e,t),o=await this.storage.list(r);for(let s of o)await this.storage.delete(s.key);return o.length}async prune(e,t=10){let o=(await this.list(e)).slice(t),s=0;for(let i of o)await this.remove(e,i.id),s++;return s}};async function ne(n,e){let t=new g(n),o=(await t.list(e))[0];if(!o)throw new Error("No snapshot available");let s=await t.restore(e,o.id);return{snapshot:o.id,createdAt:o.createdAt,...s}}async function ot(){let n=process.argv[2],e=K(),t=new A().detect(),r=ee(Q({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3}),o=new E(r,t.id,t.name,t.remote??t.name),s=new g(o);if(n==="list"){let i=await s.list(t.id);console.log(i.map(a=>({id:a.id,createdAt:a.createdAt,reason:a.reason})));return}if(n==="create"){let i=process.argv.slice(3).join(" ")||"manual-cli";console.log(await s.create(t.id,i));return}if(n==="restore"){let i=process.argv[3];if(!i)throw new Error("snapshot id required");await s.create(t.id,"before-cli-restore"),console.log(await s.restore(t.id,i));return}if(n==="recover-latest"){console.log(await ne(o,t.id));return}throw new Error("Usage: snapshot-cli list|create|restore|recover-latest")}ot().catch(n=>{console.error(n instanceof Error?n.message:n),process.exit(1)});
|
package/bundle/status-cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{existsSync as
|
|
2
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function
|
|
3
|
-
`,{encoding:"utf8",mode:384}),Ge(n,o)}function W(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 O=class{detect(e=process.cwd()){let r=S(e),o=Ye(r),i=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(p=>T(A(o,p))),s=Be(r,i?o:void 0);if(s){let p=D(s),c=qe(p);return c.rootPath!==s&&(c.rootPath=s,c.updatedAt=new Date().toISOString(),G(s,c)),W(c,s)}let u=new Date().toISOString(),l=Ue(o),a={version:1,id:ze(o),name:l,remote:l,rootPath:o,createdAt:u,updatedAt:u,graphVersion:0,memoryVersion:0};return G(o,a),W(a,o)}};import{homedir as St}from"node:os";import{join as xt}from"node:path";import{DeleteObjectCommand as Qe,GetObjectCommand as Xe,HeadObjectCommand as Ze,ListObjectsV2Command as et,PutObjectCommand as tt,S3Client as rt}from"@aws-sdk/client-s3";import{getSignedUrl as ot}from"@aws-sdk/s3-request-presigner";var M=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new rt({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 n=typeof r=="string"?Buffer.from(r,"utf8"):r;await this.client.send(new tt({Bucket:this.bucket,Key:e,Body:n,ContentType:o}))}async get(e){let r=await ot(this.client,new Xe({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 Ze({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 Qe({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],o;do{let n=await this.client.send(new et({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let i of n.Contents??[])i.Key&&r.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});o=n.IsTruncated?n.NextContinuationToken:void 0}while(o);return r}};import{access as z,mkdir as nt,readFile as st,readdir as it,rm as ct,stat as J,writeFile as at}from"node:fs/promises";import{dirname as ut,join as lt,relative as B,resolve as pt}from"node:path";var x=class{constructor(e){this.root=e}root;name="local";path(e){let r=e.replace(/^\/+/,"");return pt(this.root,r)}async put(e,r){let o=this.path(e);await nt(ut(o),{recursive:!0}),await at(o,r)}async get(e){try{return await st(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 z(this.path(e)),!0}catch{return!1}}async delete(e){await ct(this.path(e),{force:!0})}async list(e=""){let r=this.path(e),o=[];try{await z(r)}catch{return o}let n=async s=>{let u=await it(s,{withFileTypes:!0});for(let l of u){let a=lt(s,l.name);if(l.isDirectory()){await n(a);continue}let p=await J(a);o.push({key:B(this.root,a),size:p.size,updatedAt:p.mtime.toISOString()})}},i=await J(r);return i.isDirectory()?await n(r):o.push({key:B(this.root,r),size:i.size,updatedAt:i.mtime.toISOString()}),o}};import{DeleteObjectCommand as dt,GetObjectCommand as gt,HeadObjectCommand as mt,ListObjectsV2Command as ft,PutObjectCommand as yt,S3Client as ht}from"@aws-sdk/client-s3";import{getSignedUrl as kt}from"@aws-sdk/s3-request-presigner";var C=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new ht({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 n=typeof r=="string"?Buffer.from(r,"utf8"):r;await this.client.send(new yt({Bucket:this.bucket,Key:e,Body:n,ContentType:o}))}async get(e){let r=await kt(this.client,new gt({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 mt({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 dt({Bucket:this.bucket,Key:e}))}async list(e=""){let r=[],o;do{let n=await this.client.send(new ft({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:o}));for(let i of n.Contents??[])i.Key&&r.push({key:i.Key,size:i.Size,updatedAt:i.LastModified?.toISOString()});o=n.IsTruncated?n.NextContinuationToken:void 0}while(o);return r}};function _(t,e){return console.warn(e),new x(t)}function Y(t){let e=t.localRoot??xt(St(),".toolnet-memory","storage");if(t.provider==="r2"){let r=t.r2;return r?.accountId&&r.bucket&&r.accessKeyId&&r.secretAccessKey?new C({name:"r2",endpoint:`https://${r.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:r.bucket,forcePathStyle:!0,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):_(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 C({name:"s3",endpoint:r.endpoint,region:r.region??"us-east-1",bucket:r.bucket,forcePathStyle:r.forcePathStyle??!1,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):_(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 M({namespace:r.namespace,bucket:r.bucket,accessKeyId:r.accessKeyId,secretAccessKey:r.secretAccessKey}):_(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new x(e)}function Ct(t){return new Promise(e=>setTimeout(e,t))}async function q(t,e={}){let r=Math.max(1,e.attempts??3),o=e.baseDelayMs??150,n=e.maxDelayMs??2e3,i;for(let s=1;s<=r;s++)try{return await t()}catch(u){if(i=u,s>=r)break;let l=Math.min(n,o*2**(s-1)),a=Math.floor(Math.random()*Math.max(1,l*.2));await Ct(l+a)}throw i}var vt=new Set(["put","get","getText","delete","list"]);function Q(t,e={}){return new Proxy(t,{get(r,o){let n=Reflect.get(r,o,r);return typeof n!="function"?n:vt.has(o)?(...i)=>q(()=>Promise.resolve(n.apply(r,i)),e):n.bind(r)}})}function X(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 Z(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 n=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return n?`${n[1]}memory/records/${n[2]}`:(n=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),n?`${n[1]}memory/vectors/${n[2]}`:(n=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),n?`${n[1]}code/graph/${n[2]}`:e))}var R=class{constructor(e,r,o,n){this.provider=e;this.name=e.name,this.projectId=r,this.projectName=o,this.folder=X(n??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,n=await this.provider.getText(e);if(n){let s;try{s=JSON.parse(n)}catch(u){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${u instanceof Error?u.message:String(u)}`)}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"&&(o=s.createdAt)}let i={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:o,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=Z(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 ne,readFileSync as Ot,readdirSync as te}from"node:fs";import{join as v}from"node:path";var yn=new Int32Array(new SharedArrayBuffer(4));import{closeSync as Cn,existsSync as bt,fsyncSync as vn,mkdirSync as bn,openSync as Pn,readFileSync as Pt,renameSync as wn,writeFileSync as jn}from"node:fs";import{dirname as An,join as wt}from"node:path";function jt(t){return wt(t.rootPath,".toolnet","work","current.json")}function ee(t){let e=jt(t);if(!bt(e))return null;try{let r=JSON.parse(Pt(e,"utf8"));return r.version!==1||r.projectId!==t.id?null:r}catch{return null}}function se(t){if(!ne(t))return null;try{return JSON.parse(Ot(t,"utf8"))}catch{return null}}function re(t,e){if(!ne(t))return[];let r=[];for(let o of te(t,{withFileTypes:!0})){if(!o.isDirectory())continue;let n=v(t,o.name);for(let i of te(n,{withFileTypes:!0})){if(!i.isDirectory())continue;let s=se(v(n,i.name,"state.json"));s&&s.version===1&&s.projectId===e.id&&r.push(s)}}return r}function At(t){let e=v(t.rootPath,".toolnet","runtime","sources"),r=v(t.rootPath,".toolnet","sessions"),o=re(e,t),n=re(r,t),i=new Map;for(let s of n)i.set(`${s.agent}:${s.nativeSessionId}`,s);for(let s of o)i.set(`${s.agent}:${s.nativeSessionId}`,s);return Array.from(i.values())}function oe(t){return t.filter(e=>!!e).sort().at(-1)}function Mt(t){let e=se(v(t.rootPath,".toolnet","runtime","opencode-status.json"));return!e||e.projectRoot&&e.projectRoot!==t.rootPath?null:e}function ie(t){let e=At(t),o=[...e].sort((c,d)=>(c.lastLocalEventAt??c.updatedAt).localeCompare(d.lastLocalEventAt??d.updatedAt)).at(-1),n=Array.from(new Set(e.map(c=>c.agent))).sort(),i=e.reduce((c,d)=>c+Math.max(0,d.lastSequence-d.lastRemoteSequence),0),s=Mt(t),u=s?.state==="capture-failed",l=s?.state==="sync-failed",a;u?a="degraded":i>0||l?a="pending":e.length>0?a="healthy":a="unknown";let p=ee(t);return{ok:a!=="degraded",agents:n,sessions:e.length,latestAgent:o?.agent,latestSessionId:o?.nativeSessionId,lastCaptureAt:oe(e.map(c=>c.lastLocalEventAt??c.updatedAt)),lastFlushAt:oe(e.map(c=>c.lastRemoteAt)),pendingWal:i,currentTask:p?.currentTask?.title,currentFile:p?.activeFiles?.at(-1)??p?.filesTouched.at(-1),syncHealth:a,opencode:s?{state:s.state,reason:s.reason,timestamp:s.timestamp,error:s.error}:void 0}}import{existsSync as je}from"node:fs";import{homedir as Xt}from"node:os";import{join as Zt}from"node:path";import{spawnSync as er}from"node:child_process";import{homedir as Rt}from"node:os";import{join as b}from"node:path";function ce(t={}){return b(t.home??Rt(),".gemini")}function It(t={}){return b(ce(t),"antigravity-cli")}function ae(t={}){return b(ce(t),"config")}function Et(t={}){return b(ae(t),"mcp_config.json")}function Tt(t={}){let e=t.cwd??process.cwd();return b(e,".agents","mcp_config.json")}function ue(t={}){return[It(t),Et(t),ae(t),Tt(t)]}import{homedir as Dt}from"node:os";import{join as le}from"node:path";function pe(t={}){let e=process.env.OPENCODE_CONFIG_DIR?.trim();if(e)return e;let r=t.xdgConfigHome??process.env.XDG_CONFIG_HOME?.trim();return r?le(r,"opencode"):le(t.home??Dt(),".config","opencode")}import{homedir as _t}from"node:os";import{join as Nt}from"node:path";function de(t={}){return Nt(t.home??_t(),".claude")}import{homedir as Ft}from"node:os";import{join as P}from"node:path";function N(t={}){return t.kiroHome??process.env.KIRO_HOME??P(t.home??Ft(),".kiro")}function Kt(t={}){return P(N(t),"settings")}function F(t={}){return P(Kt(t),"mcp.json")}function Ht(t={}){return P(N(t),"hooks")}function ge(t={}){return P(Ht(t),"toolnet-memory.json")}function me(t={}){return[N(t),F(t)]}import{homedir as $t}from"node:os";import{join as fe}from"node:path";function ye(t={}){return fe(t.home??$t(),".toolnetcli")}function Lt(t={}){return fe(ye(t),"config.json")}function he(t={}){let e=ye(t),r=Lt(t);return[e,r]}import{homedir as Gt}from"node:os";import{join as K}from"node:path";function ke(t={}){if(t.kiloHome)return t.kiloHome;if(process.env.KILO_HOME)return process.env.KILO_HOME;let e=t.xdgConfigHome??process.env.XDG_CONFIG_HOME;return e?K(e,"kilo"):K(t.home??Gt(),".config","kilo")}function Wt(t={}){return K(ke(t),"kilo.jsonc")}function Se(t={}){let e=ke(t),r=Wt(t);return[e,r]}import{homedir as Ut}from"node:os";import{join as xe,resolve as es}from"node:path";function Ce(t={}){return t.cursorHome??xe(t.home??Ut(),".cursor")}function Vt(t={}){return t.cursorConfigDir??process.env.CURSOR_CONFIG_DIR??(t.xdgConfigHome??process.env.XDG_CONFIG_HOME?xe(t.xdgConfigHome??process.env.XDG_CONFIG_HOME,"cursor"):void 0)??Ce(t)}function ve(t={}){return Array.from(new Set([Ce(t),Vt(t)]))}import{homedir as zt}from"node:os";import{join as Jt,resolve as ns}from"node:path";function Bt(t={}){return t.copilotHome??process.env.COPILOT_HOME??Jt(t.home??zt(),".copilot")}function be(t={}){return[Bt(t)]}import{homedir as Yt}from"node:os";import{join as qt,resolve as as}from"node:path";function Qt(t={}){return t.grokHome??process.env.GROK_HOME??qt(t.home??Yt(),".grok")}function Pe(t={}){return[Qt(t)]}function tr(t){return er("sh",["-lc",`command -v ${JSON.stringify(t)} >/dev/null 2>&1`],{stdio:"ignore"}).status===0}function g(t){let e=t.commandExists(t.command),r=t.configPaths.filter(i=>je(i)),o=r.length>0,n=[];e&&n.push(`command:${t.command}`);for(let i of r)n.push(`config:${i}`);return{agent:t.agent,detected:e||o,commandDetected:e,configDetected:o,evidence:n}}function we(t){let e=t.commands.filter(s=>t.commandExists(s)),r=t.configPaths.filter(s=>je(s)),o=e.length>0,n=r.length>0,i=[...e.map(s=>`command:${s}`),...r.map(s=>`config:${s}`)];return{agent:t.agent,detected:o||n,commandDetected:o,configDetected:n,evidence:i}}function Oe(t={}){let e=t.home??Xt(),r=t.commandExists??tr,o=t.codexHome??process.env.CODEX_HOME??Zt(e,".codex");return[g({agent:"agy",command:"agy",commandExists:r,configPaths:ue({home:e})}),g({agent:"opencode",command:"opencode",commandExists:r,configPaths:[pe({home:e,xdgConfigHome:t.xdgConfigHome})]}),g({agent:"claude",command:"claude",commandExists:r,configPaths:[de({home:e})]}),g({agent:"kiro",command:"kiro-cli",commandExists:r,configPaths:me({home:e,kiroHome:t.kiroHome})}),we({agent:"cursor",commands:["agent","cursor-agent"],commandExists:r,configPaths:ve({home:e,cursorHome:t.cursorHome,cursorConfigDir:t.cursorConfigDir,xdgConfigHome:t.xdgConfigHome})}),g({agent:"copilot",command:"copilot",commandExists:r,configPaths:be({home:e,copilotHome:t.copilotHome})}),g({agent:"grok",command:"grok",commandExists:r,configPaths:Pe({home:e,grokHome:t.grokHome})}),g({agent:"toolnet-cli",command:"toolnet",commandExists:r,configPaths:he({home:e})}),we({agent:"kilo",commands:["kilo","kilo-code"],commandExists:r,configPaths:Se({home:e,kiloHome:t.kiloHome})}),g({agent:"codex",command:"codex",commandExists:r,configPaths:[o]})]}import{existsSync as H,readFileSync as rr}from"node:fs";var or="ToolNet Memory - ",nr=["SessionStart","UserPromptSubmit","PreToolUse","PostToolUse","Stop"];function f(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Ae(t){if(!H(t))return{};let e;try{e=JSON.parse(rr(t,"utf8"))}catch(r){return{error:r instanceof Error?r.message:String(r)}}return f(e)?{value:e}:{error:"root must be a JSON object"}}function sr(t){if(!t||!f(t.mcpServers))return!1;let e=t.mcpServers["toolnet-memory"];return f(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(!(!f(t)||!f(t.action)))return typeof t.action.command=="string"?t.action.command:void 0}function cr(t){if(!t||t.version!=="v1"||!Array.isArray(t.hooks))return[];let e=new Set;for(let r of t.hooks){if(!f(r)||typeof r.name!="string"||!r.name.startsWith(or))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 Me(t={}){let e=t.configFile??F(),r=t.hooksFile??ge(),o=Ae(e),n=Ae(r),i=!o.error&&sr(o.value),s=n.error?[]:cr(n.value),u=nr.every(d=>s.includes(d)),l=[];o.error&&l.push(`MCP config: ${o.error}`),n.error&&l.push(`Hooks config: ${n.error}`);let a=i&&u,p=H(e)||H(r),c=l.length>0?"invalid":a?"ready":p?"partial":"not-installed";return{installed:a,state:c,mcp:{configured:i,configFile:e,error:o.error},hooks:{configured:u,hooksFile:r,triggers:s,error:n.error},errors:l}}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"},ur={spinner:[".","*","+","x","*","+"],barFilled:"#",barEmpty:"-",phaseDone:"[OK]",phaseActive:"[>>]",rail:"|",branch:"|",corner:"\\",dash:"-"};function lr(){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 $;function Re(){return $||($=lr()?ar:ur),$}var y={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 pr(t){return t.noColor||process.env.NO_COLOR?!1:t.tty??process.stdout.isTTY??!1}function w(t,e,r){return pr(r)?`${e}${t}${y.reset}`:t}function I(t,e){return w(t,y.dim,e)}function dr(t,e){return w(t,y.bold,e)}function gr(t,e){return w(t,y.cyan,e)}function mr(t,e){return w(t,y.red,e)}function fr(t,e){return w(t,y.white,e)}function Ie(t,e,r){let o=Re(),n=e?` ${I(`v${e}`,r)}`:"";return`${gr(o.phaseDone,r)} ${t}${n}`}function E(t,e){return dr(t,e)}function m(t,e,r,o){let n=" ".repeat(Math.max(0,r-t.length));return` ${I(t,o)}${n} ${fr(e,o)}`}function Ee(t){return mr("\u2717",t)}function yr(t){return{tty:t.tty,noColor:t.noColor}}async function hr(t){let e=yr(t);console.log(""),console.log(Ie("ToolNet Status",void 0,e)),console.log("");try{let r=new O().detect(),o=L();console.log(E("PROJECT",e)),console.log(m("Name",r.name,8,e));let n=Q(Y({provider:o.storage.provider,r2:o.storage.r2,s3:o.storage.s3,huggingface:o.storage.huggingface,localRoot:o.storage.localRoot}),{attempts:3}),i=new R(n,r.id,r.name,r.remote??r.name),s="unknown",u="unknown";try{s=await i.exists(`${r.id}/memory.json`)?"ready":"not initialized"}catch{s="error"}try{u=await i.exists(`${r.id}/code-graph.json`)?"ready":"not built"}catch{u="error"}console.log(m("Memory",s,8,e)),console.log(m("Index",u,8,e)),console.log("");let l=Oe(),a=l.filter(c=>c.detected).map(c=>c.agent);if(a.length>0){if(console.log(E("INTEGRATIONS",e)),console.log(m("Detected",a.join(", "),8,e)),l.find(d=>d.agent==="kiro")?.detected){let d=Me();console.log(m("Kiro",d.installed?"ready":d.state,8,e))}console.log("")}let p=ie(r);if(p.agents.length>0){console.log(E("SERVICE",e));let c=p.syncHealth==="healthy"?"running":p.syncHealth==="degraded"?"degraded":"stopped";console.log(m("Daemon",c,8,e)),console.log("")}}catch(r){console.log(Ee(e)+" Failed to get status"),console.log(""),console.log(I(` ${r instanceof Error?r.message:String(r)}`,e)),console.log(""),process.exitCode=1}}async function kr(){let t=process.argv.slice(2),e={tty:process.stdout.isTTY,noColor:process.env.NO_COLOR!==void 0||t.includes("--no-color")};await hr(e)}kr().catch(t=>{console.error(""),console.error(t instanceof Error?t.message:String(t)),console.error(""),process.exitCode=1});
|
|
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});
|