@rohan9024/redact0 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mcp.cjs ADDED
@@ -0,0 +1 @@
1
+ 'use strict';var nt=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),st=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),N=new TextEncoder;function A(n,t){return n>>>t|n<<32-t}function C(n){let t=n.length*8,r=Math.ceil((n.length+9)/64)*64,i=new Uint8Array(r);i.set(n),i[n.length]=128;let s=new DataView(i.buffer),a=Math.floor(t/4294967296),o=t>>>0;s.setUint32(r-8,a,false),s.setUint32(r-4,o,false);let e=new Uint32Array(st),c=new Uint32Array(64);for(let u=0;u<r;u+=64){for(let y=0;y<16;y++)c[y]=s.getUint32(u+y*4,false);for(let y=16;y<64;y++){let v=c[y-15],k=c[y-2],S=A(v,7)^A(v,18)^v>>>3,D=A(k,17)^A(k,19)^k>>>10;c[y]=c[y-16]+S+c[y-7]+D>>>0;}let l=e[0],d=e[1],p=e[2],h=e[3],x=e[4],T=e[5],_=e[6],M=e[7];for(let y=0;y<64;y++){let v=A(x,6)^A(x,11)^A(x,25),k=x&T^~x&_,S=M+v+k+nt[y]+c[y]>>>0,D=A(l,2)^A(l,13)^A(l,22),et=l&d^l&p^d&p,rt=D+et>>>0;M=_,_=T,T=x,x=h+S>>>0,h=p,p=d,d=l,l=S+rt>>>0;}e[0]=e[0]+l>>>0,e[1]=e[1]+d>>>0,e[2]=e[2]+p>>>0,e[3]=e[3]+h>>>0,e[4]=e[4]+x>>>0,e[5]=e[5]+T>>>0,e[6]=e[6]+_>>>0,e[7]=e[7]+M>>>0;}let f=new Uint8Array(32),g=new DataView(f.buffer);for(let u=0;u<8;u++)g.setUint32(u*4,e[u],false);return f}function I(n,t,r=64){let i=N.encode(n),s=i.length>64?C(i):i,a=new Uint8Array(64);a.set(s);let o=new Uint8Array(64),e=new Uint8Array(64);for(let d=0;d<64;d++){let p=a[d];o[d]=p^92,e[d]=p^54;}let c=N.encode(t),f=new Uint8Array(64+c.length);f.set(e,0),f.set(c,64);let g=C(f),u=new Uint8Array(96);u.set(o,0),u.set(g,64);let l=C(u);return O(l).slice(0,r)}function V(n,t=64){return O(C(N.encode(n))).slice(0,t)}function O(n){let t="";for(let r=0;r<n.length;r++)t+=n[r].toString(16).padStart(2,"0");return t}function Z(n=8){let t=new Uint8Array(n);if(typeof globalThis.crypto?.getRandomValues=="function")globalThis.crypto.getRandomValues(t);else for(let r=0;r<n;r++)t[r]=Math.floor(Math.random()*256);return O(t)}function m(n){return n.replace(/\D/g,"")}function K(n){let t=m(n);if(t.length<13||t.length>19||/^(\d)\1+$/.test(t))return false;let r=0,i=false;for(let s=t.length-1;s>=0;s--){let a=t.charCodeAt(s)-48;i&&(a*=2,a>9&&(a-=9)),r+=a,i=!i;}return r%10===0}function U(n){let t=m(n);if(!/^[12]\d{9}$/.test(t))return false;let r="80840"+t,i=0,s=false;for(let a=r.length-1;a>=0;a--){let o=r.charCodeAt(a)-48;s&&(o*=2,o>9&&(o-=9)),i+=o,s=!s;}return i%10===0}function F(n){let t=n.trim().toUpperCase();if(!/^[ABFGMPRX][A-Z9]\d{7}$/.test(t))return false;let r=o=>t.charCodeAt(2+o)-48,i=r(0)+r(2)+r(4),s=r(1)+r(3)+r(5);return (i+2*s)%10===r(6)}var w="ACDEFGHJKMNPQRTUVWXY",z="0123456789"+w;function L(n){let t=n.replace(/-/g,"").toUpperCase();if(t.length!==11)return false;let r=t.charCodeAt(0);return !(r<49||r>57||!w.includes(t[1])||!z.includes(t[2])||!/\d/.test(t[3])||!w.includes(t[4])||!z.includes(t[5])||!/\d/.test(t[6])||!w.includes(t[7])||!w.includes(t[8])||!/\d\d/.test(t.slice(9,11)))}var it={AD:24,AE:23,AL:28,AT:20,AZ:28,BA:20,BE:16,BG:22,BH:22,BR:29,BY:28,CH:21,CR:22,CY:28,CZ:24,DE:22,DK:18,DO:28,EE:20,EG:29,ES:24,FI:18,FO:18,FR:27,GB:22,GE:22,GI:23,GL:18,GR:27,GT:28,HR:21,HU:28,IE:22,IL:23,IQ:23,IS:26,IT:27,JO:30,KW:30,KZ:20,LB:28,LC:32,LI:21,LT:20,LU:20,LV:21,MC:27,MD:24,ME:22,MK:19,MR:27,MT:31,MU:30,NL:18,NO:15,PK:24,PL:28,PS:29,PT:25,QA:29,RO:24,RS:22,SA:24,SE:24,SI:19,SK:24,SM:27,ST:25,SV:28,TL:23,TN:24,TR:26,UA:29,VA:22,VG:24,XK:20};function $(n){let t=n.replace(/[\s-]+/g,"").toUpperCase();if(!/^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$/.test(t))return false;let r=it[t.slice(0,2)];if(r!==void 0&&t.length!==r)return false;let i=t.slice(4)+t.slice(0,4),s=0;for(let a=0;a<i.length;a++){let o=i.charCodeAt(a);if(o>=48&&o<=57)s=(s*10+(o-48))%97;else if(o>=65&&o<=90){let e=o-55;s=(s*100+e)%97;}else return false}return s===1}function H(n){let t=m(n);if(t.length!==10||/^(\d)\1+$/.test(t))return false;let r=0;for(let a=0;a<9;a++)r+=(t.charCodeAt(a)-48)*(10-a);let s=11-r%11;return s===11&&(s=0),s===10?false:s===t.charCodeAt(9)-48}function G(n,t){let r=n.trim(),i=/[-\s]/.test(r),s=m(r);if(s.length!==9)return false;let a=Number(s.slice(0,3)),o=Number(s.slice(3,5)),e=Number(s.slice(5,9));if(a===0||a===666||a>=900||o===0||e===0||/^(\d)\1+$/.test(s))return false;if(!i&&t){let c=t.fullText.slice(Math.max(0,t.start-36),t.start);return /\b(ssn|social[\s_-]?security|tin)\b/i.test(c)}return true}var at=[[0,1,2,3,4,5,6,7,8,9],[1,2,3,4,0,6,7,8,9,5],[2,3,4,0,1,7,8,9,5,6],[3,4,0,1,2,8,9,5,6,7],[4,0,1,2,3,9,5,6,7,8],[5,9,8,7,6,0,4,3,2,1],[6,5,9,8,7,1,0,4,3,2],[7,6,5,9,8,2,1,0,4,3],[8,7,6,5,9,3,2,1,0,4],[9,8,7,6,5,4,3,2,1,0]],ot=[[0,1,2,3,4,5,6,7,8,9],[1,5,7,6,2,8,3,0,9,4],[5,8,0,3,7,9,6,1,4,2],[8,9,1,6,0,4,3,5,2,7],[9,4,5,3,1,2,6,8,7,0],[4,2,8,6,5,7,3,9,0,1],[2,7,9,3,8,0,6,4,1,5],[7,0,4,6,9,1,3,2,5,8]];function B(n){let t=m(n);if(!/^[2-9]\d{11}$/.test(t))return false;let r=0;for(let i=0;i<t.length;i++){let s=t.charCodeAt(t.length-1-i)-48;r=at[r][ot[i%8][s]];}return r===0}function j(n){let t=m(n);if(!/^[1-9]\d{10}$/.test(t))return false;let r=new Array(10).fill(0);for(let e=0;e<10;e++)r[t.charCodeAt(e)-48]+=1;let i=r.filter(e=>e===2||e===3).length,s=Math.max(...r);if(i!==1||s>3)return false;let a=10;for(let e=0;e<10;e++){let c=(t.charCodeAt(e)-48+a)%10;c===0&&(c=10),a=c*2%11;}let o=11-a;return o===10&&(o=0),o===t.charCodeAt(10)-48}function Y(n){let t=n.split(".");if(t.length!==3)return false;let r=t[0];if(!r.startsWith("eyJ"))return false;try{let i=r.replace(/-/g,"+").replace(/_/g,"/"),s=(4-i.length%4)%4,a=atob(i+"=".repeat(s));return a.startsWith("{")&&a.includes('"')}catch{return false}}function W(n){let t=n.split(".").map(Number);if(t.length!==4)return false;let[r,i]=t;return r===void 0||i===void 0?false:r===10||r===127||r===0||r===192&&i===168||r===172&&i>=16&&i<=31||r===169&&i===254}function J(n){let t=n.split(".");if(t.length!==4)return false;for(let r of t){if(r.length===0||r.length>1&&r.startsWith("0"))return false;let i=Number(r);if(!Number.isInteger(i)||i<0||i>255)return false}return true}function q(n){if(n.length===0)return 0;let t=new Map;for(let s=0;s<n.length;s++){let a=n.charCodeAt(s);t.set(a,(t.get(a)??0)+1);}let r=0,i=n.length;for(let s of t.values()){let a=s/i;r-=a*Math.log2(a);}return r}var b=["default","secrets","hipaa","gdpr","strict"],R=["default","hipaa","gdpr","strict"],E=["hipaa","strict"],ct=["gdpr","strict"],X=[{id:"pem-private-key",category:"PRIVATE_KEY",priority:100,presets:b,pattern:/-----BEGIN (?:RSA |EC |DSA |OPENSSH |PGP |ENCRYPTED )?PRIVATE KEY-----[\s\S]{16,8192}?-----END (?:RSA |EC |DSA |OPENSSH |PGP |ENCRYPTED )?PRIVATE KEY-----/g},{id:"connection-uri-password",category:"CONNECTION_URI",priority:96,presets:b,captureGroup:1,pattern:/\b(?:postgres(?:ql)?|mysql|mariadb|mongodb(?:\+srv)?|redis(?:s)?|amqp(?:s)?|mssql|clickhouse|cockroachdb):\/\/[^:\s/@]+:([^@\s/]{3,256})@[^\s"'<>]+/gi},{id:"anthropic-key",category:"API_KEY",priority:95,presets:b,pattern:/\bsk-ant-(?:api\d{2}|admin\d{2}|oat\d{2}|[a-z0-9]+)-[A-Za-z0-9_-]{24,}\b/g},{id:"openai-key",category:"API_KEY",priority:95,presets:b,pattern:/\bsk-(?:proj|svcacct|admin)-[A-Za-z0-9_-]{24,}\b|\bsk-[A-Za-z0-9]{16,}T3BlbkFJ[A-Za-z0-9]{16,}\b/g},{id:"github-token",category:"API_KEY",priority:95,presets:b,pattern:/\b(?:gh[pousr]_[A-Za-z0-9_]{36,}|github_pat_[A-Za-z0-9]{22}_[A-Za-z0-9]{40,})\b/g},{id:"aws-access-key",category:"API_KEY",priority:94,presets:b,pattern:/\b(?:AKIA|ASIA|AROA|AIDA)[0-9A-Z]{16}\b/g},{id:"stripe-secret",category:"API_KEY",priority:94,presets:b,pattern:/\b(?:sk_live|rk_live|whsec)_[A-Za-z0-9]{20,}\b/g},{id:"google-api-key",category:"API_KEY",priority:93,presets:b,pattern:/\bAIza[0-9A-Za-z_-]{35}\b/g},{id:"slack-token",category:"TOKEN",priority:93,presets:b,pattern:/\bxox[baprs]-[0-9A-Za-z-]{14,}\b|https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]+/g},{id:"discord-webhook",category:"SECRET",priority:92,presets:b,pattern:/https:\/\/discord(?:app)?\.com\/api\/webhooks\/\d{16,22}\/[A-Za-z0-9_-]{40,}/g},{id:"provider-prefixed-keys",category:"API_KEY",priority:92,presets:b,pattern:/\b(?:hf_[A-Za-z0-9]{30,}|gsk_[A-Za-z0-9]{36,}|xai-[A-Za-z0-9]{36,}|pplx-[A-Za-z0-9]{36,}|sbp_[A-Za-z0-9]{36,}|sb_secret_[A-Za-z0-9_-]{24,}|re_[A-Za-z0-9_]{24,}|npm_[A-Za-z0-9]{36}|pypi-AgEIcHlwaS5vcmc[A-Za-z0-9_-]{50,}|SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43})\b/g},{id:"jwt-token",category:"JWT",priority:90,presets:b,pattern:/\beyJ[A-Za-z0-9_-]{6,}\.eyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{8,}\b/g,validate:n=>Y(n)},{id:"bearer-auth-header",category:"TOKEN",priority:88,presets:b,captureGroup:1,pattern:/\b(?:Authorization|Proxy-Authorization)\s*[:=]\s*["']?(?:Bearer|Basic|Token)\s+([A-Za-z0-9._~+/=-]{12,})["']?/gi},{id:"contextual-secret-assignment",category:"SECRET",priority:72,presets:b,captureGroup:1,pattern:/\b(?:api[_-]?key|secret[_-]?key|access[_-]?token|refresh[_-]?token|auth[_-]?token|client[_-]?secret|private[_-]?key|aws_secret_access_key|password|passwd|pwd|signing[_-]?secret)\b\s*[:=]\s*["']?([^\s"',;}{]{10,128})["']?/gi,validate:n=>!n.startsWith("[")&&!n.startsWith("<")&&q(n)>=2.8},{id:"medicare-mbi",category:"MBI",priority:84,presets:E,pattern:/\b[1-9][AC-HJKMNP-RT-Y][0-9AC-HJKMNP-RT-Y]-?\d[AC-HJKMNP-RT-Y][0-9AC-HJKMNP-RT-Y]-?\d[AC-HJKMNP-RT-Y]{2}\d{2}\b/gi,validate:n=>L(n)},{id:"us-dea",category:"DEA",priority:83,presets:E,pattern:/\b[ABFGMPRX][A-Z9]\d{7}\b/g,validate:n=>F(n)},{id:"us-npi",category:"NPI",priority:80,presets:E,contextWindow:40,contextRegex:/\b(?:npi|provider|prescriber|practitioner|physician)\b/i,pattern:/\b[12]\d{9}\b/g,validate:n=>U(n)},{id:"uk-nhs-number",category:"NHS",priority:80,presets:["hipaa","gdpr","strict"],contextWindow:40,contextRegex:/\b(?:nhs|patient|health|care|medical)\b/i,pattern:/\b\d{3}[-\s]?\d{3}[-\s]?\d{4}\b/g,validate:n=>H(n)},{id:"medical-record-number",category:"MRN",priority:78,presets:E,captureGroup:1,pattern:/\b(?:mrn|medical[\s_-]?record(?:[\s_-]?number)?|patient[\s_-]?id)\s*[:=#]?\s*([A-Z0-9-]{5,20})\b/gi},{id:"iban",category:"IBAN",priority:84,presets:R,pattern:/\b[A-Z]{2}\d{2}(?:[\s-]?[A-Z0-9]){11,30}\b/g,validate:n=>$(n)},{id:"credit-card",category:"CREDIT_CARD",priority:82,presets:R,pattern:/\b(?:\d[ -]?){13,18}\d\b/g,validate:n=>{let t=n.replace(/\D/g,"");return /^(?:4\d{12}(?:\d{3})?(?:\d{3})?|5[1-5]\d{14}|2(?:2[2-9]|[3-6]\d|7[01]|720)\d{12}|3[47]\d{13}|6(?:011|5\d\d)\d{12}|3(?:0[0-5]|[68]\d)\d{11}|(?:2131|1800|35\d{3})\d{11})$/.test(t)&&K(t)}},{id:"us-ssn",category:"SSN",priority:81,presets:R,pattern:/\b\d{3}[-\s]\d{2}[-\s]\d{4}\b|\b\d{9}\b/g,validate:(n,t)=>G(n,t)},{id:"aadhaar-in",category:"AADHAAR",priority:76,presets:["gdpr","strict"],contextWindow:40,contextRegex:/\b(?:aadhaar|aadhar|uidai)\b/i,pattern:/\b[2-9]\d{3}[-\s]?\d{4}[-\s]?\d{4}\b/g,validate:n=>B(n)},{id:"de-tax-id",category:"TAX_ID",priority:76,presets:ct,contextWindow:45,contextRegex:/\b(?:steuer|tax|tin|idnr|identifikationsnummer)\b/i,pattern:/\b[1-9]\d{10}\b/g,validate:n=>j(n)},{id:"email",category:"EMAIL",priority:75,presets:R,pattern:/\b[A-Za-z0-9._%+-]{1,64}@(?:[A-Za-z0-9-]{1,63}\.)+[A-Za-z]{2,24}\b/g},{id:"phone",category:"PHONE",priority:65,presets:R,pattern:/(?:\+\d{1,3}[-.\s]?)?(?:\(\d{2,4}\)[-.\s]?|\b\d{3}[-.\s])\d{3,4}[-.\s]\d{4}\b|\+\d{1,3}[-.\s]?\d{2,4}[-.\s]?\d{3,4}[-.\s]?\d{3,4}\b/g,validate:n=>{let t=n.replace(/\D/g,"");return t.length>=10&&t.length<=15&&!/^(\d)\1+$/.test(t)}},{id:"ipv4",category:"IP_ADDRESS",priority:60,presets:R,pattern:/\b(?:25[0-5]|2[0-4]\d|1?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|1?\d?\d)){3}\b/g,validate:n=>J(n)},{id:"ipv6",category:"IP_ADDRESS",priority:58,presets:["hipaa","gdpr","strict"],pattern:/\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b|\b(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}\b/g},{id:"mac-address",category:"MAC_ADDRESS",priority:58,presets:["hipaa","gdpr","strict"],pattern:/\b(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}\b/g},{id:"labeled-person-name",category:"PERSON",priority:55,presets:["hipaa","strict"],captureGroup:1,pattern:/\b(?:Patient(?:\s+Name)?|Dr\.|Doctor|Clinician|Provider|Mr\.|Mrs\.|Ms\.|Full\s+Name|Beneficiary)\s*[:.]?\s*([A-Z][a-z]{1,24}(?:\s+[A-Z]\.?)?(?:\s+[A-Z][a-z]{1,24}){1,2})/g},{id:"dob-or-clinical-date",category:"DATE",priority:52,presets:E,contextWindow:40,contextRegex:/\b(?:dob|birth|born|admit(?:ted)?|discharg(?:e|ed)|visit|encounter|date)\b/i,pattern:/\b(?:\d{4}-\d{2}-\d{2}|(?:0?[1-9]|1[0-2])[/-](?:0?[1-9]|[12]\d|3[01])[/-](?:19|20)\d{2})\b/g}];var ut=/^(?:password|passwd|pwd|passphrase|secret|api[_-]?key|access[_-]?token|refresh[_-]?token|auth[_-]?token|authorization|cookie|set-cookie|x-api-key|client[_-]?secret|private[_-]?key|ssn|social[_-]?security(?:[_-]?number)?|cvv|cvc|pin|iban|dob|birth[_-]?date|mrn)$/i,lt=/\[[A-Z_]+_\d+(?:#[a-f0-9]{4,8})?\]|<[A-Z_]+_\d+(?:#[a-f0-9]{4,8})?>/g;function Q(n){let t=n.toLowerCase();return t.includes("ssn")||t.includes("social")?"SSN":t.includes("iban")?"IBAN":t.includes("mrn")?"MRN":t.includes("dob")||t.includes("birth")?"DATE":t.includes("password")||t.includes("passwd")||t.includes("secret")||t==="cvv"||t==="cvc"||t==="pin"?"SECRET":t.includes("token")||t==="authorization"||t==="cookie"||t==="set-cookie"?"TOKEN":t.includes("key")?"API_KEY":"CUSTOM"}function dt(n){let t=n.preset??"default",r=n.rules?[...n.rules]:X.filter(a=>a.presets.includes(t)),s=[...(n.customRules??[]).map(a=>({id:a.id,category:a.category??"CUSTOM",pattern:a.pattern,captureGroup:a.captureGroup,priority:a.priority??85,presets:["default","secrets","hipaa","gdpr","strict"],validate:a.validate})),...r];if(n.categories?.length){let a=new Set(n.categories);s=s.filter(o=>a.has(o.category));}if(n.excludeCategories?.length){let a=new Set(n.excludeCategories);s=s.filter(o=>!a.has(o.category));}return s}function ft(n,t){let r=[];for(let i of t){if(!i||i.length<4)continue;let s=0;for(;;){let a=n.indexOf(i,s);if(a===-1)break;r.push({id:"literal-secret",category:"SECRET",priority:99,start:a,end:a+i.length,value:i}),s=a+i.length;}}return r}function tt(n,t,r){let i=[],s=r.allowlist?new Set(r.allowlist):void 0,a=r.redactPrivateIps??(r.preset==="strict"||r.preset==="hipaa");r.literals?.length&&i.push(...ft(n,r.literals));for(let e of t){let c=e.pattern.flags.includes("g")?e.pattern.flags:e.pattern.flags+"g",f=new RegExp(e.pattern.source,c),g;for(;(g=f.exec(n))!==null;){if(g[0].length===0){f.lastIndex+=1;continue}let u=g.index,l=g[0];if(e.captureGroup!==void 0&&g[e.captureGroup]!==void 0){let p=g[e.captureGroup],h=g[0].indexOf(p);h!==-1&&(u=g.index+h,l=p);}let d=u+l.length;if(!s?.has(l)&&!(e.id==="ipv4"&&!a&&W(l))){if(e.contextRegex){let p=e.contextWindow??40,h=n.slice(Math.max(0,u-p),u),x=n.slice(d,Math.min(n.length,d+p));if(!e.contextRegex.test(h)&&!e.contextRegex.test(x))continue}if(e.validate){let p={fullText:n,match:g,start:u,end:d,value:l};if(!e.validate(l,p))continue}i.push({id:e.id,category:e.category,priority:e.priority,start:u,end:d,value:l});}}}i.sort((e,c)=>{if(c.priority!==e.priority)return c.priority-e.priority;let f=c.end-c.start-(e.end-e.start);return f!==0?f:e.start-c.start});let o=[];for(let e of i){let c=false;for(let f of o)if(e.start<f.end&&e.end>f.start){c=true;break}c||o.push(e);}return o.sort((e,c)=>e.start-c.start),o}var P=class n{options;rules;tokenFormat;vaultKey;sensitiveKeyRe;forward=new Map;reverse=new Map;counters=new Map;reservedTokens=new Set;_version=0;constructor(t={}){this.options=t,this.rules=dt(t),this.tokenFormat=t.tokenFormat??"bracket",this.vaultKey=t.secret??Z(16),this.sensitiveKeyRe=t.sensitiveKeys?.length?new RegExp(`^(?:${t.sensitiveKeys.map(r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|")})$`,"i"):ut;}get version(){return this._version}fingerprint(t){return I(this.vaultKey,t,12)}reserveExistingTokens(t){let r=new RegExp(lt.source,"g"),i;for(;(i=r.exec(t))!==null;)this.reverse.has(i[0])||this.reservedTokens.add(i[0]);}tokenize(t,r){let i=`${t}:${r}`,s=this.forward.get(i);if(s!==void 0)return s;if(this.tokenFormat==="mask")return (this.options.maskChar??"*").repeat(Math.min(Math.max(r.length,4),16));if(this.tokenFormat==="hash"){let e=I(this.vaultKey,i,8),c=`[${t}:${e}]`;return this.forward.set(i,c),this.reverse.set(c,{category:t,value:r}),this._version+=1,c}let a=this.counters.get(t)??0,o;do if(a+=1,this.tokenFormat==="angle")o=`<${t}_${a}>`;else if(this.tokenFormat==="signed"){let e=I(this.vaultKey,`${t}:${a}:${r}`,4);o=`[${t}_${a}#${e}]`;}else o=`[${t}_${a}]`;while(this.reservedTokens.has(o)||this.reverse.has(o));return this.counters.set(t,a),this.forward.set(i,o),this.reverse.set(o,{category:t,value:r}),this._version+=1,o}scan(t){return typeof t!="string"||t.length===0?[]:tt(t,this.rules,this.options).map(i=>({id:i.id,category:i.category,start:i.start,end:i.end,token:`[${i.category}]`,length:i.value.length,fingerprint:V(i.value,12)}))}redactText(t){if(typeof t!="string"||t.length===0)return {value:t,findings:[],count:0};this.reserveExistingTokens(t);let r=tt(t,this.rules,this.options);if(r.length===0)return {value:t,findings:[],count:0};let i="",s=0,a=[];for(let o of r){i+=t.slice(s,o.start);let e=this.tokenize(o.category,o.value);i+=e,s=o.end,a.push({id:o.id,category:o.category,start:o.start,end:o.end,token:e,length:o.value.length,fingerprint:this.fingerprint(o.value)});}return i+=t.slice(s),{value:i,findings:a,count:a.length}}redactObject(t){let r=[],i=this.options.maxDepth??32,s=new WeakMap,a=(e,c,f)=>{if(e==null)return e;if(typeof e=="string"){if(f&&this.sensitiveKeyRe.test(f)&&e.length>0&&!this.reverse.has(e)){let l=Q(f),d=this.tokenize(l,e);return r.push({id:"sensitive-key",category:l,start:0,end:e.length,token:d,length:e.length,fingerprint:this.fingerprint(e)}),d}let u=this.redactText(e);return u.count>0&&r.push(...u.findings),u.value}if(typeof e!="object")return e;if(c>=i)return "[MAX_DEPTH_TRUNCATED]";if(s.has(e))return s.get(e);if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return new RegExp(e.source,e.flags);if(e instanceof URL){let u=new URL(e.toString());u.password&&(u.password=this.tokenize("SECRET",u.password));let l=[];u.searchParams.forEach((d,p)=>{l.push([p,d]);});for(let[d,p]of l)if(this.sensitiveKeyRe.test(d)&&p)u.searchParams.set(d,this.tokenize(Q(d),p));else {let h=this.redactText(p);h.count>0&&(r.push(...h.findings),u.searchParams.set(d,h.value));}return u}if(typeof Headers<"u"&&e instanceof Headers){let u=new Headers;return e.forEach((l,d)=>{u.set(d,a(l,c+1,d));}),u}if(e instanceof Error){let u={name:e.name,message:this.options.redactErrors!==false?a(e.message,c+1):e.message};e.stack!==void 0&&(u.stack=this.options.redactErrors!==false?a(e.stack,c+1):e.stack),"cause"in e&&e.cause!==void 0&&(u.cause=a(e.cause,c+1));for(let l of Object.keys(e))u[l]=a(e[l],c+1,l);return u}if(Array.isArray(e)){let u=[];s.set(e,u);for(let l=0;l<e.length;l++)u.push(a(e[l],c+1,f));return u}if(e instanceof Map){let u=new Map;s.set(e,u);for(let[l,d]of e.entries()){let p=typeof l=="string"?l:void 0;u.set(a(l,c+1),a(d,c+1,p));}return u}if(e instanceof Set){let u=new Set;s.set(e,u);for(let l of e.values())u.add(a(l,c+1));return u}let g={};s.set(e,g);for(let[u,l]of Object.entries(e))g[u]=a(l,c+1,u);return g};return {value:a(t,0),findings:r,count:r.length}}redact(t){return typeof t=="string"?this.redactText(t):this.redactObject(t)}restore(t){if(typeof t!="string"||t.length===0||this.reverse.size===0)return t;let i=Array.from(this.reverse.keys()).sort((a,o)=>o.length-a.length).map(a=>a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")),s=new RegExp(i.join("|"),"g");return t.replace(s,a=>this.reverse.get(a)?.value??a)}restoreObject(t){let r=new WeakMap,i=(s,a)=>{if(s==null)return s;if(typeof s=="string")return this.restore(s);if(typeof s!="object"||a>=32)return s;if(r.has(s))return r.get(s);if(Array.isArray(s)){let e=[];r.set(s,e);for(let c of s)e.push(i(c,a+1));return e}if(s instanceof Date||s instanceof RegExp||s instanceof URL)return s;let o={};r.set(s,o);for(let[e,c]of Object.entries(s))o[e]=i(c,a+1);return o};return i(t,0)}entries(){return Array.from(this.reverse.entries()).map(([t,r])=>({token:t,category:r.category,value:r.value}))}export(){let t={};for(let[r,i]of this.counters.entries())t[r]=i;return {version:1,tokenFormat:this.tokenFormat,counters:t,entries:this.entries()}}static fromJSON(t,r={}){let i=new n({...r,tokenFormat:t.tokenFormat});for(let[s,a]of Object.entries(t.counters))i.counters.set(s,a);for(let s of t.entries)i.forward.set(`${s.category}:${s.value}`,s.token),i.reverse.set(s.token,{category:s.category,value:s.value});return i._version+=1,i}clear(){this.forward.clear(),this.reverse.clear(),this.counters.clear(),this.reservedTokens.clear(),this._version+=1;}};function vt(n,t={}){let r=t.vault??new P(t),i=t.direction??"output",s=t.rehydrateToolInputs??true,a=(o,e)=>async(...c)=>{let f=[...c];if(f.length>0&&f[0]&&typeof f[0]=="object"){if(s&&i!=="input")f[0]=r.restoreObject(f[0]);else if(i==="input"||i==="both"){let d=r.redactObject(f[0]);f[0]=d.value,d.count>0&&t.onRedaction?.({toolName:o,direction:"input",count:d.count});}}let g=await e(...f);if(!g||typeof g!="object"||i==="input")return g;let u={...g},l=0;if(Array.isArray(u.content)&&(u.content=u.content.map(d=>{if(!d||typeof d!="object")return d;let p={...d};if(p.type==="text"&&typeof p.text=="string"){let h=r.redactText(p.text);l+=h.count,p.text=h.value;}else {let h=r.redactObject(p);return l+=h.count,h.value}return p})),u.structuredContent!==void 0){let d=r.redactObject(u.structuredContent);l+=d.count,u.structuredContent=d.value;}return l>0&&t.onRedaction?.({toolName:o,direction:"output",count:l}),u};if(typeof n.registerTool=="function"){let o=n.registerTool.bind(n);n.registerTool=(e,c,f)=>typeof f=="function"?o(e,c,a(e,f)):o(e,c,f);}if(typeof n.tool=="function"){let o=n.tool.bind(n);n.tool=(e,...c)=>{let f=c.length-1;if(f>=0&&typeof c[f]=="function"){let g=[...c];return g[f]=a(e,c[f]),o(e,...g)}return o(e,...c)};}if(typeof n.registerResource=="function"){let o=n.registerResource.bind(n);n.registerResource=(...e)=>{let c=e.length-1;if(c>=0&&typeof e[c]=="function"){let f=e[c],g=[...e];return g[c]=async(...u)=>{let l=await f(...u);return r.redactObject(l).value},o(...g)}return o(...e)};}return n}exports.guardMcpServer=vt;
package/dist/mcp.d.cts ADDED
@@ -0,0 +1,31 @@
1
+ import { V as Vault } from './engine-CBII6Rkn.cjs';
2
+ import { R as RedactOptions } from './types-DZbmtyhn.cjs';
3
+
4
+ interface McpGuardOptions extends RedactOptions {
5
+ /** Shared vault for rehydrating tokens across MCP tool calls and LLM prompts. */
6
+ vault?: Vault;
7
+ /**
8
+ * 'output' (default): scrubs tool responses before returning to LLM.
9
+ * 'input': scrubs arguments before invoking tool.
10
+ * 'both': scrubs inputs and outputs.
11
+ */
12
+ direction?: 'output' | 'input' | 'both';
13
+ /**
14
+ * When true (default), restores vault tokens inside incoming tool arguments
15
+ * so trusted local tools execute with real values while outputs stay scrubbed.
16
+ */
17
+ rehydrateToolInputs?: boolean;
18
+ /** Optional hook invoked when sensitive data is scrubbed from tool outputs/inputs. */
19
+ onRedaction?: (info: {
20
+ toolName: string;
21
+ direction: 'input' | 'output';
22
+ count: number;
23
+ }) => void;
24
+ }
25
+ /**
26
+ * Zero-dependency guard for `@modelcontextprotocol/sdk` v1 (`server.tool` & `server.registerTool`)
27
+ * and `@modelcontextprotocol/server` v2 (`server.registerTool`).
28
+ */
29
+ declare function guardMcpServer<T extends Record<string, any>>(server: T, options?: McpGuardOptions): T;
30
+
31
+ export { type McpGuardOptions, guardMcpServer };
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { V as Vault } from './engine-DXYt06CR.js';
2
+ import { R as RedactOptions } from './types-DZbmtyhn.js';
3
+
4
+ interface McpGuardOptions extends RedactOptions {
5
+ /** Shared vault for rehydrating tokens across MCP tool calls and LLM prompts. */
6
+ vault?: Vault;
7
+ /**
8
+ * 'output' (default): scrubs tool responses before returning to LLM.
9
+ * 'input': scrubs arguments before invoking tool.
10
+ * 'both': scrubs inputs and outputs.
11
+ */
12
+ direction?: 'output' | 'input' | 'both';
13
+ /**
14
+ * When true (default), restores vault tokens inside incoming tool arguments
15
+ * so trusted local tools execute with real values while outputs stay scrubbed.
16
+ */
17
+ rehydrateToolInputs?: boolean;
18
+ /** Optional hook invoked when sensitive data is scrubbed from tool outputs/inputs. */
19
+ onRedaction?: (info: {
20
+ toolName: string;
21
+ direction: 'input' | 'output';
22
+ count: number;
23
+ }) => void;
24
+ }
25
+ /**
26
+ * Zero-dependency guard for `@modelcontextprotocol/sdk` v1 (`server.tool` & `server.registerTool`)
27
+ * and `@modelcontextprotocol/server` v2 (`server.registerTool`).
28
+ */
29
+ declare function guardMcpServer<T extends Record<string, any>>(server: T, options?: McpGuardOptions): T;
30
+
31
+ export { type McpGuardOptions, guardMcpServer };
package/dist/mcp.mjs ADDED
@@ -0,0 +1 @@
1
+ var nt=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),st=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),N=new TextEncoder;function A(n,t){return n>>>t|n<<32-t}function C(n){let t=n.length*8,r=Math.ceil((n.length+9)/64)*64,i=new Uint8Array(r);i.set(n),i[n.length]=128;let s=new DataView(i.buffer),a=Math.floor(t/4294967296),o=t>>>0;s.setUint32(r-8,a,false),s.setUint32(r-4,o,false);let e=new Uint32Array(st),c=new Uint32Array(64);for(let u=0;u<r;u+=64){for(let y=0;y<16;y++)c[y]=s.getUint32(u+y*4,false);for(let y=16;y<64;y++){let v=c[y-15],k=c[y-2],S=A(v,7)^A(v,18)^v>>>3,D=A(k,17)^A(k,19)^k>>>10;c[y]=c[y-16]+S+c[y-7]+D>>>0;}let l=e[0],d=e[1],p=e[2],h=e[3],x=e[4],T=e[5],_=e[6],M=e[7];for(let y=0;y<64;y++){let v=A(x,6)^A(x,11)^A(x,25),k=x&T^~x&_,S=M+v+k+nt[y]+c[y]>>>0,D=A(l,2)^A(l,13)^A(l,22),et=l&d^l&p^d&p,rt=D+et>>>0;M=_,_=T,T=x,x=h+S>>>0,h=p,p=d,d=l,l=S+rt>>>0;}e[0]=e[0]+l>>>0,e[1]=e[1]+d>>>0,e[2]=e[2]+p>>>0,e[3]=e[3]+h>>>0,e[4]=e[4]+x>>>0,e[5]=e[5]+T>>>0,e[6]=e[6]+_>>>0,e[7]=e[7]+M>>>0;}let f=new Uint8Array(32),g=new DataView(f.buffer);for(let u=0;u<8;u++)g.setUint32(u*4,e[u],false);return f}function I(n,t,r=64){let i=N.encode(n),s=i.length>64?C(i):i,a=new Uint8Array(64);a.set(s);let o=new Uint8Array(64),e=new Uint8Array(64);for(let d=0;d<64;d++){let p=a[d];o[d]=p^92,e[d]=p^54;}let c=N.encode(t),f=new Uint8Array(64+c.length);f.set(e,0),f.set(c,64);let g=C(f),u=new Uint8Array(96);u.set(o,0),u.set(g,64);let l=C(u);return O(l).slice(0,r)}function V(n,t=64){return O(C(N.encode(n))).slice(0,t)}function O(n){let t="";for(let r=0;r<n.length;r++)t+=n[r].toString(16).padStart(2,"0");return t}function Z(n=8){let t=new Uint8Array(n);if(typeof globalThis.crypto?.getRandomValues=="function")globalThis.crypto.getRandomValues(t);else for(let r=0;r<n;r++)t[r]=Math.floor(Math.random()*256);return O(t)}function m(n){return n.replace(/\D/g,"")}function K(n){let t=m(n);if(t.length<13||t.length>19||/^(\d)\1+$/.test(t))return false;let r=0,i=false;for(let s=t.length-1;s>=0;s--){let a=t.charCodeAt(s)-48;i&&(a*=2,a>9&&(a-=9)),r+=a,i=!i;}return r%10===0}function U(n){let t=m(n);if(!/^[12]\d{9}$/.test(t))return false;let r="80840"+t,i=0,s=false;for(let a=r.length-1;a>=0;a--){let o=r.charCodeAt(a)-48;s&&(o*=2,o>9&&(o-=9)),i+=o,s=!s;}return i%10===0}function F(n){let t=n.trim().toUpperCase();if(!/^[ABFGMPRX][A-Z9]\d{7}$/.test(t))return false;let r=o=>t.charCodeAt(2+o)-48,i=r(0)+r(2)+r(4),s=r(1)+r(3)+r(5);return (i+2*s)%10===r(6)}var w="ACDEFGHJKMNPQRTUVWXY",z="0123456789"+w;function L(n){let t=n.replace(/-/g,"").toUpperCase();if(t.length!==11)return false;let r=t.charCodeAt(0);return !(r<49||r>57||!w.includes(t[1])||!z.includes(t[2])||!/\d/.test(t[3])||!w.includes(t[4])||!z.includes(t[5])||!/\d/.test(t[6])||!w.includes(t[7])||!w.includes(t[8])||!/\d\d/.test(t.slice(9,11)))}var it={AD:24,AE:23,AL:28,AT:20,AZ:28,BA:20,BE:16,BG:22,BH:22,BR:29,BY:28,CH:21,CR:22,CY:28,CZ:24,DE:22,DK:18,DO:28,EE:20,EG:29,ES:24,FI:18,FO:18,FR:27,GB:22,GE:22,GI:23,GL:18,GR:27,GT:28,HR:21,HU:28,IE:22,IL:23,IQ:23,IS:26,IT:27,JO:30,KW:30,KZ:20,LB:28,LC:32,LI:21,LT:20,LU:20,LV:21,MC:27,MD:24,ME:22,MK:19,MR:27,MT:31,MU:30,NL:18,NO:15,PK:24,PL:28,PS:29,PT:25,QA:29,RO:24,RS:22,SA:24,SE:24,SI:19,SK:24,SM:27,ST:25,SV:28,TL:23,TN:24,TR:26,UA:29,VA:22,VG:24,XK:20};function $(n){let t=n.replace(/[\s-]+/g,"").toUpperCase();if(!/^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$/.test(t))return false;let r=it[t.slice(0,2)];if(r!==void 0&&t.length!==r)return false;let i=t.slice(4)+t.slice(0,4),s=0;for(let a=0;a<i.length;a++){let o=i.charCodeAt(a);if(o>=48&&o<=57)s=(s*10+(o-48))%97;else if(o>=65&&o<=90){let e=o-55;s=(s*100+e)%97;}else return false}return s===1}function H(n){let t=m(n);if(t.length!==10||/^(\d)\1+$/.test(t))return false;let r=0;for(let a=0;a<9;a++)r+=(t.charCodeAt(a)-48)*(10-a);let s=11-r%11;return s===11&&(s=0),s===10?false:s===t.charCodeAt(9)-48}function G(n,t){let r=n.trim(),i=/[-\s]/.test(r),s=m(r);if(s.length!==9)return false;let a=Number(s.slice(0,3)),o=Number(s.slice(3,5)),e=Number(s.slice(5,9));if(a===0||a===666||a>=900||o===0||e===0||/^(\d)\1+$/.test(s))return false;if(!i&&t){let c=t.fullText.slice(Math.max(0,t.start-36),t.start);return /\b(ssn|social[\s_-]?security|tin)\b/i.test(c)}return true}var at=[[0,1,2,3,4,5,6,7,8,9],[1,2,3,4,0,6,7,8,9,5],[2,3,4,0,1,7,8,9,5,6],[3,4,0,1,2,8,9,5,6,7],[4,0,1,2,3,9,5,6,7,8],[5,9,8,7,6,0,4,3,2,1],[6,5,9,8,7,1,0,4,3,2],[7,6,5,9,8,2,1,0,4,3],[8,7,6,5,9,3,2,1,0,4],[9,8,7,6,5,4,3,2,1,0]],ot=[[0,1,2,3,4,5,6,7,8,9],[1,5,7,6,2,8,3,0,9,4],[5,8,0,3,7,9,6,1,4,2],[8,9,1,6,0,4,3,5,2,7],[9,4,5,3,1,2,6,8,7,0],[4,2,8,6,5,7,3,9,0,1],[2,7,9,3,8,0,6,4,1,5],[7,0,4,6,9,1,3,2,5,8]];function B(n){let t=m(n);if(!/^[2-9]\d{11}$/.test(t))return false;let r=0;for(let i=0;i<t.length;i++){let s=t.charCodeAt(t.length-1-i)-48;r=at[r][ot[i%8][s]];}return r===0}function j(n){let t=m(n);if(!/^[1-9]\d{10}$/.test(t))return false;let r=new Array(10).fill(0);for(let e=0;e<10;e++)r[t.charCodeAt(e)-48]+=1;let i=r.filter(e=>e===2||e===3).length,s=Math.max(...r);if(i!==1||s>3)return false;let a=10;for(let e=0;e<10;e++){let c=(t.charCodeAt(e)-48+a)%10;c===0&&(c=10),a=c*2%11;}let o=11-a;return o===10&&(o=0),o===t.charCodeAt(10)-48}function Y(n){let t=n.split(".");if(t.length!==3)return false;let r=t[0];if(!r.startsWith("eyJ"))return false;try{let i=r.replace(/-/g,"+").replace(/_/g,"/"),s=(4-i.length%4)%4,a=atob(i+"=".repeat(s));return a.startsWith("{")&&a.includes('"')}catch{return false}}function W(n){let t=n.split(".").map(Number);if(t.length!==4)return false;let[r,i]=t;return r===void 0||i===void 0?false:r===10||r===127||r===0||r===192&&i===168||r===172&&i>=16&&i<=31||r===169&&i===254}function J(n){let t=n.split(".");if(t.length!==4)return false;for(let r of t){if(r.length===0||r.length>1&&r.startsWith("0"))return false;let i=Number(r);if(!Number.isInteger(i)||i<0||i>255)return false}return true}function q(n){if(n.length===0)return 0;let t=new Map;for(let s=0;s<n.length;s++){let a=n.charCodeAt(s);t.set(a,(t.get(a)??0)+1);}let r=0,i=n.length;for(let s of t.values()){let a=s/i;r-=a*Math.log2(a);}return r}var b=["default","secrets","hipaa","gdpr","strict"],R=["default","hipaa","gdpr","strict"],E=["hipaa","strict"],ct=["gdpr","strict"],X=[{id:"pem-private-key",category:"PRIVATE_KEY",priority:100,presets:b,pattern:/-----BEGIN (?:RSA |EC |DSA |OPENSSH |PGP |ENCRYPTED )?PRIVATE KEY-----[\s\S]{16,8192}?-----END (?:RSA |EC |DSA |OPENSSH |PGP |ENCRYPTED )?PRIVATE KEY-----/g},{id:"connection-uri-password",category:"CONNECTION_URI",priority:96,presets:b,captureGroup:1,pattern:/\b(?:postgres(?:ql)?|mysql|mariadb|mongodb(?:\+srv)?|redis(?:s)?|amqp(?:s)?|mssql|clickhouse|cockroachdb):\/\/[^:\s/@]+:([^@\s/]{3,256})@[^\s"'<>]+/gi},{id:"anthropic-key",category:"API_KEY",priority:95,presets:b,pattern:/\bsk-ant-(?:api\d{2}|admin\d{2}|oat\d{2}|[a-z0-9]+)-[A-Za-z0-9_-]{24,}\b/g},{id:"openai-key",category:"API_KEY",priority:95,presets:b,pattern:/\bsk-(?:proj|svcacct|admin)-[A-Za-z0-9_-]{24,}\b|\bsk-[A-Za-z0-9]{16,}T3BlbkFJ[A-Za-z0-9]{16,}\b/g},{id:"github-token",category:"API_KEY",priority:95,presets:b,pattern:/\b(?:gh[pousr]_[A-Za-z0-9_]{36,}|github_pat_[A-Za-z0-9]{22}_[A-Za-z0-9]{40,})\b/g},{id:"aws-access-key",category:"API_KEY",priority:94,presets:b,pattern:/\b(?:AKIA|ASIA|AROA|AIDA)[0-9A-Z]{16}\b/g},{id:"stripe-secret",category:"API_KEY",priority:94,presets:b,pattern:/\b(?:sk_live|rk_live|whsec)_[A-Za-z0-9]{20,}\b/g},{id:"google-api-key",category:"API_KEY",priority:93,presets:b,pattern:/\bAIza[0-9A-Za-z_-]{35}\b/g},{id:"slack-token",category:"TOKEN",priority:93,presets:b,pattern:/\bxox[baprs]-[0-9A-Za-z-]{14,}\b|https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]+/g},{id:"discord-webhook",category:"SECRET",priority:92,presets:b,pattern:/https:\/\/discord(?:app)?\.com\/api\/webhooks\/\d{16,22}\/[A-Za-z0-9_-]{40,}/g},{id:"provider-prefixed-keys",category:"API_KEY",priority:92,presets:b,pattern:/\b(?:hf_[A-Za-z0-9]{30,}|gsk_[A-Za-z0-9]{36,}|xai-[A-Za-z0-9]{36,}|pplx-[A-Za-z0-9]{36,}|sbp_[A-Za-z0-9]{36,}|sb_secret_[A-Za-z0-9_-]{24,}|re_[A-Za-z0-9_]{24,}|npm_[A-Za-z0-9]{36}|pypi-AgEIcHlwaS5vcmc[A-Za-z0-9_-]{50,}|SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43})\b/g},{id:"jwt-token",category:"JWT",priority:90,presets:b,pattern:/\beyJ[A-Za-z0-9_-]{6,}\.eyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{8,}\b/g,validate:n=>Y(n)},{id:"bearer-auth-header",category:"TOKEN",priority:88,presets:b,captureGroup:1,pattern:/\b(?:Authorization|Proxy-Authorization)\s*[:=]\s*["']?(?:Bearer|Basic|Token)\s+([A-Za-z0-9._~+/=-]{12,})["']?/gi},{id:"contextual-secret-assignment",category:"SECRET",priority:72,presets:b,captureGroup:1,pattern:/\b(?:api[_-]?key|secret[_-]?key|access[_-]?token|refresh[_-]?token|auth[_-]?token|client[_-]?secret|private[_-]?key|aws_secret_access_key|password|passwd|pwd|signing[_-]?secret)\b\s*[:=]\s*["']?([^\s"',;}{]{10,128})["']?/gi,validate:n=>!n.startsWith("[")&&!n.startsWith("<")&&q(n)>=2.8},{id:"medicare-mbi",category:"MBI",priority:84,presets:E,pattern:/\b[1-9][AC-HJKMNP-RT-Y][0-9AC-HJKMNP-RT-Y]-?\d[AC-HJKMNP-RT-Y][0-9AC-HJKMNP-RT-Y]-?\d[AC-HJKMNP-RT-Y]{2}\d{2}\b/gi,validate:n=>L(n)},{id:"us-dea",category:"DEA",priority:83,presets:E,pattern:/\b[ABFGMPRX][A-Z9]\d{7}\b/g,validate:n=>F(n)},{id:"us-npi",category:"NPI",priority:80,presets:E,contextWindow:40,contextRegex:/\b(?:npi|provider|prescriber|practitioner|physician)\b/i,pattern:/\b[12]\d{9}\b/g,validate:n=>U(n)},{id:"uk-nhs-number",category:"NHS",priority:80,presets:["hipaa","gdpr","strict"],contextWindow:40,contextRegex:/\b(?:nhs|patient|health|care|medical)\b/i,pattern:/\b\d{3}[-\s]?\d{3}[-\s]?\d{4}\b/g,validate:n=>H(n)},{id:"medical-record-number",category:"MRN",priority:78,presets:E,captureGroup:1,pattern:/\b(?:mrn|medical[\s_-]?record(?:[\s_-]?number)?|patient[\s_-]?id)\s*[:=#]?\s*([A-Z0-9-]{5,20})\b/gi},{id:"iban",category:"IBAN",priority:84,presets:R,pattern:/\b[A-Z]{2}\d{2}(?:[\s-]?[A-Z0-9]){11,30}\b/g,validate:n=>$(n)},{id:"credit-card",category:"CREDIT_CARD",priority:82,presets:R,pattern:/\b(?:\d[ -]?){13,18}\d\b/g,validate:n=>{let t=n.replace(/\D/g,"");return /^(?:4\d{12}(?:\d{3})?(?:\d{3})?|5[1-5]\d{14}|2(?:2[2-9]|[3-6]\d|7[01]|720)\d{12}|3[47]\d{13}|6(?:011|5\d\d)\d{12}|3(?:0[0-5]|[68]\d)\d{11}|(?:2131|1800|35\d{3})\d{11})$/.test(t)&&K(t)}},{id:"us-ssn",category:"SSN",priority:81,presets:R,pattern:/\b\d{3}[-\s]\d{2}[-\s]\d{4}\b|\b\d{9}\b/g,validate:(n,t)=>G(n,t)},{id:"aadhaar-in",category:"AADHAAR",priority:76,presets:["gdpr","strict"],contextWindow:40,contextRegex:/\b(?:aadhaar|aadhar|uidai)\b/i,pattern:/\b[2-9]\d{3}[-\s]?\d{4}[-\s]?\d{4}\b/g,validate:n=>B(n)},{id:"de-tax-id",category:"TAX_ID",priority:76,presets:ct,contextWindow:45,contextRegex:/\b(?:steuer|tax|tin|idnr|identifikationsnummer)\b/i,pattern:/\b[1-9]\d{10}\b/g,validate:n=>j(n)},{id:"email",category:"EMAIL",priority:75,presets:R,pattern:/\b[A-Za-z0-9._%+-]{1,64}@(?:[A-Za-z0-9-]{1,63}\.)+[A-Za-z]{2,24}\b/g},{id:"phone",category:"PHONE",priority:65,presets:R,pattern:/(?:\+\d{1,3}[-.\s]?)?(?:\(\d{2,4}\)[-.\s]?|\b\d{3}[-.\s])\d{3,4}[-.\s]\d{4}\b|\+\d{1,3}[-.\s]?\d{2,4}[-.\s]?\d{3,4}[-.\s]?\d{3,4}\b/g,validate:n=>{let t=n.replace(/\D/g,"");return t.length>=10&&t.length<=15&&!/^(\d)\1+$/.test(t)}},{id:"ipv4",category:"IP_ADDRESS",priority:60,presets:R,pattern:/\b(?:25[0-5]|2[0-4]\d|1?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|1?\d?\d)){3}\b/g,validate:n=>J(n)},{id:"ipv6",category:"IP_ADDRESS",priority:58,presets:["hipaa","gdpr","strict"],pattern:/\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b|\b(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}\b/g},{id:"mac-address",category:"MAC_ADDRESS",priority:58,presets:["hipaa","gdpr","strict"],pattern:/\b(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}\b/g},{id:"labeled-person-name",category:"PERSON",priority:55,presets:["hipaa","strict"],captureGroup:1,pattern:/\b(?:Patient(?:\s+Name)?|Dr\.|Doctor|Clinician|Provider|Mr\.|Mrs\.|Ms\.|Full\s+Name|Beneficiary)\s*[:.]?\s*([A-Z][a-z]{1,24}(?:\s+[A-Z]\.?)?(?:\s+[A-Z][a-z]{1,24}){1,2})/g},{id:"dob-or-clinical-date",category:"DATE",priority:52,presets:E,contextWindow:40,contextRegex:/\b(?:dob|birth|born|admit(?:ted)?|discharg(?:e|ed)|visit|encounter|date)\b/i,pattern:/\b(?:\d{4}-\d{2}-\d{2}|(?:0?[1-9]|1[0-2])[/-](?:0?[1-9]|[12]\d|3[01])[/-](?:19|20)\d{2})\b/g}];var ut=/^(?:password|passwd|pwd|passphrase|secret|api[_-]?key|access[_-]?token|refresh[_-]?token|auth[_-]?token|authorization|cookie|set-cookie|x-api-key|client[_-]?secret|private[_-]?key|ssn|social[_-]?security(?:[_-]?number)?|cvv|cvc|pin|iban|dob|birth[_-]?date|mrn)$/i,lt=/\[[A-Z_]+_\d+(?:#[a-f0-9]{4,8})?\]|<[A-Z_]+_\d+(?:#[a-f0-9]{4,8})?>/g;function Q(n){let t=n.toLowerCase();return t.includes("ssn")||t.includes("social")?"SSN":t.includes("iban")?"IBAN":t.includes("mrn")?"MRN":t.includes("dob")||t.includes("birth")?"DATE":t.includes("password")||t.includes("passwd")||t.includes("secret")||t==="cvv"||t==="cvc"||t==="pin"?"SECRET":t.includes("token")||t==="authorization"||t==="cookie"||t==="set-cookie"?"TOKEN":t.includes("key")?"API_KEY":"CUSTOM"}function dt(n){let t=n.preset??"default",r=n.rules?[...n.rules]:X.filter(a=>a.presets.includes(t)),s=[...(n.customRules??[]).map(a=>({id:a.id,category:a.category??"CUSTOM",pattern:a.pattern,captureGroup:a.captureGroup,priority:a.priority??85,presets:["default","secrets","hipaa","gdpr","strict"],validate:a.validate})),...r];if(n.categories?.length){let a=new Set(n.categories);s=s.filter(o=>a.has(o.category));}if(n.excludeCategories?.length){let a=new Set(n.excludeCategories);s=s.filter(o=>!a.has(o.category));}return s}function ft(n,t){let r=[];for(let i of t){if(!i||i.length<4)continue;let s=0;for(;;){let a=n.indexOf(i,s);if(a===-1)break;r.push({id:"literal-secret",category:"SECRET",priority:99,start:a,end:a+i.length,value:i}),s=a+i.length;}}return r}function tt(n,t,r){let i=[],s=r.allowlist?new Set(r.allowlist):void 0,a=r.redactPrivateIps??(r.preset==="strict"||r.preset==="hipaa");r.literals?.length&&i.push(...ft(n,r.literals));for(let e of t){let c=e.pattern.flags.includes("g")?e.pattern.flags:e.pattern.flags+"g",f=new RegExp(e.pattern.source,c),g;for(;(g=f.exec(n))!==null;){if(g[0].length===0){f.lastIndex+=1;continue}let u=g.index,l=g[0];if(e.captureGroup!==void 0&&g[e.captureGroup]!==void 0){let p=g[e.captureGroup],h=g[0].indexOf(p);h!==-1&&(u=g.index+h,l=p);}let d=u+l.length;if(!s?.has(l)&&!(e.id==="ipv4"&&!a&&W(l))){if(e.contextRegex){let p=e.contextWindow??40,h=n.slice(Math.max(0,u-p),u),x=n.slice(d,Math.min(n.length,d+p));if(!e.contextRegex.test(h)&&!e.contextRegex.test(x))continue}if(e.validate){let p={fullText:n,match:g,start:u,end:d,value:l};if(!e.validate(l,p))continue}i.push({id:e.id,category:e.category,priority:e.priority,start:u,end:d,value:l});}}}i.sort((e,c)=>{if(c.priority!==e.priority)return c.priority-e.priority;let f=c.end-c.start-(e.end-e.start);return f!==0?f:e.start-c.start});let o=[];for(let e of i){let c=false;for(let f of o)if(e.start<f.end&&e.end>f.start){c=true;break}c||o.push(e);}return o.sort((e,c)=>e.start-c.start),o}var P=class n{options;rules;tokenFormat;vaultKey;sensitiveKeyRe;forward=new Map;reverse=new Map;counters=new Map;reservedTokens=new Set;_version=0;constructor(t={}){this.options=t,this.rules=dt(t),this.tokenFormat=t.tokenFormat??"bracket",this.vaultKey=t.secret??Z(16),this.sensitiveKeyRe=t.sensitiveKeys?.length?new RegExp(`^(?:${t.sensitiveKeys.map(r=>r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|")})$`,"i"):ut;}get version(){return this._version}fingerprint(t){return I(this.vaultKey,t,12)}reserveExistingTokens(t){let r=new RegExp(lt.source,"g"),i;for(;(i=r.exec(t))!==null;)this.reverse.has(i[0])||this.reservedTokens.add(i[0]);}tokenize(t,r){let i=`${t}:${r}`,s=this.forward.get(i);if(s!==void 0)return s;if(this.tokenFormat==="mask")return (this.options.maskChar??"*").repeat(Math.min(Math.max(r.length,4),16));if(this.tokenFormat==="hash"){let e=I(this.vaultKey,i,8),c=`[${t}:${e}]`;return this.forward.set(i,c),this.reverse.set(c,{category:t,value:r}),this._version+=1,c}let a=this.counters.get(t)??0,o;do if(a+=1,this.tokenFormat==="angle")o=`<${t}_${a}>`;else if(this.tokenFormat==="signed"){let e=I(this.vaultKey,`${t}:${a}:${r}`,4);o=`[${t}_${a}#${e}]`;}else o=`[${t}_${a}]`;while(this.reservedTokens.has(o)||this.reverse.has(o));return this.counters.set(t,a),this.forward.set(i,o),this.reverse.set(o,{category:t,value:r}),this._version+=1,o}scan(t){return typeof t!="string"||t.length===0?[]:tt(t,this.rules,this.options).map(i=>({id:i.id,category:i.category,start:i.start,end:i.end,token:`[${i.category}]`,length:i.value.length,fingerprint:V(i.value,12)}))}redactText(t){if(typeof t!="string"||t.length===0)return {value:t,findings:[],count:0};this.reserveExistingTokens(t);let r=tt(t,this.rules,this.options);if(r.length===0)return {value:t,findings:[],count:0};let i="",s=0,a=[];for(let o of r){i+=t.slice(s,o.start);let e=this.tokenize(o.category,o.value);i+=e,s=o.end,a.push({id:o.id,category:o.category,start:o.start,end:o.end,token:e,length:o.value.length,fingerprint:this.fingerprint(o.value)});}return i+=t.slice(s),{value:i,findings:a,count:a.length}}redactObject(t){let r=[],i=this.options.maxDepth??32,s=new WeakMap,a=(e,c,f)=>{if(e==null)return e;if(typeof e=="string"){if(f&&this.sensitiveKeyRe.test(f)&&e.length>0&&!this.reverse.has(e)){let l=Q(f),d=this.tokenize(l,e);return r.push({id:"sensitive-key",category:l,start:0,end:e.length,token:d,length:e.length,fingerprint:this.fingerprint(e)}),d}let u=this.redactText(e);return u.count>0&&r.push(...u.findings),u.value}if(typeof e!="object")return e;if(c>=i)return "[MAX_DEPTH_TRUNCATED]";if(s.has(e))return s.get(e);if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return new RegExp(e.source,e.flags);if(e instanceof URL){let u=new URL(e.toString());u.password&&(u.password=this.tokenize("SECRET",u.password));let l=[];u.searchParams.forEach((d,p)=>{l.push([p,d]);});for(let[d,p]of l)if(this.sensitiveKeyRe.test(d)&&p)u.searchParams.set(d,this.tokenize(Q(d),p));else {let h=this.redactText(p);h.count>0&&(r.push(...h.findings),u.searchParams.set(d,h.value));}return u}if(typeof Headers<"u"&&e instanceof Headers){let u=new Headers;return e.forEach((l,d)=>{u.set(d,a(l,c+1,d));}),u}if(e instanceof Error){let u={name:e.name,message:this.options.redactErrors!==false?a(e.message,c+1):e.message};e.stack!==void 0&&(u.stack=this.options.redactErrors!==false?a(e.stack,c+1):e.stack),"cause"in e&&e.cause!==void 0&&(u.cause=a(e.cause,c+1));for(let l of Object.keys(e))u[l]=a(e[l],c+1,l);return u}if(Array.isArray(e)){let u=[];s.set(e,u);for(let l=0;l<e.length;l++)u.push(a(e[l],c+1,f));return u}if(e instanceof Map){let u=new Map;s.set(e,u);for(let[l,d]of e.entries()){let p=typeof l=="string"?l:void 0;u.set(a(l,c+1),a(d,c+1,p));}return u}if(e instanceof Set){let u=new Set;s.set(e,u);for(let l of e.values())u.add(a(l,c+1));return u}let g={};s.set(e,g);for(let[u,l]of Object.entries(e))g[u]=a(l,c+1,u);return g};return {value:a(t,0),findings:r,count:r.length}}redact(t){return typeof t=="string"?this.redactText(t):this.redactObject(t)}restore(t){if(typeof t!="string"||t.length===0||this.reverse.size===0)return t;let i=Array.from(this.reverse.keys()).sort((a,o)=>o.length-a.length).map(a=>a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")),s=new RegExp(i.join("|"),"g");return t.replace(s,a=>this.reverse.get(a)?.value??a)}restoreObject(t){let r=new WeakMap,i=(s,a)=>{if(s==null)return s;if(typeof s=="string")return this.restore(s);if(typeof s!="object"||a>=32)return s;if(r.has(s))return r.get(s);if(Array.isArray(s)){let e=[];r.set(s,e);for(let c of s)e.push(i(c,a+1));return e}if(s instanceof Date||s instanceof RegExp||s instanceof URL)return s;let o={};r.set(s,o);for(let[e,c]of Object.entries(s))o[e]=i(c,a+1);return o};return i(t,0)}entries(){return Array.from(this.reverse.entries()).map(([t,r])=>({token:t,category:r.category,value:r.value}))}export(){let t={};for(let[r,i]of this.counters.entries())t[r]=i;return {version:1,tokenFormat:this.tokenFormat,counters:t,entries:this.entries()}}static fromJSON(t,r={}){let i=new n({...r,tokenFormat:t.tokenFormat});for(let[s,a]of Object.entries(t.counters))i.counters.set(s,a);for(let s of t.entries)i.forward.set(`${s.category}:${s.value}`,s.token),i.reverse.set(s.token,{category:s.category,value:s.value});return i._version+=1,i}clear(){this.forward.clear(),this.reverse.clear(),this.counters.clear(),this.reservedTokens.clear(),this._version+=1;}};function vt(n,t={}){let r=t.vault??new P(t),i=t.direction??"output",s=t.rehydrateToolInputs??true,a=(o,e)=>async(...c)=>{let f=[...c];if(f.length>0&&f[0]&&typeof f[0]=="object"){if(s&&i!=="input")f[0]=r.restoreObject(f[0]);else if(i==="input"||i==="both"){let d=r.redactObject(f[0]);f[0]=d.value,d.count>0&&t.onRedaction?.({toolName:o,direction:"input",count:d.count});}}let g=await e(...f);if(!g||typeof g!="object"||i==="input")return g;let u={...g},l=0;if(Array.isArray(u.content)&&(u.content=u.content.map(d=>{if(!d||typeof d!="object")return d;let p={...d};if(p.type==="text"&&typeof p.text=="string"){let h=r.redactText(p.text);l+=h.count,p.text=h.value;}else {let h=r.redactObject(p);return l+=h.count,h.value}return p})),u.structuredContent!==void 0){let d=r.redactObject(u.structuredContent);l+=d.count,u.structuredContent=d.value;}return l>0&&t.onRedaction?.({toolName:o,direction:"output",count:l}),u};if(typeof n.registerTool=="function"){let o=n.registerTool.bind(n);n.registerTool=(e,c,f)=>typeof f=="function"?o(e,c,a(e,f)):o(e,c,f);}if(typeof n.tool=="function"){let o=n.tool.bind(n);n.tool=(e,...c)=>{let f=c.length-1;if(f>=0&&typeof c[f]=="function"){let g=[...c];return g[f]=a(e,c[f]),o(e,...g)}return o(e,...c)};}if(typeof n.registerResource=="function"){let o=n.registerResource.bind(n);n.registerResource=(...e)=>{let c=e.length-1;if(c>=0&&typeof e[c]=="function"){let f=e[c],g=[...e];return g[c]=async(...u)=>{let l=await f(...u);return r.redactObject(l).value},o(...g)}return o(...e)};}return n}export{vt as guardMcpServer};
@@ -0,0 +1,8 @@
1
+ 'use strict';function S(l){let c=-1,a=new Map,h=new Set,u=new Set,t=0,s=()=>{if(l.version!==c){c=l.version,a=new Map,h=new Set,u=new Set,t=0;for(let{token:n,value:r}of l.entries())if(n){a.set(n,r),u.add(n[0]),n.length>t&&(t=n.length);for(let o=1;o<n.length;o++)h.add(n.slice(0,o));}}},e="",i=n=>{if(s(),e.length===0)return "";if(a.size===0){let f=e;return e="",f}let r="",o=0;for(;o<e.length;){let f=e[o];if(!u.has(f)){r+=f,o+=1;continue}let g=e.slice(o);if(!n&&g.length<t&&h.has(g))break;let y=Math.min(t,g.length),d;for(let p=y;p>=1;p--){let m=g.slice(0,p);if(a.has(m)){d=m;break}}d!==void 0?(r+=a.get(d),o+=d.length):(r+=f,o+=1);}return e=e.slice(o),r};return {push(n){return n?(e+=n,i(false)):""},flush(){return i(true)},async*restoreIterable(n){for await(let o of n){let f=this.push(o);f.length>0&&(yield f);}let r=this.flush();r.length>0&&(yield r);},createTransformStream(){return new TransformStream({transform:(n,r)=>{let o=this.push(n);o.length>0&&r.enqueue(o);},flush:n=>{let r=this.flush();r.length>0&&n.enqueue(r);}})}}}function x(l){let c=S(l),a="",h=(t,s=false)=>{let e=false;if(Array.isArray(t.choices)){for(let i of t.choices)if(i&&typeof i=="object"){let n=i.delta;n&&typeof n.content=="string"&&(n.content=c.push(n.content)+(s?c.flush():""),e=true);}}if(typeof t.delta=="string"&&(t.type==="text-delta"||t.type==="response.output_text.delta"||t.type==="reasoning-delta")&&(t.delta=c.push(t.delta)+(s?c.flush():""),e=true),t.delta&&typeof t.delta=="object"){let i=t.delta;typeof i.text=="string"&&(i.text=c.push(i.text)+(s?c.flush():""),e=true);}if(Array.isArray(t.candidates))for(let i of t.candidates){let n=i?.content?.parts;if(Array.isArray(n))for(let r of n)typeof r.text=="string"&&(r.text=c.push(r.text)+(s?c.flush():""),e=true);}return e},u=t=>{if(t.startsWith("0:"))try{let e=JSON.parse(t.slice(2));if(typeof e=="string")return "0:"+JSON.stringify(c.push(e))}catch{return t}if(!t.startsWith("data:"))return t;let s=t.slice(5).trim();if(s==="[DONE]"){let e=c.flush();return e.length>0?`data: ${JSON.stringify({choices:[{index:0,delta:{content:e}}]})}
2
+
3
+ `+t:t}try{let e=JSON.parse(s);if(h(e))return "data: "+JSON.stringify(e)}catch{return "data: "+c.push(s)}return t};return {push(t){a+=t;let s=a.split(`
4
+ `);return a=s.pop()??"",s.map(u).join(`
5
+ `)+(s.length>0?`
6
+ `:"")},flush(){let t="";a.length>0&&(t+=u(a),a="");let s=c.flush();return s.length>0&&(t+=`data: ${JSON.stringify({type:"text-delta",delta:s})}
7
+
8
+ `),t},createByteTransformStream(){let t=new TextDecoder,s=new TextEncoder;return new TransformStream({transform:(e,i)=>{let n=t.decode(e,{stream:true}),r=this.push(n);r.length>0&&i.enqueue(s.encode(r));},flush:e=>{let i=this.push(t.decode())+this.flush();i.length>0&&e.enqueue(s.encode(i));}})}}}exports.createSSERestorer=x;exports.createStreamRestorer=S;
@@ -0,0 +1,20 @@
1
+ import { V as Vault } from './engine-CBII6Rkn.cjs';
2
+ import { S as StreamRestorer } from './types-DZbmtyhn.cjs';
3
+
4
+ /**
5
+ * Chunk-boundary-safe reversible stream restorer.
6
+ * Handles placeholder tokens split across arbitrary chunk boundaries (e.g. "[EM" + "AIL_1]")
7
+ * as well as overlapping token prefixes (e.g. "TOK_1" vs "TOK_10") with minimal hold buffering.
8
+ */
9
+ declare function createStreamRestorer(vault: Vault): StreamRestorer;
10
+ /**
11
+ * Restores SSE payloads across OpenAI (Chat Completions & Responses),
12
+ * Anthropic Messages, Gemini, and Vercel AI SDK UI/Data streams while preserving framing.
13
+ */
14
+ declare function createSSERestorer(vault: Vault): {
15
+ push(sseChunk: string): string;
16
+ flush(): string;
17
+ createByteTransformStream(): TransformStream<Uint8Array, Uint8Array>;
18
+ };
19
+
20
+ export { createSSERestorer, createStreamRestorer };
@@ -0,0 +1,20 @@
1
+ import { V as Vault } from './engine-DXYt06CR.js';
2
+ import { S as StreamRestorer } from './types-DZbmtyhn.js';
3
+
4
+ /**
5
+ * Chunk-boundary-safe reversible stream restorer.
6
+ * Handles placeholder tokens split across arbitrary chunk boundaries (e.g. "[EM" + "AIL_1]")
7
+ * as well as overlapping token prefixes (e.g. "TOK_1" vs "TOK_10") with minimal hold buffering.
8
+ */
9
+ declare function createStreamRestorer(vault: Vault): StreamRestorer;
10
+ /**
11
+ * Restores SSE payloads across OpenAI (Chat Completions & Responses),
12
+ * Anthropic Messages, Gemini, and Vercel AI SDK UI/Data streams while preserving framing.
13
+ */
14
+ declare function createSSERestorer(vault: Vault): {
15
+ push(sseChunk: string): string;
16
+ flush(): string;
17
+ createByteTransformStream(): TransformStream<Uint8Array, Uint8Array>;
18
+ };
19
+
20
+ export { createSSERestorer, createStreamRestorer };
@@ -0,0 +1,8 @@
1
+ function S(l){let c=-1,a=new Map,h=new Set,u=new Set,t=0,s=()=>{if(l.version!==c){c=l.version,a=new Map,h=new Set,u=new Set,t=0;for(let{token:n,value:r}of l.entries())if(n){a.set(n,r),u.add(n[0]),n.length>t&&(t=n.length);for(let o=1;o<n.length;o++)h.add(n.slice(0,o));}}},e="",i=n=>{if(s(),e.length===0)return "";if(a.size===0){let f=e;return e="",f}let r="",o=0;for(;o<e.length;){let f=e[o];if(!u.has(f)){r+=f,o+=1;continue}let g=e.slice(o);if(!n&&g.length<t&&h.has(g))break;let y=Math.min(t,g.length),d;for(let p=y;p>=1;p--){let m=g.slice(0,p);if(a.has(m)){d=m;break}}d!==void 0?(r+=a.get(d),o+=d.length):(r+=f,o+=1);}return e=e.slice(o),r};return {push(n){return n?(e+=n,i(false)):""},flush(){return i(true)},async*restoreIterable(n){for await(let o of n){let f=this.push(o);f.length>0&&(yield f);}let r=this.flush();r.length>0&&(yield r);},createTransformStream(){return new TransformStream({transform:(n,r)=>{let o=this.push(n);o.length>0&&r.enqueue(o);},flush:n=>{let r=this.flush();r.length>0&&n.enqueue(r);}})}}}function x(l){let c=S(l),a="",h=(t,s=false)=>{let e=false;if(Array.isArray(t.choices)){for(let i of t.choices)if(i&&typeof i=="object"){let n=i.delta;n&&typeof n.content=="string"&&(n.content=c.push(n.content)+(s?c.flush():""),e=true);}}if(typeof t.delta=="string"&&(t.type==="text-delta"||t.type==="response.output_text.delta"||t.type==="reasoning-delta")&&(t.delta=c.push(t.delta)+(s?c.flush():""),e=true),t.delta&&typeof t.delta=="object"){let i=t.delta;typeof i.text=="string"&&(i.text=c.push(i.text)+(s?c.flush():""),e=true);}if(Array.isArray(t.candidates))for(let i of t.candidates){let n=i?.content?.parts;if(Array.isArray(n))for(let r of n)typeof r.text=="string"&&(r.text=c.push(r.text)+(s?c.flush():""),e=true);}return e},u=t=>{if(t.startsWith("0:"))try{let e=JSON.parse(t.slice(2));if(typeof e=="string")return "0:"+JSON.stringify(c.push(e))}catch{return t}if(!t.startsWith("data:"))return t;let s=t.slice(5).trim();if(s==="[DONE]"){let e=c.flush();return e.length>0?`data: ${JSON.stringify({choices:[{index:0,delta:{content:e}}]})}
2
+
3
+ `+t:t}try{let e=JSON.parse(s);if(h(e))return "data: "+JSON.stringify(e)}catch{return "data: "+c.push(s)}return t};return {push(t){a+=t;let s=a.split(`
4
+ `);return a=s.pop()??"",s.map(u).join(`
5
+ `)+(s.length>0?`
6
+ `:"")},flush(){let t="";a.length>0&&(t+=u(a),a="");let s=c.flush();return s.length>0&&(t+=`data: ${JSON.stringify({type:"text-delta",delta:s})}
7
+
8
+ `),t},createByteTransformStream(){let t=new TextDecoder,s=new TextEncoder;return new TransformStream({transform:(e,i)=>{let n=t.decode(e,{stream:true}),r=this.push(n);r.length>0&&i.enqueue(s.encode(r));},flush:e=>{let i=this.push(t.decode())+this.flush();i.length>0&&e.enqueue(s.encode(i));}})}}}export{x as createSSERestorer,S as createStreamRestorer};
@@ -0,0 +1,107 @@
1
+ type EntityCategory = 'API_KEY' | 'SECRET' | 'TOKEN' | 'JWT' | 'PRIVATE_KEY' | 'CONNECTION_URI' | 'EMAIL' | 'PHONE' | 'CREDIT_CARD' | 'IBAN' | 'SSN' | 'NPI' | 'DEA' | 'MBI' | 'NHS' | 'MRN' | 'AADHAAR' | 'TAX_ID' | 'IP_ADDRESS' | 'MAC_ADDRESS' | 'DATE' | 'AGE' | 'ZIP' | 'ADDRESS' | 'PERSON' | 'CUSTOM';
2
+ type PolicyPreset = 'default' | 'secrets' | 'hipaa' | 'gdpr' | 'strict';
3
+ type TokenFormat = 'bracket' | 'angle' | 'signed' | 'mask' | 'hash';
4
+ interface RuleMatchContext {
5
+ fullText: string;
6
+ match: RegExpExecArray;
7
+ start: number;
8
+ end: number;
9
+ value: string;
10
+ }
11
+ interface DetectorRule {
12
+ id: string;
13
+ category: EntityCategory;
14
+ pattern: RegExp;
15
+ /** Capture group index to redact instead of the full match (e.g. URI password). */
16
+ captureGroup?: number;
17
+ /** Higher priority wins when spans overlap. Range 1..100. */
18
+ priority: number;
19
+ /** Presets in which this rule is active. */
20
+ presets: readonly PolicyPreset[];
21
+ /** Optional structural/checksum verifier; must return true to accept match. */
22
+ validate?: (value: string, ctx: RuleMatchContext) => boolean;
23
+ /** Optional context gate evaluated against surrounding characters. */
24
+ contextRegex?: RegExp;
25
+ /** Lookbehind chars inspected for contextRegex (default 40). */
26
+ contextWindow?: number;
27
+ }
28
+ interface Finding {
29
+ id: string;
30
+ category: EntityCategory;
31
+ start: number;
32
+ end: number;
33
+ /** Redacted replacement token emitted into output. */
34
+ token: string;
35
+ /** Length of original value (never exposes raw secret in findings/audit). */
36
+ length: number;
37
+ /** Deterministic truncated SHA-256 fingerprint of raw value for audit trails. */
38
+ fingerprint: string;
39
+ }
40
+ interface CustomRuleInput {
41
+ id: string;
42
+ category?: EntityCategory;
43
+ pattern: RegExp;
44
+ captureGroup?: number;
45
+ priority?: number;
46
+ validate?: (value: string, ctx: RuleMatchContext) => boolean;
47
+ }
48
+ interface RedactOptions {
49
+ preset?: PolicyPreset;
50
+ categories?: readonly EntityCategory[];
51
+ excludeCategories?: readonly EntityCategory[];
52
+ rules?: readonly DetectorRule[];
53
+ customRules?: readonly CustomRuleInput[];
54
+ /** Exact literal strings (e.g. loaded from .env) to always redact. */
55
+ literals?: readonly string[];
56
+ /** JSON keys whose string values should always be redacted. */
57
+ sensitiveKeys?: readonly string[];
58
+ /** Substrings or normalized values never to redact. */
59
+ allowlist?: readonly string[];
60
+ /** Keyed secret used for HMAC fingerprints and signed tokens. */
61
+ secret?: string;
62
+ /** Placeholder format: [EMAIL_1], <EMAIL_1>, [EMAIL_1#a1b2], ***, or [EMAIL:a1b2c3d4]. */
63
+ tokenFormat?: TokenFormat;
64
+ /** Redact private/loopback IPv4 ranges like 127.0.0.1 / 10.x / 192.168.x (default false unless strict/hipaa). */
65
+ redactPrivateIps?: boolean;
66
+ /** Maximum recursion depth for object/JSON walking (default 32). */
67
+ maxDepth?: number;
68
+ /** Redact string keys inside Error stack traces and messages (default true). */
69
+ redactErrors?: boolean;
70
+ /** Fixed replacement string when tokenFormat === 'mask'. */
71
+ maskChar?: string;
72
+ }
73
+ interface RedactResult<T = string> {
74
+ value: T;
75
+ findings: Finding[];
76
+ count: number;
77
+ }
78
+ interface VaultSnapshot {
79
+ version: 1;
80
+ tokenFormat: TokenFormat;
81
+ counters: Record<string, number>;
82
+ entries: Array<{
83
+ token: string;
84
+ category: EntityCategory;
85
+ value: string;
86
+ }>;
87
+ }
88
+ interface StreamRestorer {
89
+ push(chunk: string): string;
90
+ flush(): string;
91
+ restoreIterable(source: AsyncIterable<string>): AsyncIterable<string>;
92
+ createTransformStream(): TransformStream<string, string>;
93
+ }
94
+ interface FhirRedactOptions extends RedactOptions {
95
+ /** 'hhs-2000' (17 ZIP3 prefixes) or 'conservative-union' (19 prefixes incl. 205 & 369). Default 'conservative-union'. */
96
+ zipBaseline?: 'hhs-2000' | 'conservative-union';
97
+ /** 'shift' applies deterministic patient-scoped offset; 'year-only' keeps YYYY; 'redact' tokenizes dates. Default 'shift'. */
98
+ dateStrategy?: 'shift' | 'year-only' | 'redact';
99
+ /** Deterministic seed for date shifting (if omitted, generated per vault/call). */
100
+ dateShiftDays?: number;
101
+ /** Cap ages over 89 to '90+' per HIPAA Safe Harbor (default true). */
102
+ capAgeOver89?: boolean;
103
+ /** Preserve clinical coding fields (coding, code, system, valueQuantity, unit). Default true. */
104
+ preserveClinicalCodes?: boolean;
105
+ }
106
+
107
+ export type { CustomRuleInput as C, DetectorRule as D, EntityCategory as E, FhirRedactOptions as F, PolicyPreset as P, RedactOptions as R, StreamRestorer as S, TokenFormat as T, VaultSnapshot as V, RedactResult as a, RuleMatchContext as b, Finding as c };
@@ -0,0 +1,107 @@
1
+ type EntityCategory = 'API_KEY' | 'SECRET' | 'TOKEN' | 'JWT' | 'PRIVATE_KEY' | 'CONNECTION_URI' | 'EMAIL' | 'PHONE' | 'CREDIT_CARD' | 'IBAN' | 'SSN' | 'NPI' | 'DEA' | 'MBI' | 'NHS' | 'MRN' | 'AADHAAR' | 'TAX_ID' | 'IP_ADDRESS' | 'MAC_ADDRESS' | 'DATE' | 'AGE' | 'ZIP' | 'ADDRESS' | 'PERSON' | 'CUSTOM';
2
+ type PolicyPreset = 'default' | 'secrets' | 'hipaa' | 'gdpr' | 'strict';
3
+ type TokenFormat = 'bracket' | 'angle' | 'signed' | 'mask' | 'hash';
4
+ interface RuleMatchContext {
5
+ fullText: string;
6
+ match: RegExpExecArray;
7
+ start: number;
8
+ end: number;
9
+ value: string;
10
+ }
11
+ interface DetectorRule {
12
+ id: string;
13
+ category: EntityCategory;
14
+ pattern: RegExp;
15
+ /** Capture group index to redact instead of the full match (e.g. URI password). */
16
+ captureGroup?: number;
17
+ /** Higher priority wins when spans overlap. Range 1..100. */
18
+ priority: number;
19
+ /** Presets in which this rule is active. */
20
+ presets: readonly PolicyPreset[];
21
+ /** Optional structural/checksum verifier; must return true to accept match. */
22
+ validate?: (value: string, ctx: RuleMatchContext) => boolean;
23
+ /** Optional context gate evaluated against surrounding characters. */
24
+ contextRegex?: RegExp;
25
+ /** Lookbehind chars inspected for contextRegex (default 40). */
26
+ contextWindow?: number;
27
+ }
28
+ interface Finding {
29
+ id: string;
30
+ category: EntityCategory;
31
+ start: number;
32
+ end: number;
33
+ /** Redacted replacement token emitted into output. */
34
+ token: string;
35
+ /** Length of original value (never exposes raw secret in findings/audit). */
36
+ length: number;
37
+ /** Deterministic truncated SHA-256 fingerprint of raw value for audit trails. */
38
+ fingerprint: string;
39
+ }
40
+ interface CustomRuleInput {
41
+ id: string;
42
+ category?: EntityCategory;
43
+ pattern: RegExp;
44
+ captureGroup?: number;
45
+ priority?: number;
46
+ validate?: (value: string, ctx: RuleMatchContext) => boolean;
47
+ }
48
+ interface RedactOptions {
49
+ preset?: PolicyPreset;
50
+ categories?: readonly EntityCategory[];
51
+ excludeCategories?: readonly EntityCategory[];
52
+ rules?: readonly DetectorRule[];
53
+ customRules?: readonly CustomRuleInput[];
54
+ /** Exact literal strings (e.g. loaded from .env) to always redact. */
55
+ literals?: readonly string[];
56
+ /** JSON keys whose string values should always be redacted. */
57
+ sensitiveKeys?: readonly string[];
58
+ /** Substrings or normalized values never to redact. */
59
+ allowlist?: readonly string[];
60
+ /** Keyed secret used for HMAC fingerprints and signed tokens. */
61
+ secret?: string;
62
+ /** Placeholder format: [EMAIL_1], <EMAIL_1>, [EMAIL_1#a1b2], ***, or [EMAIL:a1b2c3d4]. */
63
+ tokenFormat?: TokenFormat;
64
+ /** Redact private/loopback IPv4 ranges like 127.0.0.1 / 10.x / 192.168.x (default false unless strict/hipaa). */
65
+ redactPrivateIps?: boolean;
66
+ /** Maximum recursion depth for object/JSON walking (default 32). */
67
+ maxDepth?: number;
68
+ /** Redact string keys inside Error stack traces and messages (default true). */
69
+ redactErrors?: boolean;
70
+ /** Fixed replacement string when tokenFormat === 'mask'. */
71
+ maskChar?: string;
72
+ }
73
+ interface RedactResult<T = string> {
74
+ value: T;
75
+ findings: Finding[];
76
+ count: number;
77
+ }
78
+ interface VaultSnapshot {
79
+ version: 1;
80
+ tokenFormat: TokenFormat;
81
+ counters: Record<string, number>;
82
+ entries: Array<{
83
+ token: string;
84
+ category: EntityCategory;
85
+ value: string;
86
+ }>;
87
+ }
88
+ interface StreamRestorer {
89
+ push(chunk: string): string;
90
+ flush(): string;
91
+ restoreIterable(source: AsyncIterable<string>): AsyncIterable<string>;
92
+ createTransformStream(): TransformStream<string, string>;
93
+ }
94
+ interface FhirRedactOptions extends RedactOptions {
95
+ /** 'hhs-2000' (17 ZIP3 prefixes) or 'conservative-union' (19 prefixes incl. 205 & 369). Default 'conservative-union'. */
96
+ zipBaseline?: 'hhs-2000' | 'conservative-union';
97
+ /** 'shift' applies deterministic patient-scoped offset; 'year-only' keeps YYYY; 'redact' tokenizes dates. Default 'shift'. */
98
+ dateStrategy?: 'shift' | 'year-only' | 'redact';
99
+ /** Deterministic seed for date shifting (if omitted, generated per vault/call). */
100
+ dateShiftDays?: number;
101
+ /** Cap ages over 89 to '90+' per HIPAA Safe Harbor (default true). */
102
+ capAgeOver89?: boolean;
103
+ /** Preserve clinical coding fields (coding, code, system, valueQuantity, unit). Default true. */
104
+ preserveClinicalCodes?: boolean;
105
+ }
106
+
107
+ export type { CustomRuleInput as C, DetectorRule as D, EntityCategory as E, FhirRedactOptions as F, PolicyPreset as P, RedactOptions as R, StreamRestorer as S, TokenFormat as T, VaultSnapshot as V, RedactResult as a, RuleMatchContext as b, Finding as c };
package/llms-full.txt ADDED
@@ -0,0 +1,5 @@
1
+ # redact0 — Full API & Integration Reference
2
+
3
+ Zero runtime dependencies (`"dependencies": {}`), MIT license, synchronous pure-TS execution in Node, Deno, Bun, Cloudflare Workers, Vercel Edge, and Browsers.
4
+
5
+ ## Core
package/llms.txt ADDED
@@ -0,0 +1,16 @@
1
+ # redact0
2
+
3
+ > Zero-dependency, MIT-licensed, <25 KB reversible PII, secret, FHIR HIPAA Safe Harbor, and streaming SSE redactor for npm and PyPI.
4
+
5
+ ## Install
6
+ - JavaScript / TypeScript: `npm install redact0`
7
+ - Python (drop-in llm-guard replacement): `pip install redact0`
8
+
9
+ ## Subpath Exports (npm)
10
+ - [Core API](llms-full.txt#core): `redact(input)`, `createVault()`, `scan(text)`, `Vault.fromJSON()`
11
+ - [AI SDKs](llms-full.txt#ai): `redactMiddleware()` (Vercel AI SDK v5/v6/v7), `wrapOpenAI()`, `wrapAnthropic()`, `wrapFetch()`
12
+ - [MCP Servers](llms-full.txt#mcp): `guardMcpServer(server)` for `@modelcontextprotocol/sdk` v1 & v2
13
+ - [Streaming SSE](llms-full.txt#stream): `createStreamRestorer(vault)`, `createSSERestorer(vault)`
14
+ - [FHIR / HIPAA](llms-full.txt#fhir): `redactFHIR(bundle)` (Safe Harbor ZIP3, age 90+, deterministic date shifting)
15
+ - [Loggers](llms-full.txt#logger): `pinoRedactor()`, `winstonFormat()`, `redactAttributes()`
16
+ - [CLI & Built-in MCP](llms-full.txt#cli): `npx redact0 scan --sarif --fail-on-match`, `npx redact0 init`, `npx redact0 mcp`
package/package.json CHANGED
@@ -1,6 +1,96 @@
1
1
  {
2
2
  "name": "@rohan9024/redact0",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "1.0.0",
4
+ "description": "Zero-dependency reversible PII, secret, FHIR HIPAA Safe Harbor, and streaming SSE redactor for AI SDKs, MCP servers, Pino/Winston logs, and Edge runtimes.",
5
+ "license": "MIT",
6
+ "author": "redact0 contributors",
7
+ "keywords": [
8
+ "pii",
9
+ "redaction",
10
+ "redact",
11
+ "secrets",
12
+ "hipaa",
13
+ "phi",
14
+ "fhir",
15
+ "gdpr",
16
+ "ai-sdk",
17
+ "mcp",
18
+ "pino",
19
+ "winston",
20
+ "sse",
21
+ "streaming",
22
+ "reversible",
23
+ "zero-dependency",
24
+ "llm-security",
25
+ "openai",
26
+ "anthropic"
27
+ ],
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "engines": {
31
+ "node": ">=18.0.0"
32
+ },
33
+ "bin": {
34
+ "redact0": "./dist/cli.cjs"
35
+ },
36
+ "main": "./dist/index.cjs",
37
+ "module": "./dist/index.mjs",
38
+ "types": "./dist/index.d.ts",
39
+ "exports": {
40
+ ".": {
41
+ "types": "./dist/index.d.ts",
42
+ "import": "./dist/index.mjs",
43
+ "require": "./dist/index.cjs"
44
+ },
45
+ "./stream": {
46
+ "types": "./dist/stream.d.ts",
47
+ "import": "./dist/stream.mjs",
48
+ "require": "./dist/stream.cjs"
49
+ },
50
+ "./fhir": {
51
+ "types": "./dist/fhir.d.ts",
52
+ "import": "./dist/fhir.mjs",
53
+ "require": "./dist/fhir.cjs"
54
+ },
55
+ "./ai": {
56
+ "types": "./dist/ai.d.ts",
57
+ "import": "./dist/ai.mjs",
58
+ "require": "./dist/ai.cjs"
59
+ },
60
+ "./mcp": {
61
+ "types": "./dist/mcp.d.ts",
62
+ "import": "./dist/mcp.mjs",
63
+ "require": "./dist/mcp.cjs"
64
+ },
65
+ "./logger": {
66
+ "types": "./dist/logger.d.ts",
67
+ "import": "./dist/logger.mjs",
68
+ "require": "./dist/logger.cjs"
69
+ },
70
+ "./llms.txt": "./llms.txt",
71
+ "./package.json": "./package.json"
72
+ },
73
+ "files": [
74
+ "dist",
75
+ "llms.txt",
76
+ "llms-full.txt",
77
+ "context7.json",
78
+ "AGENTS.md",
79
+ "README.md",
80
+ "LICENSE"
81
+ ],
82
+ "dependencies": {},
83
+ "devDependencies": {
84
+ "@types/node": "^22.10.0",
85
+ "tsup": "^8.5.0",
86
+ "tsx": "^4.19.3",
87
+ "typescript": "^5.7.3"
88
+ },
89
+ "scripts": {
90
+ "build": "tsup",
91
+ "typecheck": "tsc --noEmit",
92
+ "test": "tsx --test tests/core.test.ts",
93
+ "check:size": "node -e \"const fs=require('fs'),zlib=require('zlib');const gz=zlib.gzipSync(fs.readFileSync('dist/index.mjs')).length;console.log('Core ESM gzip:',gz,'bytes');if(gz>30720)process.exit(1);\"",
94
+ "prepublishOnly": "npm run typecheck && npm run build && npm test && npm run check:size"
95
+ }
6
96
  }