@nodatachat/mcp 1.6.27 → 1.6.28

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/gate.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! @nodatachat/mcp 1.6.27 | Copyright 2026 Capsule Ltd. | FSL-1.1-ALv2 | see LICENSE.md */
1
+ /*! @nodatachat/mcp 1.6.28 | Copyright 2026 Capsule Ltd. | FSL-1.1-ALv2 | see LICENSE.md */
2
2
  import{appendFileSync as hc,copyFileSync as nh,existsSync as In,mkdirSync as vs,readdirSync as mc,readFileSync as Tn,statSync as xt,writeFileSync as gc}from"node:fs";import{homedir as Y}from"node:os";import{basename as wt,extname as Ss,isAbsolute as ne,join as _e,relative as Es,resolve as D}from"node:path";import{TextDecoder as $r}from"node:util";var H={text:[],header:[],secrets:[],table:null,amounts:null,severity:null};function $t(e){e.table&&(H.table=e.table),e.severity&&(H.severity=e.severity),e.amounts&&(H.amounts=e.amounts);for(let t of e.text??[])H.text.some(r=>r.kind===t.kind)||H.text.push(t);e.header&&!H.header.includes(e.header)&&H.header.push(e.header);for(let t of e.secrets??[])H.secrets.some(r=>r.id===t.id)||H.secrets.push(t)}function Rt(){return H.amounts?.()===!0}function De(){return H.text}function jn(){return H.header}function ve(){return H.table}function Hn(){return H.secrets}var Fe=[{id:"aws-access-key",name:"AWS Access Key",pattern:/(?:^|[^A-Z0-9])AKIA(?!X{16})[A-Z2-7]{16}(?:[^A-Z2-7]|$)/,severity:"critical"},{id:"aws-secret-key",name:"AWS Secret Key",pattern:/(?:aws_secret_access_key|aws_secret_key|secret_access_key)\s*[=:]\s*['"]?[A-Za-z0-9/+=]{40}['"]?/,severity:"critical"},{id:"gcp-api-key",name:"GCP API Key",pattern:/AIza[0-9A-Za-z_-]{35}/,severity:"critical"},{id:"gcp-service-account",name:"GCP Service Account",pattern:/"type"\s*:\s*"service_account"/,severity:"critical"},{id:"github-token",name:"GitHub Token",pattern:/gh[pousr]_[0-9a-zA-Z]{36,}/,severity:"critical"},{id:"github-fine-grained",name:"GitHub Fine-Grained Token",pattern:/github_pat_[0-9a-zA-Z_]{22,}/,severity:"critical"},{id:"gitlab-token",name:"GitLab Token",pattern:/glpat-[0-9a-zA-Z_-]{20,}/,severity:"critical"},{id:"stripe-secret",name:"Stripe Secret Key",pattern:/sk_live_[0-9a-zA-Z]{24,}/,severity:"critical"},{id:"stripe-restricted",name:"Stripe Restricted Key",pattern:/rk_live_[0-9a-zA-Z]{24,}/,severity:"critical"},{id:"slack-token",name:"Slack Token",pattern:/xox[baprs]-[0-9a-zA-Z-]{10,}/,severity:"high"},{id:"slack-webhook",name:"Slack Webhook",pattern:/hooks\.slack\.com\/services\/T[0-9A-Z]{8,}\/B[0-9A-Z]{8,}\/[0-9a-zA-Z]{24}/,severity:"high"},{id:"twilio-api-key",name:"Twilio API Key",pattern:/SK[0-9a-fA-F]{32}/,severity:"high"},{id:"sendgrid-api-key",name:"SendGrid API Key",pattern:/SG\.[0-9a-zA-Z_-]{22}\.[0-9a-zA-Z_-]{43}/,severity:"critical"},{id:"postgres-uri",name:"PostgreSQL Connection String",pattern:/postgres(?:ql)?:\/\/[^\s'"]{10,}/,severity:"critical"},{id:"mongodb-uri",name:"MongoDB Connection String",pattern:/mongodb(?:\+srv)?:\/\/[^\s'"]{10,}/,severity:"critical"},{id:"redis-uri",name:"Redis Connection String",pattern:/redis(?:s)?:\/\/[^\s'"]{10,}/,severity:"high"},{id:"openai-key",name:"OpenAI API Key",pattern:/sk-[0-9a-zA-Z]{20,}T3BlbkFJ[0-9a-zA-Z]{20,}/,severity:"critical"},{id:"openai-project-key",name:"OpenAI API Key",pattern:/sk-(?:proj|svcacct|admin)-[0-9A-Za-z_-]{40,}/,severity:"critical"},{id:"anthropic-key",name:"Anthropic API Key",pattern:/sk-ant-[0-9a-zA-Z_-]{40,}/,severity:"critical"},{id:"firebase-key",name:"Firebase API Key",pattern:/AIza[0-9A-Za-z_-]{35}/,severity:"high"},{id:"supabase-key",name:"Supabase Service Key",pattern:/eyJ[0-9a-zA-Z_-]{100,}/,severity:"critical"},{id:"supabase-access-token",name:"Supabase Access Token",pattern:/\bsbp_[0-9a-f]{40}\b/,severity:"critical"},{id:"supabase-secret-key",name:"Supabase Secret Key",pattern:/\bsb_secret_[0-9A-Za-z_-]{20,}/,severity:"critical"},{id:"private-key",name:"Private Key",pattern:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/,severity:"critical"},{id:"jwt-secret",name:"JWT/Generic Secret",pattern:/(?:jwt_secret|JWT_SECRET|secret_key|SECRET_KEY|api_secret|API_SECRET)\s*[=:]\s*['"][^'"]{8,}['"]/,severity:"high"},{id:"password-in-code",name:"Password in Code",pattern:/(?:password|passwd|pwd)\s*[=:]\s*['"][^'"]{8,}['"]/,severity:"high"},{id:"bearer-token",name:"Bearer Token in Code",pattern:/['"]Bearer\s+[0-9a-zA-Z._-]{20,}['"]/,severity:"high"}];function Se(){let e=Hn().filter(t=>!Fe.some(r=>r.id===t.id));return[...Fe,...e]}var eo=[{pattern:/^(full_?name|first_?name|last_?name|spouse_?name|beneficiary_?name)$/i,type:"name",label:"Person name"},{pattern:/^(email|e_?mail|email_?address)$/i,type:"email",label:"Email address"},{pattern:/^(phone|mobile|telephone|phone_?number|cell_?phone)$/i,type:"phone",label:"Phone number"},{pattern:/^(id_?number|identity|ssn|social_?security|national_?id|teudat_?zehut)$/i,type:"id",label:"ID number"},{pattern:/^(address|street_?address|home_?address)$/i,type:"address",label:"Address"},{pattern:/^(date_?of_?birth|dob|birth_?date|birthday)$/i,type:"dob",label:"Date of birth"},{pattern:/^(bank_?account|iban|account_?number|bank_?details|routing_?number)$/i,type:"financial",label:"Bank account"},{pattern:/^(credit_?card|card_?number|cvv|cc_?number)$/i,type:"financial",label:"Credit card"},{pattern:/^(salary|income|commission|premium|compensation)$/i,type:"financial",label:"Salary / income"},{pattern:/^(medical_?info|health_?conditions|diagnosis|medication|prescription)$/i,type:"medical",label:"Medical"},{pattern:/^(passport|passport_?number|passport_?id)$/i,type:"id",label:"Passport"},{pattern:/^(driver_?license|drivers_?license|dl_?number)$/i,type:"id",label:"Driver license"},{pattern:/^(tax_?id|tin|vat_?number|ein)$/i,type:"financial",label:"Tax ID"},{pattern:/^(insurance_?number|policy_?number|member_?id)$/i,type:"id",label:"Insurance/Policy"},{pattern:/^(biometric|fingerprint|face_?id|retina)$/i,type:"biometric",label:"Biometric"},{pattern:/^(latitude|longitude|lat|lng|geo_?location|coordinates)$/i,type:"location",label:"Geolocation"}],to=[{pattern:/^(?:שם|שם_מלא|שם פרטי|שם_פרטי|שם משפחה|שם_משפחה|שם הלקוח|שם בן זוג|שם המבוטח|שם המוטב|שם הילד|שם הקטין)$/i,type:"name",label:"\u05E9\u05DD \u05D0\u05D3\u05DD"},{pattern:/^(?:ת"ז|ת\.ז|ת ז|תז|תעודת זהות|תעודת_זהות|מספר זהות|מס' זהות|teudat_zehut|tz|israeli_id|il_id)$/i,type:"id",label:"\u05EA\u05E2\u05D5\u05D3\u05EA \u05D6\u05D4\u05D5\u05EA"},{pattern:/^(?:דרכון|מספר דרכון|רישיון נהיגה|רישיון_נהיגה|רשיון נהיגה)$/i,type:"id",label:"\u05D3\u05E8\u05DB\u05D5\u05DF/\u05E8\u05D9\u05E9\u05D9\u05D5\u05DF"},{pattern:/^(?:מייל|דוא"ל|דוא_ל|דואר אלקטרוני|אימייל|כתובת מייל)$/i,type:"email",label:"\u05D3\u05D5\u05D0\u05E8 \u05D0\u05DC\u05E7\u05D8\u05E8\u05D5\u05E0\u05D9"},{pattern:/^(?:טלפון|טל'|נייד|פלאפון|סלולרי|מספר טלפון|טלפון נייד)$/i,type:"phone",label:"\u05DE\u05E1\u05E4\u05E8 \u05D8\u05DC\u05E4\u05D5\u05DF"},{pattern:/^(?:כתובת|כתובת מגורים|רחוב|מס בית|עיר|ישוב|יישוב|מיקוד|כתובת מלאה|מען)$/i,type:"address",label:"\u05DB\u05EA\u05D5\u05D1\u05EA"},{pattern:/^(?:תאריך לידה|ת לידה|תאריך הולדת|יום הולדת|גיל)$/i,type:"dob",label:"\u05EA\u05D0\u05E8\u05D9\u05DA \u05DC\u05D9\u05D3\u05D4"},{pattern:/^(?:חשבון בנק|מספר חשבון|מס חשבון|סניף|iban|iban_il)$/i,type:"financial",label:"\u05D7\u05E9\u05D1\u05D5\u05DF \u05D1\u05E0\u05E7"},{pattern:/^(?:כרטיס אשראי|מספר אשראי|cvv|אשראי)$/i,type:"financial",label:"\u05DB\u05E8\u05D8\u05D9\u05E1 \u05D0\u05E9\u05E8\u05D0\u05D9"},{pattern:/^(?:שכר|משכורת|הכנסה|פרמיה|שכר ברוטו|שכר נטו|תגמול|בונוס|פיצוי)$/i,type:"financial",label:"\u05E9\u05DB\u05E8/\u05D4\u05DB\u05E0\u05E1\u05D4"},{pattern:/^(?:אבחון|אבחנה|מחלה|תרופה|מרשם|בדיקה רפואית|מצב רפואי|חיסון|רגישות|אלרגיה|סוג דם)$/i,type:"medical",label:"\u05DE\u05D9\u05D3\u05E2 \u05E8\u05E4\u05D5\u05D0\u05D9"},{pattern:/^(?:מספר פוליסה|מס פוליסה|פוליסה|מספר חבר|מספר ביטוח)$/i,type:"id",label:"\u05E4\u05D5\u05DC\u05D9\u05E1\u05D4/\u05D7\u05D1\u05E8\u05D5\u05EA"},{pattern:/^(?:שם הילד|תעודת זהות של ילד|ילדים|קטין|מספר ילדים|תעודת לידה)$/i,type:"minor_data",label:"\u05DE\u05D9\u05D3\u05E2 \u05E2\u05DC \u05E7\u05D8\u05D9\u05DF"},{pattern:/^(?:דת|לאום|מין|נטייה מינית|השקפה פוליטית|מצב משפחתי|עדה|מוצא)$/i,type:"sensitive_personal",label:"\u05DE\u05D9\u05D3\u05E2 \u05D0\u05D9\u05E9\u05D9 \u05E8\u05D2\u05D9\u05E9"},{pattern:/^(?:מספר רכב|מס רכב|לוחית רישוי|מספר רישוי)$/i,type:"tracking",label:"\u05DE\u05E1\u05E4\u05E8 \u05E8\u05DB\u05D1"}],no=/^(id|uuid|created_?at|updated_?at|deleted_?at|status|type|category|description|title|slug|url|path|key|value|enabled|active|public|version|metadata|config|settings|data|content|note|comment|label|color|icon)$/i,ro=/^שם[ _](?:ה)?(?:קובץ|מוצר|פריט|חברה|ארגון|עסק|פרויקט|גיליון|טבלה|שדה|קטגוריה|סניף|בנק|עיר|רחוב|ישוב|יישוב|מסמך|תוכנית|חבילה|קורס|מחלקה|אתר|דומיין|מותג|ספק|שירות|תפקיד)$|^(file|product|item|company|org|organization|project|sheet|table|field|category|branch|bank|city|street|document|plan|course|department|site|domain|brand|vendor|service|role)[ _-]?name$/i;function Ee(e){if(!e)return null;let t=e.trim();if(no.test(t)||/^name$/i.test(t)||/^\[[A-Z_]+(?:-\d+)?\]$/.test(t))return null;let r=t.replace(/[\s-]+/g,"_");for(let n of[...to,...eo])if(n.pattern.test(t)||n.pattern.test(r))return{type:n.type,label:n.label};if(ro.test(t))return null;if(/^שם[ _][\u0590-\u05FF"'׳ ]{2,20}$/.test(t))return{type:"name",label:"\u05E9\u05DD \u05D0\u05D3\u05DD"};if(/^(customer|client|employee|inspector|supervisor|contact|person|patient|user|owner|manager|agent|member|driver|tenant|student|parent|beneficiary|insured)_?(full_?)?name$/i.test(r))return{type:"name",label:"Person name"};for(let n of jn()){let s=n(t);if(s)return{type:s.type,label:s.label}}return null}function Un(e){let t=String(e??"").replace(/\D/g,"");if(t.length===0||t.length>9)return!1;let r=t.padStart(9,"0"),n=0;for(let s=0;s<9;s++){let o=parseInt(r[s]??"0",10)*(s%2+1);o>9&&(o-=9),n+=o}return n%10===0&&parseInt(r,10)>0}function so(e){let t=String(e??"").replace(/\D/g,"");if(t.length<12||t.length>19)return!1;let r=0,n=!1;for(let s=t.length-1;s>=0;s-=1){let o=parseInt(t[s]??"0",10);n&&(o*=2,o>9&&(o-=9)),r+=o,n=!n}return r%10===0}function Bn(e){let t=String(e??"").replace(/\s/g,"").toUpperCase();if(!/^[A-Z]{2}\d{2}[A-Z0-9]{10,30}$/.test(t))return!1;let r=t.slice(4)+t.slice(0,4),n=0;for(let s of r){let o=s>="A"&&s<="Z"?String(s.charCodeAt(0)-55):s;for(let i of o)n=(n*10+Number(i))%97}return n===1}var It="(?<!\\d)(?<!\\d[.,])",Tt="(?!\\d)(?![.,]\\d)",Ct=[{subkind:"israeli_id",severity:"high",pattern:new RegExp(`${It}(?:\\d{8}-\\d|\\d{9})${Tt}`,"g"),validate:Un,hint:"Israeli national ID (check digit verified) in plaintext. Encrypt the column or mask it at rest."},{subkind:"credit_card",severity:"critical",pattern:new RegExp(`${It}[2-6][ -]?(?:\\d[ -]?){11,17}\\d${Tt}`,"g"),validate:so,hint:"Payment card number (Luhn verified) in plaintext. This is PCI scope."},{subkind:"iban",severity:"high",pattern:/\b[A-Z]{2}\d{2}(?: ?[A-Z0-9]{4}){2,7}(?: ?[A-Z0-9]{1,4})?\b/g,validate:Bn,hint:"Bank account in IBAN form (mod-97 verified) in plaintext."},{subkind:"israeli_phone",severity:"medium",pattern:new RegExp(`${It}(?:\\+972[- ]?|0)(?:[57]\\d|[2-489])[- ]?\\d{3}[- ]?\\d{4}${Tt}`,"g"),validate:e=>{let t=e.replace(/\D/g,"").replace(/^972/,"0");return/^0[57]\d{8}$/.test(t)?!0:/^0[2-489]\d{7}$/.test(t)&&(/[- ]/.test(e)||e.startsWith("+972"))},hint:"Israeli phone number in plaintext."}];function Me(e,t){let r=[],n="",s=!1;for(let o=0;o<e.length;o++){let i=e[o];s?i==='"'&&e[o+1]==='"'?(n+='"',o++):i==='"'?s=!1:n+=i:i==='"'?s=!0:i===t?(r.push(n),n=""):n+=i}return r.push(n),r}import{inflateRawSync as ei}from"node:zlib";import{inflateSync as zn}from"node:zlib";var je=new Set([".pdf"]),Wn=8*1024*1024;function Kn(e){let t=e.toString("latin1"),r=new Map,n=/(\d+)\s+(\d+)\s+obj\b/g,s;for(;(s=n.exec(t))!==null;){let o=Number(s[1]),i=n.lastIndex,a=t.indexOf("endobj",i);if(a<0)continue;let c=t.indexOf("stream",i),l,f=null;if(c>=0&&c<a){l=t.slice(i,c);let d=c+6;t[d]==="\r"&&(d+=1),t[d]===`
3
3
  `&&(d+=1);let h=t.indexOf("endstream",d);h>d&&(f=e.subarray(d,h))}else l=t.slice(i,a);r.set(o,{num:o,dict:l,stream:f})}for(let o of[...r.values()]){if(!o.stream||!/\/Type\s*\/ObjStm\b/.test(o.dict))continue;let i=He(o),a=Number(/\/N\s+(\d+)/.exec(o.dict)?.[1]??0),c=Number(/\/First\s+(\d+)/.exec(o.dict)?.[1]??-1);if(i===null||!a||c<0)continue;let l=i.slice(0,c).trim().split(/\s+/).map(Number);for(let f=0;f<a;f+=1){let d=l[2*f],h=l[2*f+1];if(d===void 0||h===void 0||Number.isNaN(d)||Number.isNaN(h))break;let p=f+1<a?l[2*(f+1)+1]:void 0,g=i.slice(c+h,p!==void 0?c+p:void 0);r.has(d)||r.set(d,{num:d,dict:g,stream:null})}}return r}function Pt(e){let t=[...e.replace(/\s+/g,"")];if(t.length<40)return!1;let r=0,n=0;for(let s of t){let o=s.codePointAt(0)??0;o<32||o>=127&&o<=191||o===65533||o>=57344&&o<=63743?r+=1:/[\p{L}\p{N}]/u.test(s)&&(n+=1)}return r/t.length>.2||n/t.length<.25}function oo(e){let t=e.toString("latin1").replace(/\s/g,"");t.startsWith("<~")&&(t=t.slice(2));let r=t.indexOf("~>");r>=0&&(t=t.slice(0,r));let n=[],s=0,o=0;for(let i of t){if(i==="z"&&o===0){n.push(0,0,0,0);continue}let a=i.charCodeAt(0)-33;if(a<0||a>84)return null;s=s*85+a,o+=1,o===5&&(n.push(s>>>24&255,s>>>16&255,s>>>8&255,s&255),s=0,o=0)}if(o>0){for(let a=o;a<5;a+=1)s=s*85+84;let i=[s>>>24&255,s>>>16&255,s>>>8&255,s&255];for(let a=0;a<o-1;a+=1)n.push(i[a]??0)}return Buffer.from(n)}function io(e){let t=e.toString("latin1").replace(/\s/g,"").split(">")[0]??"",r=t.length%2?t+"0":t;return/^[0-9A-Fa-f]*$/.test(r)?Buffer.from(r,"hex"):null}function ao(e){let t=/\/Filter\s*(\[[^\]]*\]|\/\w+)/.exec(e);return!t||!t[1]?[]:[...t[1].matchAll(/\/(\w+)/g)].map(r=>r[1]??"")}function He(e,t){if(!e.stream)return null;let r=e.stream;for(let n of ao(e.dict)){let s=null;if(n==="FlateDecode")try{s=t!==void 0?zn(r,{maxOutputLength:Math.max(1,t)}):zn(r)}catch{return null}else if(n==="ASCII85Decode")s=oo(r);else if(n==="ASCIIHexDecode")s=io(r);else return null;if(s===null)return null;r=s}return r.toString("latin1")}function co(e){let t=new Map,r=1,n=/begincodespacerange([\s\S]*?)endcodespacerange/.exec(e);if(n&&n[1]){let c=/<([0-9A-Fa-f]+)>/.exec(n[1]);c&&c[1]&&c[1].length>=4&&(r=2)}let s=c=>{let l="";for(let f=0;f+3<c.length+1;f+=4){let d=parseInt(c.slice(f,f+4),16);Number.isFinite(d)&&d>0&&(l+=String.fromCharCode(d))}return l},o=/beginbfchar([\s\S]*?)endbfchar/g,i;for(;(i=o.exec(e))!==null;){let c=/<([0-9A-Fa-f]+)>\s*<([0-9A-Fa-f]*)>/g,l;for(;(l=c.exec(i[1]??""))!==null;)t.set(parseInt(l[1]??"0",16),s(l[2]??""))}let a=/beginbfrange([\s\S]*?)endbfrange/g;for(;(i=a.exec(e))!==null;){let c=i[1]??"",l=/<([0-9A-Fa-f]+)>\s*<([0-9A-Fa-f]+)>\s*<([0-9A-Fa-f]*)>/g,f;for(;(f=l.exec(c))!==null;){let d=parseInt(f[1]??"0",16),h=parseInt(f[2]??"0",16),p=parseInt((f[3]??"0").slice(0,4)||"0",16);if(!(h-d>65535))for(let g=d;g<=h;g+=1)t.set(g,String.fromCharCode(p+(g-d)))}}return{map:t,bytes:r}}function lo(e){let t=new Map,r=[],n=[];for(let o of e.values()){for(let i of o.dict.matchAll(/\/Font\s*<<([\s\S]*?)>>/g))i[1]&&n.push(i[1]);for(let i of o.dict.matchAll(/\/Font\s+(\d+)\s+\d+\s+R/g)){let a=e.get(Number(i[1]));a&&n.push(a.dict)}}let s=new Set;for(let o of n){let i=/\/([^\s/<>[\]()]+)\s+(\d+)\s+\d+\s+R/g,a;for(;(a=i.exec(o))!==null;){let c=`${a[1]}#${a[2]}`;s.has(c)||(s.add(c),r.push([a[1]??"",Number(a[2])]))}}for(let[o,i]of r){let a=e.get(i);if(!a)continue;let c=null,l=/\/ToUnicode\s+(\d+)\s+\d+\s+R/.exec(a.dict);if(l){let d=e.get(Number(l[1])),h=d?He(d):null;h&&(c=co(h))}if(c||(c=po(a.dict,e)),!c)continue;let f=t.get(o)??[];f.push(c),t.set(o,f)}return t}var uo=["alef","bet","gimel","dalet","he","vav","zayin","het","tet","yod","finalkaf","kaf","lamed","finalmem","mem","finalnun","nun","samekh","ayin","finalpe","pe","finaltsadi","tsadi","qof","resh","shin","tav"];function fo(e){let t=/^uni([0-9A-Fa-f]{4})$/.exec(e)??/^u([0-9A-Fa-f]{4,6})$/.exec(e);if(t)return String.fromCodePoint(parseInt(t[1],16));let r=/^afii(\d{5})$/.exec(e);if(r){let o=Number(r[1]);if(o>=57664&&o<=57690)return String.fromCharCode(1488+(o-57664))}let n=uo.indexOf(e.replace(/hebrew$/,""));return n>=0?String.fromCharCode(1488+n):e==="space"?" ":/^[A-Za-z]$/.test(e)?e:{zero:"0",one:"1",two:"2",three:"3",four:"4",five:"5",six:"6",seven:"7",eight:"8",nine:"9",period:".",comma:",",hyphen:"-",colon:":",slash:"/",at:"@"}[e]??null}function po(e,t){let r=e,n=/\/Encoding\s+(\d+)\s+\d+\s+R/.exec(e);n&&(r=t.get(Number(n[1]))?.dict??"");let s=/\/Differences\s*\[([^\]]*)\]/.exec(r);if(!s?.[1])return null;let o=new Map,i=0;for(let a of s[1].match(/\d+|\/[^\s/[\]]+/g)??[]){if(/^\d+$/.test(a)){i=Number(a);continue}let c=fo(a.slice(1));c!==null&&o.set(i,c),i+=1}return o.size?{map:o,bytes:1}:null}function Zn(e){let t=[];for(let r=0;r<e.length;r+=1){let n=e[r];if(n!=="\\"){t.push(n.charCodeAt(0)&255);continue}let s=e[r+1];if(s===void 0)break;if(s>="0"&&s<="7"){let i="",a=r+1;for(;a<e.length&&i.length<3&&e[a]>="0"&&e[a]<="7";)i+=e[a],a+=1;t.push(parseInt(i,8)&255),r=a-1;continue}let o={n:10,r:13,t:9,b:8,f:12};t.push(o[s]??s.charCodeAt(0)&255),r+=1}return t}function Yn(e){if(e.length<2||e[0]!==254||e[1]!==255)return null;let t="";for(let r=2;r+1<e.length;r+=2)t+=String.fromCharCode((e[r]??0)<<8|(e[r+1]??0));return t}function Vn(e,t){let r=Yn(e);if(r!==null)return r;if(!t)return e.map(s=>String.fromCharCode(s)).join("");let n="";if(t.bytes===2)for(let s=0;s+1<e.length;s+=2){let o=(e[s]??0)<<8|(e[s+1]??0);n+=t.map.get(o)??""}else for(let s of e)n+=t.map.get(s)??String.fromCharCode(s);return n}function ho(e){let t=0;for(let r of e){let n=r.codePointAt(0)??0;/[\p{L}\p{N}]/u.test(r)?t+=1:(n<32||n>=127&&n<=191||n===65533)&&(t-=2)}return t}function Gn(e,t){if(!t||t.length<=1)return Vn(e,t?.[0]);let r="",n=-1/0;for(let s of t){let o=Vn(e,s),i=ho(o);i>n&&(r=o,n=i)}return r}function mo(e,t){let r="",n="",s,o=!1,i="",a=0,c=null,l=()=>{n.trim()&&(r+=n+`
4
4
  `),n="",a=0},f=()=>{n&&!n.endsWith(" ")&&a>1&&(n+=" ")},d=/\/([^\s/<>[\]()]+)\s+-?[\d.]+\s+Tf|(-?[\d.]+)\s+(-?[\d.]+)\s+T[dD]\b|(?:-?[\d.]+\s+){5}(-?[\d.]+)\s+Tm\b|T\*|\((?:\\.|[^\\)])*\)|<[0-9A-Fa-f\s]*>|\[|\]|-?\d+(?:\.\d+)?|TJ|Tj|'|"/g,h;for(;(h=d.exec(e))!==null;){let p=h[0];if(h[1]!==void 0&&p.endsWith("Tf")){s=t.get(h[1]);continue}if(h[2]!==void 0){Math.abs(Number(h[3]))>.01?l():Number(h[2])!==0&&f();continue}if(h[4]!==void 0){let g=Number(h[4]);c!==null&&Math.abs(g-c)>.01?l():c!==null&&f(),c=g;continue}if(p==="T*"){l();continue}if(p==="["){o=!0;continue}if(p==="]"){o=!1;continue}if(p==="TJ"||p==="Tj"||p==="'"||p==='"'){(p==="'"||p==='"')&&l(),i&&(n+=i,a=i.trim().length,i="");continue}if(p.startsWith("("))i+=Gn(Zn(p.slice(1,-1)),s);else if(p.startsWith("<")){let g=p.slice(1,-1).replace(/\s+/g,""),u=[];for(let y=0;y+1<g.length;y+=2)u.push(parseInt(g.slice(y,y+2),16));i+=Gn(u,s)}else o&&Number(p)<-200&&i&&!i.endsWith(" ")&&(i+=" ")}return i&&(n+=i),l(),r}function go(e,t){let r=e.toString("latin1"),n=/\/Info\s+(\d+)\s+\d+\s+R/.exec(r),s=n?t.get(Number(n[1]))?.dict:void 0;if(!s)return"";let o=[],i=/\/(Author|Title|Subject|Keywords|Creator|Producer)\s*(\((?:\\.|[^\\)])*\)|<[0-9A-Fa-f\s]*>)/g,a;for(;(a=i.exec(s))!==null;){let c=a[2]??"";if(c.startsWith("(")){let l=Zn(c.slice(1,-1));o.push(Yn(l)??l.map(f=>String.fromCharCode(f)).join(""))}else{let l=c.slice(1,-1).replace(/\s+/g,""),f="";if(l.toUpperCase().startsWith("FEFF"))for(let d=4;d+3<l.length+1;d+=4)f+=String.fromCharCode(parseInt(l.slice(d,d+4),16));else for(let d=0;d+1<l.length;d+=2)f+=String.fromCharCode(parseInt(l.slice(d,d+2),16));o.push(f)}}return o.join(`
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- /*! @nodatachat/mcp 1.6.27 | Copyright 2026 Capsule Ltd. | FSL-1.1-ALv2 | see LICENSE.md */
2
+ /*! @nodatachat/mcp 1.6.28 | Copyright 2026 Capsule Ltd. | FSL-1.1-ALv2 | see LICENSE.md */
3
3
  import{createRequire as __ndReq}from"node:module";const[__ndMaj,__ndMin]=process.versions.node.split(".").map(Number);if(!((__ndMaj===20&&__ndMin>=19)||(__ndMaj===22&&__ndMin>=12)||__ndMaj>=23)){process.stderr.write("NoData needs Node.js 20.19+, 22.12+ or 23+; this computer has "+process.version+".\nInstall the current LTS from https://nodejs.org (or: nvm install --lts), then run the same command again.\n");process.exit(1)}const require=__ndReq(import.meta.url);
4
4
  var T1=Object.create;var Zu=Object.defineProperty;var P1=Object.getOwnPropertyDescriptor;var R1=Object.getOwnPropertyNames;var N1=Object.getPrototypeOf,O1=Object.prototype.hasOwnProperty;var re=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var K=(e,t)=>()=>(e&&(t=e(e=0)),t);var ge=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),vc=(e,t)=>{for(var n in t)Zu(e,n,{get:t[n],enumerable:!0})},C1=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of R1(t))!O1.call(e,o)&&o!==n&&Zu(e,o,{get:()=>t[o],enumerable:!(r=P1(t,o))||r.enumerable});return e};var Ce=(e,t,n)=>(n=e!=null?T1(N1(e)):{},C1(t||!e||!e.__esModule?Zu(n,"default",{value:e,enumerable:!0}):n,e));function Qu(e){e.table&&(at.table=e.table),e.severity&&(at.severity=e.severity),e.amounts&&(at.amounts=e.amounts);for(let t of e.text??[])at.text.some(n=>n.kind===t.kind)||at.text.push(t);e.header&&!at.header.includes(e.header)&&at.header.push(e.header);for(let t of e.secrets??[])at.secrets.some(n=>n.id===t.id)||at.secrets.push(t)}function kc(e){return at.severity?.(e)}function ep(){return at.amounts?.()===!0}function Ho(){return at.text}function f_(){return at.header}function Uo(){return at.table}function h_(){return at.secrets}var at,nr=K(()=>{"use strict";at={text:[],header:[],secrets:[],table:null,amounts:null,severity:null}});function At(){let e=h_().filter(t=>!Sc.some(n=>n.id===t.id));return[...Sc,...e]}function D1(e,t){let n=i=>i.replace(/^[^0-9]*/,"").split(".").map(s=>parseInt(s,10)||0),r=n(e),o=n(t);for(let i=0;i<3;i++){if((r[i]||0)<(o[i]||0))return!0;if((r[i]||0)>(o[i]||0))return!1}return!1}function y_(e){let t=[],n;try{n=JSON.parse(e)}catch{return t}let r={...n.dependencies??{},...n.devDependencies??{}};for(let[o,i]of Object.entries(r)){let s=(i||"").replace(/^[\^~>=<\s]+/,""),a=I1.find(c=>c.name===o&&D1(s,c.below));a&&t.push({name:o,version:s,vuln:a})}return t}function jn(e){if(!e)return null;let t=e.trim();if(F1.test(t)||/^name$/i.test(t)||/^\[[A-Z_]+(?:-\d+)?\]$/.test(t))return null;let n=t.replace(/[\s-]+/g,"_");for(let r of[...L1,...j1])if(r.pattern.test(t)||r.pattern.test(n))return{type:r.type,label:r.label};if(M1.test(t))return null;if(/^שם[ _][\u0590-\u05FF"'׳ ]{2,20}$/.test(t))return{type:"name",label:"\u05E9\u05DD \u05D0\u05D3\u05DD"};if(/^(customer|client|employee|inspector|supervisor|contact|person|patient|user|owner|manager|agent|member|driver|tenant|student|parent|beneficiary|insured)_?(full_?)?name$/i.test(n))return{type:"name",label:"Person name"};for(let r of f_()){let o=r(t);if(o)return{type:o.type,label:o.label}}return null}function $c(e){let t=String(e??"").replace(/\D/g,"");if(t.length===0||t.length>9)return!1;let n=t.padStart(9,"0"),r=0;for(let o=0;o<9;o++){let i=parseInt(n[o]??"0",10)*(o%2+1);i>9&&(i-=9),r+=i}return r%10===0&&parseInt(n,10)>0}function B1(e){let t=String(e??"").replace(/\D/g,"");if(t.length<12||t.length>19)return!1;let n=0,r=!1;for(let o=t.length-1;o>=0;o-=1){let i=parseInt(t[o]??"0",10);r&&(i*=2,i>9&&(i-=9)),n+=i,r=!r}return n%10===0}function Ec(e){let t=String(e??"").replace(/\s/g,"").toUpperCase();if(!/^[A-Z]{2}\d{2}[A-Z0-9]{10,30}$/.test(t))return!1;let n=t.slice(4)+t.slice(0,4),r=0;for(let o of n){let i=o>="A"&&o<="Z"?String(o.charCodeAt(0)-55):o;for(let s of i)r=(r*10+Number(s))%97}return r===1}function __(e){if(e.length!==14&&e.length!==17)return!1;let t=+e.slice(0,4),n=+e.slice(4,6),r=+e.slice(6,8),o=+e.slice(8,10),i=+e.slice(10,12),s=+e.slice(12,14);return t>=1970&&t<=2099&&n>=1&&n<=12&&r>=1&&r<=31&&o<24&&i<60&&s<60}function b_(e){let t=Number(e);return!Number.isSafeInteger(t)||t<1024?!1:Number.isInteger(Math.log2(t))||t%1048576===0}function ks(e){return H1.has(e.replace(/\D/g,""))}function Ac(e){let t=e.replace(/\D/g,"");return __(t)||b_(t)}function Gr(e,t){let n=[];for(let r of xs){r.pattern.lastIndex=0;let o=new Set,i,s=0;for(;(i=r.pattern.exec(e))!==null&&(s+=1,!(s>2e5));){let a=i[0];if(!(r.subkind!=="iban"&&r.subkind!=="israeli_phone"&&Ac(a))&&(r.validate(a)&&o.add(a.replace(/[\s-]/g,"")),o.size>=1e5))break}if(o.size>0){if(t)for(let c of o)ks(c)||t(r.subkind,c);let a=[...o].filter(c=>!ks(c)).length;n.push({subkind:r.subkind,severity:a===0?"low":r.severity,hint:a===0?`${r.hint} All ${o.size} are published test numbers.`:r.hint,count:o.size,real:a})}}for(let r of Ho()){let o=new Set;for(let i of r.find(e))o.add(e.slice(i.start,i.end).trim());o.size>0&&n.push({subkind:r.kind,severity:r.severity,hint:r.hint,count:o.size})}return n}function Vr(e,t){let n=[],r="",o=!1;for(let i=0;i<e.length;i++){let s=e[i];o?s==='"'&&e[i+1]==='"'?(r+='"',i++):s==='"'?o=!1:r+=s:s==='"'?o=!0:s===t?(n.push(r),r=""):r+=s}return n.push(r),n}var Sc,g_,m_,rp,I1,j1,L1,F1,M1,xc,op,Ss,tp,np,xs,H1,rr=K(()=>{"use strict";nr();Sc=[{id:"aws-access-key",name:"AWS Access Key",pattern:/(?:^|[^A-Z0-9])AKIA(?!X{16})[A-Z2-7]{16}(?:[^A-Z2-7]|$)/,severity:"critical"},{id:"aws-secret-key",name:"AWS Secret Key",pattern:/(?:aws_secret_access_key|aws_secret_key|secret_access_key)\s*[=:]\s*['"]?[A-Za-z0-9/+=]{40}['"]?/,severity:"critical"},{id:"gcp-api-key",name:"GCP API Key",pattern:/AIza[0-9A-Za-z_-]{35}/,severity:"critical"},{id:"gcp-service-account",name:"GCP Service Account",pattern:/"type"\s*:\s*"service_account"/,severity:"critical"},{id:"github-token",name:"GitHub Token",pattern:/gh[pousr]_[0-9a-zA-Z]{36,}/,severity:"critical"},{id:"github-fine-grained",name:"GitHub Fine-Grained Token",pattern:/github_pat_[0-9a-zA-Z_]{22,}/,severity:"critical"},{id:"gitlab-token",name:"GitLab Token",pattern:/glpat-[0-9a-zA-Z_-]{20,}/,severity:"critical"},{id:"stripe-secret",name:"Stripe Secret Key",pattern:/sk_live_[0-9a-zA-Z]{24,}/,severity:"critical"},{id:"stripe-restricted",name:"Stripe Restricted Key",pattern:/rk_live_[0-9a-zA-Z]{24,}/,severity:"critical"},{id:"slack-token",name:"Slack Token",pattern:/xox[baprs]-[0-9a-zA-Z-]{10,}/,severity:"high"},{id:"slack-webhook",name:"Slack Webhook",pattern:/hooks\.slack\.com\/services\/T[0-9A-Z]{8,}\/B[0-9A-Z]{8,}\/[0-9a-zA-Z]{24}/,severity:"high"},{id:"twilio-api-key",name:"Twilio API Key",pattern:/SK[0-9a-fA-F]{32}/,severity:"high"},{id:"sendgrid-api-key",name:"SendGrid API Key",pattern:/SG\.[0-9a-zA-Z_-]{22}\.[0-9a-zA-Z_-]{43}/,severity:"critical"},{id:"postgres-uri",name:"PostgreSQL Connection String",pattern:/postgres(?:ql)?:\/\/[^\s'"]{10,}/,severity:"critical"},{id:"mongodb-uri",name:"MongoDB Connection String",pattern:/mongodb(?:\+srv)?:\/\/[^\s'"]{10,}/,severity:"critical"},{id:"redis-uri",name:"Redis Connection String",pattern:/redis(?:s)?:\/\/[^\s'"]{10,}/,severity:"high"},{id:"openai-key",name:"OpenAI API Key",pattern:/sk-[0-9a-zA-Z]{20,}T3BlbkFJ[0-9a-zA-Z]{20,}/,severity:"critical"},{id:"openai-project-key",name:"OpenAI API Key",pattern:/sk-(?:proj|svcacct|admin)-[0-9A-Za-z_-]{40,}/,severity:"critical"},{id:"anthropic-key",name:"Anthropic API Key",pattern:/sk-ant-[0-9a-zA-Z_-]{40,}/,severity:"critical"},{id:"firebase-key",name:"Firebase API Key",pattern:/AIza[0-9A-Za-z_-]{35}/,severity:"high"},{id:"supabase-key",name:"Supabase Service Key",pattern:/eyJ[0-9a-zA-Z_-]{100,}/,severity:"critical"},{id:"supabase-access-token",name:"Supabase Access Token",pattern:/\bsbp_[0-9a-f]{40}\b/,severity:"critical"},{id:"supabase-secret-key",name:"Supabase Secret Key",pattern:/\bsb_secret_[0-9A-Za-z_-]{20,}/,severity:"critical"},{id:"private-key",name:"Private Key",pattern:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/,severity:"critical"},{id:"jwt-secret",name:"JWT/Generic Secret",pattern:/(?:jwt_secret|JWT_SECRET|secret_key|SECRET_KEY|api_secret|API_SECRET)\s*[=:]\s*['"][^'"]{8,}['"]/,severity:"high"},{id:"password-in-code",name:"Password in Code",pattern:/(?:password|passwd|pwd)\s*[=:]\s*['"][^'"]{8,}['"]/,severity:"high"},{id:"bearer-token",name:"Bearer Token in Code",pattern:/['"]Bearer\s+[0-9a-zA-Z._-]{20,}['"]/,severity:"high"}];g_=/node_modules\/|\.next\/|\.test\.|\.spec\.|__tests__\/|\.nodata-proof\.json$|\.git\//,m_=/(^|\/)\.env(\.[\w-]+)*\.(example|sample|template|dist)$|\.(example|sample|template)$|(^|\/)[^/]*\.(example|sample)\.[a-z0-9]+$/i,rp=/(^|\/)(__tests__|__mocks__|tests?|spec|fixtures?|mocks?|samples?|examples?|demo|testdata)(\/|$)|\.(test|spec)\.[a-z0-9]+$|\.min\.(m?js|css)$|(^|\/)[^/]*\.worker\.min\.m?js$/i,I1=[{name:"lodash",below:"4.17.21",severity:"critical",cve:"CVE-2021-23337",desc:"Command injection via template"},{name:"minimist",below:"1.2.6",severity:"critical",cve:"CVE-2021-44906",desc:"Prototype pollution"},{name:"json5",below:"2.2.2",severity:"high",cve:"CVE-2022-46175",desc:"Prototype pollution"},{name:"express",below:"4.19.2",severity:"high",cve:"CVE-2024-29041",desc:"Open redirect"},{name:"path-to-regexp",below:"6.3.0",severity:"high",cve:"CVE-2024-45296",desc:"ReDoS"},{name:"sanitize-html",below:"2.12.1",severity:"high",cve:"CVE-2024-21501",desc:"XSS bypass"},{name:"dompurify",below:"3.0.9",severity:"high",cve:"CVE-2024-45801",desc:"mXSS"},{name:"jsonwebtoken",below:"9.0.0",severity:"critical",cve:"CVE-2022-23529",desc:"Key confusion attack"},{name:"jose",below:"4.15.5",severity:"high",cve:"CVE-2024-28176",desc:"DoS via JWE"},{name:"axios",below:"1.6.0",severity:"high",cve:"CVE-2023-45857",desc:"CSRF cookie leak"},{name:"node-fetch",below:"2.6.7",severity:"high",cve:"CVE-2022-0235",desc:"Header leak on redirect"},{name:"serialize-javascript",below:"6.0.2",severity:"critical",cve:"CVE-2024-11831",desc:"XSS via serialization"},{name:"xml2js",below:"0.6.0",severity:"high",cve:"CVE-2023-0842",desc:"Prototype pollution"},{name:"next",below:"14.1.1",severity:"high",cve:"CVE-2024-34350",desc:"SSRF via headers"},{name:"sharp",below:"0.32.6",severity:"high",cve:"CVE-2023-4863",desc:"libwebp heap overflow"},{name:"multer",below:"1.4.5",severity:"high",cve:"CVE-2022-24434",desc:"Prototype pollution"},{name:"tough-cookie",below:"4.1.3",severity:"medium",cve:"CVE-2023-26136",desc:"Prototype pollution"},{name:"semver",below:"7.5.4",severity:"medium",cve:"CVE-2022-25883",desc:"ReDoS"},{name:"ip",below:"2.0.1",severity:"critical",cve:"CVE-2024-29415",desc:"SSRF bypass via octal IP"},{name:"tar",below:"6.2.1",severity:"high",cve:"CVE-2024-28863",desc:"DoS via path traversal"}];j1=[{pattern:/^(full_?name|first_?name|last_?name|spouse_?name|beneficiary_?name)$/i,type:"name",label:"Person name"},{pattern:/^(email|e_?mail|email_?address)$/i,type:"email",label:"Email address"},{pattern:/^(phone|mobile|telephone|phone_?number|cell_?phone)$/i,type:"phone",label:"Phone number"},{pattern:/^(id_?number|identity|ssn|social_?security|national_?id|teudat_?zehut)$/i,type:"id",label:"ID number"},{pattern:/^(address|street_?address|home_?address)$/i,type:"address",label:"Address"},{pattern:/^(date_?of_?birth|dob|birth_?date|birthday)$/i,type:"dob",label:"Date of birth"},{pattern:/^(bank_?account|iban|account_?number|bank_?details|routing_?number)$/i,type:"financial",label:"Bank account"},{pattern:/^(credit_?card|card_?number|cvv|cc_?number)$/i,type:"financial",label:"Credit card"},{pattern:/^(salary|income|commission|premium|compensation)$/i,type:"financial",label:"Salary / income"},{pattern:/^(medical_?info|health_?conditions|diagnosis|medication|prescription)$/i,type:"medical",label:"Medical"},{pattern:/^(passport|passport_?number|passport_?id)$/i,type:"id",label:"Passport"},{pattern:/^(driver_?license|drivers_?license|dl_?number)$/i,type:"id",label:"Driver license"},{pattern:/^(tax_?id|tin|vat_?number|ein)$/i,type:"financial",label:"Tax ID"},{pattern:/^(insurance_?number|policy_?number|member_?id)$/i,type:"id",label:"Insurance/Policy"},{pattern:/^(biometric|fingerprint|face_?id|retina)$/i,type:"biometric",label:"Biometric"},{pattern:/^(latitude|longitude|lat|lng|geo_?location|coordinates)$/i,type:"location",label:"Geolocation"}],L1=[{pattern:/^(?:שם|שם_מלא|שם פרטי|שם_פרטי|שם משפחה|שם_משפחה|שם הלקוח|שם בן זוג|שם המבוטח|שם המוטב|שם הילד|שם הקטין)$/i,type:"name",label:"\u05E9\u05DD \u05D0\u05D3\u05DD"},{pattern:/^(?:ת"ז|ת\.ז|ת ז|תז|תעודת זהות|תעודת_זהות|מספר זהות|מס' זהות|teudat_zehut|tz|israeli_id|il_id)$/i,type:"id",label:"\u05EA\u05E2\u05D5\u05D3\u05EA \u05D6\u05D4\u05D5\u05EA"},{pattern:/^(?:דרכון|מספר דרכון|רישיון נהיגה|רישיון_נהיגה|רשיון נהיגה)$/i,type:"id",label:"\u05D3\u05E8\u05DB\u05D5\u05DF/\u05E8\u05D9\u05E9\u05D9\u05D5\u05DF"},{pattern:/^(?:מייל|דוא"ל|דוא_ל|דואר אלקטרוני|אימייל|כתובת מייל)$/i,type:"email",label:"\u05D3\u05D5\u05D0\u05E8 \u05D0\u05DC\u05E7\u05D8\u05E8\u05D5\u05E0\u05D9"},{pattern:/^(?:טלפון|טל'|נייד|פלאפון|סלולרי|מספר טלפון|טלפון נייד)$/i,type:"phone",label:"\u05DE\u05E1\u05E4\u05E8 \u05D8\u05DC\u05E4\u05D5\u05DF"},{pattern:/^(?:כתובת|כתובת מגורים|רחוב|מס בית|עיר|ישוב|יישוב|מיקוד|כתובת מלאה|מען)$/i,type:"address",label:"\u05DB\u05EA\u05D5\u05D1\u05EA"},{pattern:/^(?:תאריך לידה|ת לידה|תאריך הולדת|יום הולדת|גיל)$/i,type:"dob",label:"\u05EA\u05D0\u05E8\u05D9\u05DA \u05DC\u05D9\u05D3\u05D4"},{pattern:/^(?:חשבון בנק|מספר חשבון|מס חשבון|סניף|iban|iban_il)$/i,type:"financial",label:"\u05D7\u05E9\u05D1\u05D5\u05DF \u05D1\u05E0\u05E7"},{pattern:/^(?:כרטיס אשראי|מספר אשראי|cvv|אשראי)$/i,type:"financial",label:"\u05DB\u05E8\u05D8\u05D9\u05E1 \u05D0\u05E9\u05E8\u05D0\u05D9"},{pattern:/^(?:שכר|משכורת|הכנסה|פרמיה|שכר ברוטו|שכר נטו|תגמול|בונוס|פיצוי)$/i,type:"financial",label:"\u05E9\u05DB\u05E8/\u05D4\u05DB\u05E0\u05E1\u05D4"},{pattern:/^(?:אבחון|אבחנה|מחלה|תרופה|מרשם|בדיקה רפואית|מצב רפואי|חיסון|רגישות|אלרגיה|סוג דם)$/i,type:"medical",label:"\u05DE\u05D9\u05D3\u05E2 \u05E8\u05E4\u05D5\u05D0\u05D9"},{pattern:/^(?:מספר פוליסה|מס פוליסה|פוליסה|מספר חבר|מספר ביטוח)$/i,type:"id",label:"\u05E4\u05D5\u05DC\u05D9\u05E1\u05D4/\u05D7\u05D1\u05E8\u05D5\u05EA"},{pattern:/^(?:שם הילד|תעודת זהות של ילד|ילדים|קטין|מספר ילדים|תעודת לידה)$/i,type:"minor_data",label:"\u05DE\u05D9\u05D3\u05E2 \u05E2\u05DC \u05E7\u05D8\u05D9\u05DF"},{pattern:/^(?:דת|לאום|מין|נטייה מינית|השקפה פוליטית|מצב משפחתי|עדה|מוצא)$/i,type:"sensitive_personal",label:"\u05DE\u05D9\u05D3\u05E2 \u05D0\u05D9\u05E9\u05D9 \u05E8\u05D2\u05D9\u05E9"},{pattern:/^(?:מספר רכב|מס רכב|לוחית רישוי|מספר רישוי)$/i,type:"tracking",label:"\u05DE\u05E1\u05E4\u05E8 \u05E8\u05DB\u05D1"}],F1=/^(id|uuid|created_?at|updated_?at|deleted_?at|status|type|category|description|title|slug|url|path|key|value|enabled|active|public|version|metadata|config|settings|data|content|note|comment|label|color|icon)$/i,M1=/^שם[ _](?:ה)?(?:קובץ|מוצר|פריט|חברה|ארגון|עסק|פרויקט|גיליון|טבלה|שדה|קטגוריה|סניף|בנק|עיר|רחוב|ישוב|יישוב|מסמך|תוכנית|חבילה|קורס|מחלקה|אתר|דומיין|מותג|ספק|שירות|תפקיד)$|^(file|product|item|company|org|organization|project|sheet|table|field|category|branch|bank|city|street|document|plan|course|department|site|domain|brand|vendor|service|role)[ _-]?name$/i;xc={id:"critical",financial:"critical",medical:"critical",biometric:"critical",minor_data:"critical",sensitive_personal:"critical",email:"high",phone:"high",name:"high",address:"high",dob:"high",tracking:"medium",location:"high",auth:"critical",employment:"medium",education:"medium",behavior:"high"};op=/(?<!\d)(?<!\d[.,])(?:\+972[\s-]?|0)(?:5[0-9]|7[0-9]|[2-4]|[89])(?:[\s-]?\d){7}(?!\d)(?![.,]\d)/g,Ss=/\bIL\d{2}\s?(?:\d{4}\s?){4}\d{3}\b/g;tp="(?<!\\d)(?<!\\d[.,])",np="(?!\\d)(?![.,]\\d)",xs=[{subkind:"israeli_id",severity:"high",pattern:new RegExp(`${tp}(?:\\d{8}-\\d|\\d{9})${np}`,"g"),validate:$c,hint:"Israeli national ID (check digit verified) in plaintext. Encrypt the column or mask it at rest."},{subkind:"credit_card",severity:"critical",pattern:new RegExp(`${tp}[2-6][ -]?(?:\\d[ -]?){11,17}\\d${np}`,"g"),validate:B1,hint:"Payment card number (Luhn verified) in plaintext. This is PCI scope."},{subkind:"iban",severity:"high",pattern:/\b[A-Z]{2}\d{2}(?: ?[A-Z0-9]{4}){2,7}(?: ?[A-Z0-9]{1,4})?\b/g,validate:Ec,hint:"Bank account in IBAN form (mod-97 verified) in plaintext."},{subkind:"israeli_phone",severity:"medium",pattern:new RegExp(`${tp}(?:\\+972[- ]?|0)(?:[57]\\d|[2-489])[- ]?\\d{3}[- ]?\\d{4}${np}`,"g"),validate:e=>{let t=e.replace(/\D/g,"").replace(/^972/,"0");return/^0[57]\d{8}$/.test(t)?!0:/^0[2-489]\d{7}$/.test(t)&&(/[- ]/.test(e)||e.startsWith("+972"))},hint:"Israeli phone number in plaintext."}];H1=new Set(["000000018","123456782","111111118","222222226","333333334","999999998","4111111111111111","4242424242424242","4000056655665556","5555555555554444","5105105105105100","2223003122003222","378282246310005","371449635398431","6011111111111117","3056930009020004","4012888888881881","4000000000000002"])});import{inflateSync as w_}from"node:zlib";function Tc(e){let t=e.toString("latin1"),n=new Map,r=/(\d+)\s+(\d+)\s+obj\b/g,o;for(;(o=r.exec(t))!==null;){let i=Number(o[1]),s=r.lastIndex,a=t.indexOf("endobj",s);if(a<0)continue;let c=t.indexOf("stream",s),l,d=null;if(c>=0&&c<a){l=t.slice(s,c);let u=c+6;t[u]==="\r"&&(u+=1),t[u]===`
5
5
  `&&(u+=1);let p=t.indexOf("endstream",u);p>u&&(d=e.subarray(u,p))}else l=t.slice(s,a);n.set(i,{num:i,dict:l,stream:d})}for(let i of[...n.values()]){if(!i.stream||!/\/Type\s*\/ObjStm\b/.test(i.dict))continue;let s=Es(i),a=Number(/\/N\s+(\d+)/.exec(i.dict)?.[1]??0),c=Number(/\/First\s+(\d+)/.exec(i.dict)?.[1]??-1);if(s===null||!a||c<0)continue;let l=s.slice(0,c).trim().split(/\s+/).map(Number);for(let d=0;d<a;d+=1){let u=l[2*d],p=l[2*d+1];if(u===void 0||p===void 0||Number.isNaN(u)||Number.isNaN(p))break;let f=d+1<a?l[2*(d+1)+1]:void 0,h=s.slice(c+p,f!==void 0?c+f:void 0);n.has(u)||n.set(u,{num:u,dict:h,stream:null})}}return n}function ip(e){let t=[...e.replace(/\s+/g,"")];if(t.length<40)return!1;let n=0,r=0;for(let o of t){let i=o.codePointAt(0)??0;i<32||i>=127&&i<=191||i===65533||i>=57344&&i<=63743?n+=1:/[\p{L}\p{N}]/u.test(o)&&(r+=1)}return n/t.length>.2||r/t.length<.25}function U1(e){let t=e.toString("latin1").replace(/\s/g,"");t.startsWith("<~")&&(t=t.slice(2));let n=t.indexOf("~>");n>=0&&(t=t.slice(0,n));let r=[],o=0,i=0;for(let s of t){if(s==="z"&&i===0){r.push(0,0,0,0);continue}let a=s.charCodeAt(0)-33;if(a<0||a>84)return null;o=o*85+a,i+=1,i===5&&(r.push(o>>>24&255,o>>>16&255,o>>>8&255,o&255),o=0,i=0)}if(i>0){for(let a=i;a<5;a+=1)o=o*85+84;let s=[o>>>24&255,o>>>16&255,o>>>8&255,o&255];for(let a=0;a<i-1;a+=1)r.push(s[a]??0)}return Buffer.from(r)}function K1(e){let t=e.toString("latin1").replace(/\s/g,"").split(">")[0]??"",n=t.length%2?t+"0":t;return/^[0-9A-Fa-f]*$/.test(n)?Buffer.from(n,"hex"):null}function W1(e){let t=/\/Filter\s*(\[[^\]]*\]|\/\w+)/.exec(e);return!t||!t[1]?[]:[...t[1].matchAll(/\/(\w+)/g)].map(n=>n[1]??"")}function Es(e,t){if(!e.stream)return null;let n=e.stream;for(let r of W1(e.dict)){let o=null;if(r==="FlateDecode")try{o=t!==void 0?w_(n,{maxOutputLength:Math.max(1,t)}):w_(n)}catch{return null}else if(r==="ASCII85Decode")o=U1(n);else if(r==="ASCIIHexDecode")o=K1(n);else return null;if(o===null)return null;n=o}return n.toString("latin1")}function G1(e){let t=new Map,n=1,r=/begincodespacerange([\s\S]*?)endcodespacerange/.exec(e);if(r&&r[1]){let c=/<([0-9A-Fa-f]+)>/.exec(r[1]);c&&c[1]&&c[1].length>=4&&(n=2)}let o=c=>{let l="";for(let d=0;d+3<c.length+1;d+=4){let u=parseInt(c.slice(d,d+4),16);Number.isFinite(u)&&u>0&&(l+=String.fromCharCode(u))}return l},i=/beginbfchar([\s\S]*?)endbfchar/g,s;for(;(s=i.exec(e))!==null;){let c=/<([0-9A-Fa-f]+)>\s*<([0-9A-Fa-f]*)>/g,l;for(;(l=c.exec(s[1]??""))!==null;)t.set(parseInt(l[1]??"0",16),o(l[2]??""))}let a=/beginbfrange([\s\S]*?)endbfrange/g;for(;(s=a.exec(e))!==null;){let c=s[1]??"",l=/<([0-9A-Fa-f]+)>\s*<([0-9A-Fa-f]+)>\s*<([0-9A-Fa-f]*)>/g,d;for(;(d=l.exec(c))!==null;){let u=parseInt(d[1]??"0",16),p=parseInt(d[2]??"0",16),f=parseInt((d[3]??"0").slice(0,4)||"0",16);if(!(p-u>65535))for(let h=u;h<=p;h+=1)t.set(h,String.fromCharCode(f+(h-u)))}}return{map:t,bytes:n}}function V1(e){let t=new Map,n=[],r=[];for(let i of e.values()){for(let s of i.dict.matchAll(/\/Font\s*<<([\s\S]*?)>>/g))s[1]&&r.push(s[1]);for(let s of i.dict.matchAll(/\/Font\s+(\d+)\s+\d+\s+R/g)){let a=e.get(Number(s[1]));a&&r.push(a.dict)}}let o=new Set;for(let i of r){let s=/\/([^\s/<>[\]()]+)\s+(\d+)\s+\d+\s+R/g,a;for(;(a=s.exec(i))!==null;){let c=`${a[1]}#${a[2]}`;o.has(c)||(o.add(c),n.push([a[1]??"",Number(a[2])]))}}for(let[i,s]of n){let a=e.get(s);if(!a)continue;let c=null,l=/\/ToUnicode\s+(\d+)\s+\d+\s+R/.exec(a.dict);if(l){let u=e.get(Number(l[1])),p=u?Es(u):null;p&&(c=G1(p))}if(c||(c=Y1(a.dict,e)),!c)continue;let d=t.get(i)??[];d.push(c),t.set(i,d)}return t}function z1(e){let t=/^uni([0-9A-Fa-f]{4})$/.exec(e)??/^u([0-9A-Fa-f]{4,6})$/.exec(e);if(t)return String.fromCodePoint(parseInt(t[1],16));let n=/^afii(\d{5})$/.exec(e);if(n){let i=Number(n[1]);if(i>=57664&&i<=57690)return String.fromCharCode(1488+(i-57664))}let r=q1.indexOf(e.replace(/hebrew$/,""));return r>=0?String.fromCharCode(1488+r):e==="space"?" ":/^[A-Za-z]$/.test(e)?e:{zero:"0",one:"1",two:"2",three:"3",four:"4",five:"5",six:"6",seven:"7",eight:"8",nine:"9",period:".",comma:",",hyphen:"-",colon:":",slash:"/",at:"@"}[e]??null}function Y1(e,t){let n=e,r=/\/Encoding\s+(\d+)\s+\d+\s+R/.exec(e);r&&(n=t.get(Number(r[1]))?.dict??"");let o=/\/Differences\s*\[([^\]]*)\]/.exec(n);if(!o?.[1])return null;let i=new Map,s=0;for(let a of o[1].match(/\d+|\/[^\s/[\]]+/g)??[]){if(/^\d+$/.test(a)){s=Number(a);continue}let c=z1(a.slice(1));c!==null&&i.set(s,c),s+=1}return i.size?{map:i,bytes:1}:null}function A_(e){let t=[];for(let n=0;n<e.length;n+=1){let r=e[n];if(r!=="\\"){t.push(r.charCodeAt(0)&255);continue}let o=e[n+1];if(o===void 0)break;if(o>="0"&&o<="7"){let s="",a=n+1;for(;a<e.length&&s.length<3&&e[a]>="0"&&e[a]<="7";)s+=e[a],a+=1;t.push(parseInt(s,8)&255),n=a-1;continue}let i={n:10,r:13,t:9,b:8,f:12};t.push(i[o]??o.charCodeAt(0)&255),n+=1}return t}function T_(e){if(e.length<2||e[0]!==254||e[1]!==255)return null;let t="";for(let n=2;n+1<e.length;n+=2)t+=String.fromCharCode((e[n]??0)<<8|(e[n+1]??0));return t}function k_(e,t){let n=T_(e);if(n!==null)return n;if(!t)return e.map(o=>String.fromCharCode(o)).join("");let r="";if(t.bytes===2)for(let o=0;o+1<e.length;o+=2){let i=(e[o]??0)<<8|(e[o+1]??0);r+=t.map.get(i)??""}else for(let o of e)r+=t.map.get(o)??String.fromCharCode(o);return r}function J1(e){let t=0;for(let n of e){let r=n.codePointAt(0)??0;/[\p{L}\p{N}]/u.test(n)?t+=1:(r<32||r>=127&&r<=191||r===65533)&&(t-=2)}return t}function S_(e,t){if(!t||t.length<=1)return k_(e,t?.[0]);let n="",r=-1/0;for(let o of t){let i=k_(e,o),s=J1(i);s>r&&(n=i,r=s)}return n}function X1(e,t){let n="",r="",o,i=!1,s="",a=0,c=null,l=()=>{r.trim()&&(n+=r+`
@@ -315,7 +315,7 @@ Ask the user to approve, then call nodata_burn again with confirm: true.`);let i
315
315
  `));if(n==="use")return et([`To use ${s.join(", ")} for a job: nodata_run with project "${a}" and the command (the keys reach the command's memory only, under each key's rule; you never see them).`,`In a terminal: ${yu} secrets-run --project ${a} -- <command>`].join(`
316
316
  `));if(n==="login"){let l=s.find(d=>/PASS/i.test(d))??s[0];return et(["A login is a person's, never an agent's: the user runs this in their own terminal, approves it in the browser, and the password sits on the clipboard for 20 seconds, then is cleared:",` ${yu} secrets-copy --project ${a} ${l}`,"Do not run it yourself and do not read the clipboard."].join(`
317
317
  `))}let c=await e("POST","/api/v1/fabric-grants",{action:"account",op:n,project:a,keys:s});return c.ok?et(n==="off"?`Switched off: ${s.join(", ")} of ${a}. Every next use is refused (agents, people, partners); a receipt was left. Switching back on is the key board, for an organisation admin.`:`A person only: ${s.join(", ")} of ${a}. An agent is refused from the next use; the person keeps it. A receipt was left.`):et(`not switched (HTTP ${c.status}): ${String(c.data.why??c.data.error??"")}${Array.isArray(c.data.keys)?` \xB7 ${c.data.keys.join(", ")}`:""}`,!0)}async function VM(e,t,n){let r=n.project?.trim()??"",o=n.agent_name?.trim()??"",i=n.agent_device?.trim()??"";if(!r||!o||!i)return et("agent needs the client's `project`, `agent_name` and `agent_device` (the computer it runs on, its NoData name); `agent_role` and `keys` optionally.",!0);let s=t.accounts.filter(d=>d.project===r).flatMap(d=>d.keys);if(!s.length)return et(`no keys of ${r} in the vault yet: add them first (account_op 'add').`,!0);let a=new Map((t.keys??[]).filter(d=>d.project===r).map(d=>[d.name,d.login])),c=n.keys?.length?n.keys.map(d=>d.trim()).filter(Boolean):s.filter(d=>!a.get(d)),l=await e("POST","/api/v1/fabric-grants",{action:"account",op:"agent",project:r,agent:{name:o,role:n.agent_role?.trim()??"",device:i,keys:c}});return l.ok?et([`${o} is ${r}'s agent: only from ${i}, only ${c.join(", ")||"no key"}. Every other agent is refused ${r}'s keys at the key board; a receipt was left.`,`It works with nodata_run, project "${r}" (keys in the command's memory only). On another computer the key board refuses.`].join(`
318
- `)):l.data.error==="loosens_needs_a_person"?et(`Not from here: this gives the agent more than it has (another computer, more keys). A person does it in the NoData console, on ${r}'s cube, Dial, Its agent.`,!0):et(`not saved (HTTP ${l.status}): ${String(l.data.why??l.data.error??"")}${Array.isArray(l.data.keys)?` \xB7 ${l.data.keys.join(", ")}`:""}`,!0)}var XM="2026-10-02-connect-v1",ZM="/legal/connect-terms",ie=(e,t=!1)=>({content:[{type:"text",text:e}],...t?{isError:t}:{}});function nA(e,t,n,r=()=>!1){let o=Br(t,n);e.registerTool("nodata_partner",{description:"NoData Connect: this organisation's agent working with ANOTHER organisation's agent. Only commands travel between organisations, never files. action 'connections' (default) lists who we are connected to, both directions, and whether our private command card (~/.nodata/commands.json, downloaded from the Connect page) covers them. 'accept' (invite = the link or its token) accepts an invitation with this computer's address, both ways (they send to us and we to them; one_way: true = only they to us); from this computer it waits for its owner to approve that acceptance in the browser (you cannot approve it). 'send' (to = partner name or address, cmd, fields) shapes the fields by OUR card (fields marked never are dropped, masked ones masked), seals them here and sends the command; returns what left and what was held back. 'inbox' opens commands that arrived, checks each against OUR card (a command or field we did not agree to is refused and its fields are not shown), and checks the sender's hash commitment and the signed receipt. 'reply' (to, cmd, fields, reply_to = the id of the command being answered) answers a command. 'invite' (note?, days?, template? (default ping), and to lend keys: project + keys + cap_per_day?) makes an invitation link for ONE partner, naming this computer's address so the partner can answer; our command card for them is written when they accept; from this computer it waits for its owner to approve that exact invitation in the browser (you cannot approve it), and inside an organisation for another admin to sign it too; then returns the link to send them. Keys lent must be split keys of that project (secrets-set). 'invite' with ask: true (project = a short name for the client, keys = the client's key names you need, cap_per_day?) is the other direction, a studio setting up a CLIENT: the client accepts on their own computer, types each key into their own vault, and the rule they accept names THIS computer, which then runs `secrets-run --project <project> --from <client org id> -- <job>`; you never receive the keys. Whoever is invited starts free (the invitation's answer says how many governed decisions a month): say so when you hand over the link. Offer an invitation, once per session, when the user works with someone outside the organisation; make it only after their yes. 'switch_off' (partner = name or address from 'connections') ends a connection we gave: their next request is refused at once. No approval needed \u2014 it only narrows access. 'leave' (partner) ends a connection another organisation gave US: we stop receiving from them, and both organisations get a receipt. No approval needed \u2014 it only narrows access. 'status' (partner) is one partner in one place: both directions, their keys' use today, the invitations we sent them and where each stands, and the Connect page link for the dials the console holds. Before 'accept', give the user the Connect Terms link and pass terms: true only after their yes. 'connections' also lists the invitations we sent, in order: waiting, accepted (by whom) or expired. 'accounts' is the accounts board: the clients' platform accounts (TikTok, Instagram, Google Ads\u2026) and systems (GitHub, Vercel, Supabase, Cloudflare, Stripe\u2026) kept in the vault, one project per client. account_op 'list' (default) shows every client with counts per platform, who may use each key (person / agent / partner), today's use and the last rotation; 'add' (project, platform, account?, use: agent | login | both) and 'rotate' (project + platform/account or keys) give the ONE line the USER runs in their own terminal (values typed hidden: never ask for a value, never run it for them); 'use' says how a job uses it (nodata_run, memory only); 'login' gives the person's line (secrets-copy: browser approval, clipboard for seconds; never run it, never read the clipboard); 'off' switches keys off and 'person_only' refuses agents a login (both only narrow; on again is the key board, an admin); 'agent' sets the client's own agent (agent_name, agent_device = the computer's NoData name, agent_role?, keys = the client's keys it may use, default its tokens): every other agent is refused the client's keys and this one is refused off its computer. From here it may only narrow (a first agent, fewer keys, a rename); giving an agent more (another computer, more keys, removing it) is a person's, in the console's client dial. To have a client keep a key in THEIR own vault: 'invite' with ask: true. Names only, never a value. Each command is shown once. To act on commands without anyone in the loop, the organisation runs `nodata-mcp partner-watch --handler \"<its own program>\"` on its machine: every accepted command goes to that program on stdin, and a printed {\"reply\":{cmd,fields}} is sent back by the card.",inputSchema:{action:fe.enum(["connections","accept","send","inbox","reply","invite","switch_off","leave","status","accounts"]).optional(),account_op:fe.enum(["list","add","rotate","use","login","off","person_only","agent"]).optional().describe("accounts: what to do (default list)"),agent_name:fe.string().optional().describe("accounts agent: the client agent's name"),agent_role:fe.string().optional().describe("accounts agent: its job, in a few words"),agent_device:fe.string().optional().describe("accounts agent: the ONE computer it runs on (its NoData name)"),platform:fe.string().optional().describe("accounts: the platform or system id (tiktok, instagram, facebook, youtube, google_ads, linkedin, x, github, vercel, supabase, cloudflare, stripe\u2026)"),account:fe.string().optional().describe("accounts: the account's name on the platform"),use:fe.enum(["agent","login","both"]).optional().describe("accounts add: an agent posts with a token, a person logs in with a username + password, or both"),invite:fe.string().optional(),to:fe.string().optional(),cmd:fe.string().optional(),fields:fe.record(fe.string(),fe.union([fe.string(),fe.number(),fe.boolean(),fe.null()])).optional(),reply_to:fe.string().optional(),note:fe.string().optional().describe("invite: a note the partner sees"),days:fe.number().int().min(1).max(365).optional().describe("invite: how long the connection lasts once accepted (default 30)"),template:fe.enum(["ping","orders","delivery"]).optional().describe("invite: the kind of collaboration, so both command cards start matching"),project:fe.string().optional().describe("invite: the project whose keys the partner's computer may use \xB7 accounts: the client's project"),keys:fe.array(fe.string()).optional().describe("invite: the key names the partner's computer may use (split keys of `project`) \xB7 accounts: the keys to act on"),cap_per_day:fe.number().int().min(1).max(1e4).optional().describe("invite: at most this many uses a day (omit for no daily cap)"),max_minutes:fe.number().int().min(1).max(1440).optional().describe("invite: the job that uses a key is stopped after this many minutes (omit for no run limit)"),usd_per_day:fe.number().min(.01).max(1e5).optional().describe("invite: at most this many dollars a day, counted from the price each job declares (nodata_run cost_usd / secrets-run --cost); a job that states no price is refused (omit for no dollar cap)"),ask:fe.boolean().optional().describe("invite: true = ask a CLIENT for THEIR keys (project + keys), for this computer to use; false/omitted = lend ours"),approval_id:fe.string().optional().describe("invite / accept: the approval id a previous call returned, after the owner approved it in the browser"),org_approval_id:fe.string().optional().describe("invite / accept: the organisation approval id a previous call returned, after another admin signed it"),partner:fe.string().optional().describe("switch_off / leave / status: the partner's name or address"),one_way:fe.boolean().optional().describe("accept: true = only they send to us; omitted = both ways, so commands can be answered"),terms:fe.boolean().optional().describe(`accept: true only after the user read and agreed to the Connect Terms (${ZM}); recorded on both receipts with the version`)}},async i=>{let s=i.action??"connections";return s==="connections"?tB(o):s==="accept"?uy(o,i.invite??"",r,{approval_id:i.approval_id,org_approval_id:i.org_approval_id,one_way:i.one_way,terms:i.terms}):s==="leave"?nB(o,i.partner??""):s==="status"?rB(o,i.partner??"",t):s==="inbox"?lB(o):s==="invite"?QM(o,i,r):s==="switch_off"?eB(o,i.partner??""):s==="accounts"?tA(o,i):s==="send"||s==="reply"?!i.to||!i.cmd?ie("send needs `to` (partner name or address) and `cmd`.",!0):s==="reply"&&!i.reply_to?ie("reply needs `reply_to`: the id of the command you are answering.",!0):cB(o,i.to,i.cmd,i.fields??{},s==="reply"?i.reply_to:null):ie(`unknown action ${s}`,!0)})}async function QM(e,t,n,r={}){let o=(t.keys??[]).map(m=>m.trim()).filter(Boolean);if(o.length&&!t.project)return ie("to lend keys, name the `project` they belong to.",!0);if(t.ask&&(!t.project||!o.length))return ie("to ask a client for their keys, name the client (`project`, a short name) and the `keys` you need from them.",!0);let i=await Mr(e);if("error"in i&&t.ask)return ie(i.error,!0);let s="error"in i?null:i.kid,a=t.template??"ping",c=o.length?{project:t.project,keys:o,cap_per_day:t.cap_per_day??null,...t.max_minutes?{max_minutes:t.max_minutes}:{},...t.usd_per_day?{usd_per_day:t.usd_per_day}:{}}:null,l={action:"invite",...t.note?{note:t.note}:{},...t.days?{grant_days:t.days}:{},template:a,...s?{my_kid:s}:{},...c?t.ask?{ask:c}:{work:c}:{}},d=await ps(e,l,{approval_id:t.approval_id,org_approval_id:t.org_approval_id},n,"nodata_partner",'action "invite", the same arguments',r);if("text"in d)return d.text;let u=d;if(u.status===400&&u.data.error==="work_keys_unknown")return ie(`These are not split keys of project ${t.project}: ${(u.data.missing??o).join(", ")}. Set them first, on this computer: npx -y @nodatachat/mcp@latest secrets-set --project ${t.project} <KEY>`,!0);if(u.status===400&&u.data.error==="ask_needs_computer")return ie("Asking a client for keys needs this computer connected as one of your organisation's computers (the client's rule names it): npx -y @nodatachat/mcp@latest connect, then ask again.",!0);if(!u.ok)return ie(`could not make the invitation (HTTP ${u.status}): ${String(u.data.error??"")}${u.data.why?` \u2014 ${String(u.data.why)}`:""}`,!0);let p=String(u.data.invite_url??""),f=typeof u.data.invite_nonce=="string"?u.data.invite_nonce:"",h=typeof u.data.template=="string"&&u.data.template in tc?u.data.template:null;if(f&&h)try{iu({...ou(),[f]:h})}catch{}let g=s?`When they accept, both of you can send (${h??"ping"} commands): your command card for them is written on this computer then.`:"This computer has no address yet, so they can send to you but not answer; run npx -y @nodatachat/mcp@latest connect for both ways.",y=typeof u.data.expires_at=="string"?u.data.expires_at.slice(0,10):"",_=Ix(u.data);if(t.ask)return ie([`Invitation made for your client. Send them this link (it works once${y?`, until ${y}`:""}):`,p,`They open the link in their browser, sign in, type each key there (hidden: ${o.join(", ")}) and approve. Nothing to install. You never receive the keys.`,`Prefer a terminal? On their own computer: npx -y @nodatachat/mcp@latest setup "${p}" (it asks for the keys, hidden, at the end).`,`Once they have, this computer runs each job with: npx -y @nodatachat/mcp@latest secrets-run --project ${t.project} --from <their org id> -- <job> (nodata_partner connections shows the id after they accept).`,_].filter(Boolean).join(`
318
+ `)):l.data.error==="loosens_needs_a_person"?et(`Not from here: this gives the agent more than it has (another computer, more keys). A person does it in the NoData console, on ${r}'s cube, Dial, Its agent.`,!0):et(`not saved (HTTP ${l.status}): ${String(l.data.why??l.data.error??"")}${Array.isArray(l.data.keys)?` \xB7 ${l.data.keys.join(", ")}`:""}`,!0)}var XM="2026-10-02-connect-v1",ZM="/legal/connect-terms",ie=(e,t=!1)=>({content:[{type:"text",text:e}],...t?{isError:t}:{}});function nA(e,t,n,r=()=>!1){let o=Br(t,n);e.registerTool("nodata_partner",{description:"NoData Connect: this organisation's agent working with ANOTHER organisation's agent. Only commands travel between organisations, never files. action 'connections' (default) lists who we are connected to, both directions, and whether our private command card (~/.nodata/commands.json, downloaded from the Connect page) covers them. 'accept' (invite = the link or its token) accepts an invitation with this computer's address, both ways (they send to us and we to them; one_way: true = only they to us); from this computer it waits for its owner to approve that acceptance in the browser (you cannot approve it). 'send' (to = partner name or address, cmd, fields) shapes the fields by OUR card (fields marked never are dropped, masked ones masked), seals them here and sends the command; returns what left and what was held back. 'inbox' opens commands that arrived, checks each against OUR card (a command or field we did not agree to is refused and its fields are not shown), and checks the sender's hash commitment and the signed receipt. 'reply' (to, cmd, fields, reply_to = the id of the command being answered) answers a command. 'invite' (note?, days?, template? (default ping), and to lend keys: project + keys + cap_per_day?) makes an invitation link for ONE partner, naming this computer's address so the partner can answer; our command card for them is written when they accept; from this computer it waits for its owner to approve that exact invitation in the browser (you cannot approve it), and inside an organisation for another admin to sign it too; then returns the link to send them. Keys lent must be split keys of that project (secrets-set). 'invite' with ask: true (project = a short name for the client, keys = the client's key names you need, cap_per_day?) is the other direction, a studio setting up a CLIENT: the client accepts on their own computer, types each key into their own vault, and the rule they accept names THIS computer, which then runs `secrets-run --project <project> --from <client org id> -- <job>`; you never receive the keys. Whoever is invited starts free (the invitation's answer says how many governed decisions a month): say so when you hand over the link. Offer an invitation, once per session, when the user works with someone outside the organisation; make it only after their yes. 'switch_off' (partner = name or address from 'connections') ends a connection we gave: their next request is refused at once. No approval needed \u2014 it only narrows access. 'leave' (partner) ends a connection another organisation gave US: we stop receiving from them, and both organisations get a receipt. No approval needed \u2014 it only narrows access. 'status' (partner) is one partner in one place: both directions, their keys' use today, the invitations we sent them and where each stands, and the Connect page link for the dials the console holds. Before 'accept', give the user the Connect Terms link and pass terms: true only after their yes. 'connections' also lists the invitations we sent, in order: waiting, accepted (by whom) or expired. 'accounts' is the accounts board: the clients' platform accounts (TikTok, Instagram, Google Ads\u2026) and systems (GitHub, Vercel, Supabase, Cloudflare, Stripe\u2026) kept in the vault, one project per client. account_op 'list' (default) shows every client with counts per platform, who may use each key (person / agent / partner), today's use and the last rotation; 'add' (project, platform, account?, use: agent | login | both) and 'rotate' (project + platform/account or keys) give the ONE line the USER runs in their own terminal (values typed hidden: never ask for a value, never run it for them); 'use' says how a job uses it (nodata_run, memory only); 'login' gives the person's line (secrets-copy: browser approval, clipboard for seconds; never run it, never read the clipboard); 'off' switches keys off and 'person_only' refuses agents a login (both only narrow; on again is the key board, an admin); 'agent' sets the client's own agent (agent_name, agent_device = the computer's NoData name, agent_role?, keys = the client's keys it may use, default its tokens): every other agent is refused the client's keys and this one is refused off its computer. From here it may only narrow (a first agent, fewer keys, a rename); giving an agent more (another computer, more keys, removing it) is a person's, in the console's client dial. To have a client keep a key in THEIR own vault: 'invite' with ask: true. Names only, never a value. Each command is shown once. To act on commands without anyone in the loop, the organisation runs `nodata-mcp partner-watch --handler \"<its own program>\"` on its machine: every accepted command goes to that program on stdin, and a printed {\"reply\":{cmd,fields}} is sent back by the card.",inputSchema:{action:fe.enum(["connections","accept","send","inbox","reply","invite","switch_off","leave","status","accounts"]).optional(),account_op:fe.enum(["list","add","rotate","use","login","off","person_only","agent"]).optional().describe("accounts: what to do (default list)"),agent_name:fe.string().optional().describe("accounts agent: the client agent's name"),agent_role:fe.string().optional().describe("accounts agent: its job, in a few words"),agent_device:fe.string().optional().describe("accounts agent: the ONE computer it runs on (its NoData name)"),platform:fe.string().optional().describe("accounts: the platform or system id (tiktok, instagram, facebook, youtube, google_ads, linkedin, x, github, vercel, supabase, cloudflare, stripe\u2026)"),account:fe.string().optional().describe("accounts: the account's name on the platform"),use:fe.enum(["agent","login","both"]).optional().describe("accounts add: an agent posts with a token, a person logs in with a username + password, or both"),invite:fe.string().optional(),to:fe.string().optional(),cmd:fe.string().optional(),fields:fe.record(fe.string(),fe.union([fe.string(),fe.number(),fe.boolean(),fe.null()])).optional(),reply_to:fe.string().optional(),note:fe.string().optional().describe("invite: a note the partner sees"),days:fe.number().int().min(1).max(365).optional().describe("invite: how long the connection lasts once accepted (default 30)"),template:fe.enum(["ping","orders","delivery"]).optional().describe("invite: the kind of collaboration, so both command cards start matching"),project:fe.string().optional().describe("invite: the project whose keys the partner's computer may use \xB7 accounts: the client's project"),keys:fe.array(fe.string()).optional().describe("invite: the key names the partner's computer may use (split keys of `project`) \xB7 accounts: the keys to act on"),cap_per_day:fe.number().int().min(1).max(1e4).optional().describe("invite: at most this many uses a day (omit for no daily cap)"),max_minutes:fe.number().int().min(1).max(1440).optional().describe("invite: the job that uses a key is stopped after this many minutes (omit for no run limit)"),usd_per_day:fe.number().min(.01).max(1e5).optional().describe("invite: at most this many dollars a day, counted from the price each job declares (nodata_run cost_usd / secrets-run --cost); a job that states no price is refused (omit for no dollar cap)"),ask:fe.boolean().optional().describe("invite: true = ask a CLIENT for THEIR keys (project + keys), for this computer to use; false/omitted = lend ours"),approval_id:fe.string().optional().describe("invite / accept: the approval id a previous call returned, after the owner approved it in the browser"),org_approval_id:fe.string().optional().describe("invite / accept: the organisation approval id a previous call returned, after another admin signed it"),partner:fe.string().optional().describe("switch_off / leave / status: the partner's name or address"),one_way:fe.boolean().optional().describe("accept: true = only they send to us; omitted = both ways, so commands can be answered"),terms:fe.boolean().optional().describe(`accept: true only after the user read and agreed to the Connect Terms (${ZM}); recorded on both receipts with the version`)}},async i=>{let s=i.action??"connections";return s==="connections"?tB(o):s==="accept"?uy(o,i.invite??"",r,{approval_id:i.approval_id,org_approval_id:i.org_approval_id,one_way:i.one_way,terms:i.terms}):s==="leave"?nB(o,i.partner??""):s==="status"?rB(o,i.partner??"",t):s==="inbox"?lB(o):s==="invite"?QM(o,i,r):s==="switch_off"?eB(o,i.partner??""):s==="accounts"?tA(o,i):s==="send"||s==="reply"?!i.to||!i.cmd?ie("send needs `to` (partner name or address) and `cmd`.",!0):s==="reply"&&!i.reply_to?ie("reply needs `reply_to`: the id of the command you are answering.",!0):cB(o,i.to,i.cmd,i.fields??{},s==="reply"?i.reply_to:null):ie(`unknown action ${s}`,!0)})}async function QM(e,t,n,r={}){let o=(t.keys??[]).map(m=>m.trim()).filter(Boolean);if(o.length&&!t.project)return ie("to lend keys, name the `project` they belong to.",!0);if(t.ask&&(!t.project||!o.length))return ie("to ask a client for their keys, name the client (`project`, a short name) and the `keys` you need from them.",!0);let i=await Mr(e);if("error"in i)return ie(`No invitation was sent: this computer has no address, so your partner could send to you but you could not answer. ${i.error} Then invite again (npx -y @nodatachat/mcp@latest connect sets up the address).`,!0);let s=i.kid,a=t.template??"ping",c=o.length?{project:t.project,keys:o,cap_per_day:t.cap_per_day??null,...t.max_minutes?{max_minutes:t.max_minutes}:{},...t.usd_per_day?{usd_per_day:t.usd_per_day}:{}}:null,l={action:"invite",...t.note?{note:t.note}:{},...t.days?{grant_days:t.days}:{},template:a,my_kid:s,...c?t.ask?{ask:c}:{work:c}:{}},d=await ps(e,l,{approval_id:t.approval_id,org_approval_id:t.org_approval_id},n,"nodata_partner",'action "invite", the same arguments',r);if("text"in d)return d.text;let u=d;if(u.status===400&&u.data.error==="work_keys_unknown")return ie(`These are not split keys of project ${t.project}: ${(u.data.missing??o).join(", ")}. Set them first, on this computer: npx -y @nodatachat/mcp@latest secrets-set --project ${t.project} <KEY>`,!0);if(u.status===400&&u.data.error==="ask_needs_computer")return ie("Asking a client for keys needs this computer connected as one of your organisation's computers (the client's rule names it): npx -y @nodatachat/mcp@latest connect, then ask again.",!0);if(!u.ok)return ie(`could not make the invitation (HTTP ${u.status}): ${String(u.data.error??"")}${u.data.why?` \u2014 ${String(u.data.why)}`:""}`,!0);let p=String(u.data.invite_url??""),f=typeof u.data.invite_nonce=="string"?u.data.invite_nonce:"",h=typeof u.data.template=="string"&&u.data.template in tc?u.data.template:null;if(f&&h)try{iu({...ou(),[f]:h})}catch{}let g=`When they accept, both of you can send (${h??"ping"} commands): your command card for them is written on this computer then.`,y=typeof u.data.expires_at=="string"?u.data.expires_at.slice(0,10):"",_=Ix(u.data);if(t.ask)return ie([`Invitation made for your client. Send them this link (it works once${y?`, until ${y}`:""}):`,p,`They open the link in their browser, sign in, type each key there (hidden: ${o.join(", ")}) and approve. Nothing to install. You never receive the keys.`,`Prefer a terminal? On their own computer: npx -y @nodatachat/mcp@latest setup "${p}" (it asks for the keys, hidden, at the end).`,`Once they have, this computer runs each job with: npx -y @nodatachat/mcp@latest secrets-run --project ${t.project} --from <their org id> -- <job> (nodata_partner connections shows the id after they accept).`,_].filter(Boolean).join(`
319
319
  `));let v=o.length?` When they accept from their computer, it may use ${o.join(", ")} (project ${t.project}${t.cap_per_day?`, up to ${t.cap_per_day} a day`:""}) under a rule on your key board; your half is shared with that computer only when you approve it.`:"";return ie(`Invitation made. Send this link to the partner (it works once${y?`, until ${y}`:""}):
320
320
  ${p}
321
321
  They open it, or run on their computer: npx -y @nodatachat/mcp@latest setup ${p}${v}
@@ -437,7 +437,7 @@ Finish it once in the console (Recovery setup), then wrap again. NoData never se
437
437
  `),S.length>0&&k.length===0)})}ui();import{createHash as Qy}from"node:crypto";import{appendFileSync as $H,existsSync as EH,mkdirSync as AH,readFileSync as TH}from"node:fs";import{homedir as GT}from"node:os";import{join as VT}from"node:path";var e_=[{id:"overview",topics:["what","nodata","does","do","product","about","can","\u05DE\u05D4","\u05E2\u05D5\u05E9\u05D4","\u05D9\u05D5\u05D3\u05E2","\u05DE\u05D5\u05E6\u05E8","\u05E0\u05D5 \u05D3\u05D0\u05D8\u05D4","\u05D9\u05DB\u05D5\u05DC\u05D5\u05EA"],answer:"NoData keeps sensitive information safe where you work: on your computer and in your AI agents' work. It finds what is exposed in your files (ID numbers, cards, bank numbers, phones, emails, names, API keys: in text, Excel, Word, PowerPoint and PDF), locks files so only the approved computer that sealed them can open them, makes clean copies to work on, runs commands with secrets they never write to disk, shares files through links you can cancel, gives AI agents access to exactly the columns you allow, and keeps a proof of every step. Scanning and clean copies run entirely on this computer; locking encrypts here and registers at NoData only a key half sealed to this computer."},{id:"privacy",topics:["safe","secure","privacy","private","who can see","trust","upload","\u05D1\u05D8\u05D5\u05D7","\u05E4\u05E8\u05D8\u05D9\u05D5\u05EA","\u05DE\u05D9 \u05D9\u05DB\u05D5\u05DC \u05DC\u05E8\u05D0\u05D5\u05EA","\u05DE\u05D9 \u05E8\u05D5\u05D0\u05D4","\u05D4\u05DE\u05D9\u05D3\u05E2 \u05E9\u05DC\u05D9","\u05E2\u05D5\u05DC\u05D4 \u05DC\u05E2\u05E0\u05DF","\u05D0\u05DE\u05D5\u05DF"],answer:"Where your information stays: scanning and clean copies (nodata_scan_folder, nodata_redact) run on this computer and upload nothing, and the scan reports counts and places, not the values. Locking (nodata_protect) encrypts on this computer; the file never leaves it, and NoData receives only the file key sealed to this computer's key, which only this computer opens. A locked file opens on the computer that sealed it and on the same person's other connected computers (its key is sealed to each of them, each with its own key), after NoData checks that computer, a person approves the opening, and a proof is recorded. A file sent with nodata_send is stored by NoData only as ciphertext, with the key in the part of the link NoData never receives. An archive made with nodata_wrap opens only with your organisation's 12 words."},{id:"capsule",topics:["capsule","ndc","\u05E7\u05E4\u05E1\u05D5\u05DC\u05D4","\u05E7\u05E4\u05E1\u05D5\u05DC\u05D5\u05EA"],answer:"A capsule is a file sealed so it opens only under its own policy: on the approved computer that sealed it (nodata_protect, a .ndc file; it also opens on your other connected computers; every opening is recorded and can be revoked), as a governed link with expiry and cancel (nodata_send), or to your organisation's 12-word key (nodata_wrap)."},{id:"scan",topics:["scan","find","folder","exposed","sensitive","pii","report","\u05E1\u05E8\u05D9\u05E7\u05D4","\u05DC\u05E1\u05E8\u05D5\u05E7","\u05DC\u05DE\u05E6\u05D5\u05D0","\u05EA\u05D9\u05E7\u05D9\u05D9\u05D4","\u05E8\u05D2\u05D9\u05E9","\u05D7\u05E9\u05D5\u05E3","\u05D3\u05D5\u05D7"],answer:"nodata_scan_folder scans a folder on this computer and reports what is exposed: checksum-validated Israeli IDs, credit cards (Luhn), IBANs, phones, emails, names and addresses, and hard-coded keys and passwords. It reads Excel, Word, PowerPoint and PDF, including Hebrew. The result shows counts by type, folder and file, a full HTML report, and a line saying how many documents were read. Nothing is uploaded."},{id:"pdf",topics:["pdf","scanned","ocr","hebrew","read","document","\u05E1\u05E8\u05D5\u05E7","\u05E1\u05E8\u05D9\u05E7\u05D4","\u05E2\u05D1\u05E8\u05D9\u05EA","\u05DE\u05E1\u05DE\u05DA","\u05DC\u05E7\u05E8\u05D5\u05D0","\u05E7\u05E8\u05D9\u05D0\u05D4"],answer:"PDFs are read by NoData's own reader, including Hebrew and documents stamped by marking tools. With two free tools installed on this computer it reads more: Poppler (pdftotext) reads every PDF a second time, and Tesseract reads scanned pages (OCR). They run only here. See what is installed: npx -y @nodatachat/mcp@latest pdf-tools"},{id:"gate",topics:["claude","read","gate","block","ask before","\u05E7\u05DC\u05D5\u05D3","\u05E1\u05D5\u05DB\u05DF","\u05D7\u05E1\u05D9\u05DE\u05D4","\u05DC\u05D7\u05E1\u05D5\u05DD","\u05E9\u05E2\u05E8","\u05E7\u05E8\u05D0","\u05E7\u05D5\u05E8\u05D0","\u05D9\u05E7\u05E8\u05D0"],answer:"The read gate asks you before Claude Code reads a file where the scan found sensitive data, or refuses it if you choose. It also covers env files and never lets an agent read the device key. Turn it on in a terminal: npx -y @nodatachat/mcp@latest install-gate (add --block to refuse instead of asking)."},{id:"protect",topics:["lock","protect","encrypt","seal","unlock","release","\u05E0\u05E2\u05D9\u05DC\u05D4","\u05DC\u05E0\u05E2\u05D5\u05DC","\u05E0\u05D5\u05E2\u05DC","\u05E0\u05E2\u05D5\u05DC","\u05D4\u05E6\u05E4\u05E0\u05D4","\u05DC\u05D4\u05E6\u05E4\u05D9\u05DF","\u05DE\u05E6\u05E4\u05D9\u05DF","\u05DC\u05E4\u05EA\u05D5\u05D7"],answer:"nodata_protect locks files: each is sealed as <file>.ndc (AES-256-GCM) to this computer's key, which never leaves it. Locking needs this computer to be connected and approved by a person in the organisation: every seal belongs to that computer, is registered at NoData with a signed proof (NoData holds only a key half sealed to this computer), and can be revoked. Given a folder, it locks the files the scan found exposure in. nodata_open opens a sealed file back next to it, only on the computer that sealed it, and checks its hash; the opening is recorded. A kept original is still readable, so for .env secrets use nodata_run. nodata_policy lists every sealed file of the organisation, which computer it belongs to and its openings; nodata_seal_revoke opens the console where a person revokes one for good (a leaked file, a lost computer). Both show what they will do and ask before acting."},{id:"redact",topics:["clean","copy","redact","anonymise","anonymize","share","work","\u05E2\u05D5\u05EA\u05E7","\u05E0\u05E7\u05D9","\u05D4\u05EA\u05DE\u05DE\u05D4","\u05DC\u05D4\u05E1\u05EA\u05D9\u05E8","\u05DC\u05E2\u05D1\u05D5\u05D3"],answer:"nodata_redact makes a clean copy to work on: IDs, cards, IBANs, phones, emails and keys become typed tokens ([ID], [CARD], [SECRET] \u2026); in Excel and CSV a personal-data column becomes one stable token per person, so the copy still groups and counts. The copy is re-scanned before it is handed back, and a receipt is written."},{id:"plan",topics:["policy","recommend","plan","decide","what to do","\u05DE\u05D3\u05D9\u05E0\u05D9\u05D5\u05EA","\u05D4\u05DE\u05DC\u05E6\u05D4","\u05EA\u05D5\u05DB\u05E0\u05D9\u05EA","\u05DE\u05D4 \u05DC\u05E2\u05E9\u05D5\u05EA"],answer:"nodata_plan recommends a policy per file after a scan \u2014 a tier (Restricted / Confidential / Internal) and an action: clean copy, lock, both, or keep \u2014 and applies it only after you approve. Leaked keys also get where-and-how-to-replace steps per provider."},{id:"scan-feedback",topics:["false positive","wrong","mistake","missed","not sensitive","feedback","report","\u05D8\u05E2\u05D5\u05EA","\u05E9\u05D2\u05D5\u05D9","\u05E4\u05E1\u05E4\u05E1","\u05DC\u05D0 \u05E8\u05D2\u05D9\u05E9","\u05DE\u05E9\u05D5\u05D1","\u05D3\u05D9\u05D5\u05D5\u05D7"],answer:'When a scan gets it wrong, say so: nodata_scan_feedback reports what it flagged that is not sensitive and what kinds it missed. Only kind labels and counts leave your machine ("ID\xD72 not sensitive \xB7 phone\xD71 missed") \u2014 never a value, a file name or free text \u2014 and you see the exact line sent. It changes no file; to leave a file alone use nodata_plan with keep.'},{id:"secrets",topics:["secret","secrets","env",".env","key","keys","password","token","vault","run","\u05E1\u05D5\u05D3","\u05E1\u05D5\u05D3\u05D5\u05EA","\u05DE\u05E4\u05EA\u05D7","\u05DE\u05E4\u05EA\u05D7\u05D5\u05EA","\u05E1\u05D9\u05E1\u05DE\u05D4","\u05DB\u05E1\u05E4\u05EA"],answer:"Secrets reach a command without a .env on disk. In a terminal: npx -y @nodatachat/mcp@latest secrets-login --project <name> once, then npx -y @nodatachat/mcp@latest secrets-run -- <command>; the secrets exist only in that command's memory. An agent does the same with nodata_run: every command needs your approval, and the output it sees has every secret value blanked."},{id:"leaked-keys",topics:["leaked","leak","rotate","rotation","git","history","commit","exposed key","\u05D3\u05DC\u05E3","\u05D3\u05DC\u05D9\u05E4\u05D4","\u05DC\u05D4\u05D7\u05DC\u05D9\u05E3","\u05D2\u05D9\u05D8","\u05D4\u05D9\u05E1\u05D8\u05D5\u05E8\u05D9\u05D4"],answer:"The scan finds API keys and passwords written in files (OpenAI, Anthropic, Supabase, AWS, Stripe, database URLs and more) and, with git_history, in past commits too \u2014 including ones deleted since. nodata_plan then lists, per provider, where to replace each key, which is the step that stops its use."},{id:"send",topics:["send","share","link","burn","revoke","expire","recipient","\u05DC\u05E9\u05DC\u05D5\u05D7","\u05DC\u05E9\u05EA\u05E3","\u05E7\u05D9\u05E9\u05D5\u05E8","\u05DC\u05D1\u05D8\u05DC","\u05DC\u05E9\u05E8\u05D5\u05E3","\u05E0\u05DE\u05E2\u05DF"],answer:"nodata_send shares a file as a governed link (or, with to:<NoData address>, over the NoData road \u2014 see fabric): encrypted on this computer, stored by NoData only as ciphertext, with the key in the part of the link NoData never receives. It expires after a time and a number of opens; nodata_link_status shows opens so far; nodata_burn cancels it for good, with a signed receipt. With code:true (or your own code of 8+ letters) the link opens only together with a code you send on a different channel; the recipient types it and their browser checks it, and NoData never receives it \u2014 a forwarded link alone opens nothing."},{id:"fabric",topics:["fabric","road","network","address","partner","organisation","organization","other company","inbox","mcp to mcp","\u05E4\u05D1\u05E8\u05D9\u05E7","\u05E8\u05E9\u05EA","\u05DB\u05EA\u05D5\u05D1\u05EA","\u05E9\u05D5\u05EA\u05E3","\u05D0\u05E8\u05D2\u05D5\u05DF \u05D0\u05D7\u05E8","\u05D7\u05D1\u05E8\u05D4 \u05D0\u05D7\u05E8\u05EA","\u05EA\u05D9\u05D1\u05D4","\u05D3\u05D5\u05D0\u05E8 \u05E0\u05DB\u05E0\u05E1","\u05D1\u05D9\u05DF \u05D0\u05E8\u05D2\u05D5\u05E0\u05D9\u05DD"],answer:"The NoData road (Fabric) connects this computer to other organisations with no link to leak. nodata_inbox (action 'address') makes this computer's address: a key pair made here, the private half never leaves it (~/.nodata/fabric-key.json), NoData knows only its fingerprint. A partner sends with nodata_send to:<address> \u2014 or to your email once your computers are on the road, and it reaches each of them \u2014 (or from the console); it is sealed on their computer to yours, NoData stores ciphertext only, and a proof is written on both organisations' chains before anything moves. nodata_inbox 'list' shows what arrived, 'open' unseals it here into a folder without showing its content to the agent."},{id:"fabric-plate",topics:["who can send","who can reach","approve","block","spam","unknown sender","plate","policy","disclose","\u05DE\u05D9 \u05D9\u05DB\u05D5\u05DC \u05DC\u05E9\u05DC\u05D5\u05D7","\u05DC\u05D0\u05E9\u05E8","\u05DC\u05D7\u05E1\u05D5\u05DD","\u05E9\u05D5\u05DC\u05D7 \u05DC\u05D0 \u05DE\u05D5\u05DB\u05E8","\u05DC\u05D5\u05D7\u05D9\u05EA","\u05DE\u05D3\u05D9\u05E0\u05D9\u05D5\u05EA","\u05DC\u05D7\u05E9\u05D5\u05E3","\u05DE\u05D4 \u05E8\u05D5\u05D0\u05D9\u05DD \u05E2\u05DC\u05D9\u05D9"],answer:"Your address carries a plate \u2014 its policy, changeable any time with nodata_inbox action 'policy': open, verified (a first message from an unknown organisation waits, still sealed, until you approve or block it) or closed (only your allow list); allow and block lists; whether a sender must declare a purpose; and what senders learn about you (organisation name, only 'verified', or just the address). nodata_inbox 'approve' admits a waiting sender and delivers what it sent; 'block' refuses it and shreds what it sent, unread. Every decision is on both sides' proof chains, and each asks you first."},{id:"file-folder-rules",topics:["rules","rule","folder rules","file rules","folder policy","per folder","per file","agent may","block folder","\u05D7\u05D5\u05E7\u05D9\u05DD","\u05DB\u05DC\u05DC\u05D9\u05DD","\u05DE\u05D3\u05D9\u05E0\u05D9\u05D5\u05EA \u05DC\u05EA\u05D9\u05E7\u05D9\u05D9\u05D4"],answer:"nodata_rules is the board of rules for each file and folder on this computer: what an AI agent may do there \u2014 allowed, ask you, clean copy only (it works on a nodata_redact copy), or not allowed \u2014 with several rules per path and conditions on the action (read, search, run, write), the hour, the weekday and the file type. The most specific path decides; among its rules, the first whose conditions hold. The read gate enforces them on every read, search, command and write, whatever the agent. Tightening is a preview then confirm; allowing a path, or removing a restriction, needs your own approval. The rules are signed on this computer: changed by hand, every path they name is closed until you save them again. Your organisation can also set folder rules for every computer (in the browser: the capsule page \u2192 the organisation's folder rules); they arrive with its policy, and on your computer the stricter of its rule and yours wins. For keys, each key has its own rules in the vault (Courier \u2192 secrets \u2192 key policy board), applied by nodata_run."},{id:"access-not-copies",topics:["access instead","not send","without sending","ownership","copy","query","share data","expose","folder","partner ask","\u05D2\u05D9\u05E9\u05D4","\u05D1\u05DC\u05D9 \u05DC\u05E9\u05DC\u05D5\u05D7","\u05D1\u05E2\u05DC\u05D5\u05EA","\u05D4\u05E2\u05EA\u05E7","\u05DC\u05E9\u05EA\u05E3 \u05DE\u05D9\u05D3\u05E2","\u05DC\u05D7\u05E9\u05D5\u05E3","\u05D7\u05E9\u05D9\u05E4\u05D4","\u05EA\u05D9\u05E7\u05D9\u05D9\u05D4","\u05DC\u05EA\u05EA \u05D2\u05D9\u05E9\u05D4"],answer:"Most sharing should be access, not a copy. For files on this computer: nodata_expose lets a partner's computer ask for files in a folder you choose \u2014 it gets the verified clean copy of each file it asks for (identifiers replaced, checked before it leaves), only while the rule lives, and you stop it at once; they ask with nodata_inbox action 'ask'. For your tables: the other side's agent gets a scoped grant (nodata_grant) and reads only the fields it is allowed (nodata_retrieve / nodata_read), cut at once with nodata_revoke. A file moves whole only when a copy must: nodata_send, as a governed link or over the NoData road."},{id:"archive",topics:["archive","wrap","backup","recovery","12 words","lost","\u05D0\u05E8\u05DB\u05D9\u05D5\u05DF","\u05D2\u05D9\u05D1\u05D5\u05D9","\u05E9\u05D7\u05D6\u05D5\u05E8","12 \u05DE\u05D9\u05DC\u05D9\u05DD","\u05D0\u05D1\u05D3"],answer:"nodata_wrap archives files encrypted on this computer to your organisation's 12-word key; only ciphertext is uploaded, and only your 12 words (or recovery file) open it \u2014 even if this computer is lost."},{id:"key-backup",topics:["device key","back up","backup","usb","lost computer","\u05DE\u05E4\u05EA\u05D7 \u05D4\u05DE\u05DB\u05E9\u05D9\u05E8","\u05DE\u05E4\u05EA\u05D7","\u05D2\u05D9\u05D1\u05D5\u05D9","\u05DC\u05D2\u05D1\u05D5\u05EA","\u05DE\u05D2\u05D1\u05D9\u05DD","\u05DE\u05D2\u05D1\u05D4","\u05D3\u05D9\u05E1\u05E7 \u05D0\u05D5\u05DF \u05E7\u05D9"],answer:"Locked files open on the computer that sealed them, with its device key. Back it up once, in a terminal: npx -y @nodatachat/mcp@latest key-backup E: (E: is your USB drive): it copies the key, checks the copy is identical, and records the backup."},{id:"agents-data",topics:["agent","agents","database","table","grant","access","columns","revoke","ai","\u05E1\u05D5\u05DB\u05E0\u05D9\u05DD","\u05D8\u05D1\u05DC\u05D4","\u05DE\u05E1\u05D3","\u05D4\u05E8\u05E9\u05D0\u05D4","\u05D2\u05D9\u05E9\u05D4","\u05E2\u05DE\u05D5\u05D3\u05D5\u05EA"],answer:"AI agents get exactly what you allow over your own tables: nodata_register_table declares the sensitive columns, nodata_grant gives one agent a scoped grant (after your approval), nodata_policy shows every agent and what it can reach, and nodata_revoke cuts it at once. An agent asks with nodata_decide, pulls allowed fields with nodata_retrieve, and denied columns never decrypt."},{id:"proofs",topics:["proof","proofs","receipt","audit","verify","evidence","\u05D4\u05D5\u05DB\u05D7\u05D4","\u05D4\u05D5\u05DB\u05D7\u05D5\u05EA","\u05E7\u05D1\u05DC\u05D4","\u05D1\u05D9\u05E7\u05D5\u05E8\u05EA","\u05DC\u05D0\u05DE\u05EA"],answer:"nodata_proofs lists your organisation's signed proofs \u2014 every grant, agent read and denial \u2014 content-free. Anyone can verify one without an account at /api/access/verify. Locking, clean copies and cancelled links write their own receipts too."},{id:"start",topics:["start","install","connect","signup","setup","begin","\u05DC\u05D4\u05EA\u05D7\u05D9\u05DC","\u05DE\u05EA\u05D7\u05D9\u05DC\u05D9\u05DD","\u05D4\u05EA\u05E7\u05E0\u05D4","\u05D4\u05E8\u05E9\u05DE\u05D4","\u05D7\u05D9\u05D1\u05D5\u05E8"],answer:"Accept the terms once (nodata_terms) and scanning, locking and clean copies work on this computer. For the organisation tools (agents, sending, proofs) call nodata_connect: a page opens in your browser, you sign in (or create a free account) and click Approve \u2014 nothing to copy. Then type /mcp."}],qT=Qy("sha256").update(JSON.stringify(e_)).digest("hex").slice(0,12);function PH(e,t){return e.topics.reduce((n,r)=>n+(t.includes(r.toLowerCase())?1:0),0)}function RH(e){let t=` ${e.toLowerCase()} `,r=e_.map(o=>({a:o,s:PH(o,t)})).filter(o=>o.s>0).sort((o,i)=>i.s-o.s).filter(o=>o.a.id!=="overview").slice(0,3).map(o=>o.a);return r.length?r:[e_[0]]}var Zy=()=>VT(GT(),".nodata","answers.log");function NH(e){let t="genesis";try{let r=EH(Zy())?TH(Zy(),"utf8").trimEnd().split(`
438
438
  `):[],o=r[r.length-1];o&&(t=Qy("sha256").update(o).digest("hex").slice(0,16))}catch{}let n=JSON.stringify({at:new Date().toISOString(),entries:e,bank:qT,prev:t});try{AH(VT(GT(),".nodata"),{recursive:!0}),$H(Zy(),n+`
439
439
  `,{mode:384})}catch{}return Qy("sha256").update(n).digest("hex").slice(0,16)}function zT(e){let t=RH(e),n=NH(t.map(r=>r.id));return["ANSWER FROM THE NODATA ANSWER BANK \u2014 relay this in the user's language, and nothing beyond it:","",...t.map(r=>`\u2022 ${r.answer}`),"",`Source: NoData answer bank ${qT} \xB7 entries: ${t.map(r=>r.id).join(", ")} \xB7 recorded ${n} in ~/.nodata/answers.log`].join(`
440
- `)}ga();import{existsSync as QT,mkdirSync as OH,readFileSync as CH,writeFileSync as IH}from"node:fs";import{homedir as r_}from"node:os";import{join as o_}from"node:path";var DH=60*6e4;function jH(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}var t_=()=>o_(r_(),".nodata","connection.json"),LH=()=>o_(r_(),".nodata","pending-link.json"),n_=6e4,YT=15*n_,JT=[3e4,2*n_,5*n_];function XT(e,t){switch(e.connection){case"connected":return{state:"connected"};case"unstable":case"offline":return{state:"reconnecting"};case"restart":return{state:"restart",step:"/mcp"};case"not-connected":return t?{state:"waiting"}:{state:"local"};case"reconnect":return t?{state:"waiting"}:{state:"needs-you",step:e.refused==="org-has-no-key"?"console \u2192 API keys":e.refused==="flag-key"||e.refused==="env-key"?"remove the old key":"nodata_connect"}}}function Vu(e,t=new Date){try{OH(o_(r_(),".nodata"),{recursive:!0});let n=t.toISOString(),r={};for(let[o,i]of Object.entries(FH()?.versions??{}))t.getTime()-Date.parse(i.at)<DH&&jH(Number(o))&&(r[o]=i);e.version&&(r[String(process.pid)]={version:e.version,at:n}),IH(t_(),JSON.stringify({...e,...Object.keys(r).length?{versions:r}:{},at:n}),{mode:384})}catch{}}function FH(){try{return QT(t_())?JSON.parse(CH(t_(),"utf8")):null}catch{return null}}var ZT=()=>QT(LH());function MH(e,t){return e==="reconnecting"?JT[Math.min(t,JT.length-1)]??YT:e==="waiting"?3e4:YT}function e1(e,t,n,r){let o=0,i=n?{version:n}:{},s=XT(t,ZT());Vu({...s,...i});let a=null,c=()=>{a=setTimeout(l,MH(s.state,o)),a.unref?.()},l=async()=>{try{let d=XT(await e(),ZT());o=d.state==="reconnecting"?o+1:0,(d.state!==s.state||d.step!==s.step)&&r?.(d),s=d,Vu({...d,...i})}catch{o+=1}c()};return c(),()=>{a&&clearTimeout(a)}}mt();import{homedir as v1,hostname as QH,userInfo as e3}from"node:os";import{join as u1,resolve as qu}from"node:path";import{existsSync as a_,readFileSync as u_,writeFileSync as t3,mkdirSync as n3}from"node:fs";import{spawn as zu,spawnSync as Yu}from"node:child_process";import{generateKeyPairSync as r3,createPrivateKey as o3,sign as i3,randomBytes as s3}from"node:crypto";async function t1(e=process.env){if(!(e.HTTPS_PROXY||e.https_proxy||e.HTTP_PROXY||e.http_proxy)||/^(1|true)$/i.test(e.NODE_USE_ENV_PROXY??""))return!1;try{let{EnvHttpProxyAgent:t,setGlobalDispatcher:n}=await import("undici");return n(new t),!0}catch{return!1}}import{readFileSync as BH}from"node:fs";function vs(e=process.env,t=process.platform,n=r1()){return!(t==="linux"&&!n&&!e.DISPLAY&&!e.WAYLAND_DISPLAY)}function n1(e=process.env,t=process.platform,n=r1()){return e.VITEST||/^(1|true|yes)$/i.test(e.NODATA_NO_BROWSER??"")?!1:vs(e,t,n)}function r1(){try{return process.platform==="linux"&&/microsoft/i.test(BH("/proc/version","utf8"))}catch{return!1}}var tr="1.6.27";function Ju(e=process.cwd()){try{let t=St(e),n=t?kf(t):null;if(!n||!a_(n))return null;let r=JSON.parse(u_(n,"utf8"));if(!r)return null;let o=r.device&&typeof r.device.private_key_pkcs8_b64=="string",i=typeof r.api_key=="string"&&r.api_key;return o||i?r:null}catch{return null}}function c_(e,t=process.cwd()){let n=fl(e);if(!n)throw new Error("nothing to save: no organisation in the credential");Hw(n,e),t&&Uw(t,n)}var a3=`nodata-mcp v${tr} \u2014 NoData MCP server
440
+ `)}ga();import{existsSync as QT,mkdirSync as OH,readFileSync as CH,writeFileSync as IH}from"node:fs";import{homedir as r_}from"node:os";import{join as o_}from"node:path";var DH=60*6e4;function jH(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}var t_=()=>o_(r_(),".nodata","connection.json"),LH=()=>o_(r_(),".nodata","pending-link.json"),n_=6e4,YT=15*n_,JT=[3e4,2*n_,5*n_];function XT(e,t){switch(e.connection){case"connected":return{state:"connected"};case"unstable":case"offline":return{state:"reconnecting"};case"restart":return{state:"restart",step:"/mcp"};case"not-connected":return t?{state:"waiting"}:{state:"local"};case"reconnect":return t?{state:"waiting"}:{state:"needs-you",step:e.refused==="org-has-no-key"?"console \u2192 API keys":e.refused==="flag-key"||e.refused==="env-key"?"remove the old key":"nodata_connect"}}}function Vu(e,t=new Date){try{OH(o_(r_(),".nodata"),{recursive:!0});let n=t.toISOString(),r={};for(let[o,i]of Object.entries(FH()?.versions??{}))t.getTime()-Date.parse(i.at)<DH&&jH(Number(o))&&(r[o]=i);e.version&&(r[String(process.pid)]={version:e.version,at:n}),IH(t_(),JSON.stringify({...e,...Object.keys(r).length?{versions:r}:{},at:n}),{mode:384})}catch{}}function FH(){try{return QT(t_())?JSON.parse(CH(t_(),"utf8")):null}catch{return null}}var ZT=()=>QT(LH());function MH(e,t){return e==="reconnecting"?JT[Math.min(t,JT.length-1)]??YT:e==="waiting"?3e4:YT}function e1(e,t,n,r){let o=0,i=n?{version:n}:{},s=XT(t,ZT());Vu({...s,...i});let a=null,c=()=>{a=setTimeout(l,MH(s.state,o)),a.unref?.()},l=async()=>{try{let d=XT(await e(),ZT());o=d.state==="reconnecting"?o+1:0,(d.state!==s.state||d.step!==s.step)&&r?.(d),s=d,Vu({...d,...i})}catch{o+=1}c()};return c(),()=>{a&&clearTimeout(a)}}mt();import{homedir as v1,hostname as QH,userInfo as e3}from"node:os";import{join as u1,resolve as qu}from"node:path";import{existsSync as a_,readFileSync as u_,writeFileSync as t3,mkdirSync as n3}from"node:fs";import{spawn as zu,spawnSync as Yu}from"node:child_process";import{generateKeyPairSync as r3,createPrivateKey as o3,sign as i3,randomBytes as s3}from"node:crypto";async function t1(e=process.env){if(!(e.HTTPS_PROXY||e.https_proxy||e.HTTP_PROXY||e.http_proxy)||/^(1|true)$/i.test(e.NODE_USE_ENV_PROXY??""))return!1;try{let{EnvHttpProxyAgent:t,setGlobalDispatcher:n}=await import("undici");return n(new t),!0}catch{return!1}}import{readFileSync as BH}from"node:fs";function vs(e=process.env,t=process.platform,n=r1()){return!(t==="linux"&&!n&&!e.DISPLAY&&!e.WAYLAND_DISPLAY)}function n1(e=process.env,t=process.platform,n=r1()){return e.VITEST||/^(1|true|yes)$/i.test(e.NODATA_NO_BROWSER??"")?!1:vs(e,t,n)}function r1(){try{return process.platform==="linux"&&/microsoft/i.test(BH("/proc/version","utf8"))}catch{return!1}}var tr="1.6.28";function Ju(e=process.cwd()){try{let t=St(e),n=t?kf(t):null;if(!n||!a_(n))return null;let r=JSON.parse(u_(n,"utf8"));if(!r)return null;let o=r.device&&typeof r.device.private_key_pkcs8_b64=="string",i=typeof r.api_key=="string"&&r.api_key;return o||i?r:null}catch{return null}}function c_(e,t=process.cwd()){let n=fl(e);if(!n)throw new Error("nothing to save: no organisation in the credential");Hw(n,e),t&&Uw(t,n)}var a3=`nodata-mcp v${tr} \u2014 NoData MCP server
441
441
 
442
442
  ADMIN mode: nodata-mcp --api-key sk_live_...
443
443
  AGENT mode: nodata-mcp --grant-token ndca-...
@@ -1,4 +1,4 @@
1
- /*! @nodatachat/mcp 1.6.27 | Copyright 2026 Capsule Ltd. | FSL-1.1-ALv2 | see LICENSE.md */
1
+ /*! @nodatachat/mcp 1.6.28 | Copyright 2026 Capsule Ltd. | FSL-1.1-ALv2 | see LICENSE.md */
2
2
  import{createRequire as __ndReq}from"node:module";const require=__ndReq(import.meta.url);
3
3
  import{parentPort as At}from"node:worker_threads";import{createHash as Js}from"node:crypto";import{closeSync as Ys,existsSync as qs,openSync as Qs,readSync as eo,readdirSync as mr,readFileSync as to,statSync as xt}from"node:fs";import{homedir as no}from"node:os";import{basename as gr,join as Ge}from"node:path";import{TextDecoder as Sr}from"node:util";var Q={text:[],header:[],secrets:[],table:null,amounts:null,severity:null};function Tt(e){e.table&&(Q.table=e.table),e.severity&&(Q.severity=e.severity),e.amounts&&(Q.amounts=e.amounts);for(let t of e.text??[])Q.text.some(n=>n.kind===t.kind)||Q.text.push(t);e.header&&!Q.header.includes(e.header)&&Q.header.push(e.header);for(let t of e.secrets??[])Q.secrets.some(n=>n.id===t.id)||Q.secrets.push(t)}function Ye(e){return Q.severity?.(e)}function qe(){return Q.text}function yn(){return Q.header}function Ce(){return Q.table}function bn(){return Q.secrets}var _n=[{id:"aws-access-key",name:"AWS Access Key",pattern:/(?:^|[^A-Z0-9])AKIA(?!X{16})[A-Z2-7]{16}(?:[^A-Z2-7]|$)/,severity:"critical"},{id:"aws-secret-key",name:"AWS Secret Key",pattern:/(?:aws_secret_access_key|aws_secret_key|secret_access_key)\s*[=:]\s*['"]?[A-Za-z0-9/+=]{40}['"]?/,severity:"critical"},{id:"gcp-api-key",name:"GCP API Key",pattern:/AIza[0-9A-Za-z_-]{35}/,severity:"critical"},{id:"gcp-service-account",name:"GCP Service Account",pattern:/"type"\s*:\s*"service_account"/,severity:"critical"},{id:"github-token",name:"GitHub Token",pattern:/gh[pousr]_[0-9a-zA-Z]{36,}/,severity:"critical"},{id:"github-fine-grained",name:"GitHub Fine-Grained Token",pattern:/github_pat_[0-9a-zA-Z_]{22,}/,severity:"critical"},{id:"gitlab-token",name:"GitLab Token",pattern:/glpat-[0-9a-zA-Z_-]{20,}/,severity:"critical"},{id:"stripe-secret",name:"Stripe Secret Key",pattern:/sk_live_[0-9a-zA-Z]{24,}/,severity:"critical"},{id:"stripe-restricted",name:"Stripe Restricted Key",pattern:/rk_live_[0-9a-zA-Z]{24,}/,severity:"critical"},{id:"slack-token",name:"Slack Token",pattern:/xox[baprs]-[0-9a-zA-Z-]{10,}/,severity:"high"},{id:"slack-webhook",name:"Slack Webhook",pattern:/hooks\.slack\.com\/services\/T[0-9A-Z]{8,}\/B[0-9A-Z]{8,}\/[0-9a-zA-Z]{24}/,severity:"high"},{id:"twilio-api-key",name:"Twilio API Key",pattern:/SK[0-9a-fA-F]{32}/,severity:"high"},{id:"sendgrid-api-key",name:"SendGrid API Key",pattern:/SG\.[0-9a-zA-Z_-]{22}\.[0-9a-zA-Z_-]{43}/,severity:"critical"},{id:"postgres-uri",name:"PostgreSQL Connection String",pattern:/postgres(?:ql)?:\/\/[^\s'"]{10,}/,severity:"critical"},{id:"mongodb-uri",name:"MongoDB Connection String",pattern:/mongodb(?:\+srv)?:\/\/[^\s'"]{10,}/,severity:"critical"},{id:"redis-uri",name:"Redis Connection String",pattern:/redis(?:s)?:\/\/[^\s'"]{10,}/,severity:"high"},{id:"openai-key",name:"OpenAI API Key",pattern:/sk-[0-9a-zA-Z]{20,}T3BlbkFJ[0-9a-zA-Z]{20,}/,severity:"critical"},{id:"openai-project-key",name:"OpenAI API Key",pattern:/sk-(?:proj|svcacct|admin)-[0-9A-Za-z_-]{40,}/,severity:"critical"},{id:"anthropic-key",name:"Anthropic API Key",pattern:/sk-ant-[0-9a-zA-Z_-]{40,}/,severity:"critical"},{id:"firebase-key",name:"Firebase API Key",pattern:/AIza[0-9A-Za-z_-]{35}/,severity:"high"},{id:"supabase-key",name:"Supabase Service Key",pattern:/eyJ[0-9a-zA-Z_-]{100,}/,severity:"critical"},{id:"supabase-access-token",name:"Supabase Access Token",pattern:/\bsbp_[0-9a-f]{40}\b/,severity:"critical"},{id:"supabase-secret-key",name:"Supabase Secret Key",pattern:/\bsb_secret_[0-9A-Za-z_-]{20,}/,severity:"critical"},{id:"private-key",name:"Private Key",pattern:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/,severity:"critical"},{id:"jwt-secret",name:"JWT/Generic Secret",pattern:/(?:jwt_secret|JWT_SECRET|secret_key|SECRET_KEY|api_secret|API_SECRET)\s*[=:]\s*['"][^'"]{8,}['"]/,severity:"high"},{id:"password-in-code",name:"Password in Code",pattern:/(?:password|passwd|pwd)\s*[=:]\s*['"][^'"]{8,}['"]/,severity:"high"},{id:"bearer-token",name:"Bearer Token in Code",pattern:/['"]Bearer\s+[0-9a-zA-Z._-]{20,}['"]/,severity:"high"}];function Lt(){let e=bn().filter(t=>!_n.some(n=>n.id===t.id));return[..._n,...e]}var xn=/node_modules\/|\.next\/|\.test\.|\.spec\.|__tests__\/|\.nodata-proof\.json$|\.git\//,wn=/(^|\/)\.env(\.[\w-]+)*\.(example|sample|template|dist)$|\.(example|sample|template)$|(^|\/)[^/]*\.(example|sample)\.[a-z0-9]+$/i,Ct=/(^|\/)(__tests__|__mocks__|tests?|spec|fixtures?|mocks?|samples?|examples?|demo|testdata)(\/|$)|\.(test|spec)\.[a-z0-9]+$|\.min\.(m?js|css)$|(^|\/)[^/]*\.worker\.min\.m?js$/i,Kr=[{name:"lodash",below:"4.17.21",severity:"critical",cve:"CVE-2021-23337",desc:"Command injection via template"},{name:"minimist",below:"1.2.6",severity:"critical",cve:"CVE-2021-44906",desc:"Prototype pollution"},{name:"json5",below:"2.2.2",severity:"high",cve:"CVE-2022-46175",desc:"Prototype pollution"},{name:"express",below:"4.19.2",severity:"high",cve:"CVE-2024-29041",desc:"Open redirect"},{name:"path-to-regexp",below:"6.3.0",severity:"high",cve:"CVE-2024-45296",desc:"ReDoS"},{name:"sanitize-html",below:"2.12.1",severity:"high",cve:"CVE-2024-21501",desc:"XSS bypass"},{name:"dompurify",below:"3.0.9",severity:"high",cve:"CVE-2024-45801",desc:"mXSS"},{name:"jsonwebtoken",below:"9.0.0",severity:"critical",cve:"CVE-2022-23529",desc:"Key confusion attack"},{name:"jose",below:"4.15.5",severity:"high",cve:"CVE-2024-28176",desc:"DoS via JWE"},{name:"axios",below:"1.6.0",severity:"high",cve:"CVE-2023-45857",desc:"CSRF cookie leak"},{name:"node-fetch",below:"2.6.7",severity:"high",cve:"CVE-2022-0235",desc:"Header leak on redirect"},{name:"serialize-javascript",below:"6.0.2",severity:"critical",cve:"CVE-2024-11831",desc:"XSS via serialization"},{name:"xml2js",below:"0.6.0",severity:"high",cve:"CVE-2023-0842",desc:"Prototype pollution"},{name:"next",below:"14.1.1",severity:"high",cve:"CVE-2024-34350",desc:"SSRF via headers"},{name:"sharp",below:"0.32.6",severity:"high",cve:"CVE-2023-4863",desc:"libwebp heap overflow"},{name:"multer",below:"1.4.5",severity:"high",cve:"CVE-2022-24434",desc:"Prototype pollution"},{name:"tough-cookie",below:"4.1.3",severity:"medium",cve:"CVE-2023-26136",desc:"Prototype pollution"},{name:"semver",below:"7.5.4",severity:"medium",cve:"CVE-2022-25883",desc:"ReDoS"},{name:"ip",below:"2.0.1",severity:"critical",cve:"CVE-2024-29415",desc:"SSRF bypass via octal IP"},{name:"tar",below:"6.2.1",severity:"high",cve:"CVE-2024-28863",desc:"DoS via path traversal"}];function Jr(e,t){let n=s=>s.replace(/^[^0-9]*/,"").split(".").map(o=>parseInt(o,10)||0),r=n(e),i=n(t);for(let s=0;s<3;s++){if((r[s]||0)<(i[s]||0))return!0;if((r[s]||0)>(i[s]||0))return!1}return!1}function vn(e){let t=[],n;try{n=JSON.parse(e)}catch{return t}let r={...n.dependencies??{},...n.devDependencies??{}};for(let[i,s]of Object.entries(r)){let o=(s||"").replace(/^[\^~>=<\s]+/,""),a=Kr.find(c=>c.name===i&&Jr(o,c.below));a&&t.push({name:i,version:o,vuln:a})}return t}var Yr=[{pattern:/^(full_?name|first_?name|last_?name|spouse_?name|beneficiary_?name)$/i,type:"name",label:"Person name"},{pattern:/^(email|e_?mail|email_?address)$/i,type:"email",label:"Email address"},{pattern:/^(phone|mobile|telephone|phone_?number|cell_?phone)$/i,type:"phone",label:"Phone number"},{pattern:/^(id_?number|identity|ssn|social_?security|national_?id|teudat_?zehut)$/i,type:"id",label:"ID number"},{pattern:/^(address|street_?address|home_?address)$/i,type:"address",label:"Address"},{pattern:/^(date_?of_?birth|dob|birth_?date|birthday)$/i,type:"dob",label:"Date of birth"},{pattern:/^(bank_?account|iban|account_?number|bank_?details|routing_?number)$/i,type:"financial",label:"Bank account"},{pattern:/^(credit_?card|card_?number|cvv|cc_?number)$/i,type:"financial",label:"Credit card"},{pattern:/^(salary|income|commission|premium|compensation)$/i,type:"financial",label:"Salary / income"},{pattern:/^(medical_?info|health_?conditions|diagnosis|medication|prescription)$/i,type:"medical",label:"Medical"},{pattern:/^(passport|passport_?number|passport_?id)$/i,type:"id",label:"Passport"},{pattern:/^(driver_?license|drivers_?license|dl_?number)$/i,type:"id",label:"Driver license"},{pattern:/^(tax_?id|tin|vat_?number|ein)$/i,type:"financial",label:"Tax ID"},{pattern:/^(insurance_?number|policy_?number|member_?id)$/i,type:"id",label:"Insurance/Policy"},{pattern:/^(biometric|fingerprint|face_?id|retina)$/i,type:"biometric",label:"Biometric"},{pattern:/^(latitude|longitude|lat|lng|geo_?location|coordinates)$/i,type:"location",label:"Geolocation"}],qr=[{pattern:/^(?:שם|שם_מלא|שם פרטי|שם_פרטי|שם משפחה|שם_משפחה|שם הלקוח|שם בן זוג|שם המבוטח|שם המוטב|שם הילד|שם הקטין)$/i,type:"name",label:"\u05E9\u05DD \u05D0\u05D3\u05DD"},{pattern:/^(?:ת"ז|ת\.ז|ת ז|תז|תעודת זהות|תעודת_זהות|מספר זהות|מס' זהות|teudat_zehut|tz|israeli_id|il_id)$/i,type:"id",label:"\u05EA\u05E2\u05D5\u05D3\u05EA \u05D6\u05D4\u05D5\u05EA"},{pattern:/^(?:דרכון|מספר דרכון|רישיון נהיגה|רישיון_נהיגה|רשיון נהיגה)$/i,type:"id",label:"\u05D3\u05E8\u05DB\u05D5\u05DF/\u05E8\u05D9\u05E9\u05D9\u05D5\u05DF"},{pattern:/^(?:מייל|דוא"ל|דוא_ל|דואר אלקטרוני|אימייל|כתובת מייל)$/i,type:"email",label:"\u05D3\u05D5\u05D0\u05E8 \u05D0\u05DC\u05E7\u05D8\u05E8\u05D5\u05E0\u05D9"},{pattern:/^(?:טלפון|טל'|נייד|פלאפון|סלולרי|מספר טלפון|טלפון נייד)$/i,type:"phone",label:"\u05DE\u05E1\u05E4\u05E8 \u05D8\u05DC\u05E4\u05D5\u05DF"},{pattern:/^(?:כתובת|כתובת מגורים|רחוב|מס בית|עיר|ישוב|יישוב|מיקוד|כתובת מלאה|מען)$/i,type:"address",label:"\u05DB\u05EA\u05D5\u05D1\u05EA"},{pattern:/^(?:תאריך לידה|ת לידה|תאריך הולדת|יום הולדת|גיל)$/i,type:"dob",label:"\u05EA\u05D0\u05E8\u05D9\u05DA \u05DC\u05D9\u05D3\u05D4"},{pattern:/^(?:חשבון בנק|מספר חשבון|מס חשבון|סניף|iban|iban_il)$/i,type:"financial",label:"\u05D7\u05E9\u05D1\u05D5\u05DF \u05D1\u05E0\u05E7"},{pattern:/^(?:כרטיס אשראי|מספר אשראי|cvv|אשראי)$/i,type:"financial",label:"\u05DB\u05E8\u05D8\u05D9\u05E1 \u05D0\u05E9\u05E8\u05D0\u05D9"},{pattern:/^(?:שכר|משכורת|הכנסה|פרמיה|שכר ברוטו|שכר נטו|תגמול|בונוס|פיצוי)$/i,type:"financial",label:"\u05E9\u05DB\u05E8/\u05D4\u05DB\u05E0\u05E1\u05D4"},{pattern:/^(?:אבחון|אבחנה|מחלה|תרופה|מרשם|בדיקה רפואית|מצב רפואי|חיסון|רגישות|אלרגיה|סוג דם)$/i,type:"medical",label:"\u05DE\u05D9\u05D3\u05E2 \u05E8\u05E4\u05D5\u05D0\u05D9"},{pattern:/^(?:מספר פוליסה|מס פוליסה|פוליסה|מספר חבר|מספר ביטוח)$/i,type:"id",label:"\u05E4\u05D5\u05DC\u05D9\u05E1\u05D4/\u05D7\u05D1\u05E8\u05D5\u05EA"},{pattern:/^(?:שם הילד|תעודת זהות של ילד|ילדים|קטין|מספר ילדים|תעודת לידה)$/i,type:"minor_data",label:"\u05DE\u05D9\u05D3\u05E2 \u05E2\u05DC \u05E7\u05D8\u05D9\u05DF"},{pattern:/^(?:דת|לאום|מין|נטייה מינית|השקפה פוליטית|מצב משפחתי|עדה|מוצא)$/i,type:"sensitive_personal",label:"\u05DE\u05D9\u05D3\u05E2 \u05D0\u05D9\u05E9\u05D9 \u05E8\u05D2\u05D9\u05E9"},{pattern:/^(?:מספר רכב|מס רכב|לוחית רישוי|מספר רישוי)$/i,type:"tracking",label:"\u05DE\u05E1\u05E4\u05E8 \u05E8\u05DB\u05D1"}],Qr=/^(id|uuid|created_?at|updated_?at|deleted_?at|status|type|category|description|title|slug|url|path|key|value|enabled|active|public|version|metadata|config|settings|data|content|note|comment|label|color|icon)$/i,ei=/^שם[ _](?:ה)?(?:קובץ|מוצר|פריט|חברה|ארגון|עסק|פרויקט|גיליון|טבלה|שדה|קטגוריה|סניף|בנק|עיר|רחוב|ישוב|יישוב|מסמך|תוכנית|חבילה|קורס|מחלקה|אתר|דומיין|מותג|ספק|שירות|תפקיד)$|^(file|product|item|company|org|organization|project|sheet|table|field|category|branch|bank|city|street|document|plan|course|department|site|domain|brand|vendor|service|role)[ _-]?name$/i;function _e(e){if(!e)return null;let t=e.trim();if(Qr.test(t)||/^name$/i.test(t)||/^\[[A-Z_]+(?:-\d+)?\]$/.test(t))return null;let n=t.replace(/[\s-]+/g,"_");for(let r of[...qr,...Yr])if(r.pattern.test(t)||r.pattern.test(n))return{type:r.type,label:r.label};if(ei.test(t))return null;if(/^שם[ _][\u0590-\u05FF"'׳ ]{2,20}$/.test(t))return{type:"name",label:"\u05E9\u05DD \u05D0\u05D3\u05DD"};if(/^(customer|client|employee|inspector|supervisor|contact|person|patient|user|owner|manager|agent|member|driver|tenant|student|parent|beneficiary|insured)_?(full_?)?name$/i.test(n))return{type:"name",label:"Person name"};for(let r of yn()){let i=r(t);if(i)return{type:i.type,label:i.label}}return null}var Qe={id:"critical",financial:"critical",medical:"critical",biometric:"critical",minor_data:"critical",sensitive_personal:"critical",email:"high",phone:"high",name:"high",address:"high",dob:"high",tracking:"medium",location:"high",auth:"critical",employment:"medium",education:"medium",behavior:"high"};function et(e){let t=String(e??"").replace(/\D/g,"");if(t.length===0||t.length>9)return!1;let n=t.padStart(9,"0"),r=0;for(let i=0;i<9;i++){let s=parseInt(n[i]??"0",10)*(i%2+1);s>9&&(s-=9),r+=s}return r%10===0&&parseInt(n,10)>0}var Pt=/(?<!\d)(?<!\d[.,])(?:\+972[\s-]?|0)(?:5[0-9]|7[0-9]|[2-4]|[89])(?:[\s-]?\d){7}(?!\d)(?![.,]\d)/g;var Oe=/\bIL\d{2}\s?(?:\d{4}\s?){4}\d{3}\b/g;function ti(e){let t=String(e??"").replace(/\D/g,"");if(t.length<12||t.length>19)return!1;let n=0,r=!1;for(let i=t.length-1;i>=0;i-=1){let s=parseInt(t[i]??"0",10);r&&(s*=2,s>9&&(s-=9)),n+=s,r=!r}return n%10===0}function tt(e){let t=String(e??"").replace(/\s/g,"").toUpperCase();if(!/^[A-Z]{2}\d{2}[A-Z0-9]{10,30}$/.test(t))return!1;let n=t.slice(4)+t.slice(0,4),r=0;for(let i of n){let s=i>="A"&&i<="Z"?String(i.charCodeAt(0)-55):i;for(let o of s)r=(r*10+Number(o))%97}return r===1}var $t="(?<!\\d)(?<!\\d[.,])",Rt="(?!\\d)(?![.,]\\d)",De=[{subkind:"israeli_id",severity:"high",pattern:new RegExp(`${$t}(?:\\d{8}-\\d|\\d{9})${Rt}`,"g"),validate:et,hint:"Israeli national ID (check digit verified) in plaintext. Encrypt the column or mask it at rest."},{subkind:"credit_card",severity:"critical",pattern:new RegExp(`${$t}[2-6][ -]?(?:\\d[ -]?){11,17}\\d${Rt}`,"g"),validate:ti,hint:"Payment card number (Luhn verified) in plaintext. This is PCI scope."},{subkind:"iban",severity:"high",pattern:/\b[A-Z]{2}\d{2}(?: ?[A-Z0-9]{4}){2,7}(?: ?[A-Z0-9]{1,4})?\b/g,validate:tt,hint:"Bank account in IBAN form (mod-97 verified) in plaintext."},{subkind:"israeli_phone",severity:"medium",pattern:new RegExp(`${$t}(?:\\+972[- ]?|0)(?:[57]\\d|[2-489])[- ]?\\d{3}[- ]?\\d{4}${Rt}`,"g"),validate:e=>{let t=e.replace(/\D/g,"").replace(/^972/,"0");return/^0[57]\d{8}$/.test(t)?!0:/^0[2-489]\d{7}$/.test(t)&&(/[- ]/.test(e)||e.startsWith("+972"))},hint:"Israeli phone number in plaintext."}];function kn(e){if(e.length!==14&&e.length!==17)return!1;let t=+e.slice(0,4),n=+e.slice(4,6),r=+e.slice(6,8),i=+e.slice(8,10),s=+e.slice(10,12),o=+e.slice(12,14);return t>=1970&&t<=2099&&n>=1&&n<=12&&r>=1&&r<=31&&i<24&&s<60&&o<60}function Sn(e){let t=Number(e);return!Number.isSafeInteger(t)||t<1024?!1:Number.isInteger(Math.log2(t))||t%1048576===0}var ni=new Set(["000000018","123456782","111111118","222222226","333333334","999999998","4111111111111111","4242424242424242","4000056655665556","5555555555554444","5105105105105100","2223003122003222","378282246310005","371449635398431","6011111111111117","3056930009020004","4012888888881881","4000000000000002"]);function Pe(e){return ni.has(e.replace(/\D/g,""))}function nt(e){let t=e.replace(/\D/g,"");return kn(t)||Sn(t)}function Ne(e,t){let n=[];for(let r of De){r.pattern.lastIndex=0;let i=new Set,s,o=0;for(;(s=r.pattern.exec(e))!==null&&(o+=1,!(o>2e5));){let a=s[0];if(!(r.subkind!=="iban"&&r.subkind!=="israeli_phone"&&nt(a))&&(r.validate(a)&&i.add(a.replace(/[\s-]/g,"")),i.size>=1e5))break}if(i.size>0){if(t)for(let c of i)Pe(c)||t(r.subkind,c);let a=[...i].filter(c=>!Pe(c)).length;n.push({subkind:r.subkind,severity:a===0?"low":r.severity,hint:a===0?`${r.hint} All ${i.size} are published test numbers.`:r.hint,count:i.size,real:a})}}for(let r of qe()){let i=new Set;for(let s of r.find(e))i.add(e.slice(s.start,s.end).trim());i.size>0&&n.push({subkind:r.kind,severity:r.severity,hint:r.hint,count:i.size})}return n}function Fe(e,t){let n=[],r="",i=!1;for(let s=0;s<e.length;s++){let o=e[s];i?o==='"'&&e[s+1]==='"'?(r+='"',s++):o==='"'?i=!1:r+=o:o==='"'?i=!0:o===t?(n.push(r),r=""):r+=o}return n.push(r),n}import{inflateRawSync as ns}from"node:zlib";import{inflateSync as En}from"node:zlib";var Me=new Set([".pdf"]),An=8*1024*1024;function rt(e){let t=e.toString("latin1"),n=new Map,r=/(\d+)\s+(\d+)\s+obj\b/g,i;for(;(i=r.exec(t))!==null;){let s=Number(i[1]),o=r.lastIndex,a=t.indexOf("endobj",o);if(a<0)continue;let c=t.indexOf("stream",o),l,p=null;if(c>=0&&c<a){l=t.slice(o,c);let u=c+6;t[u]==="\r"&&(u+=1),t[u]===`
4
4
  `&&(u+=1);let h=t.indexOf("endstream",u);h>u&&(p=e.subarray(u,h))}else l=t.slice(o,a);n.set(s,{num:s,dict:l,stream:p})}for(let s of[...n.values()]){if(!s.stream||!/\/Type\s*\/ObjStm\b/.test(s.dict))continue;let o=je(s),a=Number(/\/N\s+(\d+)/.exec(s.dict)?.[1]??0),c=Number(/\/First\s+(\d+)/.exec(s.dict)?.[1]??-1);if(o===null||!a||c<0)continue;let l=o.slice(0,c).trim().split(/\s+/).map(Number);for(let p=0;p<a;p+=1){let u=l[2*p],h=l[2*p+1];if(u===void 0||h===void 0||Number.isNaN(u)||Number.isNaN(h))break;let y=p+1<a?l[2*(p+1)+1]:void 0,_=o.slice(c+h,y!==void 0?c+y:void 0);n.has(u)||n.set(u,{num:u,dict:_,stream:null})}}return n}function Ot(e){let t=[...e.replace(/\s+/g,"")];if(t.length<40)return!1;let n=0,r=0;for(let i of t){let s=i.codePointAt(0)??0;s<32||s>=127&&s<=191||s===65533||s>=57344&&s<=63743?n+=1:/[\p{L}\p{N}]/u.test(i)&&(r+=1)}return n/t.length>.2||r/t.length<.25}function ri(e){let t=e.toString("latin1").replace(/\s/g,"");t.startsWith("<~")&&(t=t.slice(2));let n=t.indexOf("~>");n>=0&&(t=t.slice(0,n));let r=[],i=0,s=0;for(let o of t){if(o==="z"&&s===0){r.push(0,0,0,0);continue}let a=o.charCodeAt(0)-33;if(a<0||a>84)return null;i=i*85+a,s+=1,s===5&&(r.push(i>>>24&255,i>>>16&255,i>>>8&255,i&255),i=0,s=0)}if(s>0){for(let a=s;a<5;a+=1)i=i*85+84;let o=[i>>>24&255,i>>>16&255,i>>>8&255,i&255];for(let a=0;a<s-1;a+=1)r.push(o[a]??0)}return Buffer.from(r)}function ii(e){let t=e.toString("latin1").replace(/\s/g,"").split(">")[0]??"",n=t.length%2?t+"0":t;return/^[0-9A-Fa-f]*$/.test(n)?Buffer.from(n,"hex"):null}function si(e){let t=/\/Filter\s*(\[[^\]]*\]|\/\w+)/.exec(e);return!t||!t[1]?[]:[...t[1].matchAll(/\/(\w+)/g)].map(n=>n[1]??"")}function je(e,t){if(!e.stream)return null;let n=e.stream;for(let r of si(e.dict)){let i=null;if(r==="FlateDecode")try{i=t!==void 0?En(n,{maxOutputLength:Math.max(1,t)}):En(n)}catch{return null}else if(r==="ASCII85Decode")i=ri(n);else if(r==="ASCIIHexDecode")i=ii(n);else return null;if(i===null)return null;n=i}return n.toString("latin1")}function oi(e){let t=new Map,n=1,r=/begincodespacerange([\s\S]*?)endcodespacerange/.exec(e);if(r&&r[1]){let c=/<([0-9A-Fa-f]+)>/.exec(r[1]);c&&c[1]&&c[1].length>=4&&(n=2)}let i=c=>{let l="";for(let p=0;p+3<c.length+1;p+=4){let u=parseInt(c.slice(p,p+4),16);Number.isFinite(u)&&u>0&&(l+=String.fromCharCode(u))}return l},s=/beginbfchar([\s\S]*?)endbfchar/g,o;for(;(o=s.exec(e))!==null;){let c=/<([0-9A-Fa-f]+)>\s*<([0-9A-Fa-f]*)>/g,l;for(;(l=c.exec(o[1]??""))!==null;)t.set(parseInt(l[1]??"0",16),i(l[2]??""))}let a=/beginbfrange([\s\S]*?)endbfrange/g;for(;(o=a.exec(e))!==null;){let c=o[1]??"",l=/<([0-9A-Fa-f]+)>\s*<([0-9A-Fa-f]+)>\s*<([0-9A-Fa-f]*)>/g,p;for(;(p=l.exec(c))!==null;){let u=parseInt(p[1]??"0",16),h=parseInt(p[2]??"0",16),y=parseInt((p[3]??"0").slice(0,4)||"0",16);if(!(h-u>65535))for(let _=u;_<=h;_+=1)t.set(_,String.fromCharCode(y+(_-u)))}}return{map:t,bytes:n}}function ai(e){let t=new Map,n=[],r=[];for(let s of e.values()){for(let o of s.dict.matchAll(/\/Font\s*<<([\s\S]*?)>>/g))o[1]&&r.push(o[1]);for(let o of s.dict.matchAll(/\/Font\s+(\d+)\s+\d+\s+R/g)){let a=e.get(Number(o[1]));a&&r.push(a.dict)}}let i=new Set;for(let s of r){let o=/\/([^\s/<>[\]()]+)\s+(\d+)\s+\d+\s+R/g,a;for(;(a=o.exec(s))!==null;){let c=`${a[1]}#${a[2]}`;i.has(c)||(i.add(c),n.push([a[1]??"",Number(a[2])]))}}for(let[s,o]of n){let a=e.get(o);if(!a)continue;let c=null,l=/\/ToUnicode\s+(\d+)\s+\d+\s+R/.exec(a.dict);if(l){let u=e.get(Number(l[1])),h=u?je(u):null;h&&(c=oi(h))}if(c||(c=ui(a.dict,e)),!c)continue;let p=t.get(s)??[];p.push(c),t.set(s,p)}return t}var ci=["alef","bet","gimel","dalet","he","vav","zayin","het","tet","yod","finalkaf","kaf","lamed","finalmem","mem","finalnun","nun","samekh","ayin","finalpe","pe","finaltsadi","tsadi","qof","resh","shin","tav"];function li(e){let t=/^uni([0-9A-Fa-f]{4})$/.exec(e)??/^u([0-9A-Fa-f]{4,6})$/.exec(e);if(t)return String.fromCodePoint(parseInt(t[1],16));let n=/^afii(\d{5})$/.exec(e);if(n){let s=Number(n[1]);if(s>=57664&&s<=57690)return String.fromCharCode(1488+(s-57664))}let r=ci.indexOf(e.replace(/hebrew$/,""));return r>=0?String.fromCharCode(1488+r):e==="space"?" ":/^[A-Za-z]$/.test(e)?e:{zero:"0",one:"1",two:"2",three:"3",four:"4",five:"5",six:"6",seven:"7",eight:"8",nine:"9",period:".",comma:",",hyphen:"-",colon:":",slash:"/",at:"@"}[e]??null}function ui(e,t){let n=e,r=/\/Encoding\s+(\d+)\s+\d+\s+R/.exec(e);r&&(n=t.get(Number(r[1]))?.dict??"");let i=/\/Differences\s*\[([^\]]*)\]/.exec(n);if(!i?.[1])return null;let s=new Map,o=0;for(let a of i[1].match(/\d+|\/[^\s/[\]]+/g)??[]){if(/^\d+$/.test(a)){o=Number(a);continue}let c=li(a.slice(1));c!==null&&s.set(o,c),o+=1}return s.size?{map:s,bytes:1}:null}function Cn(e){let t=[];for(let n=0;n<e.length;n+=1){let r=e[n];if(r!=="\\"){t.push(r.charCodeAt(0)&255);continue}let i=e[n+1];if(i===void 0)break;if(i>="0"&&i<="7"){let o="",a=n+1;for(;a<e.length&&o.length<3&&e[a]>="0"&&e[a]<="7";)o+=e[a],a+=1;t.push(parseInt(o,8)&255),n=a-1;continue}let s={n:10,r:13,t:9,b:8,f:12};t.push(s[i]??i.charCodeAt(0)&255),n+=1}return t}function Pn(e){if(e.length<2||e[0]!==254||e[1]!==255)return null;let t="";for(let n=2;n+1<e.length;n+=2)t+=String.fromCharCode((e[n]??0)<<8|(e[n+1]??0));return t}function In(e,t){let n=Pn(e);if(n!==null)return n;if(!t)return e.map(i=>String.fromCharCode(i)).join("");let r="";if(t.bytes===2)for(let i=0;i+1<e.length;i+=2){let s=(e[i]??0)<<8|(e[i+1]??0);r+=t.map.get(s)??""}else for(let i of e)r+=t.map.get(i)??String.fromCharCode(i);return r}function di(e){let t=0;for(let n of e){let r=n.codePointAt(0)??0;/[\p{L}\p{N}]/u.test(n)?t+=1:(r<32||r>=127&&r<=191||r===65533)&&(t-=2)}return t}function Tn(e,t){if(!t||t.length<=1)return In(e,t?.[0]);let n="",r=-1/0;for(let i of t){let s=In(e,i),o=di(s);o>r&&(n=s,r=o)}return n}function fi(e,t){let n="",r="",i,s=!1,o="",a=0,c=null,l=()=>{r.trim()&&(n+=r+`
package/dist/status.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! @nodatachat/mcp 1.6.27 | Copyright 2026 Capsule Ltd. | FSL-1.1-ALv2 | see LICENSE.md */
1
+ /*! @nodatachat/mcp 1.6.28 | Copyright 2026 Capsule Ltd. | FSL-1.1-ALv2 | see LICENSE.md */
2
2
  import{execSync as vn}from"node:child_process";import{existsSync as xn,readFileSync as Z}from"node:fs";import{existsSync as T,mkdirSync as Dn,readdirSync as X,readFileSync as nn,rmSync as An,writeFileSync as Rn,chmodSync as Bn}from"node:fs";import{homedir as L}from"node:os";import{basename as Mn,isAbsolute as en,join as u,relative as tn,resolve as rn}from"node:path";var g=()=>u(L(),".nodata"),on=()=>u(g(),"credentials.json"),b=()=>u(g(),"orgs"),sn=()=>u(g(),"bindings.json"),ln=/^[A-Za-z0-9_.-]{1,80}$/,v=n=>ln.test(n)&&n!=="."&&n!=="..";function F(n){try{return T(n)?JSON.parse(nn(n,"utf8")):null}catch{return null}}function cn(n){return n?n.device?.org_id?n.device.org_id:n.api_key?`key-${(n.key_prefix??n.api_key.slice(0,12)).replace(/[^A-Za-z0-9_-]/g,"")}`:null:null}function E(){return cn(F(on()))}function m(){let n=[],t=E();t&&n.push(t);try{for(let e of X(b()))v(e)&&!n.includes(e)&&T(u(b(),e,"credentials.json"))&&n.push(e)}catch{}return n}function an(n){return n===E()?g():v(n)?u(b(),n):null}var un=n=>process.platform==="win32"||process.platform==="darwin"?n.toLowerCase():n,h=n=>un(rn(n.replace(/^~(?=[\\/]|$)/,L())));function dn(n,t){let e=tn(h(n),h(t));return e===""||!e.startsWith("..")&&!en(e)}function D(){let n=F(sn());return(Array.isArray(n?.bindings)?n.bindings:[]).filter(e=>!!e&&typeof e.folder=="string"&&typeof e.org_id=="string"&&v(e.org_id)).map(e=>e.project===void 0||hn(e.project)===e.project?e:{...e,project:void 0}).map(e=>e.client===void 0||typeof e.client?.org_id=="string"&&fn.test(e.client.org_id)?e:{...e,client:void 0})}var fn=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function gn(n,t=D()){let e=null;for(let s of t)dn(s.folder,n)&&(!e||h(s.folder).length>h(e.folder).length)&&(e=s);return e}function x(n,t=m(),e=D()){if(t.length===0)return{kind:"none"};let s=gn(n,e.filter(c=>t.includes(c.org_id)));return s?{kind:"bound",org_id:s.org_id,folder:s.folder}:t.length===1?{kind:"only",org_id:t[0]}:{kind:"unbound",orgs:t}}function pn(n){let t=x(n);return t.kind==="bound"||t.kind==="only"?t.org_id:null}function hn(n){if(typeof n!="string")return null;let t=n.trim();return t&&t.length<=120&&!/[\u0000-\u001f\\/]/.test(t)?t:null}function A(n,t=process.cwd()){if(m().length===0)return g();let e=n??pn(t);return e?an(e):null}import{homedir as Sn}from"node:os";import{join as d}from"node:path";var R=["\u{1F7E3}","\u{1F535}","\u{1F7E0}","\u{1F7E4}","\u{1F7E1}"];function mn(n){let t=0;for(let e of n)t=t*31+e.codePointAt(0)>>>0;return R[t%R.length]}function B(n,t){let e=(n||"agent").toLowerCase().replace(/[^a-z0-9._-]+/g,"-").slice(0,40);return t?`${e}@${t}`:e}function J(n){return`${mn(n)} ${n}`}var P="2026-09-24-v3";import{existsSync as $n,mkdirSync as Kn,readFileSync as _n,writeFileSync as Un}from"node:fs";import{homedir as yn}from"node:os";import{join as jn}from"node:path";var M=()=>jn(yn(),".nodata","prefs.json");function kn(){try{let n=$n(M())?JSON.parse(_n(M(),"utf8")).lang:null;return n==="he"||n==="en"?n:null}catch{return null}}function wn(){let t=process.env.LC_ALL||process.env.LC_MESSAGES||process.env.LANG||"";try{t||=Intl.DateTimeFormat().resolvedOptions().locale}catch{}return/^(he|iw)(?:[-_.@]|$)/i.test(t)?"he":"en"}function bn(){return kn()??wn()}function r(n,t,e=bn()){return e==="he"?n:t}var On="\x1B[32m",a="\x1B[33m",w="\x1B[31m",N="\x1B[2m",i="\x1B[0m";function f(n){try{return xn(n)?JSON.parse(Z(n,"utf8")):null}catch{return null}}var C="";try{C=Z(0,"utf8")}catch{}var p=Sn(),Nn=f(d(p,".claude","settings.json")),I=(Nn?.hooks?.PreToolUse??[]).flatMap(n=>n.hooks??[]).find(n=>n.command.includes("gate.mjs"))?.command,S=I?I.includes("--block")?"block":"ask":null,Cn=f(d(p,".nodata","consent.json")),Tn=Cn?.terms_version===P,q=f(d(p,".nodata","credentials.json")),Ln=B("claude-code",q?.device?.label),o=[],_;Tn?S?(_=On,o.push(r(`\u05E9\u05E2\u05E8 ${S==="block"?"\u05D7\u05D5\u05E1\u05DD":"\u05E9\u05D5\u05D0\u05DC"}`,`gate ${S}`),r("\u05EA\u05E0\u05D0\u05D9\u05DD \u2713","terms \u2713"))):(_=a,o.push(r("\u05E9\u05E2\u05E8 \u05DB\u05D1\u05D5\u05D9","gate off"))):(_=w,o.push(r("\u05EA\u05E0\u05D0\u05D9 \u05E9\u05D9\u05DE\u05D5\u05E9 \u05DC\u05D0 \u05D0\u05D5\u05E9\u05E8\u05D5 \u2014 nodata_terms","terms not accepted \u2014 nodata_terms")));var l=f(d(p,".nodata","connection.json")),z=l?.at?Date.now()-Date.parse(l.at)<60*6e4:!1,H=`${a}${r("\u05DC\u05D0 \u05DE\u05D7\u05D5\u05D1\u05E8","not connected")}${i}`;z&&l?.state==="waiting"?o.push(`${a}${r("\u05DE\u05DE\u05EA\u05D9\u05DF \u05DC\u05D0\u05D9\u05E9\u05D5\u05E8","waiting for approval")}${i}`):q?!l||!z?o.push(`${a}${r("\u05D7\u05D9\u05D1\u05D5\u05E8 \u05DC\u05D0 \u05E0\u05D1\u05D3\u05E7","connection not checked")}${i}`):l.state==="connected"?o.push(r("\u05DE\u05D7\u05D5\u05D1\u05E8 \u2713","connected \u2713")):l.state==="reconnecting"?o.push(`${a}${r("\u05DE\u05EA\u05D7\u05D1\u05E8 \u05DE\u05D7\u05D3\u05E9\u2026","reconnecting\u2026")}${i}`):l.state==="restart"?o.push(`${a}${r("\u05D0\u05D5\u05E9\u05E8 \u2014 \u05D4\u05E7\u05DC\u05D3 /mcp","approved \u2014 type /mcp")}${i}`):l.state==="needs-you"?o.push(`${w}${r("\u05DC\u05D0 \u05DE\u05D7\u05D5\u05D1\u05E8","not connected")} \u2192 ${l.step??"nodata_connect"}${i}`):o.push(H):o.push(H);var G=m(),y=process.cwd();try{let n=JSON.parse(C);y=n.workspace?.current_dir||n.cwd||y}catch{}if(G.length>1){let n=x(y,G);n.kind==="bound"||n.kind==="only"?o.push(`${r("\u05D0\u05E8\u05D2\u05D5\u05DF","org")} ${n.org_id.slice(0,8)}`):o.push(`${w}${r("\u05D4\u05EA\u05D9\u05E7\u05D9\u05D9\u05D4 \u05DC\u05D0 \u05E9\u05D5\u05D9\u05DB\u05D4 \u05DC\u05D0\u05E8\u05D2\u05D5\u05DF","folder bound to no org")}${i}`)}var K=A(null,y),$=K?f(d(K,"capsule.json")):null;if($){let n=$.last_heartbeat_ok_at?Date.parse($.last_heartbeat_ok_at):NaN,t=Number.isFinite(n)?Math.round((Date.now()-n)/6e4):1/0,e=s=>s<120?r(`${s} \u05D3'`,`${s}m`):r(`${Math.round(s/60)} \u05E9'`,`${Math.round(s/60)}h`);$.revoked?o.push(`${w}${r('\u05D4\u05E6\u05D5\u05DE\u05EA \u05D4\u05D5\u05E9\u05D4\u05D4 \u05E2"\u05D9 \u05D4\u05D0\u05E8\u05D2\u05D5\u05DF',"node paused by org")}${i}`):t<=15?o.push(`${r("\u05E6\u05D5\u05DE\u05EA","node")} \u2713 ${t<1?r("\u05E2\u05DB\u05E9\u05D9\u05D5","now"):e(t)}`):o.push(`${a}${r("\u05E6\u05D5\u05DE\u05EA \u05DC\u05D0 \u05D0\u05D5\u05DE\u05EA","node not verified")}${Number.isFinite(t)?` ${e(t)}`:""}${i}`)}o.push(J(Ln));var U=n=>n.split(".").map(Number),Y=(n,t)=>{let[e,s]=[U(n),U(t)];for(let c=0;c<3;c++)if(e[c]!==s[c])return e[c]>s[c];return!1},Q=[...new Set(Object.values(l?.versions??{}).map(n=>n.version).concat(l?.version??[]))].filter(n=>/^\d+\.\d+\.\d+$/.test(n)),j=Q.reduce((n,t)=>!n||Y(t,n)?t:n,null),O=Q.filter(n=>j&&Y(j,n)),Fn=j?` ${N}v${j}${i}${O.length?` ${a}${r(`(v${O.join(", v")} \u05D1\u05D7\u05DC\u05D5\u05DF \u05D0\u05D7\u05E8: /mcp)`,`(v${O.join(", v")} in another window: /mcp)`)}${i}`:""}`:"",V=`${_}\u25CF NoData${i}${Fn} ${N}\xB7${i} ${o.join(` ${N}\xB7${i} `)}`,W=f(d(p,".nodata","statusline-prev.json"))?.command,k="";if(W)try{k=vn(W,{input:C,timeout:2e3,encoding:"utf8"}).trim()}catch{k=""}process.stdout.write(k?`${k} \u2502 ${V}`:V);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodatachat/mcp",
3
- "version": "1.6.27",
3
+ "version": "1.6.28",
4
4
  "description": "NoData MCP server: connect any MCP client (Claude Code, Codex, Cursor, VS Code) to the NoData Information Access Processor. Governed access for AI agents, with a verifiable proof for every decision.",
5
5
  "bin": {
6
6
  "nodata-mcp": "dist/index.js"