toolnet-memory 0.3.16 → 0.3.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/.env.example +74 -0
  2. package/.release-target +1 -1
  3. package/README.md +157 -7
  4. package/bin/toolnet-memory +12 -0
  5. package/bundle/agy-hook.js +59 -59
  6. package/bundle/agy.js +58 -58
  7. package/bundle/api.js +15 -15
  8. package/bundle/audit.js +2 -0
  9. package/bundle/background-refresh.js +7 -7
  10. package/bundle/code-capabilities.js +2 -0
  11. package/bundle/codex.js +63 -63
  12. package/bundle/context-runtime.js +41 -41
  13. package/bundle/context.js +15 -15
  14. package/bundle/copilot-hook.js +73 -73
  15. package/bundle/cursor-hook.js +73 -73
  16. package/bundle/docker-healthcheck.js +3 -0
  17. package/bundle/doctor.js +4 -4
  18. package/bundle/full-index.js +20 -19
  19. package/bundle/gc.js +5 -3
  20. package/bundle/graph-cli.js +1 -1
  21. package/bundle/graph-index.js +5 -4
  22. package/bundle/graph-ui.js +4 -3
  23. package/bundle/grok-hook.js +52 -52
  24. package/bundle/handoff-refresh.js +2 -2
  25. package/bundle/help-cli.js +4 -4
  26. package/bundle/impact.js +5 -4
  27. package/bundle/incremental.js +5 -5
  28. package/bundle/init.js +35 -35
  29. package/bundle/kiro-hook.js +74 -74
  30. package/bundle/learner.js +8 -6
  31. package/bundle/mcp.js +19 -17
  32. package/bundle/memory-agent.js +4 -4
  33. package/bundle/memory-query.js +3 -3
  34. package/bundle/opencode.js +73 -73
  35. package/bundle/project-manual.js +7 -7
  36. package/bundle/public/index.html +1089 -2306
  37. package/bundle/runtime.js +16 -13
  38. package/bundle/semantic.js +6 -5
  39. package/bundle/service.js +11 -6
  40. package/bundle/snapshot.js +6 -4
  41. package/bundle/status-cli.js +4 -4
  42. package/bundle/toolnet-cli.js +49 -49
  43. package/bundle/work-continuity.js +7 -7
  44. package/package.json +26 -2
  45. package/release-manifest.json +57 -1
@@ -1,5 +1,5 @@
1
- import"dotenv/config";import{existsSync as Ze,readFileSync as Qe}from"node:fs";import{homedir as Xe}from"node:os";import{join as et}from"node:path";function tt(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 rt(){let n=process.env.TOOLNET_GLOBAL_ENV??et(Xe(),".config","toolnet-memory",".env");if(!Ze(n))return;let e=Qe(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]=tt(r.slice(o+1)))}}rt();function I(n,e){return n===void 0?e:["1","true","yes","on"].includes(n.toLowerCase())}function T(n,e){if(!n)return e;let t=Number(n);return Number.isFinite(t)?t:e}function pe(){return{memory:{autoCapture:I(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:I(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:I(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:I(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:T(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:T(process.env.MEMORY_RERANK_TOP,10),finalContext:T(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:T(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:I(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:T(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as dt}from"node:crypto";import{existsSync as B,mkdirSync as lt,readFileSync as ut,renameSync as pt,writeFileSync as mt}from"node:fs";import{basename as ft,dirname as G,join as _,parse as xe,resolve as j}from"node:path";import{createHash as ge}from"node:crypto";import{spawnSync as nt}from"node:child_process";var O="git-remote-v1",ot=new Set(["github.com","gitlab.com","bitbucket.org"]);function ye(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:(ot.has(n)&&(t=t.toLowerCase()),t)}function st(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=ye(t,e.pathname);return s?`${o}/${s}`:null}function it(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=ye(t,e[2]??"");return r?`${t}/${r}`:null}function me(n){let e=n.trim();return e?e.includes("://")?st(e):it(e):null}function at(n){return ge("sha256").update(`${O}:${n}`).digest("hex")}function he(n){return ge("sha256").update(`toolnet-project:${O}:${n}`).digest("hex").slice(0,16)}function ct(n){return n.split("/").filter(Boolean).at(-1)?.trim()||null}function te(n,e){let t=nt("git",["-C",n,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return t.error||t.status!==0?null:t.stdout?.trim()||null}function fe(n,e){let t=ct(n);return t?{scheme:O,canonicalRemote:n,fingerprint:at(n),repositoryName:t,source:e}:null}function Se(n){let e=te(n,["remote","get-url","origin"]);if(e){let o=me(e);if(o)return fe(o,"origin")}let t=te(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=te(n,["remote","get-url",o]);if(!s)continue;let a=me(s);a&&r.add(a)}return r.size!==1?null:fe([...r][0],"unique-remote")}var ve=".toolnet",gt="project.json";function yt(n){return dt("sha256").update(n).digest("hex").slice(0,16)}function E(n){return _(n,ve,gt)}function we(n){return B(E(n))}function be(n,e){let t=j(n),r=xe(t).root;for(;;){if(we(t))return t;if(t===r||e&&t===j(e))break;let o=G(t);if(o===t)break;t=o}return null}function re(n){let e=j(n),t=xe(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>B(_(e,s))))return e;if(e===t)break;let o=G(e);if(o===e)break;e=o}return j(n)}function L(n){let e;try{e=JSON.parse(ut(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:G(G(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 z(n,e){let t=_(n,ve);lt(t,{recursive:!0});let r=E(n),o=`${r}.tmp-${process.pid}`;mt(o,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),pt(o,r)}function P(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 ne(n){return{version:1,scheme:O,canonicalRemote:n.canonicalRemote,fingerprint:n.fingerprint,repositoryName:n.repositoryName}}function ht(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 V=class{adopt(e,t){let r=re(j(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(we(r)){let i=L(E(r));if(i.id!==t.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${i.id}`,`requested=${t.id}`].join(" "));return P(i,r)}let o=new Date().toISOString(),s={...t.metadata};t.gitIdentity&&(s.toolnetIdentity=ne(t.gitIdentity));let a={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 z(r,a),P(a,r)}recordGitIdentity(e,t,r={}){let o=this.requireExisting(e),s=E(o.rootPath),a=L(s),i=ht(a);if(i&&i!==t.fingerprint&&!r.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${i}`,`current=${t.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let d=a.metadata?.toolnetIdentity;return d&&typeof d=="object"&&!Array.isArray(d)&&d.fingerprint===t.fingerprint||(a.metadata={...a.metadata,toolnetIdentity:ne(t)},a.updatedAt=new Date().toISOString(),z(o.rootPath,a)),P(a,o.rootPath)}findExisting(e=process.cwd()){let t=j(e),r=re(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>B(_(r,d))),a=be(t,s?r:void 0);if(!a)return null;let i=L(E(a));return P(i,a)}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=j(e),r=re(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>B(_(r,l))),a=be(t,s?r:void 0);if(a){let l=E(a),m=L(l);return m.rootPath!==a&&(m.rootPath=a,m.updatedAt=new Date().toISOString(),z(a,m)),P(m,a)}let i=new Date().toISOString(),d=ft(r),c=Se(r),u={version:1,id:c?he(c.canonicalRemote):yt(r),name:d,remote:c?.repositoryName??d,rootPath:r,createdAt:i,updatedAt:i,graphVersion:0,memoryVersion:0,metadata:c?{toolnetIdentity:ne(c)}:void 0};return z(r,u),P(u,r)}};var St=[{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"}],bt=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function ke(n){return n.normalize("NFKC").trim().toLowerCase()}function xt(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 vt(n){return/^[a-f0-9]{32}$/iu.test(n)||/^[a-f0-9]{40}$/iu.test(n)||/^[a-f0-9]{64}$/iu.test(n)}function wt(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 kt(n,e){return n.start<e.end&&e.start<n.end}function Re(n){return n.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var H=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let r=ke(t);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let s of St){let a=new RegExp(s.regex.source,s.regex.flags);for(let i of e.matchAll(a))i.index===void 0||!i[0]||this.allowed(i[0])||t.push({type:s.type,value:i[0],start:i.index,end:i.index+i[0].length,confidence:s.confidence})}this.enableEntropyHeuristic&&t.push(...this.entropyMatches(e));let r=Re(t),o=[];for(let s of r)o.some(a=>kt(a,s))||o.push(s);return Re(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=ke(e);return bt.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)||vt(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||wt(e,o.index,o.index+s.length)&&(xt(s)<3.7||t.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return t}};var U=class{scanner;constructor(e={}){this.scanner=new H(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((a,i)=>i.start-a.start),s=new Set;for(let a of o)s.add(a.type),r=r.slice(0,a.start)+`[REDACTED:${a.type}]`+r.slice(a.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 pn=new U;import{homedir as Ut}from"node:os";import{join as Wt}from"node:path";import{DeleteObjectCommand as Rt,GetObjectCommand as Ct,HeadObjectCommand as Mt,ListObjectsV2Command as Pt,PutObjectCommand as jt,S3Client as Et}from"@aws-sdk/client-s3";import{getSignedUrl as At}from"@aws-sdk/s3-request-presigner";var W=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Et({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,r="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new jt({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await At(this.client,new Ct({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 Mt({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 Rt({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new Pt({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 Ce,mkdir as It,readFile as Tt,readdir as Ot,rm as _t,stat as Me,writeFile as Nt}from"node:fs/promises";import{dirname as $t,join as Dt,relative as Pe,resolve as Ft}from"node:path";var N=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 r=this.path(e);await It($t(r),{recursive:!0}),await Nt(r,t)}async get(e){try{return await Tt(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 Ce(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),r=[];try{await Ce(t)}catch{return r}let o=async a=>{let i=await Ot(a,{withFileTypes:!0});for(let d of i){let c=Dt(a,d.name);if(d.isDirectory()){await o(c);continue}let u=await Me(c);r.push({key:Pe(this.root,c),size:u.size,updatedAt:u.mtime.toISOString()})}},s=await Me(t);return s.isDirectory()?await o(t):r.push({key:Pe(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as Kt,GetObjectCommand as Lt,HeadObjectCommand as zt,ListObjectsV2Command as Bt,PutObjectCommand as Gt,S3Client as Vt}from"@aws-sdk/client-s3";import{getSignedUrl as Ht}from"@aws-sdk/s3-request-presigner";var $=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Vt({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 Gt({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await Ht(this.client,new Lt({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 zt({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 Kt({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new Bt({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 oe(n,e){return console.warn(e),new N(n)}function je(n){let e=n.localRoot??Wt(Ut(),".toolnet-memory","storage");if(n.provider==="r2"){let t=n.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new $({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):oe(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 $({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):oe(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 W({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):oe(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new N(e)}var Y=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,"graph","manifest.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 Ee(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 Ae(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 q=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=Ee(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 a;try{a=JSON.parse(o)}catch(i){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${i instanceof Error?i.message:String(i)}`)}if(typeof a.id=="string"&&a.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${a.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof a.createdAt=="string"&&(r=a.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=Ae(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))}};import{createHash as Yt}from"node:crypto";import{dirname as Jt,extname as qt,normalize as Zt,posix as Qt}from"node:path";var Z=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)}};function Xt(n,e,t,r){return Yt("sha256").update(`${n}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function C(n){return Zt(n).replaceAll("\\","/")}function er(n,e,t){if(!e.startsWith("."))return;let r=C(Qt.join(Jt(n),e)),o=qt(r),s;if(o===".js"){let a=r.slice(0,-3);s=[`${a}.ts`,`${a}.tsx`,`${a}.js`,`${a}.jsx`]}else if(o===".mjs"){let a=r.slice(0,-4);s=[`${a}.mts`,`${a}.ts`,`${a}.mjs`]}else if(o===".cjs"){let a=r.slice(0,-4);s=[`${a}.cts`,`${a}.ts`,`${a}.cjs`]}else o?s=[r]:s=[`${r}.ts`,`${r}.tsx`,`${r}.mts`,`${r}.cts`,`${r}.js`,`${r}.jsx`,`${r}.mjs`,`${r}.cjs`,`${r}/index.ts`,`${r}/index.tsx`,`${r}/index.mts`,`${r}/index.cts`,`${r}/index.js`,`${r}/index.jsx`,`${r}/index.mjs`,`${r}/index.cjs`];return s.find(a=>t.has(C(a)))}function se(n,e,t,r){let o=r?.(n,e,t);if(o){let s=C(o);if(t.has(s))return s}return er(n,e,t)}var D=class{build(e,t,r={}){let o=new Z;for(let i of r.seedSymbols??[])o.addSymbol(i);for(let i of t)for(let d of i.symbols)o.addSymbol(d);let s=new Map;for(let i of o.allSymbols(e))i.type==="file"&&s.set(C(i.filePath),i);let a=new Set(s.keys());for(let i of t){let d=C(i.filePath),c=s.get(d);if(c){for(let u of i.symbols)u.id!==c.id&&o.addEdge(this.edge(e,c.id,"DEFINES",u.id));for(let u of i.imports){let l=se(d,u.source,a,r.resolveModule);if(!l)continue;let m=s.get(l);m&&o.addEdge(this.edge(e,c.id,"IMPORTS",m.id,{source:u.source,resolvedFile:l}))}for(let u of i.heritage){let l=o.findByName(e,u.targetName).filter(m=>m.type==="class"||m.type==="interface");for(let m of l)o.addEdge(this.edge(e,u.fromId,u.type,m.id))}for(let u of i.calls){if(!u.callerId)continue;let l=this.resolveCallTargets(e,i,u.calleeName,u.qualifier,o,a,r.resolveModule);for(let m of l)m.id!==u.callerId&&o.addEdge(this.edge(e,u.callerId,"CALLS",m.id,{line:u.line,qualifier:u.qualifier}))}}}return o}resolveCallTargets(e,t,r,o,s,a,i){let d=C(t.filePath),c=s.findByName(e,r).filter(u=>C(u.filePath)===d);if(!o&&c.length)return c;if(o)for(let u of t.imports){if(!u.bindings.find(g=>g.kind==="namespace"&&g.localName===o))continue;let m=se(d,u.source,a,i);if(m)return s.findByName(e,r).filter(g=>C(g.filePath)===m)}for(let u of t.imports){let l=u.bindings.find(v=>v.localName===r);if(!l)continue;let m=se(d,u.source,a,i);if(!m)continue;let g=l.importedName==="default"?r:l.importedName,w=s.findByName(e,g).filter(v=>C(v.filePath)===m);if(w.length)return w}return s.findByName(e,r).filter(u=>u.type==="function"||u.type==="method")}edge(e,t,r,o,s){return{id:Xt(e,t,r,o),projectId:e,from:t,to:o,type:r,metadata:s}}};import{createHash as tr}from"node:crypto";function ie(n){return n.replaceAll("\\","/")}function rr(n,e,t,r){return tr("sha256").update(`${n}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function nr(n){return[ie(n.filePath),n.type,n.qualifiedName??n.name].join("\0")}function Ie(n){let e=new Map;for(let r of n){let o=nr(r),s=e.get(o)??[];s.push(r),e.set(o,s)}let t=new Map;for(let[r,o]of e)o.length===1&&t.set(r,o[0]);return t}function or(n,e){let t=Ie(n),r=Ie(e),o=new Map;for(let[s,a]of t){let i=r.get(s);i&&o.set(a.id,i.id)}return o}function Te(n){let e=new Map(n.previousSymbols.map(s=>[s.id,s])),t=new Set(n.currentSymbols.map(s=>s.id)),r=or(n.previousSymbols,n.currentSymbols),o=[];for(let s of n.previousEdges){let a=e.get(s.from),i=e.get(s.to);if(!a||!i)continue;let d=ie(a.filePath),c=ie(i.filePath);if(n.rebuiltSourceFiles.has(d)||n.removedFiles.has(d)||n.removedFiles.has(c))continue;let u=t.has(s.from)?s.from:r.get(s.from),l=t.has(s.to)?s.to:r.get(s.to);!u||!l||!t.has(u)||!t.has(l)||o.push({...s,id:rr(n.projectId,u,s.type,l),from:u,to:l})}return o}import{readFile as sr}from"node:fs/promises";import{join as ir}from"node:path";import{createHash as ar}from"node:crypto";import*as f from"typescript";function Oe(n,e){return ar("sha256").update(`${n}:${e}`).digest("hex").slice(0,24)}function ae(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}async function _e(n,e,t){let r=ir(e,t),o=await sr(r,"utf8"),s=f.createSourceFile(t,o,f.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?f.ScriptKind.TSX:f.ScriptKind.TS),a=[],i=[],d=[],c=[],u={id:Oe(n,`file:${t}`),projectId:n,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:s.getLineAndCharacterOfPosition(s.end).line+1};a.push(u);let l=[],m=[];function g(p,x,S,y){let h=Oe(n,`${t}:${S}:${y??x}:${p.pos}`);return a.push({id:h,projectId:n,name:x,qualifiedName:y??x,type:S,filePath:t,startLine:ae(s,p),endLine:s.getLineAndCharacterOfPosition(p.end).line+1}),h}function w(p){if(!f.isStringLiteral(p.moduleSpecifier))return;let x=[],S=p.importClause;if(S?.name&&x.push({localName:S.name.text,importedName:"default",kind:"default"}),S?.namedBindings&&f.isNamedImports(S.namedBindings))for(let y of S.namedBindings.elements)x.push({localName:y.name.text,importedName:y.propertyName?.text??y.name.text,kind:"named"});S?.namedBindings&&f.isNamespaceImport(S.namedBindings)&&x.push({localName:S.namedBindings.name.text,importedName:"*",kind:"namespace"}),i.push({source:p.moduleSpecifier.text,bindings:x})}function v(p,x){for(let S of p.heritageClauses??[])for(let y of S.types){let h=y.expression.getText(s).split(".").at(-1)??"";h&&c.push({fromId:x,targetName:h,type:S.token===f.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function k(p){let x=!1,S=!1;if(f.isImportDeclaration(p)&&w(p),f.isInterfaceDeclaration(p)&&g(p,p.name.text,"interface",p.name.text),f.isClassDeclaration(p)&&p.name){let y=g(p,p.name.text,"class",p.name.text);v(p,y),m.push({id:y,name:p.name.text}),S=!0}if(f.isFunctionDeclaration(p)&&p.name){let y=g(p,p.name.text,"function",p.name.text);l.push(y),x=!0}if(f.isMethodDeclaration(p)&&p.name){let y=p.name.getText(s),h=m.at(-1)?.name,R=g(p,y,"method",h?`${h}.${y}`:y);l.push(R),x=!0}if(f.isCallExpression(p)&&(f.isIdentifier(p.expression)&&d.push({callerId:l.at(-1),calleeName:p.expression.text,line:ae(s,p)}),f.isPropertyAccessExpression(p.expression))){let y=p.expression;d.push({callerId:l.at(-1),qualifier:y.expression.getText(s),calleeName:y.name.text,line:ae(s,p)})}f.forEachChild(p,k),x&&l.pop(),S&&m.pop()}return k(s),{filePath:t,symbols:a,imports:i,calls:d,heritage:c}}import{existsSync as cr,readFileSync as dr,readdirSync as lr,realpathSync as ur}from"node:fs";import{dirname as le,extname as pr,join as ce,parse as mr,relative as de,resolve as F}from"node:path";import*as b from"typescript";var fr="tsconfig.json",gr=new Set(["node_modules",".git",".toolnet","dist","build","out","coverage",".next",".nuxt",".cache",".turbo","target","vendor"]),Ne=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs"];function K(n){return n.replaceAll("\\","/").replace(/^\.\/+/u,"")}function Fe(n,e){let t=K(de(n,e));return t!==".."&&!t.startsWith("../")&&!t.startsWith("/")}function $e(n){try{return ur.native(n)}catch{return F(n)}}function yr(n,e){let t=F(e),r=F(n);for(;;){let o=ce(r,fr);if(cr(o))return o;if(r===t)return;let s=mr(r).root;if(r===s)return;let a=le(r);if(a===r||!Fe(t,a)&&a!==t)return;r=a}}function hr(n){let e=b.readConfigFile(n,b.sys.readFile);if(e.error)throw new Error(b.flattenDiagnosticMessageText(e.error.messageText,`
5
- `));return b.parseJsonConfigFileContent(e.config,b.sys,le(n))}function Sr(){return{allowJs:!0,checkJs:!1,noEmit:!0,skipLibCheck:!0,target:b.ScriptTarget.ES2022,module:b.ModuleKind.NodeNext,moduleResolution:b.ModuleResolutionKind.NodeNext,resolveJsonModule:!0}}function br(n){let e=K(n),t=pr(e);if(t){let o=[e];if(t===".js"){let s=e.slice(0,-3);o.push(`${s}.ts`,`${s}.tsx`)}if(t===".mjs"){let s=e.slice(0,-4);o.push(`${s}.mts`,`${s}.ts`)}if(t===".cjs"){let s=e.slice(0,-4);o.push(`${s}.cts`,`${s}.ts`)}return e.endsWith(".d.ts")&&o.push(e.slice(0,-5)+".ts"),o}let r=[e];for(let o of Ne)r.push(`${e}${o}`);for(let o of Ne)r.push(`${e}/index${o}`);return r}function De(n,e){for(let t of br(n)){let r=K(t);if(e.has(r))return r}}function Ke(n,e){if(typeof n=="string"){e.push(n);return}if(!(!n||typeof n!="object"||Array.isArray(n)))for(let t of Object.values(n))Ke(t,e)}function xr(n){let e=[];for(let t of["source","types","module","main"]){let r=n[t];typeof r=="string"&&e.push(r)}return Ke(n.exports,e),[...new Set(e)]}function vr(n){let t=[F(n)],r=[];for(;t.length>0;){let o=t.pop(),s;try{s=lr(o,{withFileTypes:!0})}catch{continue}if(s.find(i=>i.isFile()&&i.name==="package.json"))try{let i=JSON.parse(dr(ce(o,"package.json"),"utf8"));typeof i.name=="string"&&i.name.trim()&&r.push({name:i.name.trim(),directory:o,entries:xr(i)})}catch{}for(let i of s)i.isDirectory()&&(gr.has(i.name)||t.push(ce(o,i.name)))}return r.sort((o,s)=>s.name.length-o.name.length)}var Q=class{rootPath;configCache=new Map;workspacePackages;constructor(e){this.rootPath=$e(e)}resolve(e,t,r){let o=F(this.rootPath,e),s=yr(le(o),this.rootPath),a=s?this.config(s).options:Sr(),i=b.resolveModuleName(t,o,a,b.sys).resolvedModule;if(i){let d=this.matchResolvedFile(i.resolvedFileName,r);if(d)return d}return this.resolveWorkspacePackage(t,r)}config(e){let t=this.configCache.get(e);if(t)return t;let r=hr(e);return this.configCache.set(e,r),r}matchResolvedFile(e,t){let r=$e(e);if(!Fe(this.rootPath,r))return;let o=K(de(this.rootPath,r));return De(o,t)}packages(){return this.workspacePackages?this.workspacePackages:(this.workspacePackages=vr(this.rootPath),this.workspacePackages)}resolveWorkspacePackage(e,t){let r=this.packages().find(i=>e===i.name||e.startsWith(`${i.name}/`));if(!r)return;let o=K(de(this.rootPath,r.directory)),s=e===r.name?"":e.slice(r.name.length+1),a=[];if(s)a.push(`${o}/${s}`,`${o}/src/${s}`);else{for(let i of r.entries)a.push(`${o}/${i.replace(/^\.\//u,"")}`);a.push(`${o}/src/index`,`${o}/index`)}for(let i of a){let d=De(i,t);if(d)return d}}};function wr(n){let e=n??4;if(!Number.isSafeInteger(e)||e<1||e>64)throw new Error("concurrency must be an integer between 1 and 64");return e}function kr(n){if(n?.aborted)throw new Error("Operation aborted")}async function X(n,e,t={}){if(n.length===0)return[];let r=Math.min(wr(t.concurrency),n.length),o=new Array(n.length),s=0,a=0,i=async()=>{for(;;){kr(t.signal);let c=s;if(s+=1,c>=n.length)return;o[c]=await e(n[c],c),a+=1,t.onProgress?.({completed:a,total:n.length,index:c})}},d=Array.from({length:r},()=>i());return await Promise.all(d),o}import{join as Br}from"node:path";import{lstat as Pr,readdir as jr}from"node:fs/promises";import{extname as Er,join as Ar,relative as Ir,resolve as Tr}from"node:path";import{basename as Rr}from"node:path";var Cr=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),Mr=new Set([".pem",".key",".p12",".pfx"]);function Le(n){let e=Rr(n).toLowerCase();if(Cr.has(e))return!0;for(let t of Mr)if(e.endsWith(t))return!0;return!1}var Or=2*1024*1024,_r=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),Nr=new Set(["node_modules",".git",".toolnet",".toolnet-memory","dist","build","out","coverage",".next",".nuxt",".cache",".parcel-cache",".turbo","vendor","target"]);function ze(n,e){if(!Number.isSafeInteger(n)||n<1)throw new Error(`${e} must be a positive integer`);return n}function Be(n){if(n?.aborted)throw new Error("Repository scan aborted")}function $r(n){let e=n.trim().toLowerCase();if(!e)throw new Error("Repository scan extension cannot be empty");return e.startsWith(".")?e:`.${e}`}function Dr(n){let e=n.toLowerCase();return/\.min\.(?:js|mjs|cjs)$/u.test(e)||/\.bundle\.(?:js|mjs|cjs)$/u.test(e)}function Fr(n){return n.replaceAll("\\","/")}async function Kr(n,e={}){let t=Tr(n),r=e.maxFileBytes??Or;if(!Number.isSafeInteger(r)||r<1)throw new Error("maxFileBytes must be a positive integer");let o=e.maxFiles??Number.MAX_SAFE_INTEGER;ze(o,"maxFiles");let s=e.progressInterval??1e3;ze(s,"progressInterval");let a=new Set(e.extensions?[...e.extensions].map($r):_r),i=new Set(Nr);for(let l of e.extraIgnoredDirectories??[]){let m=l.trim();m&&i.add(m)}let d=[],c={directories:0,entries:0,accepted:0,skippedIgnoredDirectories:0,skippedSymlinks:0,skippedGenerated:0,skippedSensitive:0,skippedOversized:0,skippedUnreadable:0},u=[t];for(;u.length>0;){Be(e.signal);let l=u.pop(),m;try{m=await jr(l,{withFileTypes:!0})}catch{c.skippedUnreadable+=1;continue}c.directories+=1;for(let g of m){Be(e.signal),c.entries+=1,c.entries%s===0&&e.onProgress?.({directories:c.directories,entries:c.entries,accepted:c.accepted});let w=Ar(l,g.name);if(g.isSymbolicLink()){c.skippedSymlinks+=1;continue}if(g.isDirectory()){if(i.has(g.name)){c.skippedIgnoredDirectories+=1;continue}u.push(w);continue}if(!g.isFile())continue;let v=Er(g.name).toLowerCase();if(!a.has(v))continue;if(Dr(g.name)){c.skippedGenerated+=1;continue}if(Le(w)){c.skippedSensitive+=1;continue}let k;try{k=await Pr(w)}catch{c.skippedUnreadable+=1;continue}if(k.isSymbolicLink()){c.skippedSymlinks+=1;continue}if(k.isFile()){if(k.size>r){c.skippedOversized+=1;continue}if(d.length>=o)throw new Error(`Repository scan file limit exceeded: ${o}`);d.push(Fr(Ir(t,w))),c.accepted+=1}}}return d.sort(),e.onProgress?.({directories:c.directories,entries:c.entries,accepted:c.accepted}),{files:d,stats:c}}async function Ge(n,e={}){return(await Kr(n,e)).files}import{createHash as Lr}from"node:crypto";import{readFile as zr}from"node:fs/promises";async function Ve(n){let e=await zr(n);return Lr("sha256").update(e).digest("hex")}async function He(n,e,t={}){let r={...t.scan};t.signal&&(r.signal=t.signal);let o=await Ge(e,r),s=await X(o,async i=>({path:i,hash:await Ve(Br(e,i))}),{concurrency:t.concurrency??8,signal:t.signal,onProgress:({completed:i,total:d,index:c})=>{t.onProgress?.({completed:i,total:d,file:o[c]})}}),a={};for(let i of s)a[i.path]={path:i.path,hash:i.hash};return{version:1,projectId:n,updatedAt:new Date().toISOString(),files:a}}function Ue(n,e){let t=new Map;for(let r of n){let o=e[r];if(!o)continue;let s=t.get(o.hash)??[];s.push(r),t.set(o.hash,s)}return t}function Gr(n,e,t,r){let o=Ue(e,t),s=Ue(n,r),a=[];for(let[i,d]of o){let c=s.get(i);d.length!==1||!c||c.length!==1||a.push({from:d[0],to:c[0],hash:i})}return a.sort((i,d)=>i.from.localeCompare(d.from))}function We(n,e){let t=n?.files??{},r=e.files,o=[],s=[],a=[],i=[];for(let[l,m]of Object.entries(r)){let g=t[l];if(!g){o.push(l);continue}if(g.hash!==m.hash){s.push(l);continue}i.push(l)}for(let l of Object.keys(t))r[l]||a.push(l);let d=Gr(o,a,t,r),c=new Set(d.map(l=>l.from)),u=new Set(d.map(l=>l.to));return{added:o.filter(l=>!u.has(l)).sort(),modified:s.sort(),deleted:a.filter(l=>!c.has(l)).sort(),unchanged:i.sort(),renamed:d}}function Ye(n){return n.replaceAll("\\","/")}var ee=class{constructor(e){this.storage=e}storage;async index(e,t,r={}){let o=new J(this.storage),s=new Y(this.storage),a=await o.load(e),i=await s.load(e),d=await He(e,t,{concurrency:r.hashConcurrency??8,scan:r.scan,signal:r.signal,onProgress:({completed:h,total:R,file:M})=>{r.onProgress?.({phase:"hash",current:h,total:R,file:M})}}),c=We(a,d),u=c.added.length>0||c.deleted.length>0||c.renamed.length>0,l=i===null||u,m=l?Object.keys(d.files).sort():[...c.modified];if(a&&i&&m.length===0)return{firstRun:!1,scanned:Object.keys(d.files).length,parsed:0,added:0,modified:0,deleted:0,renamed:0,unchanged:c.unchanged.length,symbols:i.symbols.length,edges:i.edges.length,repairedEdges:0,fullRebuild:!1,saved:!1};let g=await X(m,async h=>_e(e,t,h),{concurrency:r.parseConcurrency??4,signal:r.signal,onProgress:({completed:h,total:R,index:M})=>{r.onProgress?.({phase:"parse",current:h,total:R,file:m[M]})}}),w=new Q(t),v,k=0;if(l||!i)v=new D().build(e,g,{resolveModule:(h,R,M)=>w.resolve(h,R,M)});else{let h=new Set(c.modified.map(Ye)),R=i.symbols.filter(A=>!h.has(Ye(A.filePath)));v=new D().build(e,g,{seedSymbols:R,resolveModule:(A,Je,qe)=>w.resolve(A,Je,qe)}),r.onProgress?.({phase:"repair",current:0,total:i.edges.length});let M=Te({projectId:e,previousSymbols:i.symbols,previousEdges:i.edges,currentSymbols:v.allSymbols(e),rebuiltSourceFiles:h,removedFiles:new Set});for(let A of M)v.addEdge(A);k=M.length,r.onProgress?.({phase:"repair",current:i.edges.length,total:i.edges.length})}let p=v.allSymbols(e),x=new Set(p.map(h=>h.id)),S=v.allEdges(e).filter(h=>x.has(h.from)&&x.has(h.to)),y={version:1,projectId:e,updatedAt:new Date().toISOString(),files:Object.keys(d.files).length,symbols:p,edges:S};return r.onProgress?.({phase:"save",current:0,total:2}),await s.save(y),r.onProgress?.({phase:"save",current:1,total:2}),await o.save(d),r.onProgress?.({phase:"save",current:2,total:2}),{firstRun:a===null,scanned:Object.keys(d.files).length,parsed:m.length,added:c.added.length,modified:c.modified.length,deleted:c.deleted.length,renamed:c.renamed.length,unchanged:c.unchanged.length,symbols:y.symbols.length,edges:y.edges.length,repairedEdges:k,fullRebuild:l,saved:!0}}};async function Hr(){let n=pe(),e=new V().detect(),t=je({provider:n.storage.provider,huggingface:n.storage.huggingface,localRoot:n.storage.localRoot}),r=new q(t,e.id,e.name,e.remote??e.name),o=await new ee(r).index(e.id,e.rootPath);console.log({ok:!0,storage:r.name,...o})}Hr().catch(n=>{console.error(n),process.exit(1)});
1
+ import"dotenv/config";import{existsSync as ht,readFileSync as St}from"node:fs";import{homedir as bt}from"node:os";import{join as xt}from"node:path";function Et(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 vt(){let n=process.env.TOOLNET_GLOBAL_ENV??xt(bt(),".config","toolnet-memory",".env");if(!ht(n))return;let e=St(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]=Et(r.slice(o+1)))}}vt();function O(n,e){return n===void 0?e:["1","true","yes","on"].includes(n.toLowerCase())}function _(n,e){if(!n)return e;let t=Number(n);return Number.isFinite(t)?t:e}function ve(){return{memory:{autoCapture:O(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:O(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:O(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:O(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:_(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:_(process.env.MEMORY_RERANK_TOP,10),finalContext:_(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:_(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:O(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:_(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as It}from"node:crypto";import{existsSync as H,mkdirSync as At,readFileSync as jt,renameSync as Tt,writeFileSync as Ot}from"node:fs";import{basename as _t,dirname as W,join as $,parse as Ae,resolve as I}from"node:path";import{createHash as Pe}from"node:crypto";import{spawnSync as wt}from"node:child_process";var N="git-remote-v1",Rt=new Set(["github.com","gitlab.com","bitbucket.org"]);function ke(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:(Rt.has(n)&&(t=t.toLowerCase()),t)}function Pt(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=ke(t,e.pathname);return s?`${o}/${s}`:null}function kt(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=ke(t,e[2]??"");return r?`${t}/${r}`:null}function we(n){let e=n.trim();return e?e.includes("://")?Pt(e):kt(e):null}function Ct(n){return Pe("sha256").update(`${N}:${n}`).digest("hex")}function Ce(n){return Pe("sha256").update(`toolnet-project:${N}:${n}`).digest("hex").slice(0,16)}function Mt(n){return n.split("/").filter(Boolean).at(-1)?.trim()||null}function ie(n,e){let t=wt("git",["-C",n,...e],{encoding:"utf8",windowsHide:!0,stdio:["ignore","pipe","ignore"]});return t.error||t.status!==0?null:t.stdout?.trim()||null}function Re(n,e){let t=Mt(n);return t?{scheme:N,canonicalRemote:n,fingerprint:Ct(n),repositoryName:t,source:e}:null}function Me(n){let e=ie(n,["remote","get-url","origin"]);if(e){let o=we(e);if(o)return Re(o,"origin")}let t=ie(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=ie(n,["remote","get-url",o]);if(!s)continue;let a=we(s);a&&r.add(a)}return r.size!==1?null:Re([...r][0],"unique-remote")}var je=".toolnet",Nt="project.json";function $t(n){return It("sha256").update(n).digest("hex").slice(0,16)}function j(n){return $(n,je,Nt)}function Te(n){return H(j(n))}function Ie(n,e){let t=I(n),r=Ae(t).root;for(;;){if(Te(t))return t;if(t===r||e&&t===I(e))break;let o=W(t);if(o===t)break;t=o}return null}function ae(n){let e=I(n),t=Ae(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(s=>H($(e,s))))return e;if(e===t)break;let o=W(e);if(o===e)break;e=o}return I(n)}function Y(n){let e;try{e=JSON.parse(jt(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:W(W(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 V(n,e){let t=$(n,je);At(t,{recursive:!0});let r=j(n),o=`${r}.tmp-${process.pid}`;Ot(o,JSON.stringify(e,null,2)+`
3
+ `,{encoding:"utf8",mode:384}),Tt(o,r)}function M(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 ce(n){return{version:1,scheme:N,canonicalRemote:n.canonicalRemote,fingerprint:n.fingerprint,repositoryName:n.repositoryName}}function Dt(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 J=class{adopt(e,t){let r=ae(I(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(Te(r)){let i=Y(j(r));if(i.id!==t.id)throw new Error(["PROJECT_IDENTITY_ALREADY_EXISTS",`existing=${i.id}`,`requested=${t.id}`].join(" "));return M(i,r)}let o=new Date().toISOString(),s={...t.metadata};t.gitIdentity&&(s.toolnetIdentity=ce(t.gitIdentity));let a={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 V(r,a),M(a,r)}recordGitIdentity(e,t,r={}){let o=this.requireExisting(e),s=j(o.rootPath),a=Y(s),i=Dt(a);if(i&&i!==t.fingerprint&&!r.allowRebind)throw new Error(["PROJECT_GIT_REMOTE_CHANGED",`existing=${i}`,`current=${t.fingerprint}`,"Use explicit rebind only when this repository identity change is intentional."].join(" "));let d=a.metadata?.toolnetIdentity;return d&&typeof d=="object"&&!Array.isArray(d)&&d.fingerprint===t.fingerprint||(a.metadata={...a.metadata,toolnetIdentity:ce(t)},a.updatedAt=new Date().toISOString(),V(o.rootPath,a)),M(a,o.rootPath)}findExisting(e=process.cwd()){let t=I(e),r=ae(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>H($(r,d))),a=Ie(t,s?r:void 0);if(!a)return null;let i=Y(j(a));return M(i,a)}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=I(e),r=ae(t),s=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(u=>H($(r,u))),a=Ie(t,s?r:void 0);if(a){let u=j(a),m=Y(u);return m.rootPath!==a&&(m.rootPath=a,m.updatedAt=new Date().toISOString(),V(a,m)),M(m,a)}let i=new Date().toISOString(),d=_t(r),c=Me(r),l={version:1,id:c?Ce(c.canonicalRemote):$t(r),name:d,remote:c?.repositoryName??d,rootPath:r,createdAt:i,updatedAt:i,graphVersion:0,memoryVersion:0,metadata:c?{toolnetIdentity:ce(c)}:void 0};return V(r,l),M(l,r)}};var Kt=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,confidence:"exact"},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g,confidence:"exact"},{type:"aws_access_key",regex:/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g,confidence:"exact"},{type:"github_token",regex:/\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{40,255})\b/g,confidence:"exact"},{type:"stripe_secret_key",regex:/\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,confidence:"exact"},{type:"google_api_key",regex:/\bAIza[A-Za-z0-9_-]{30,}\b/g,confidence:"exact"},{type:"slack_token",regex:/\bxox[baprs]-[A-Za-z0-9-]{16,}\b/g,confidence:"exact"},{type:"npm_token",regex:/\bnpm_[A-Za-z0-9]{20,}\b/g,confidence:"exact"},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,confidence:"high"},{type:"jwt",regex:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,confidence:"exact"},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g,confidence:"exact"},{type:"password_assignment",regex:/\b(?:password|passwd|pwd)\s*[:=]\s*["']?[^"' \t\r\n]{6,}["']?/gi,confidence:"high"},{type:"secret_assignment",regex:/\b(?:secret|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*["']?[^"' \t\r\n]{8,}["']?/gi,confidence:"high"},{type:"cookie",regex:/\b(?:cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi,confidence:"high"},{type:"url_credentials",regex:/\bhttps?:\/\/[^:/@\s]+:[^/@\s]{4,}@[^/\s]+/gi,confidence:"high"}],Lt=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function Oe(n){return n.normalize("NFKC").trim().toLowerCase()}function Ft(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 Bt(n){return/^[a-f0-9]{32}$/iu.test(n)||/^[a-f0-9]{40}$/iu.test(n)||/^[a-f0-9]{64}$/iu.test(n)}function Gt(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 zt(n,e){return n.start<e.end&&e.start<n.end}function _e(n){return n.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var q=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let r=Oe(t);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let s of Kt){let a=new RegExp(s.regex.source,s.regex.flags);for(let i of e.matchAll(a))i.index===void 0||!i[0]||this.allowed(i[0])||t.push({type:s.type,value:i[0],start:i.index,end:i.index+i[0].length,confidence:s.confidence})}this.enableEntropyHeuristic&&t.push(...this.entropyMatches(e));let r=_e(t),o=[];for(let s of r)o.some(a=>zt(a,s))||o.push(s);return _e(o)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=Oe(e);return Lt.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)||Bt(s)||!/[A-Za-z]/u.test(s)||!/[0-9]/u.test(s)||Gt(e,o.index,o.index+s.length)&&(Ft(s)<3.7||t.push({type:"high_entropy_secret",value:s,start:o.index,end:o.index+s.length,confidence:"heuristic"}))}return t}};var Z=class{scanner;constructor(e={}){this.scanner=new q(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((a,i)=>i.start-a.start),s=new Set;for(let a of o)s.add(a.type),r=r.slice(0,a.start)+`[REDACTED:${a.type}]`+r.slice(a.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 Fn=new Z;import{homedir as xr}from"node:os";import{join as Er}from"node:path";import{DeleteObjectCommand as Ut,GetObjectCommand as Yt,HeadObjectCommand as Vt,ListObjectsV2Command as Ht,PutObjectCommand as Wt,S3Client as Jt}from"@aws-sdk/client-s3";import{getSignedUrl as qt}from"@aws-sdk/s3-request-presigner";var Q=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new Jt({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,t,r="application/octet-stream"){let o=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new Wt({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await qt(this.client,new Yt({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 Vt({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 Ut({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new Ht({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 Ne,mkdir as Zt,readFile as Qt,readdir as Xt,rm as er,stat as $e,writeFile as tr}from"node:fs/promises";import{dirname as rr,join as nr,relative as De,resolve as or}from"node:path";var D=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return or(this.root,t)}async put(e,t){let r=this.path(e);await Zt(rr(r),{recursive:!0}),await tr(r,t)}async get(e){try{return await Qt(this.path(e))}catch(t){if(typeof t=="object"&&t!==null&&"code"in t&&t.code==="ENOENT")return null;throw t}}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){try{return await Ne(this.path(e)),!0}catch{return!1}}async delete(e){await er(this.path(e),{force:!0})}async list(e=""){let t=this.path(e),r=[];try{await Ne(t)}catch{return r}let o=async a=>{let i=await Xt(a,{withFileTypes:!0});for(let d of i){let c=nr(a,d.name);if(d.isDirectory()){await o(c);continue}let l=await $e(c);r.push({key:De(this.root,c),size:l.size,updatedAt:l.mtime.toISOString()})}},s=await $e(t);return s.isDirectory()?await o(t):r.push({key:De(this.root,t),size:s.size,updatedAt:s.mtime.toISOString()}),r}};import{DeleteObjectCommand as sr,GetObjectCommand as ir,HeadObjectCommand as ar,ListObjectsV2Command as cr,PutObjectCommand as dr,S3Client as ur}from"@aws-sdk/client-s3";import{getSignedUrl as lr}from"@aws-sdk/s3-request-presigner";var K=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new ur({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 dr({Bucket:this.bucket,Key:e,Body:o,ContentType:r}))}async get(e){let t=await lr(this.client,new ir({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 ar({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 sr({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let o=await this.client.send(new cr({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{createCipheriv as pr,createDecipheriv as mr,createHash as fr,randomBytes as gr,timingSafeEqual as yr}from"node:crypto";import{readFileSync as hr}from"node:fs";var A=Buffer.from("TNMEME01","ascii"),Le=1,L=8,F=12,de=16,Fe=A.length+1+L+F+de,Sr="toolnet-memory:remote-encryption:v1:",Be="aes-256-gcm",ue=32,b=class extends Error{constructor(t,r){super(r);this.code=t;this.name="RemoteEncryptionError"}code};function br(n){return n?["1","true","yes","on","enabled"].includes(n.trim().toLowerCase()):!1}function le(n=process.env){return br(n.TOOLNET_REMOTE_ENCRYPTION)}function Ke(n){let e=n.trim();if(!e)throw new b("REMOTE_ENCRYPTION_KEY_EMPTY","Remote encryption key is empty.");let t;if(e.startsWith("hex:")){let r=e.slice(4);if(!/^[0-9a-f]{64}$/iu.test(r))throw new b("REMOTE_ENCRYPTION_KEY_INVALID","hex: remote encryption key must contain exactly 64 hexadecimal characters.");t=Buffer.from(r,"hex")}else if(/^[0-9a-f]{64}$/iu.test(e))t=Buffer.from(e,"hex");else{let r=e.startsWith("base64:")?e.slice(7):e;if(!/^[A-Za-z0-9+/_-]+={0,2}$/u.test(r))throw new b("REMOTE_ENCRYPTION_KEY_INVALID","Remote encryption key must be 32 raw bytes encoded as hexadecimal or base64.");t=Buffer.from(r,r.includes("-")||r.includes("_")?"base64url":"base64")}if(t.length!==ue)throw new b("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH",`Remote encryption key must decode to exactly ${ue} bytes.`);return t}function Ge(n=process.env){let e=n.TOOLNET_REMOTE_ENCRYPTION_KEY?.trim(),t=n.TOOLNET_REMOTE_ENCRYPTION_KEY_FILE?.trim();if(e&&t)throw new b("REMOTE_ENCRYPTION_KEY_AMBIGUOUS","Configure either TOOLNET_REMOTE_ENCRYPTION_KEY or TOOLNET_REMOTE_ENCRYPTION_KEY_FILE, not both.");if(e)return Ke(e);if(t){let r;try{r=hr(t,"utf8")}catch(o){throw new b("REMOTE_ENCRYPTION_KEY_FILE_READ_FAILED",[`Unable to read remote encryption key file: ${t}.`,o instanceof Error?o.message:String(o)].join(" "))}return Ke(r)}}function ze(n){return fr("sha256").update(n).digest().subarray(0,L)}function Ue(n){return Buffer.from(`${Sr}${n}`,"utf8")}function pe(n){return n.byteLength<A.length?!1:Buffer.from(n).subarray(0,A.length).equals(A)}function Ye(n,e,t){if(t.byteLength!==ue)throw new b("REMOTE_ENCRYPTION_KEY_INVALID_LENGTH","AES-256-GCM requires a 32-byte key.");let r=typeof e=="string"?Buffer.from(e,"utf8"):Buffer.from(e),o=gr(F),s=pr(Be,t,o);s.setAAD(Ue(n));let a=Buffer.concat([s.update(r),s.final()]),i=s.getAuthTag(),d=Buffer.alloc(Fe),c=0;return A.copy(d,c),c+=A.length,d.writeUInt8(Le,c),c+=1,ze(t).copy(d,c),c+=L,o.copy(d,c),c+=F,i.copy(d,c),Buffer.concat([d,a])}function Ve(n,e,t){let r=Buffer.from(e);if(!pe(r))throw new b("REMOTE_ENCRYPTION_ENVELOPE_REQUIRED","Payload is not a ToolNet encrypted remote object.");if(r.length<Fe)throw new b("REMOTE_ENCRYPTION_ENVELOPE_TRUNCATED","Encrypted remote payload is truncated.");let o=A.length,s=r.readUInt8(o);if(o+=1,s!==Le)throw new b("REMOTE_ENCRYPTION_VERSION_UNSUPPORTED",`Unsupported remote encryption envelope version: ${s}.`);let a=r.subarray(o,o+L);o+=L;let i=ze(t);if(!yr(a,i))throw new b("REMOTE_ENCRYPTION_KEY_MISMATCH","Configured remote encryption key does not match this encrypted object.");let d=r.subarray(o,o+F);o+=F;let c=r.subarray(o,o+de);o+=de;let l=r.subarray(o),u=mr(Be,t,d);u.setAAD(Ue(n)),u.setAuthTag(c);try{return Buffer.concat([u.update(l),u.final()])}catch{throw new b("REMOTE_ENCRYPTION_AUTH_FAILED","Encrypted remote object failed AES-GCM authentication.")}}var me=class{constructor(e,t){this.inner=e;this.options=t;if(this.name=e.name,t.enabled&&!t.key)throw new b("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote client-side encryption is enabled but no encryption key is configured.")}inner;options;name;async put(e,t,r){if(!this.options.enabled){await this.inner.put(e,t,r);return}let o=this.options.key;if(!o)throw new b("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote encryption key is unavailable.");let s=Ye(e,t,o);await this.inner.put(e,s,"application/octet-stream")}async get(e){let t=await this.inner.get(e);if(!t)return null;if(!pe(t))return t;if(!this.options.enabled)throw new b("REMOTE_ENCRYPTION_REQUIRED",["Remote object is client-side encrypted.","Enable TOOLNET_REMOTE_ENCRYPTION and configure the matching key."].join(" "));let r=this.options.key;if(!r)throw new b("REMOTE_ENCRYPTION_KEY_REQUIRED","Remote object is encrypted but no decryption key is configured.");return Ve(e,t,r)}async getText(e){let t=await this.get(e);return t?Buffer.from(t).toString("utf8"):null}async exists(e){return this.inner.exists(e)}async delete(e){await this.inner.delete(e)}async list(e=""){return this.inner.list(e)}};function He(n,e=process.env){if(n.name==="local")return le(e)&&console.warn("[storage] Remote encryption requested but active storage provider is local; local data remains unchanged."),n;let t=le(e),r=t?Ge(e):void 0;return new me(n,{enabled:t,key:r})}function B(n){return He(n)}function fe(n,e){return console.warn(e),B(new D(n))}function We(n){let e=n.localRoot??Er(xr(),".toolnet-memory","storage");if(n.provider==="r2"){let t=n.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?B(new K({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey})):fe(e,"[storage] Cloudflare R2 credentials missing. Using local fallback.")}if(n.provider==="s3"){let t=n.s3;return t?.bucket&&t.accessKeyId&&t.secretAccessKey?B(new K({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey})):fe(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?B(new Q({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey})):fe(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return B(new D(e))}var X=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 ee=class{constructor(e){this.storage=e}storage;key(e){return["projects",e,"graph","manifest.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 Je(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 qe(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 te=class{constructor(e,t,r,o){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=Je(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 a;try{a=JSON.parse(o)}catch(i){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${i instanceof Error?i.message:String(i)}`)}if(typeof a.id=="string"&&a.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${a.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof a.createdAt=="string"&&(r=a.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=qe(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))}};import{createHash as vr}from"node:crypto";import{dirname as wr,extname as Rr,normalize as Pr,posix as kr}from"node:path";var re=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)}};function Cr(n,e,t,r){return vr("sha256").update(`${n}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function k(n){return Pr(n).replaceAll("\\","/")}function Mr(n,e,t){if(!e.startsWith("."))return;let r=k(kr.join(wr(n),e)),o=Rr(r),s;if(o===".js"){let a=r.slice(0,-3);s=[`${a}.ts`,`${a}.tsx`,`${a}.js`,`${a}.jsx`]}else if(o===".mjs"){let a=r.slice(0,-4);s=[`${a}.mts`,`${a}.ts`,`${a}.mjs`]}else if(o===".cjs"){let a=r.slice(0,-4);s=[`${a}.cts`,`${a}.ts`,`${a}.cjs`]}else o?s=[r]:s=[`${r}.ts`,`${r}.tsx`,`${r}.mts`,`${r}.cts`,`${r}.js`,`${r}.jsx`,`${r}.mjs`,`${r}.cjs`,`${r}/index.ts`,`${r}/index.tsx`,`${r}/index.mts`,`${r}/index.cts`,`${r}/index.js`,`${r}/index.jsx`,`${r}/index.mjs`,`${r}/index.cjs`];return s.find(a=>t.has(k(a)))}function ge(n,e,t,r){let o=r?.(n,e,t);if(o){let s=k(o);if(t.has(s))return s}return Mr(n,e,t)}var G=class{build(e,t,r={}){let o=new re;for(let i of r.seedSymbols??[])o.addSymbol(i);for(let i of t)for(let d of i.symbols)o.addSymbol(d);let s=new Map;for(let i of o.allSymbols(e))i.type==="file"&&s.set(k(i.filePath),i);let a=new Set(s.keys());for(let i of t){let d=k(i.filePath),c=s.get(d);if(c){for(let l of i.symbols)l.id!==c.id&&o.addEdge(this.edge(e,c.id,"DEFINES",l.id));for(let l of i.imports){let u=ge(d,l.source,a,r.resolveModule);if(!u)continue;let m=s.get(u);m&&o.addEdge(this.edge(e,c.id,"IMPORTS",m.id,{source:l.source,resolvedFile:u}))}for(let l of i.heritage){let u=o.findByName(e,l.targetName).filter(m=>m.type==="class"||m.type==="interface");for(let m of u)o.addEdge(this.edge(e,l.fromId,l.type,m.id))}for(let l of i.calls){if(!l.callerId)continue;let u=this.resolveCallTargets(e,i,l.calleeName,l.qualifier,o,a,r.resolveModule);for(let m of u)m.id!==l.callerId&&o.addEdge(this.edge(e,l.callerId,"CALLS",m.id,{line:l.line,qualifier:l.qualifier}))}}}return o}resolveCallTargets(e,t,r,o,s,a,i){let d=k(t.filePath),c=s.findByName(e,r).filter(l=>k(l.filePath)===d);if(!o&&c.length)return c;if(o)for(let l of t.imports){if(!l.bindings.find(g=>g.kind==="namespace"&&g.localName===o))continue;let m=ge(d,l.source,a,i);if(m)return s.findByName(e,r).filter(g=>k(g.filePath)===m)}for(let l of t.imports){let u=l.bindings.find(v=>v.localName===r);if(!u)continue;let m=ge(d,l.source,a,i);if(!m)continue;let g=u.importedName==="default"?r:u.importedName,w=s.findByName(e,g).filter(v=>k(v.filePath)===m);if(w.length)return w}return s.findByName(e,r).filter(l=>l.type==="function"||l.type==="method")}edge(e,t,r,o,s){return{id:Cr(e,t,r,o),projectId:e,from:t,to:o,type:r,metadata:s}}};import{createHash as Ir}from"node:crypto";function ye(n){return n.replaceAll("\\","/")}function Ar(n,e,t,r){return Ir("sha256").update(`${n}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function jr(n){return[ye(n.filePath),n.type,n.qualifiedName??n.name].join("\0")}function Ze(n){let e=new Map;for(let r of n){let o=jr(r),s=e.get(o)??[];s.push(r),e.set(o,s)}let t=new Map;for(let[r,o]of e)o.length===1&&t.set(r,o[0]);return t}function Tr(n,e){let t=Ze(n),r=Ze(e),o=new Map;for(let[s,a]of t){let i=r.get(s);i&&o.set(a.id,i.id)}return o}function Qe(n){let e=new Map(n.previousSymbols.map(s=>[s.id,s])),t=new Set(n.currentSymbols.map(s=>s.id)),r=Tr(n.previousSymbols,n.currentSymbols),o=[];for(let s of n.previousEdges){let a=e.get(s.from),i=e.get(s.to);if(!a||!i)continue;let d=ye(a.filePath),c=ye(i.filePath);if(n.rebuiltSourceFiles.has(d)||n.removedFiles.has(d)||n.removedFiles.has(c))continue;let l=t.has(s.from)?s.from:r.get(s.from),u=t.has(s.to)?s.to:r.get(s.to);!l||!u||!t.has(l)||!t.has(u)||o.push({...s,id:Ar(n.projectId,l,s.type,u),from:l,to:u})}return o}import{readFile as Or}from"node:fs/promises";import{join as _r}from"node:path";import{createHash as Nr}from"node:crypto";import*as f from"typescript";function Xe(n,e){return Nr("sha256").update(`${n}:${e}`).digest("hex").slice(0,24)}function he(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}async function et(n,e,t){let r=_r(e,t),o=await Or(r,"utf8"),s=f.createSourceFile(t,o,f.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?f.ScriptKind.TSX:f.ScriptKind.TS),a=[],i=[],d=[],c=[],l={id:Xe(n,`file:${t}`),projectId:n,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:s.getLineAndCharacterOfPosition(s.end).line+1};a.push(l);let u=[],m=[];function g(p,E,S,y){let h=Xe(n,`${t}:${S}:${y??E}:${p.pos}`);return a.push({id:h,projectId:n,name:E,qualifiedName:y??E,type:S,filePath:t,startLine:he(s,p),endLine:s.getLineAndCharacterOfPosition(p.end).line+1}),h}function w(p){if(!f.isStringLiteral(p.moduleSpecifier))return;let E=[],S=p.importClause;if(S?.name&&E.push({localName:S.name.text,importedName:"default",kind:"default"}),S?.namedBindings&&f.isNamedImports(S.namedBindings))for(let y of S.namedBindings.elements)E.push({localName:y.name.text,importedName:y.propertyName?.text??y.name.text,kind:"named"});S?.namedBindings&&f.isNamespaceImport(S.namedBindings)&&E.push({localName:S.namedBindings.name.text,importedName:"*",kind:"namespace"}),i.push({source:p.moduleSpecifier.text,bindings:E})}function v(p,E){for(let S of p.heritageClauses??[])for(let y of S.types){let h=y.expression.getText(s).split(".").at(-1)??"";h&&c.push({fromId:E,targetName:h,type:S.token===f.SyntaxKind.ExtendsKeyword?"INHERITS":"IMPLEMENTS"})}}function R(p){let E=!1,S=!1;if(f.isImportDeclaration(p)&&w(p),f.isInterfaceDeclaration(p)&&g(p,p.name.text,"interface",p.name.text),f.isClassDeclaration(p)&&p.name){let y=g(p,p.name.text,"class",p.name.text);v(p,y),m.push({id:y,name:p.name.text}),S=!0}if(f.isFunctionDeclaration(p)&&p.name){let y=g(p,p.name.text,"function",p.name.text);u.push(y),E=!0}if(f.isMethodDeclaration(p)&&p.name){let y=p.name.getText(s),h=m.at(-1)?.name,P=g(p,y,"method",h?`${h}.${y}`:y);u.push(P),E=!0}if(f.isCallExpression(p)&&(f.isIdentifier(p.expression)&&d.push({callerId:u.at(-1),calleeName:p.expression.text,line:he(s,p)}),f.isPropertyAccessExpression(p.expression))){let y=p.expression;d.push({callerId:u.at(-1),qualifier:y.expression.getText(s),calleeName:y.name.text,line:he(s,p)})}f.forEachChild(p,R),E&&u.pop(),S&&m.pop()}return R(s),{filePath:t,symbols:a,imports:i,calls:d,heritage:c}}import{existsSync as $r,readFileSync as Dr,readdirSync as Kr,realpathSync as Lr}from"node:fs";import{dirname as xe,extname as Fr,join as Se,parse as Br,relative as be,resolve as z}from"node:path";import*as x from"typescript";var Gr="tsconfig.json",zr=new Set(["node_modules",".git",".toolnet","dist","build","out","coverage",".next",".nuxt",".cache",".turbo","target","vendor"]),tt=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs"];function U(n){return n.replaceAll("\\","/").replace(/^\.\/+/u,"")}function ot(n,e){let t=U(be(n,e));return t!==".."&&!t.startsWith("../")&&!t.startsWith("/")}function rt(n){try{return Lr.native(n)}catch{return z(n)}}function Ur(n,e){let t=z(e),r=z(n);for(;;){let o=Se(r,Gr);if($r(o))return o;if(r===t)return;let s=Br(r).root;if(r===s)return;let a=xe(r);if(a===r||!ot(t,a)&&a!==t)return;r=a}}function Yr(n){let e=x.readConfigFile(n,x.sys.readFile);if(e.error)throw new Error(x.flattenDiagnosticMessageText(e.error.messageText,`
5
+ `));return x.parseJsonConfigFileContent(e.config,x.sys,xe(n))}function Vr(){return{allowJs:!0,checkJs:!1,noEmit:!0,skipLibCheck:!0,target:x.ScriptTarget.ES2022,module:x.ModuleKind.NodeNext,moduleResolution:x.ModuleResolutionKind.NodeNext,resolveJsonModule:!0}}function Hr(n){let e=U(n),t=Fr(e);if(t){let o=[e];if(t===".js"){let s=e.slice(0,-3);o.push(`${s}.ts`,`${s}.tsx`)}if(t===".mjs"){let s=e.slice(0,-4);o.push(`${s}.mts`,`${s}.ts`)}if(t===".cjs"){let s=e.slice(0,-4);o.push(`${s}.cts`,`${s}.ts`)}return e.endsWith(".d.ts")&&o.push(e.slice(0,-5)+".ts"),o}let r=[e];for(let o of tt)r.push(`${e}${o}`);for(let o of tt)r.push(`${e}/index${o}`);return r}function nt(n,e){for(let t of Hr(n)){let r=U(t);if(e.has(r))return r}}function st(n,e){if(typeof n=="string"){e.push(n);return}if(!(!n||typeof n!="object"||Array.isArray(n)))for(let t of Object.values(n))st(t,e)}function Wr(n){let e=[];for(let t of["source","types","module","main"]){let r=n[t];typeof r=="string"&&e.push(r)}return st(n.exports,e),[...new Set(e)]}function Jr(n){let t=[z(n)],r=[];for(;t.length>0;){let o=t.pop(),s;try{s=Kr(o,{withFileTypes:!0})}catch{continue}if(s.find(i=>i.isFile()&&i.name==="package.json"))try{let i=JSON.parse(Dr(Se(o,"package.json"),"utf8"));typeof i.name=="string"&&i.name.trim()&&r.push({name:i.name.trim(),directory:o,entries:Wr(i)})}catch{}for(let i of s)i.isDirectory()&&(zr.has(i.name)||t.push(Se(o,i.name)))}return r.sort((o,s)=>s.name.length-o.name.length)}var ne=class{rootPath;configCache=new Map;workspacePackages;constructor(e){this.rootPath=rt(e)}resolve(e,t,r){let o=z(this.rootPath,e),s=Ur(xe(o),this.rootPath),a=s?this.config(s).options:Vr(),i=x.resolveModuleName(t,o,a,x.sys).resolvedModule;if(i){let d=this.matchResolvedFile(i.resolvedFileName,r);if(d)return d}return this.resolveWorkspacePackage(t,r)}config(e){let t=this.configCache.get(e);if(t)return t;let r=Yr(e);return this.configCache.set(e,r),r}matchResolvedFile(e,t){let r=rt(e);if(!ot(this.rootPath,r))return;let o=U(be(this.rootPath,r));return nt(o,t)}packages(){return this.workspacePackages?this.workspacePackages:(this.workspacePackages=Jr(this.rootPath),this.workspacePackages)}resolveWorkspacePackage(e,t){let r=this.packages().find(i=>e===i.name||e.startsWith(`${i.name}/`));if(!r)return;let o=U(be(this.rootPath,r.directory)),s=e===r.name?"":e.slice(r.name.length+1),a=[];if(s)a.push(`${o}/${s}`,`${o}/src/${s}`);else{for(let i of r.entries)a.push(`${o}/${i.replace(/^\.\//u,"")}`);a.push(`${o}/src/index`,`${o}/index`)}for(let i of a){let d=nt(i,t);if(d)return d}}};function qr(n){let e=n??4;if(!Number.isSafeInteger(e)||e<1||e>64)throw new Error("concurrency must be an integer between 1 and 64");return e}function Zr(n){if(n?.aborted)throw new Error("Operation aborted")}async function oe(n,e,t={}){if(n.length===0)return[];let r=Math.min(qr(t.concurrency),n.length),o=new Array(n.length),s=0,a=0,i=async()=>{for(;;){Zr(t.signal);let c=s;if(s+=1,c>=n.length)return;o[c]=await e(n[c],c),a+=1,t.onProgress?.({completed:a,total:n.length,index:c})}},d=Array.from({length:r},()=>i());return await Promise.all(d),o}import{join as hn}from"node:path";import{lstat as tn,readdir as rn}from"node:fs/promises";import{extname as nn,join as on,relative as sn,resolve as an}from"node:path";import{basename as Qr}from"node:path";var Xr=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),en=new Set([".pem",".key",".p12",".pfx"]);function it(n){let e=Qr(n).toLowerCase();if(Xr.has(e))return!0;for(let t of en)if(e.endsWith(t))return!0;return!1}var cn=2*1024*1024,dn=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),un=new Set(["node_modules",".git",".toolnet",".toolnet-memory","dist","build","out","coverage",".next",".nuxt",".cache",".parcel-cache",".turbo","vendor","target"]);function at(n,e){if(!Number.isSafeInteger(n)||n<1)throw new Error(`${e} must be a positive integer`);return n}function ct(n){if(n?.aborted)throw new Error("Repository scan aborted")}function ln(n){let e=n.trim().toLowerCase();if(!e)throw new Error("Repository scan extension cannot be empty");return e.startsWith(".")?e:`.${e}`}function pn(n){let e=n.toLowerCase();return/\.min\.(?:js|mjs|cjs)$/u.test(e)||/\.bundle\.(?:js|mjs|cjs)$/u.test(e)}function mn(n){return n.replaceAll("\\","/")}async function fn(n,e={}){let t=an(n),r=e.maxFileBytes??cn;if(!Number.isSafeInteger(r)||r<1)throw new Error("maxFileBytes must be a positive integer");let o=e.maxFiles??Number.MAX_SAFE_INTEGER;at(o,"maxFiles");let s=e.progressInterval??1e3;at(s,"progressInterval");let a=new Set(e.extensions?[...e.extensions].map(ln):dn),i=new Set(un);for(let u of e.extraIgnoredDirectories??[]){let m=u.trim();m&&i.add(m)}let d=[],c={directories:0,entries:0,accepted:0,skippedIgnoredDirectories:0,skippedSymlinks:0,skippedGenerated:0,skippedSensitive:0,skippedOversized:0,skippedUnreadable:0},l=[t];for(;l.length>0;){ct(e.signal);let u=l.pop(),m;try{m=await rn(u,{withFileTypes:!0})}catch{c.skippedUnreadable+=1;continue}c.directories+=1;for(let g of m){ct(e.signal),c.entries+=1,c.entries%s===0&&e.onProgress?.({directories:c.directories,entries:c.entries,accepted:c.accepted});let w=on(u,g.name);if(g.isSymbolicLink()){c.skippedSymlinks+=1;continue}if(g.isDirectory()){if(i.has(g.name)){c.skippedIgnoredDirectories+=1;continue}l.push(w);continue}if(!g.isFile())continue;let v=nn(g.name).toLowerCase();if(!a.has(v))continue;if(pn(g.name)){c.skippedGenerated+=1;continue}if(it(w)){c.skippedSensitive+=1;continue}let R;try{R=await tn(w)}catch{c.skippedUnreadable+=1;continue}if(R.isSymbolicLink()){c.skippedSymlinks+=1;continue}if(R.isFile()){if(R.size>r){c.skippedOversized+=1;continue}if(d.length>=o)throw new Error(`Repository scan file limit exceeded: ${o}`);d.push(mn(sn(t,w))),c.accepted+=1}}}return d.sort(),e.onProgress?.({directories:c.directories,entries:c.entries,accepted:c.accepted}),{files:d,stats:c}}async function dt(n,e={}){return(await fn(n,e)).files}import{createHash as gn}from"node:crypto";import{readFile as yn}from"node:fs/promises";async function ut(n){let e=await yn(n);return gn("sha256").update(e).digest("hex")}async function lt(n,e,t={}){let r={...t.scan};t.signal&&(r.signal=t.signal);let o=await dt(e,r),s=await oe(o,async i=>({path:i,hash:await ut(hn(e,i))}),{concurrency:t.concurrency??8,signal:t.signal,onProgress:({completed:i,total:d,index:c})=>{t.onProgress?.({completed:i,total:d,file:o[c]})}}),a={};for(let i of s)a[i.path]={path:i.path,hash:i.hash};return{version:1,projectId:n,updatedAt:new Date().toISOString(),files:a}}function pt(n,e){let t=new Map;for(let r of n){let o=e[r];if(!o)continue;let s=t.get(o.hash)??[];s.push(r),t.set(o.hash,s)}return t}function Sn(n,e,t,r){let o=pt(e,t),s=pt(n,r),a=[];for(let[i,d]of o){let c=s.get(i);d.length!==1||!c||c.length!==1||a.push({from:d[0],to:c[0],hash:i})}return a.sort((i,d)=>i.from.localeCompare(d.from))}function mt(n,e){let t=n?.files??{},r=e.files,o=[],s=[],a=[],i=[];for(let[u,m]of Object.entries(r)){let g=t[u];if(!g){o.push(u);continue}if(g.hash!==m.hash){s.push(u);continue}i.push(u)}for(let u of Object.keys(t))r[u]||a.push(u);let d=Sn(o,a,t,r),c=new Set(d.map(u=>u.from)),l=new Set(d.map(u=>u.to));return{added:o.filter(u=>!l.has(u)).sort(),modified:s.sort(),deleted:a.filter(u=>!c.has(u)).sort(),unchanged:i.sort(),renamed:d}}function ft(n){return n.replaceAll("\\","/")}var se=class{constructor(e){this.storage=e}storage;async index(e,t,r={}){let o=new ee(this.storage),s=new X(this.storage),a=await o.load(e),i=await s.load(e),d=await lt(e,t,{concurrency:r.hashConcurrency??8,scan:r.scan,signal:r.signal,onProgress:({completed:h,total:P,file:C})=>{r.onProgress?.({phase:"hash",current:h,total:P,file:C})}}),c=mt(a,d),l=c.added.length>0||c.deleted.length>0||c.renamed.length>0,u=i===null||l,m=u?Object.keys(d.files).sort():[...c.modified];if(a&&i&&m.length===0)return{firstRun:!1,scanned:Object.keys(d.files).length,parsed:0,added:0,modified:0,deleted:0,renamed:0,unchanged:c.unchanged.length,symbols:i.symbols.length,edges:i.edges.length,repairedEdges:0,fullRebuild:!1,saved:!1};let g=await oe(m,async h=>et(e,t,h),{concurrency:r.parseConcurrency??4,signal:r.signal,onProgress:({completed:h,total:P,index:C})=>{r.onProgress?.({phase:"parse",current:h,total:P,file:m[C]})}}),w=new ne(t),v,R=0;if(u||!i)v=new G().build(e,g,{resolveModule:(h,P,C)=>w.resolve(h,P,C)});else{let h=new Set(c.modified.map(ft)),P=i.symbols.filter(T=>!h.has(ft(T.filePath)));v=new G().build(e,g,{seedSymbols:P,resolveModule:(T,gt,yt)=>w.resolve(T,gt,yt)}),r.onProgress?.({phase:"repair",current:0,total:i.edges.length});let C=Qe({projectId:e,previousSymbols:i.symbols,previousEdges:i.edges,currentSymbols:v.allSymbols(e),rebuiltSourceFiles:h,removedFiles:new Set});for(let T of C)v.addEdge(T);R=C.length,r.onProgress?.({phase:"repair",current:i.edges.length,total:i.edges.length})}let p=v.allSymbols(e),E=new Set(p.map(h=>h.id)),S=v.allEdges(e).filter(h=>E.has(h.from)&&E.has(h.to)),y={version:1,projectId:e,updatedAt:new Date().toISOString(),files:Object.keys(d.files).length,symbols:p,edges:S};return r.onProgress?.({phase:"save",current:0,total:2}),await s.save(y),r.onProgress?.({phase:"save",current:1,total:2}),await o.save(d),r.onProgress?.({phase:"save",current:2,total:2}),{firstRun:a===null,scanned:Object.keys(d.files).length,parsed:m.length,added:c.added.length,modified:c.modified.length,deleted:c.deleted.length,renamed:c.renamed.length,unchanged:c.unchanged.length,symbols:y.symbols.length,edges:y.edges.length,repairedEdges:R,fullRebuild:u,saved:!0}}};async function xn(){let n=ve(),e=new J().detect(),t=We({provider:n.storage.provider,huggingface:n.storage.huggingface,localRoot:n.storage.localRoot}),r=new te(t,e.id,e.name,e.remote??e.name),o=await new se(r).index(e.id,e.rootPath);console.log({ok:!0,storage:r.name,...o})}xn().catch(n=>{console.error(n),process.exit(1)});