toolnet-memory 0.3.15 → 0.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.env.example +74 -0
  2. package/.release-target +1 -1
  3. package/README.md +316 -6
  4. package/bin/toolnet-memory +12 -0
  5. package/bundle/agy-hook.js +66 -66
  6. package/bundle/agy.js +56 -56
  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/claude-hook.js +49 -49
  11. package/bundle/code-capabilities.js +2 -0
  12. package/bundle/codex-context.js +29 -29
  13. package/bundle/codex.js +71 -71
  14. package/bundle/context-runtime.js +39 -39
  15. package/bundle/context.js +15 -15
  16. package/bundle/copilot-hook.js +78 -78
  17. package/bundle/cursor-hook.js +78 -78
  18. package/bundle/docker-healthcheck.js +3 -0
  19. package/bundle/doctor.js +4 -4
  20. package/bundle/full-index.js +22 -21
  21. package/bundle/gc.js +5 -3
  22. package/bundle/graph-cli.js +1 -1
  23. package/bundle/graph-index.js +5 -4
  24. package/bundle/graph-ui.js +4 -3
  25. package/bundle/grok-hook.js +56 -56
  26. package/bundle/handoff-refresh.js +10 -10
  27. package/bundle/help-cli.js +4 -4
  28. package/bundle/impact.js +5 -4
  29. package/bundle/incremental.js +5 -5
  30. package/bundle/init.js +36 -35
  31. package/bundle/kiro-hook.js +85 -85
  32. package/bundle/learner.js +8 -6
  33. package/bundle/mcp.js +19 -17
  34. package/bundle/memory-agent.js +6 -6
  35. package/bundle/memory-query.js +7 -7
  36. package/bundle/opencode.js +77 -77
  37. package/bundle/project-manual.js +7 -7
  38. package/bundle/public/index.html +51 -2
  39. package/bundle/recovery-certify.js +9 -9
  40. package/bundle/runtime.js +16 -13
  41. package/bundle/semantic.js +6 -5
  42. package/bundle/service.js +11 -6
  43. package/bundle/snapshot.js +6 -4
  44. package/bundle/status-cli.js +4 -4
  45. package/bundle/toolnet-cli.js +46 -46
  46. package/bundle/work-continuity.js +7 -7
  47. package/package.json +38 -2
  48. package/release-manifest.json +143 -4
@@ -1,5 +1,5 @@
1
- import"dotenv/config";import{existsSync as ze,readFileSync as Be}from"node:fs";import{homedir as Ve}from"node:os";import{join as Ge}from"node:path";function Ue(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 He(){let n=process.env.TOOLNET_GLOBAL_ENV??Ge(Ve(),".config","toolnet-memory",".env");if(!ze(n))return;let e=Be(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]=Ue(r.slice(s+1)))}}He();function E(n,e){return n===void 0?e:["1","true","yes","on"].includes(n.toLowerCase())}function A(n,e){if(!n)return e;let t=Number(n);return Number.isFinite(t)?t:e}function ie(){return{memory:{autoCapture:E(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:E(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:E(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:E(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:A(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:A(process.env.MEMORY_RERANK_TOP,10),finalContext:A(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:A(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",r2:{accountId:process.env.R2_ACCOUNT_ID,bucket:process.env.R2_BUCKET,accessKeyId:process.env.R2_ACCESS_KEY_ID,secretAccessKey:process.env.R2_SECRET_ACCESS_KEY},s3:{endpoint:process.env.S3_ENDPOINT,region:process.env.S3_REGION,bucket:process.env.S3_BUCKET,accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY,forcePathStyle:E(process.env.S3_FORCE_PATH_STYLE,!1)},huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:A(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as We}from"node:crypto";import{existsSync as D,mkdirSync as Je,readFileSync as Ye,renameSync as Ze,writeFileSync as Qe}from"node:fs";import{basename as qe,dirname as F,join as I,parse as le,resolve as C}from"node:path";var pe=".toolnet",Xe="project.json";function et(n){return We("sha256").update(n).digest("hex").slice(0,16)}function K(n){return I(n,pe,Xe)}function tt(n){return D(K(n))}function ae(n,e){let t=C(n),r=le(t).root;for(;;){if(tt(t))return t;if(t===r||e&&t===C(e))break;let s=F(t);if(s===t)break;t=s}return null}function ce(n){let e=C(n),t=le(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>D(I(e,o))))return e;if(e===t)break;let s=F(e);if(s===e)break;e=s}return C(n)}function de(n){let e;try{e=JSON.parse(Ye(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:F(F(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 ue(n,e){let t=I(n,pe);Je(t,{recursive:!0});let r=K(n),s=`${r}.tmp-${process.pid}`;Qe(s,JSON.stringify(e,null,2)+`
3
- `,{encoding:"utf8",mode:384}),Ze(s,r)}function Q(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}}var L=class{findExisting(e=process.cwd()){let t=C(e),r=ce(t),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(d=>D(I(r,d))),a=ae(t,o?r:void 0);if(!a)return null;let i=de(K(a));return Q(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=C(e),r=ce(t),o=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"].some(l=>D(I(r,l))),a=ae(t,o?r:void 0);if(a){let l=K(a),u=de(l);return u.rootPath!==a&&(u.rootPath=a,u.updatedAt=new Date().toISOString(),ue(a,u)),Q(u,a)}let i=new Date().toISOString(),d=qe(r),c={version:1,id:et(r),name:d,remote:d,rootPath:r,createdAt:i,updatedAt:i,graphVersion:0,memoryVersion:0};return ue(r,c),Q(c,r)}};var rt=[{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"}],nt=new Set(["example","example-key","example-token","changeme","change-me","password","secret","your-api-key","your-token","<token>","<secret>","<password>","[redacted]"]);function me(n){return n.normalize("NFKC").trim().toLowerCase()}function st(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 ot(n){return/^[a-f0-9]{32}$/iu.test(n)||/^[a-f0-9]{40}$/iu.test(n)||/^[a-f0-9]{64}$/iu.test(n)}function it(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 at(n,e){return n.start<e.end&&e.start<n.end}function fe(n){return n.sort((e,t)=>e.start!==t.start?e.start-t.start:t.end-t.start-(e.end-e.start))}var z=class{allowValues=new Set;enableEntropyHeuristic;constructor(e={}){for(let t of e.allowValues??[]){let r=me(t);r&&this.allowValues.add(r)}this.enableEntropyHeuristic=e.enableEntropyHeuristic??!0}scan(e){let t=[];for(let o of rt){let a=new RegExp(o.regex.source,o.regex.flags);for(let i of e.matchAll(a))i.index===void 0||!i[0]||this.allowed(i[0])||t.push({type:o.type,value:i[0],start:i.index,end:i.index+i[0].length,confidence:o.confidence})}this.enableEntropyHeuristic&&t.push(...this.entropyMatches(e));let r=fe(t),s=[];for(let o of r)s.some(a=>at(a,o))||s.push(o);return fe(s)}hasSecrets(e){return this.scan(e).length>0}allowed(e){let t=me(e);return nt.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)||ot(o)||!/[A-Za-z]/u.test(o)||!/[0-9]/u.test(o)||it(e,s.index,s.index+o.length)&&(st(o)<3.7||t.push({type:"high_entropy_secret",value:o,start:s.index,end:s.index+o.length,confidence:"heuristic"}))}return t}};var B=class{scanner;constructor(e={}){this.scanner=new z(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((a,i)=>i.start-a.start),o=new Set;for(let a of s)o.add(a.type),r=r.slice(0,a.start)+`[REDACTED:${a.type}]`+r.slice(a.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 Ur=new B;import{homedir as At}from"node:os";import{join as It}from"node:path";import{DeleteObjectCommand as ct,GetObjectCommand as dt,HeadObjectCommand as ut,ListObjectsV2Command as lt,PutObjectCommand as pt,S3Client as mt}from"@aws-sdk/client-s3";import{getSignedUrl as ft}from"@aws-sdk/s3-request-presigner";var V=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,r="application/octet-stream"){let s=typeof t=="string"?Buffer.from(t,"utf8"):t;await this.client.send(new pt({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await ft(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(`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 ut({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 ct({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new lt({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 ge,mkdir as gt,readFile as yt,readdir as ht,rm as St,stat as ye,writeFile as bt}from"node:fs/promises";import{dirname as xt,join as vt,relative as he,resolve as wt}from"node:path";var O=class{constructor(e){this.root=e}root;name="local";path(e){let t=e.replace(/^\/+/,"");return wt(this.root,t)}async put(e,t){let r=this.path(e);await gt(xt(r),{recursive:!0}),await bt(r,t)}async get(e){try{return await yt(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 ge(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 ge(t)}catch{return r}let s=async a=>{let i=await ht(a,{withFileTypes:!0});for(let d of i){let c=vt(a,d.name);if(d.isDirectory()){await s(c);continue}let l=await ye(c);r.push({key:he(this.root,c),size:l.size,updatedAt:l.mtime.toISOString()})}},o=await ye(t);return o.isDirectory()?await s(t):r.push({key:he(this.root,t),size:o.size,updatedAt:o.mtime.toISOString()}),r}};import{DeleteObjectCommand as kt,GetObjectCommand as Rt,HeadObjectCommand as Pt,ListObjectsV2Command as jt,PutObjectCommand as Ct,S3Client as Mt}from"@aws-sdk/client-s3";import{getSignedUrl as Et}from"@aws-sdk/s3-request-presigner";var T=class{name;client;bucket;constructor(e){this.name=e.name??"s3",this.bucket=e.bucket,this.client=new Mt({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 Ct({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let t=await Et(this.client,new Rt({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 kt({Bucket:this.bucket,Key:e}))}async list(e=""){let t=[],r;do{let s=await this.client.send(new jt({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 q(n,e){return console.warn(e),new O(n)}function Se(n){let e=n.localRoot??It(At(),".toolnet-memory","storage");if(n.provider==="r2"){let t=n.r2;return t?.accountId&&t.bucket&&t.accessKeyId&&t.secretAccessKey?new T({name:"r2",endpoint:`https://${t.accountId}.r2.cloudflarestorage.com`,region:"auto",bucket:t.bucket,forcePathStyle:!0,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):q(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 T({name:"s3",endpoint:t.endpoint,region:t.region??"us-east-1",bucket:t.bucket,forcePathStyle:t.forcePathStyle??!1,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):q(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 V({namespace:t.namespace,bucket:t.bucket,accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey}):q(e,"[storage] Hugging Face credentials missing. Using local fallback.")}return new O(e)}var G=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 U=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 be(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 xe(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 H=class{constructor(e,t,r,s){this.provider=e;this.name=e.name,this.projectId=t,this.projectName=r,this.folder=be(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 a;try{a=JSON.parse(s)}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 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=xe(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 Ot}from"node:crypto";import{dirname as Tt,extname as _t,normalize as Nt,posix as $t}from"node:path";var W=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 Dt(n,e,t,r){return Ot("sha256").update(`${n}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function P(n){return Nt(n).replaceAll("\\","/")}function Ft(n,e,t){if(!e.startsWith("."))return;let r=P($t.join(Tt(n),e)),s=_t(r),o;if(s===".js"){let a=r.slice(0,-3);o=[`${a}.ts`,`${a}.tsx`,`${a}.js`,`${a}.jsx`]}else if(s===".mjs"){let a=r.slice(0,-4);o=[`${a}.mts`,`${a}.ts`,`${a}.mjs`]}else if(s===".cjs"){let a=r.slice(0,-4);o=[`${a}.cts`,`${a}.ts`,`${a}.cjs`]}else s?o=[r]:o=[`${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 o.find(a=>t.has(P(a)))}function X(n,e,t,r){let s=r?.(n,e,t);if(s){let o=P(s);if(t.has(o))return o}return Ft(n,e,t)}var _=class{build(e,t,r={}){let s=new W;for(let i of r.seedSymbols??[])s.addSymbol(i);for(let i of t)for(let d of i.symbols)s.addSymbol(d);let o=new Map;for(let i of s.allSymbols(e))i.type==="file"&&o.set(P(i.filePath),i);let a=new Set(o.keys());for(let i of t){let d=P(i.filePath),c=o.get(d);if(c){for(let l of i.symbols)l.id!==c.id&&s.addEdge(this.edge(e,c.id,"DEFINES",l.id));for(let l of i.imports){let u=X(d,l.source,a,r.resolveModule);if(!u)continue;let m=o.get(u);m&&s.addEdge(this.edge(e,c.id,"IMPORTS",m.id,{source:l.source,resolvedFile:u}))}for(let l of i.heritage){let u=s.findByName(e,l.targetName).filter(m=>m.type==="class"||m.type==="interface");for(let m of u)s.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,s,a,r.resolveModule);for(let m of u)m.id!==l.callerId&&s.addEdge(this.edge(e,l.callerId,"CALLS",m.id,{line:l.line,qualifier:l.qualifier}))}}}return s}resolveCallTargets(e,t,r,s,o,a,i){let d=P(t.filePath),c=o.findByName(e,r).filter(l=>P(l.filePath)===d);if(!s&&c.length)return c;if(s)for(let l of t.imports){if(!l.bindings.find(g=>g.kind==="namespace"&&g.localName===s))continue;let m=X(d,l.source,a,i);if(m)return o.findByName(e,r).filter(g=>P(g.filePath)===m)}for(let l of t.imports){let u=l.bindings.find(v=>v.localName===r);if(!u)continue;let m=X(d,l.source,a,i);if(!m)continue;let g=u.importedName==="default"?r:u.importedName,w=o.findByName(e,g).filter(v=>P(v.filePath)===m);if(w.length)return w}return o.findByName(e,r).filter(l=>l.type==="function"||l.type==="method")}edge(e,t,r,s,o){return{id:Dt(e,t,r,s),projectId:e,from:t,to:s,type:r,metadata:o}}};import{createHash as Kt}from"node:crypto";function ee(n){return n.replaceAll("\\","/")}function Lt(n,e,t,r){return Kt("sha256").update(`${n}:${e}:${t}:${r}`).digest("hex").slice(0,24)}function zt(n){return[ee(n.filePath),n.type,n.qualifiedName??n.name].join("\0")}function ve(n){let e=new Map;for(let r of n){let s=zt(r),o=e.get(s)??[];o.push(r),e.set(s,o)}let t=new Map;for(let[r,s]of e)s.length===1&&t.set(r,s[0]);return t}function Bt(n,e){let t=ve(n),r=ve(e),s=new Map;for(let[o,a]of t){let i=r.get(o);i&&s.set(a.id,i.id)}return s}function we(n){let e=new Map(n.previousSymbols.map(o=>[o.id,o])),t=new Set(n.currentSymbols.map(o=>o.id)),r=Bt(n.previousSymbols,n.currentSymbols),s=[];for(let o of n.previousEdges){let a=e.get(o.from),i=e.get(o.to);if(!a||!i)continue;let d=ee(a.filePath),c=ee(i.filePath);if(n.rebuiltSourceFiles.has(d)||n.removedFiles.has(d)||n.removedFiles.has(c))continue;let l=t.has(o.from)?o.from:r.get(o.from),u=t.has(o.to)?o.to:r.get(o.to);!l||!u||!t.has(l)||!t.has(u)||s.push({...o,id:Lt(n.projectId,l,o.type,u),from:l,to:u})}return s}import{readFile as Vt}from"node:fs/promises";import{join as Gt}from"node:path";import{createHash as Ut}from"node:crypto";import*as f from"typescript";function ke(n,e){return Ut("sha256").update(`${n}:${e}`).digest("hex").slice(0,24)}function te(n,e){return n.getLineAndCharacterOfPosition(e.getStart(n)).line+1}async function Re(n,e,t){let r=Gt(e,t),s=await Vt(r,"utf8"),o=f.createSourceFile(t,s,f.ScriptTarget.Latest,!0,t.endsWith(".tsx")||t.endsWith(".jsx")?f.ScriptKind.TSX:f.ScriptKind.TS),a=[],i=[],d=[],c=[],l={id:ke(n,`file:${t}`),projectId:n,name:t,qualifiedName:t,type:"file",filePath:t,startLine:1,endLine:o.getLineAndCharacterOfPosition(o.end).line+1};a.push(l);let u=[],m=[];function g(p,x,S,y){let h=ke(n,`${t}:${S}:${y??x}:${p.pos}`);return a.push({id:h,projectId:n,name:x,qualifiedName:y??x,type:S,filePath:t,startLine:te(o,p),endLine:o.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(o).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);u.push(y),x=!0}if(f.isMethodDeclaration(p)&&p.name){let y=p.name.getText(o),h=m.at(-1)?.name,R=g(p,y,"method",h?`${h}.${y}`:y);u.push(R),x=!0}if(f.isCallExpression(p)&&(f.isIdentifier(p.expression)&&d.push({callerId:u.at(-1),calleeName:p.expression.text,line:te(o,p)}),f.isPropertyAccessExpression(p.expression))){let y=p.expression;d.push({callerId:u.at(-1),qualifier:y.expression.getText(o),calleeName:y.name.text,line:te(o,p)})}f.forEachChild(p,k),x&&u.pop(),S&&m.pop()}return k(o),{filePath:t,symbols:a,imports:i,calls:d,heritage:c}}import{existsSync as Ht,readFileSync as Wt,readdirSync as Jt,realpathSync as Yt}from"node:fs";import{dirname as se,extname as Zt,join as re,parse as Qt,relative as ne,resolve as N}from"node:path";import*as b from"typescript";var qt="tsconfig.json",Xt=new Set(["node_modules",".git",".toolnet","dist","build","out","coverage",".next",".nuxt",".cache",".turbo","target","vendor"]),Pe=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs"];function $(n){return n.replaceAll("\\","/").replace(/^\.\/+/u,"")}function Me(n,e){let t=$(ne(n,e));return t!==".."&&!t.startsWith("../")&&!t.startsWith("/")}function je(n){try{return Yt.native(n)}catch{return N(n)}}function er(n,e){let t=N(e),r=N(n);for(;;){let s=re(r,qt);if(Ht(s))return s;if(r===t)return;let o=Qt(r).root;if(r===o)return;let a=se(r);if(a===r||!Me(t,a)&&a!==t)return;r=a}}function tr(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,se(n))}function rr(){return{allowJs:!0,checkJs:!1,noEmit:!0,skipLibCheck:!0,target:b.ScriptTarget.ES2022,module:b.ModuleKind.NodeNext,moduleResolution:b.ModuleResolutionKind.NodeNext,resolveJsonModule:!0}}function nr(n){let e=$(n),t=Zt(e);if(t){let s=[e];if(t===".js"){let o=e.slice(0,-3);s.push(`${o}.ts`,`${o}.tsx`)}if(t===".mjs"){let o=e.slice(0,-4);s.push(`${o}.mts`,`${o}.ts`)}if(t===".cjs"){let o=e.slice(0,-4);s.push(`${o}.cts`,`${o}.ts`)}return e.endsWith(".d.ts")&&s.push(e.slice(0,-5)+".ts"),s}let r=[e];for(let s of Pe)r.push(`${e}${s}`);for(let s of Pe)r.push(`${e}/index${s}`);return r}function Ce(n,e){for(let t of nr(n)){let r=$(t);if(e.has(r))return r}}function Ee(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))Ee(t,e)}function sr(n){let e=[];for(let t of["source","types","module","main"]){let r=n[t];typeof r=="string"&&e.push(r)}return Ee(n.exports,e),[...new Set(e)]}function or(n){let t=[N(n)],r=[];for(;t.length>0;){let s=t.pop(),o;try{o=Jt(s,{withFileTypes:!0})}catch{continue}if(o.find(i=>i.isFile()&&i.name==="package.json"))try{let i=JSON.parse(Wt(re(s,"package.json"),"utf8"));typeof i.name=="string"&&i.name.trim()&&r.push({name:i.name.trim(),directory:s,entries:sr(i)})}catch{}for(let i of o)i.isDirectory()&&(Xt.has(i.name)||t.push(re(s,i.name)))}return r.sort((s,o)=>o.name.length-s.name.length)}var J=class{rootPath;configCache=new Map;workspacePackages;constructor(e){this.rootPath=je(e)}resolve(e,t,r){let s=N(this.rootPath,e),o=er(se(s),this.rootPath),a=o?this.config(o).options:rr(),i=b.resolveModuleName(t,s,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=tr(e);return this.configCache.set(e,r),r}matchResolvedFile(e,t){let r=je(e);if(!Me(this.rootPath,r))return;let s=$(ne(this.rootPath,r));return Ce(s,t)}packages(){return this.workspacePackages?this.workspacePackages:(this.workspacePackages=or(this.rootPath),this.workspacePackages)}resolveWorkspacePackage(e,t){let r=this.packages().find(i=>e===i.name||e.startsWith(`${i.name}/`));if(!r)return;let s=$(ne(this.rootPath,r.directory)),o=e===r.name?"":e.slice(r.name.length+1),a=[];if(o)a.push(`${s}/${o}`,`${s}/src/${o}`);else{for(let i of r.entries)a.push(`${s}/${i.replace(/^\.\//u,"")}`);a.push(`${s}/src/index`,`${s}/index`)}for(let i of a){let d=Ce(i,t);if(d)return d}}};function ir(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 ar(n){if(n?.aborted)throw new Error("Operation aborted")}async function Y(n,e,t={}){if(n.length===0)return[];let r=Math.min(ir(t.concurrency),n.length),s=new Array(n.length),o=0,a=0,i=async()=>{for(;;){ar(t.signal);let c=o;if(o+=1,c>=n.length)return;s[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),s}import{join as jr}from"node:path";import{lstat as lr,readdir as pr}from"node:fs/promises";import{extname as mr,join as fr,relative as gr,resolve as yr}from"node:path";import{basename as cr}from"node:path";var dr=new Set([".env",".env.local",".env.production",".env.development","id_rsa","id_ed25519","credentials","credentials.json","service-account.json"]),ur=new Set([".pem",".key",".p12",".pfx"]);function Ae(n){let e=cr(n).toLowerCase();if(dr.has(e))return!0;for(let t of ur)if(e.endsWith(t))return!0;return!1}var hr=2*1024*1024,Sr=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".mts",".cts"]),br=new Set(["node_modules",".git",".toolnet",".toolnet-memory","dist","build","out","coverage",".next",".nuxt",".cache",".parcel-cache",".turbo","vendor","target"]);function Ie(n,e){if(!Number.isSafeInteger(n)||n<1)throw new Error(`${e} must be a positive integer`);return n}function Oe(n){if(n?.aborted)throw new Error("Repository scan aborted")}function xr(n){let e=n.trim().toLowerCase();if(!e)throw new Error("Repository scan extension cannot be empty");return e.startsWith(".")?e:`.${e}`}function vr(n){let e=n.toLowerCase();return/\.min\.(?:js|mjs|cjs)$/u.test(e)||/\.bundle\.(?:js|mjs|cjs)$/u.test(e)}function wr(n){return n.replaceAll("\\","/")}async function kr(n,e={}){let t=yr(n),r=e.maxFileBytes??hr;if(!Number.isSafeInteger(r)||r<1)throw new Error("maxFileBytes must be a positive integer");let s=e.maxFiles??Number.MAX_SAFE_INTEGER;Ie(s,"maxFiles");let o=e.progressInterval??1e3;Ie(o,"progressInterval");let a=new Set(e.extensions?[...e.extensions].map(xr):Sr),i=new Set(br);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;){Oe(e.signal);let u=l.pop(),m;try{m=await pr(u,{withFileTypes:!0})}catch{c.skippedUnreadable+=1;continue}c.directories+=1;for(let g of m){Oe(e.signal),c.entries+=1,c.entries%o===0&&e.onProgress?.({directories:c.directories,entries:c.entries,accepted:c.accepted});let w=fr(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=mr(g.name).toLowerCase();if(!a.has(v))continue;if(vr(g.name)){c.skippedGenerated+=1;continue}if(Ae(w)){c.skippedSensitive+=1;continue}let k;try{k=await lr(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>=s)throw new Error(`Repository scan file limit exceeded: ${s}`);d.push(wr(gr(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 Te(n,e={}){return(await kr(n,e)).files}import{createHash as Rr}from"node:crypto";import{readFile as Pr}from"node:fs/promises";async function _e(n){let e=await Pr(n);return Rr("sha256").update(e).digest("hex")}async function Ne(n,e,t={}){let r={...t.scan};t.signal&&(r.signal=t.signal);let s=await Te(e,r),o=await Y(s,async i=>({path:i,hash:await _e(jr(e,i))}),{concurrency:t.concurrency??8,signal:t.signal,onProgress:({completed:i,total:d,index:c})=>{t.onProgress?.({completed:i,total:d,file:s[c]})}}),a={};for(let i of o)a[i.path]={path:i.path,hash:i.hash};return{version:1,projectId:n,updatedAt:new Date().toISOString(),files:a}}function $e(n,e){let t=new Map;for(let r of n){let s=e[r];if(!s)continue;let o=t.get(s.hash)??[];o.push(r),t.set(s.hash,o)}return t}function Cr(n,e,t,r){let s=$e(e,t),o=$e(n,r),a=[];for(let[i,d]of s){let c=o.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 De(n,e){let t=n?.files??{},r=e.files,s=[],o=[],a=[],i=[];for(let[u,m]of Object.entries(r)){let g=t[u];if(!g){s.push(u);continue}if(g.hash!==m.hash){o.push(u);continue}i.push(u)}for(let u of Object.keys(t))r[u]||a.push(u);let d=Cr(s,a,t,r),c=new Set(d.map(u=>u.from)),l=new Set(d.map(u=>u.to));return{added:s.filter(u=>!l.has(u)).sort(),modified:o.sort(),deleted:a.filter(u=>!c.has(u)).sort(),unchanged:i.sort(),renamed:d}}function Fe(n){return n.replaceAll("\\","/")}var Z=class{constructor(e){this.storage=e}storage;async index(e,t,r={}){let s=new U(this.storage),o=new G(this.storage),a=await s.load(e),i=await o.load(e),d=await Ne(e,t,{concurrency:r.hashConcurrency??8,scan:r.scan,signal:r.signal,onProgress:({completed:h,total:R,file:j})=>{r.onProgress?.({phase:"hash",current:h,total:R,file:j})}}),c=De(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 Y(m,async h=>Re(e,t,h),{concurrency:r.parseConcurrency??4,signal:r.signal,onProgress:({completed:h,total:R,index:j})=>{r.onProgress?.({phase:"parse",current:h,total:R,file:m[j]})}}),w=new J(t),v,k=0;if(u||!i)v=new _().build(e,g,{resolveModule:(h,R,j)=>w.resolve(h,R,j)});else{let h=new Set(c.modified.map(Fe)),R=i.symbols.filter(M=>!h.has(Fe(M.filePath)));v=new _().build(e,g,{seedSymbols:R,resolveModule:(M,Ke,Le)=>w.resolve(M,Ke,Le)}),r.onProgress?.({phase:"repair",current:0,total:i.edges.length});let j=we({projectId:e,previousSymbols:i.symbols,previousEdges:i.edges,currentSymbols:v.allSymbols(e),rebuiltSourceFiles:h,removedFiles:new Set});for(let M of j)v.addEdge(M);k=j.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 o.save(y),r.onProgress?.({phase:"save",current:1,total:2}),await s.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:u,saved:!0}}};async function Er(){let n=ie(),e=new L().detect(),t=Se({provider:n.storage.provider,huggingface:n.storage.huggingface,localRoot:n.storage.localRoot}),r=new H(t,e.id,e.name,e.remote??e.name),s=await new Z(r).index(e.id,e.rootPath);console.log({ok:!0,storage:r.name,...s})}Er().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)});