@visiq/claude-code-harness 0.1.2 → 0.1.4
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/README.md +14 -4
- package/dist/chunk-CBUHAEGD.js +6 -0
- package/dist/chunk-XEWB3NIN.js +1 -0
- package/dist/cli/hook.js +3 -2
- package/dist/cli/main.js +1 -1
- package/dist/index.d.ts +304 -47
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-3GWLCI47.js +0 -1
- package/dist/chunk-42FZPLOF.js +0 -3
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ server decisions match by construction.
|
|
|
58
58
|
|
|
59
59
|
Credentials resolve by precedence (highest wins):
|
|
60
60
|
|
|
61
|
-
1. Env: `VISIQ_API_KEY`, `VISIQ_AGENT_ID`, `VISIQ_BASE_URL` (or `VISIQ_ENDPOINT`)
|
|
61
|
+
1. Env: `VISIQ_API_KEY`, `VISIQ_AGENT_ID`, `VISIQ_BASE_URL` (or `VISIQ_ENDPOINT`) — the base URL is optional and defaults to the managed SaaS host `https://api.visiqlabs.com`; set it only for onprem / self-hosted deployments
|
|
62
62
|
2. `VISIQ_CONFIG_PATH` JSON file
|
|
63
63
|
3. `~/.visiq/claude-code/config.json` (written by `configure`)
|
|
64
64
|
|
|
@@ -67,10 +67,20 @@ State (bundle cache, session markers) lives under `~/.visiq/claude-code/`
|
|
|
67
67
|
|
|
68
68
|
## Fail modes
|
|
69
69
|
|
|
70
|
+
Default posture is **fail-open** (owner decision 2026-07-15): a VisIQ bug or
|
|
71
|
+
outage must never disrupt the agent. Set `VISIQ_FAIL_MODE=closed` (or
|
|
72
|
+
`failMode: "closed"` in the config file) for strict blocking.
|
|
73
|
+
|
|
70
74
|
- **Unconfigured** (no credentials): every hook is a **no-op** — an installed but
|
|
71
|
-
unconfigured harness never breaks Claude Code.
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
unconfigured harness never breaks Claude Code. Each skipped PreToolUse call
|
|
76
|
+
writes a `FAIL-OPEN (unconfigured)` line to stderr. (`closed`: denies until
|
|
77
|
+
configured.)
|
|
78
|
+
- **Configured, evaluation error / no usable bundle**: the call **proceeds
|
|
79
|
+
ungoverned** and the event is reported loudly — stderr + one JSON line in
|
|
80
|
+
`~/.visiq/claude-code/fail-open.log`. (`closed`: actions denied, retrieval
|
|
81
|
+
content withheld.)
|
|
82
|
+
- **Explicit policy DENY**: always blocks, in both modes — fail-open governs
|
|
83
|
+
harness failures only, never policy outcomes.
|
|
74
84
|
- **Monitor mode**: decisions are recorded as telemetry but never block.
|
|
75
85
|
|
|
76
86
|
## Uninstall
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as Y,i as pe,k as fe,l as me,m as ge,n as he,o as _e,p as D}from"./chunk-XEWB3NIN.js";import{appendFile as Gt,mkdir as Vt}from"node:fs/promises";import{join as Wt}from"node:path";function Ht(){return Wt(Y(),"fail-open.log")}async function k(e,t=!0){let n=`[VisIQ] FAIL-OPEN (${e.stage}): ${e.detail} \u2014 tool call proceeding UNGOVERNED. Set VISIQ_FAIL_MODE=closed to block instead.`;try{process.stderr.write(`${n}
|
|
2
|
+
`)}catch{}if(t)try{await Vt(Y(),{recursive:!0}),await Gt(Ht(),`${JSON.stringify({at:new Date().toISOString(),...e})}
|
|
3
|
+
`,{mode:384})}catch{}}async function M(e,t={}){e.failOpen===!0&&await k({stage:"runtime-fail-open",detail:e.reason,...t.toolName?{toolName:t.toolName}:{},...t.sessionId?{sessionId:t.sessionId}:{}})}var Kt=new Set(["WebFetch","WebSearch","Read","Grep","Glob","LSP","NotebookRead","ListMcpResourcesTool","ReadMcpResourceTool"]),Yt=/(^|_)(search|fetch|read|list|get|query|retrieve|lookup|find|describe|download|export|dump)(_|$)/i;function Jt(e){if(typeof e!="string"||!e.startsWith("mcp__"))return typeof e=="string"?e:"";let t=e.lastIndexOf("__");return t>=0?e.slice(t+2):e}function J(e){return typeof e!="string"?!1:Kt.has(e)?!0:e.startsWith("mcp__")?Yt.test(Jt(e)):!1}function ye(e){return J(e)?["retrieval","action"]:["action"]}var Zt=["query","q","url","prompt","pattern","file_path","path"];function j(e){if(!e||typeof e!="object")return;let t=e,n=[];for(let r of Zt){let i=t[r];typeof i=="string"&&i.length>0&&n.push(i)}return n.length>0?n.join(" "):void 0}function I(e,t){let n=t?`VisIQ ${t}`:"VisIQ",r=e&&e.trim().length>0?e.trim():"blocked by policy";return`[${n}] ${r}`}function be(e){let t={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}};return e&&(t.hookSpecificOutput.updatedInput=e),t}function F(e){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:e}}}function ve(e){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"ask",permissionDecisionReason:e}}}function S(e,t){let n={hookSpecificOutput:{hookEventName:"PostToolUse",updatedToolOutput:e}};return t&&(n.hookSpecificOutput.additionalContext=t),n}function vi(e){try{let t=JSON.parse(e);return t&&typeof t=="object"&&typeof t.hook_event_name=="string"?t:null}catch{return null}}var xe="[REDACTED]",Ne=[{name:"private_key",re:/-----BEGIN (?:[A-Z]+ )?PRIVATE KEY-----[\s\S]*?-----END (?:[A-Z]+ )?PRIVATE KEY-----/g},{name:"jwt",re:/\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{6,}\b/g},{name:"aws_access_key",re:/\b(?:AKIA|ASIA|AGPA|AIDA|AROA|ANPA|ANVA|AIPA)[0-9A-Z]{16}\b/g},{name:"github_token",re:/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36}\b|\bgithub_pat_[A-Za-z0-9_]{22,}\b/g},{name:"slack_token",re:/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g},{name:"stripe_secret",re:/\b(?:sk|rk)_live_[A-Za-z0-9]{16,}\b/g},{name:"google_api_key",re:/\bAIza[0-9A-Za-z_-]{35}\b/g},{name:"llm_api_key",re:/\bsk-(?:ant-|proj-)?[A-Za-z0-9_-]{20,}\b/g},{name:"bearer_token",re:/\bBearer\s+[A-Za-z0-9._~+/=-]{20,}/g},{name:"connection_string",re:/\b(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis|amqps?):\/\/[^\s/@:]+:[^\s/@:]+@[^\s'"]+/g},{name:"us_ein",re:/\b\d{2}-\d{7}\b/g},{name:"ssn",re:/\b\d{3}[- ]\d{2}[- ]\d{4}\b/g},{name:"email",re:/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g},{name:"swift_bic",re:/\b[A-Z]{6}[A-Z0-9]{2}(?:[A-Z0-9]{3})?\b/g},{name:"us_phone",re:/\b(?:\+?1[ .-]?)?\(?\d{3}\)?[ .-]?\d{3}[ .-]?\d{4}\b/g},{name:"ipv4",re:/\b(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)\b/g},{name:"mac_address",re:/\b(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}\b/g}];function Re(e){if(!/^\d+$/.test(e))return!1;let t=0,n=!1;for(let r=e.length-1;r>=0;r--){let i=e.charCodeAt(r)-48;n&&(i*=2,i>9&&(i-=9)),t+=i,n=!n}return t%10===0}function Qt(e){let t=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=0;i<n.length;i++){let a=n[i],o=a>="A"&&a<="Z"?String(a.charCodeAt(0)-55):a;for(let s=0;s<o.length;s++)r=(r*10+(o.charCodeAt(s)-48))%97}return r===1}function Xt(e){if(!/^\d{9}$/.test(e))return!1;let t=[3,7,1,3,7,1,3,7,1],n=0;for(let r=0;r<9;r++)n+=(e.charCodeAt(r)-48)*t[r];return n%10===0}var en=[{name:"pan",re:/\d(?:[ -]?\d){12,18}/g,normalize:e=>e.replace(/[ -]/g,""),validate:e=>e.length>=13&&e.length<=19&&Re(e)},{name:"iban",re:/\b[A-Z]{2}\d{2}(?:[ ]?[A-Z0-9]){10,30}\b/g,normalize:e=>e.replace(/\s/g,"").toUpperCase(),validate:Qt},{name:"aba_routing",re:/\b\d{9}\b/g,normalize:e=>e,validate:Xt}],_=Object.fromEntries(Ne.map(e=>[e.name,e.re.source])),$e=["private_key","jwt","aws_access_key","github_token","slack_token","stripe_secret","google_api_key","llm_api_key","bearer_token","connection_string","pan","iban","aba_routing","us_ein","swift_bic","ssn","email","us_phone","ipv4","mac_address"],X={private_key:{id:"private_key",label:"Private keys (PEM)",description:"PEM-encoded private keys (RSA / EC / EdDSA / OpenSSH).",category:"secret",example:`-----BEGIN PRIVATE KEY-----
|
|
4
|
+
MIIEv\u2026
|
|
5
|
+
-----END PRIVATE KEY-----`,template:{pattern:_.private_key,mode:"full"},defaultEnabled:!0},jwt:{id:"jwt",label:"JWT / bearer tokens",description:"JSON Web Tokens (base64url header.payload.signature).",category:"secret",example:"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIn0.dBjftJeZ4CVP",template:{pattern:_.jwt,mode:"full"},defaultEnabled:!0},aws_access_key:{id:"aws_access_key",label:"AWS access key IDs",description:"AWS access / identity key ids (AKIA / ASIA / AROA \u2026).",category:"secret",example:"AKIAIOSFODNN7EXAMPLE",template:{pattern:_.aws_access_key,mode:"full"},defaultEnabled:!0},github_token:{id:"github_token",label:"GitHub tokens",description:"GitHub personal / OAuth tokens (classic ghp_\u2026 + fine-grained).",category:"secret",example:"ghp_0123456789abcdef0123456789abcdef0123",template:{pattern:_.github_token,mode:"full"},defaultEnabled:!0},slack_token:{id:"slack_token",label:"Slack tokens",description:"Slack bot / user / app tokens (xoxb- / xoxp- \u2026).",category:"secret",example:"xoxb-1234567890-abcdefghijkl",template:{pattern:_.slack_token,mode:"full"},defaultEnabled:!0},stripe_secret:{id:"stripe_secret",label:"Stripe secret keys",description:"Stripe live secret / restricted keys (sk_live_ / rk_live_).",category:"secret",example:"sk_live_0123456789abcdefABCDEF",template:{pattern:_.stripe_secret,mode:"full"},defaultEnabled:!0},google_api_key:{id:"google_api_key",label:"Google API keys",description:"Google API keys (AIza\u2026).",category:"secret",example:"AIzaSyA1234567890abcdefghijklmnopqrstuv",template:{pattern:_.google_api_key,mode:"full"},defaultEnabled:!0},llm_api_key:{id:"llm_api_key",label:"LLM provider API keys",description:"OpenAI / Anthropic secret keys (sk-\u2026, sk-proj-\u2026, sk-ant-\u2026).",category:"secret",example:"sk-ant-api03-AbCdEf0123456789AbCdEf01",template:{pattern:_.llm_api_key,mode:"full"},defaultEnabled:!0},bearer_token:{id:"bearer_token",label:"Authorization bearer tokens",description:"Credentials following an HTTP `Authorization: Bearer \u2026` header.",category:"secret",example:"Bearer abcdef0123456789abcdef0123456789",template:{pattern:_.bearer_token,mode:"full"},defaultEnabled:!0},connection_string:{id:"connection_string",label:"Connection strings (with password)",description:"Database / broker DSNs carrying an inline password (scheme://user:pass@host).",category:"secret",example:"postgres://app:s3cr3t@db.internal:5432/main",template:{pattern:_.connection_string,mode:"full"},defaultEnabled:!0},pan:{id:"pan",label:"Payment card numbers (PAN)",description:"Luhn-valid 13\u201319 digit primary account numbers (PCI-DSS).",category:"financial",example:"4242 4242 4242 4242",template:{pattern:"\\b\\d{13,19}\\b",mode:"partial",keepLast:4},defaultEnabled:!0},iban:{id:"iban",label:"IBAN bank account numbers",description:"ISO 13616 IBANs (mod-97 validated); keeps the last 4 visible.",category:"financial",example:"DE89 3704 0044 0532 0130 00",template:{pattern:"\\b[A-Z]{2}\\d{2}(?:[ ]?[A-Z0-9]){10,30}\\b",mode:"partial",keepLast:4},defaultEnabled:!0},aba_routing:{id:"aba_routing",label:"ABA routing numbers",description:"US bank routing-transit numbers (9-digit, checksum-validated). DEFAULT-OFF (9-digit false-positive surface).",category:"financial",example:"021000021",template:{pattern:"\\b\\d{9}\\b",mode:"full"},defaultEnabled:!1},us_ein:{id:"us_ein",label:"US Employer ID (EIN)",description:"US tax Employer Identification Numbers (XX-XXXXXXX).",category:"financial",example:"12-3456789",template:{pattern:_.us_ein,mode:"full"},defaultEnabled:!0},swift_bic:{id:"swift_bic",label:"SWIFT / BIC codes",description:"Bank SWIFT/BIC codes (8 or 11 chars). DEFAULT-OFF (matches uppercase tokens).",category:"financial",example:"DEUTDEFF500",template:{pattern:_.swift_bic,mode:"full"},defaultEnabled:!1},ssn:{id:"ssn",label:"US Social Security numbers",description:"Dashed / spaced US SSNs (e.g. 123-45-6789).",category:"pii",example:"123-45-6789",template:{pattern:_.ssn,mode:"partial",keepLast:4},defaultEnabled:!0},email:{id:"email",label:"Email addresses",description:"Email addresses (the mailbox is masked, the domain kept).",category:"pii",example:"alice@acme.com",template:{pattern:_.email,mode:"email"},defaultEnabled:!0},us_phone:{id:"us_phone",label:"US phone numbers",description:"US phone numbers in common formats. DEFAULT-OFF (10-digit false-positive surface).",category:"pii",example:"(415) 555-0132",template:{pattern:_.us_phone,mode:"partial",keepLast:4},defaultEnabled:!1},ipv4:{id:"ipv4",label:"IPv4 addresses",description:"Dotted-quad IPv4 addresses. DEFAULT-OFF (common + usually benign).",category:"identifier",example:"203.0.113.42",template:{pattern:_.ipv4,mode:"full"},defaultEnabled:!1},mac_address:{id:"mac_address",label:"MAC addresses",description:"Hardware MAC addresses. DEFAULT-OFF.",category:"identifier",example:"3c:22:fb:1a:2b:3c",template:{pattern:_.mac_address,mode:"full"},defaultEnabled:!1}},Ai=new Set($e.filter(e=>!X[e].defaultEnabled));function tn(e,t){let n=new Set;for(let r of $e)(X[r].defaultEnabled?!e?.has(r):t?.has(r))||n.add(r);return n}function nn(e,t,n,r){if(typeof e!="string"||e.length===0)return e;let i=e;for(let{name:a,re:o}of Ne){let s=a;n.has(s)||(i=i.replace(o,()=>(r?.(s),t)))}for(let{name:a,re:o,normalize:s,validate:l}of en)n.has(a)||(i=i.replace(o,u=>l(s(u))?(r?.(a),t):u));return i}function Pe(e,t=xe,n,r){return rn(e,t,tn(n,r))}function rn(e,t,n){let r=new Set,i=!n.has("pan"),a=s=>{r.add(s)},o=s=>{if(typeof s=="string")return nn(s,t,n,a);if(typeof s=="number"&&Number.isInteger(s)&&s>0){if(!i)return s;let l=String(s);return l.length>=13&&l.length<=19&&Re(l)?(r.add("pan"),t):s}if(Array.isArray(s))return s.map(l=>o(l));if(s!==null&&typeof s=="object"){let l=s,u={};for(let p of Object.keys(l))u[p]=o(l[p]);return u}return s};return{value:o(e),detectors:[...r].sort()}}function Le(e,t=xe){return Pe(e,t).value}var an=/[\u00AD\u200B-\u200F\u202A-\u202E\u2060\u2066-\u2069\uFEFF]/g,De=Object.freeze({\u0430:"a",\u0435:"e",\u043E:"o",\u0440:"p",\u0441:"c",\u0443:"y",\u0445:"x",\u0456:"i",\u0455:"s",\u043A:"k",\u043C:"m",\u0442:"t",\u043D:"h",\u0432:"b",\u0433:"r",\u03BF:"o",\u03B1:"a",\u03C1:"p",\u03B9:"i",\u03C4:"t",\u03B5:"e",\u03BA:"k",\u03BD:"v",\u03C5:"u",\u03B7:"n",\u0131:"i","\u04CF":"l",\u0578:"n"}),on=new RegExp(`[${Object.keys(De).join("")}]`,"gu"),sn=Object.freeze({4:"a","@":"a",3:"e",1:"i","!":"i",0:"o",5:"s",$:"s",7:"t",9:"g","(":"c",8:"b"}),Me="\u2801\u2803\u2809\u2819\u2811\u280B\u281B\u2813\u280A\u281A\u2805\u2807\u280D\u281D\u2815\u280F\u281F\u2817\u280E\u281E\u2825\u2827\u283A\u282D\u283D\u2835",ln=Object.freeze(Object.fromEntries([...Me].map((e,t)=>[e,String.fromCharCode(97+t)]))),cn=new RegExp(`[${Me}\u2800]`,"g"),je=/[⠀-⣿]/;function un(e){let t="";for(let n of e){let r=n.codePointAt(0);r!==void 0&&(r>=917536&&r<=917630?t+=String.fromCodePoint(r-917504):r>=917504&&r<=917631||(t+=n))}return t}function dn(e){return e.replace(an,"")}function Fe(e){return e.replace(on,t=>De[t]??t)}function pn(e){return e.replace(/[4@31!05$79(8]/g,t=>sn[t]??t)}function fn(e){return e.replace(/[a-zA-Z]/g,t=>{let n=t<="Z"?65:97;return String.fromCharCode((t.charCodeAt(0)-n+13)%26+n)})}function mn(e){return je.test(e)?e.replace(cn,t=>t==="\u2800"?" ":ln[t]??t):e}function we(e){let t;try{t=un(e)}catch{t=e}try{t=t.normalize("NFKC")}catch{}return t=dn(t),t=Fe(t),t}var gn=/^[A-Za-z0-9+/]{16,}={0,2}$/,hn=/^(?:[0-9a-fA-F]{2}\s*){8,}$/,Ae=/[A-Za-z0-9+/]{20,}={0,2}/g;function Q(e){if(e.length===0)return 0;let t=0;for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);(r===9||r===10||r===13||r>=32&&r<=126||r>=160&&r!==65533)&&t++}return t/e.length}var Ue=new TextDecoder("utf-8",{fatal:!1});function Be(e){let t;try{t=atob(e)}catch{return[]}let n=new Uint8Array(t.length);for(let i=0;i<t.length;i++)n[i]=t.charCodeAt(i)&255;let r=Ue.decode(n);return t===r?[t]:[r,t]}function _n(e){let t=e.replace(/\s+/g,"");if(t.length===0||t.length%2!==0)return[];let n=new Uint8Array(t.length/2);for(let a=0;a<n.length;a++){let o=Number.parseInt(t.slice(a*2,a*2+2),16);if(Number.isNaN(o))return[];n[a]=o}let r="";for(let a=0;a<n.length;a++)r+=String.fromCharCode(n[a]);let i=Ue.decode(n);return r===i?[r]:[i,r]}function ke(e){let t=e.trim(),n=[];if(hn.test(t))for(let r of _n(t))n.push({decoded:r,textiness:Q(r)});if(gn.test(t)&&t.length%4===0)for(let r of Be(t))n.push({decoded:r,textiness:Q(r)});return n}function Ie(e,t){let n=[],r;for(Ae.lastIndex=0;(r=Ae.exec(e))!==null&&n.length<t;){let i=r[0];if(i.length%4===0)for(let a of Be(i))n.push({decoded:a,textiness:Q(a)})}return n}var yn=Object.freeze({maxDepth:3,byteCap:262144,maxNodes:256,maxBlobsPerNode:8});function qe(e,t=yn){if(typeof e!="string"||e.length===0)return{views:[],anyDecoded:!1,truncated:!1,nodes:0,maxDepthSeen:0};let{maxDepth:n,byteCap:r,maxNodes:i,maxBlobsPerNode:a}=t,o=new Set,s=m=>{m.length>0&&m.length<=r&&o.add(m)},l=!1,u=!1,p=0,f=0,h=[{s:e,depth:0}];for(;h.length>0;){if(p>=i){u=!0;break}let m=h.pop();if(m===void 0)break;let{s:g,depth:y}=m;if(g.length>r){u=!0;continue}p++,y>f&&(f=y);let b=we(g);s(b);let x=pn(b);if(x!==b&&s(x),s(fn(b)),je.test(g)&&s(mn(b)),y>=n){let w=we(g);(ke(w).length>0||Ie(w,a).length>0)&&(u=!0);continue}let zt=[...ke(b),...Ie(b,a)];for(let w of zt){if(l=!0,w.decoded.length>r){u=!0;continue}w.textiness>=.85&&w.decoded!==b?h.push({s:w.decoded,depth:y+1}):s(w.decoded)}}return{views:[...o],anyDecoded:l,truncated:u,nodes:p,maxDepthSeen:f}}var ze=["hidden_text_carrier","injected_turn_boundary","mixed_script_token","nested_encoding_payload"],bn=Object.freeze(["hidden_text_carrier","injected_turn_boundary","mixed_script_token"]),vn=8,wn=new Set([173,8203,8204,8205,8206,8207,8288,65279,8234,8235,8236,8237,8238,8294,8295,8296,8297]),Se=e=>e!==void 0&&(e>=65&&e<=90||e>=97&&e<=122);function An(e){let t=[...e].map(r=>r.codePointAt(0)),n=0;for(let r=0;r<t.length;r++){let i=t[r];if(i>=917504&&i<=917631||wn.has(i)&&Se(t[r-1])&&Se(t[r+1])&&(n++,n>=vn))return!0}return!1}var kn=/^[ \t]*(?:system|assistant|developer|user)[ \t]*:/i;function In(e){let t=e.split(/\r?\n/),n=!1;for(let r of t){if(kn.test(r)){if(n)return!0;continue}r.trim().length>0&&(n=!0)}return!1}var Sn=[{name:"latin",lo:65,hi:591},{name:"greek",lo:880,hi:1023},{name:"cyrillic",lo:1024,hi:1279}];function En(e){for(let t of Sn)if(e>=t.lo&&e<=t.hi)return t.name;return null}function Cn(e){for(let t of e.split(/\s+/)){if(t.length<4)continue;let n=0,r=0,i=!0;for(let a of t){let o=En(a.codePointAt(0));if(o===null){i=!1;break}o==="latin"?n++:Fe(a)!==a&&r++}if(i&&n>0&&r>0)return!0}return!1}var Ee=Object.freeze({signals:[],contributes:!1});function Tn(e){if(typeof e!="string"||e.length===0)return{...Ee,signals:[]};let t=new Set;try{An(e)&&t.add("hidden_text_carrier"),In(e)&&t.add("injected_turn_boundary"),Cn(e)&&t.add("mixed_script_token");let{anyDecoded:n,maxDepthSeen:r,truncated:i}=qe(e);n&&(r>=2||i)&&t.add("nested_encoding_payload")}catch{return{...Ee,signals:[]}}return{signals:[...ze.filter(n=>t.has(n))],contributes:bn.some(n=>t.has(n))}}var B=[{name:"override_instructions",re:/\bignore (?:all |the )?(?:previous|above|prior) (?:instructions|prompts?)\b/i},{name:"disregard_instructions",re:/\bdisregard (?:the )?(?:above|previous|system)\b/i},{name:"role_tag",re:/<\/?(system|assistant|instructions|host_context)\b/i},{name:"privilege_override",re:/\b(grant|escalate|elevate) (admin|root|all|full) (access|privileges?)\b/i},{name:"tool_smuggle",re:/```[\s\S]*?(tool_call|function_call)/i}];function Ce(e){return typeof e!="string"||e.length===0?[]:B.filter(({re:t})=>t.test(e)).map(({name:t})=>t)}function On(e){if(typeof e!="string"||e.length===0)return[];let t=new Set(Ce(e)),{views:n}=qe(e);for(let r of n)for(let i of Ce(r))t.add(i);return B.filter(r=>t.has(r.name)).map(r=>r.name)}function xn(e){let t=new Set,n=new Set,r=!1,i=a=>{if(a!=null){if(typeof a=="string"){for(let s of On(a))t.add(s);let o=Tn(a);for(let s of o.signals)n.add(s);o.contributes&&(r=!0);return}if(Array.isArray(a)){for(let o of a)i(o);return}if(typeof a=="object")for(let o of Object.values(a))i(o)}};return i(e),{matched:t.size>0||r,signatures:B.filter(a=>t.has(a.name)).map(a=>a.name),structural:ze.filter(a=>n.has(a))}}function Nn(e){return xn(e).matched}var ki=B.map(e=>e.name);var Rn=new Set(["untrusted","external","public","public_internet","external_third_party","web"]);var $n="i:injection";function Ge(e){let t=new Set;if(e.content!==void 0&&e.content!==null){let{detectors:i}=Pe(e.content);for(let a of i){let o=X[a]?.category;o&&t.add(`c:${o}`)}Nn(e.content)&&t.add($n)}let n=e.resourceMetadata??{},r=n.source_trust;return(n.untrusted_source===!0||typeof r=="string"&&Rn.has(r.toLowerCase()))&&t.add("i:untrusted"),[...t].sort()}var Z="(?:system\\s+prompt|initial\\s+(?:instructions|prompt)|system\\s+(?:instructions|message)|hidden\\s+(?:instructions|prompt)|your\\s+(?:system\\s+prompt|initial\\s+instructions|instructions|prompt)|the\\s+prompt\\s+(?:above|you\\s+were\\s+given))",Ii=[{name:"reveal_prompt",re:new RegExp(`\\b(?:reveal|show|print|repeat|output|echo|display|expose|dump|leak|reprint|divulge|disclose)\\b[\\s\\S]{0,40}?\\b${Z}\\b`,"i")},{name:"what_is_prompt",re:new RegExp(`\\bwhat\\s+(?:is|are|were)\\b[\\s\\S]{0,20}?\\b${Z}\\b`,"i")},{name:"tell_me_prompt",re:new RegExp(`\\b(?:tell|give|send|show)\\s+me\\b[\\s\\S]{0,30}?\\b${Z}\\b`,"i")},{name:"repeat_above",re:/\b(?:repeat|print|output|echo|reproduce)\b[\s\S]{0,20}?\b(?:everything|all\s+(?:the\s+)?(?:text|words))\b[\s\S]{0,12}?\b(?:above|before|preceding|verbatim|word\s+for\s+word)\b/i}],Te="(?:instructions?|prompts?|rules?|directives?|guidelines?|constraints?|guardrails?)",Pn=`(?:(?:all\\s+|any\\s+|the\\s+|these\\s+|those\\s+)*(?:previous|prior|preceding|earlier|above|foregoing|initial|original|system|developer)\\s+${Te}|your\\s+(?:(?:system|initial|original|previous|prior|current)\\s+)?(?:${Te}|programming|training))`,Ln="(?:(?:all|any|every|the|of|and|now|please|completely|entirely|totally|immediately)\\s+){0,3}",Oe="(?:\\b(?:unrestricted|unfiltered|uncensored|unbounded|unlimited|unchained|jailbroken|lawless|amoral)\\b|\\b(?:DAN|STAN|DUDE|AIM)\\b|\\bno\\s+(?:longer\\s+)?(?:restrictions?|limits?|rules?|guidelines?|filters?|boundaries|constraints?)\\b(?!\\s+(?:on|over|regarding|upon|for)\\b)|\\bwithout\\s+(?:any\\s+)?(?:restrictions?|limits?|rules?|guidelines?|filters?|constraints?|censorship)\\b|\\b(?:free|freed|released)\\s+from\\s+(?:your\\s+)?(?:restrictions?|limits?|rules?|guidelines?|guardrails?|programming|constraints?)\\b|\\b(?:can|will|are\\s+able\\s+to)\\s+(?:do|say)\\s+anything\\b|\\bignore\\s+(?:all\\s+)?(?:your\\s+)?(?:previous\\s+|prior\\s+|system\\s+)?(?:instructions?|rules?|guidelines?)\\b)",Dn="(?:ignore|disregard|forget|override|overrule|bypass|obey|comply\\s+with|follow\\s+(?:only|my|these))",Si=[{name:"override_instructions",re:new RegExp(`\\b(?:ignore|disregard|forget|discard|override|overrule|bypass|delete|erase)\\s+${Ln}${Pn}\\b`,"i")},{name:"forget_everything_prior",re:/\b(?:forget|ignore|disregard|erase|discard)\s+(?:about\s+|all\s+|any\s+)?(?:everything|anything)\b[\s\S]{0,24}?\b(?:above|before|previously|prior|earlier|you\s+(?:were|have\s+been)\s+(?:told|instructed|given|programmed))\b/i},{name:"persona_reassignment_jailbreak",re:new RegExp(`\\byou\\s+are\\s+now\\s+(?:(?:a|an|the)\\s+)?[\\s\\S]{0,48}?${Oe}`,"i")},{name:"constraint_release",re:/\byou\s+are\s+no\s+longer\s+(?:bound|restricted|limited|constrained|obligated|governed|subject\s+to|required\s+to)\b/i},{name:"from_now_on_reassignment",re:new RegExp(`\\bfrom\\s+now\\s+on\\s*,?\\s+you\\s+(?:are|will|must|shall|have|can)\\s+(?:${Dn}\\b|[\\s\\S]{0,40}?${Oe})`,"i")},{name:"new_instructions_header",re:/^\s*(?:[#*>-]+\s*)?(?:new|real|actual|true|secret|hidden|override)\s+(?:system\s+)?(?:instructions?|prompts?|directives?)\s*:/im}];var Ei=Object.freeze({"\u2019":"'",\u02BC:"'","\uFF07":"'","\u02B9":"'","\u2032":"'"});var A=e=>`[^.!?;\\n]{0,${e}}?`,Mn=["\\bi\\s+(?:can'?t|cannot|can\\s+not|won'?t|will\\s+not)\\b","\\bi(?:'m|\\s+am)\\s+(?:not\\s+able\\s+to|unable\\s+to|not\\s+going\\s+to|not\\s+permitted\\s+to|not\\s+allowed\\s+to)\\b"].join("|"),Ve="(?:help|assist|provide|create|generate|produce|write|compose|draft|comply|fulfil|fulfill|share|disclose|reveal|perform|execute|run|send|transmit|publish|export|approve|grant|carry\\s+out|do\\s+that|do\\s+this|do\\s+so|go\\s+ahead)",Ci=Object.freeze([{id:"capability_denial",class:"strong",re:new RegExp([`(?:${Mn})\\s${A(40)}\\b${Ve}\\b`,"\\b(?:that|this|it)(?:'s|\\s+is)\\s+not\\s+something\\s+i\\s+(?:can|could|am\\s+able\\s+to|'m\\s+able\\s+to)\\b",`\\b(?:falls|sits|is)\\s+outside\\s+(?:of\\s+)?(?:what|the\\s+(?:scope|range|bounds))\\b${A(40)}\\bi\\s+(?:can|am|'m)\\b`,"\\bnot\\s+something\\s+i(?:'m|\\s+am)\\s+(?:able|willing|permitted|allowed)\\s+to\\b"].join("|"),"i")},{id:"explicit_decline",class:"strong",re:new RegExp(["\\bi\\s+(?:must|have\\s+to|need\\s+to|will\\s+have\\s+to|am\\s+going\\s+to|'m\\s+going\\s+to)\\s+(?:respectfully\\s+)?decline\\b","\\bi(?:'m|\\s+am)\\s+not\\s+(?:comfortable|willing|prepared)\\b","\\bi(?:'ll|\\s+will)\\s+(?:have\\s+to\\s+)?pass\\s+on\\b","\\bi\\s+(?:must|have\\s+to)\\s+refuse\\b"].join("|"),"i")},{id:"policy_citation",class:"strong",re:new RegExp([`\\b(?:against|contrary\\s+to|prohibited\\s+by|forbidden\\s+by|in\\s+violation\\s+of|violates)\\s${A(24)}\\b(?:polic(?:y|ies)|guidelines?|terms\\s+of\\s+(?:use|service)|rules\\s+of\\s+engagement|code\\s+of\\s+conduct)\\b`,`\\b(?:my|our|the|company|organi[sz]ation'?s?)\\s+(?:polic(?:y|ies)|guidelines?)\\s${A(24)}\\b(?:do(?:es)?\\s+not\\s+(?:allow|permit)|prohibit|forbid|prevent)\\b`,`\\bnot\\s+(?:permitted|allowed|authori[sz]ed)\\s+(?:under|by)\\s${A(24)}\\b(?:polic(?:y|ies)|guidelines?)\\b`].join("|"),"i")},{id:"guardrail_selfreference",class:"strong",re:new RegExp(["\\bi(?:'ve|\\s+have)\\s+been\\s+(?:instructed|configured|told|trained)\\s+not\\s+to\\b","\\bi(?:'m|\\s+am)\\s+(?:designed|configured|programmed|built|set\\s+up)\\s+not\\s+to\\b",`\\bmy\\s+(?:safety\\s+)?(?:instructions|configuration|guardrails?|constraints|training)\\s${A(24)}\\b(?:prevent|prohibit|forbid|do(?:es)?\\s+not\\s+(?:allow|permit)|preclude)\\b`,"\\b(?:outside|beyond)\\s+(?:my|the)\\s+(?:permitted|authori[sz]ed|configured|approved)\\s+(?:scope|remit|capabilities|actions|operations)\\b"].join("|"),"i")},{id:"ethical_objection",class:"strong",re:new RegExp(["\\b(?:that|this|doing\\s+(?:so|that)|what\\s+you(?:'re|\\s+are)\\s+asking|the\\s+request|such\\s+a\\s+request)\\s+(?:would\\s+be|is|are)\\s+(?:clearly\\s+|both\\s+|potentially\\s+)?(?:illegal|unethical|unlawful|harmful|fraudulent)\\b","\\bi\\s+(?:do\\s+not|don'?t)\\s+condone\\b","\\b(?:goes|would\\s+go|runs)\\s+against\\s+my\\s+(?:principles|values|ethics)\\b","\\bi\\s+(?:can'?t|cannot|won'?t)\\s+in\\s+good\\s+conscience\\b"].join("|"),"i")},{id:"apology_marker",class:"weak",re:new RegExp("\\b(?:i(?:'m|\\s+am)\\s+(?:really\\s+|very\\s+|terribly\\s+|so\\s+)?sorry|i\\s+apologi[sz]e|my\\s+apologies)\\b","i")}]),Ti=Object.freeze([/```/,/\b(?:here(?:'s|\s+is|\s+are)|below\s+(?:is|are|you(?:'ll|\s+will)\s+find)|the\s+following\s+(?:is|are))\b/i,new RegExp(`\\b(?:but|however|instead|although|that\\s+said)\\b${A(60)}\\b(?:i\\s+(?:can|could)(?!'t)\\s${A(30)}\\b${Ve}\\b|i(?:'d|\\s+would)\\s+be\\s+happy\\s+to\\b|i(?:'m|\\s+am)\\s+able\\s+to\\b)`,"i"),/\bwhat\s+i\s+can\s+do\s+(?:instead|is|for\s+you)\b/i]);var N=e=>`[^.!?;\\n]{0,${e}}?`,Oi=Object.freeze([{id:"vulnerability_scanning",objectPatterns:[/\b(?:vulnerability|vuln|security)\s+(?:scan|scans|scanning|assessment|audit|test|testing)\b/i,/\bpen(?:etration)?[\s-]?test(?:ing)?\b/i,/\bport\s+scan(?:ning)?\b/i,/\b(?:exploit|nmap|metasploit|nessus|burp\s+suite)\b/i,/\bCVE-\d{4}-\d{4,7}\b/i],purposeFunctions:["it_security","engineering"],purposePatterns:[/\b(?:security|vulnerability|incident\s+respon\w{0,4}|threat|soc|red\s+team|phishing|malware)\b/i]},{id:"credential_access",objectPatterns:[/\b(?:credential|password|passphrase|api\s+key|access\s+key|secret|token|private\s+key|ssh\s+key)s?\b/i,/\b(?:vault|secrets?\s+manager|keychain|keystore)\b/i,/\bservice\s+account\s+key\b/i],purposeFunctions:["it_security","engineering"],purposePatterns:[/\b(?:security|identity|iam|credential|secrets?\s+manage\w{0,4}|vault|platform|devops)\b/i]},{id:"financial_transaction",objectPatterns:[/\b(?:wire\s+transfer|bank\s+transfer|payout|disbursement|chargeback)\b/i,new RegExp(`\\b(?:approve|issue|initiate|process|release)\\s${N(20)}\\b(?:payment|refund|invoice|transfer|purchase\\s+order)s?\\b`,"i"),new RegExp(`\\b(?:move|transfer)\\s${N(20)}\\b(?:funds|money)\\b`,"i")],purposeFunctions:["finance_accounting","procurement"],purposePatterns:[/\b(?:finance|financial|accounting|invoice|invoicing|payment|payments|billing|refund|refunds|treasury|procurement|spend|purchasing|fraud|kyc)\b/i]},{id:"personnel_data",objectPatterns:[/\b(?:employee|personnel|payroll|hr|staff)\s+(?:record|records|data|file|files|information|details)\b/i,/\b(?:salary|salaries|compensation|performance\s+review|termination\s+letter)s?\b/i,/\b(?:home\s+address|social\s+security\s+number|national\s+insurance\s+number)e?s?\b/i],purposeFunctions:["hr","privacy_compliance"],purposePatterns:[/\b(?:hr|human\s+resources|people\s+ops|payroll|benefits|recruit\w{0,4}|onboarding|privacy|dsar|consent)\b/i]},{id:"regulated_advice",objectPatterns:[/\b(?:legal|medical|tax|investment|financial)\s+advice\b/i,/\bpractis\w{0,3}\s+law\b/i,/\b(?:diagnose|diagnosis|prescribe|prescription)\b/i,/\b(?:binding|enforceable)\s+(?:opinion|interpretation)\b/i],purposeFunctions:["legal","privacy_compliance"],purposePatterns:[/\b(?:legal|compliance|counsel|contract|contracts|litigation|nda|privacy|regulator\w{0,2}|audit\w{0,3})\b/i]},{id:"data_export",objectPatterns:[new RegExp(`\\b(?:export|download|dump|extract|exfiltrat\\w{0,3}|bulk\\s+copy)\\b\\s${N(30)}\\b(?:data|database|dataset|records?|table|tables|customer\\s+list|contact\\s+list|report)\\b`,"i"),/\b(?:full|entire|whole)\s+(?:database|dataset|customer\s+table)\b/i],purposeFunctions:["operations","engineering","privacy_compliance"],purposePatterns:[/\b(?:data\s+(?:pipeline|engineering|platform)|etl|export|reporting|analytics|operations|document\s+extract\w{0,3}|forecast\w{0,3})\b/i]},{id:"code_execution",objectPatterns:[new RegExp(`\\b(?:run|execute|invoke)\\s${N(24)}\\b(?:script|scripts|command|commands|shell|code|binary|query|migration)\\b`,"i"),/\b(?:shell|root|sudo|admin)\s+(?:access|command|session)\b/i,/\bagainst\s+(?:the\s+)?production\s+(?:system|server|database|environment)s?\b/i],purposeFunctions:["engineering","it_security"],purposePatterns:[/\b(?:engineering|developer|devops|platform|release|deploy\w{0,4}|build|pipeline|sandbox|test\s+data|change\s+window)\b/i]},{id:"external_communication",objectPatterns:[new RegExp(`\\b(?:send|post|publish|email|tweet|message|broadcast)\\b\\s${N(30)}\\b(?:external|customer|customers|public|press|social\\s+media|third[\\s-]party|prospect|prospects)\\b`,"i"),/\b(?:cold\s+outreach|marketing\s+blast|phishing\s+email|press\s+release)\b/i],purposeFunctions:["marketing","sales","customer_support"],purposePatterns:[/\b(?:marketing|campaign|outreach|email\s+assistant|support|customer|sales|lead|leads|communication|communications)\b/i]}]);var ee="[REDACTED]",E="\u2022",U=e=>/[A-Za-z0-9]/.test(e);function We(e,t,n,r){let i=Array.from(e),a=i.length,o=Math.max(0,Math.floor(t)||0),s=Math.max(0,Math.floor(n)||0),l=r.length>0?r:E,u=o+s>=a;return i.map((p,f)=>!u&&(f<o||f>=a-s)?p:U(p)?l:p).join("")}function jn(e,t){let n=e.indexOf("@");if(n<=0||n>=e.length-1)return We(e,0,0,t);let r=e.slice(0,n),i=e.slice(n),a=t.length>0?t:E;return(r.length<=1?a:r[0]+Array.from(r.slice(1)).map(o=>U(o)?a:o).join(""))+i}function Fn(e,t,n){let r=n.length>0?n:E,i=new Array(e.length).fill(!1);if(typeof t=="string"&&t.length>0)try{let u=new RegExp(t,"g"),p;for(;(p=u.exec(e))!==null;){if(p[0].length===0){u.lastIndex++;continue}for(let f=p.index;f<p.index+p[0].length;f++)i[f]=!0}}catch{}let a=!1,o=!0;for(let u=0;u<e.length;u++)if(U(e[u])&&(a=!0,!i[u])){o=!1;break}let s=a&&o,l="";for(let u=0;u<e.length;u++){let p=e[u];!s&&i[u]||!U(p)?l+=p:l+=r}return l}function He(e,t){let n=t.mode??"full";return n==="partial"?We(e,t.keepFirst??0,t.keepLast??0,t.maskChar??E):n==="email"?jn(e,t.maskChar??E):n==="custom"?Fn(e,t.keepPattern,t.maskChar??E):t.replacement??ee}function Un(e,t){return typeof e=="string"?He(e,t):t.replacement??ee}function Ke(e){let t=[],n=e.replacement??ee;for(let r of e.patterns??[])typeof r!="string"||r.length===0||t.push({source:r,replacer:()=>n});for(let r of e.directives??[]){let{pattern:i}=r;typeof i!="string"||i.length===0||t.push({source:i,replacer:a=>He(a,r)})}return t}function Ye(e,t){let n=e;for(let{source:r,replacer:i}of t){let a;try{a=new RegExp(r,"g")}catch(o){let s=o instanceof Error?o.message:String(o);throw new Error(`[visiq-redact] Invalid redaction pattern "${r}": ${s}`)}n=n.replace(a,o=>i(o))}return n}function te(e,t){return e==null?e:typeof e=="string"?Bn(e,t):typeof e=="object"?qn(e,t):e}function Bn(e,t){if(typeof e!="string")return e;let n=Ke(t);return n.length===0?e:Ye(e,n)}function qn(e,t){let n=new Map;for(let s of t.fields??[])typeof s=="string"&&s.length>0&&n.set(s,{field:s,mode:"full",replacement:t.replacement});for(let s of t.directives??[])typeof s.field=="string"&&s.field.length>0&&n.set(s.field,s);let r=Ke(t),i=n.size>0,a=r.length>0,o=s=>{if(s==null)return s;if(Array.isArray(s))return s.map(l=>o(l));if(typeof s=="object"){let l=s,u=Object.create(Object.getPrototypeOf(l));for(let p of Object.keys(l)){let f=i?n.get(p):void 0;if(f){u[p]=Un(l[p],f);continue}u[p]=o(l[p])}return u}return typeof s=="string"&&a?Ye(s,r):s};return o(e)}import{z as c}from"zod";import*as v from"node:os";import{randomUUID as er}from"node:crypto";var Ze="X-VisIQ-SDK",Qe="X-VisIQ-Dialect",Xe="unknown";function ne(e,t=1){return{[Ze]:e&&e.length>0?e:Xe,[Qe]:String(t)}}var et="interceptor_source",zn=c.enum(["enforce","audit","off"]),Gn=c.enum(["closed","open"]),tt=c.enum(["enforce","monitor","off"]),Vn=c.object({apiKey:c.string().min(1,"apiKey is required"),agentId:c.string().min(1,"agentId is required"),endpoint:c.string().url().optional(),mode:zn.optional(),timeoutMs:c.number().int().positive().optional(),hitlTimeoutMs:c.number().int().positive().optional(),failBehavior:Gn.optional()}),Ri=c.object({agent_id:c.string().min(1),target_app:c.string().min(1),action:c.string().min(1),context:c.record(c.unknown()).optional(),session_id:c.string().min(1).max(255).optional(),action_schema_id:c.string().min(1).max(128).optional(),telemetry:c.record(c.unknown()).optional()}),Wn=c.object({field:c.string().optional(),pattern:c.string().optional(),replacement:c.string().optional(),mode:c.enum(["full","partial","email"]).optional(),keepFirst:c.number().optional(),keepLast:c.number().optional(),maskChar:c.string().optional()}),Hn=c.object({decision_id:c.string().min(1),decision:c.enum(["permit","deny","approval_required","mask"]),reason:c.string().optional(),rule_code:c.string().nullable().optional(),enforced:c.boolean().optional(),agent_mode:tt.optional(),arg_redaction_rules:c.array(Wn).optional(),plane:c.string().nullable().optional(),operation:c.string().nullable().optional(),is_retrieval:c.boolean().optional(),metadata:c.record(c.unknown()).optional()}),Kn=c.object({field:c.string().min(1),operator:c.enum(["equals","in","not_equals","not_in","glob","gt","lt","gte","lte","contains","not_contains"]),value:c.union([c.string(),c.number(),c.array(c.string())])}),Yn=c.object({id:c.string().min(1),rule_code:c.string().default(""),name:c.string().min(1),description:c.string().nullable().default(null),effect:c.enum(["allow","deny","hitl","mask"]),resource_type:c.string().min(1),rego_source:c.string().default(""),target_app:c.string().nullable().default(null),action_pattern:c.string().nullable().default(null),conditions:c.array(Kn).default([]),priority:c.number().int().default(0)}),Jn=c.object({version:c.string().min(1),agent_mode:tt.optional(),rules:c.array(Yn),no_coverage:c.object({no_coverage_defaults:c.record(c.string()),autopilot_enabled:c.boolean(),enduser_hitl_enabled:c.boolean(),hitl_timeout_seconds:c.number()}).optional()}),Zn=2e3,nt=class{config;originalFetch;constructor(e,t){this.config=e,this.originalFetch=t}versionHeaders(){return ne(this.config.sdkVersion,this.config.sdkDialect)}async evaluate(e){let t=new AbortController,n=setTimeout(()=>t.abort(),this.config.timeoutMs),r;try{r=await this.originalFetch(`${this.config.endpoint}/allow/evaluate`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify(e),signal:t.signal})}finally{clearTimeout(n)}if(!r.ok)throw new Error(`ALLOW evaluate request failed: HTTP ${r.status} ${r.statusText}`);let i=await r.json();return Hn.parse(i)}async fetchBundle(){let e=this.config.agentId?`?agent_id=${encodeURIComponent(this.config.agentId)}`:"",t=`${this.config.endpoint}/allow/rules/bundle${e}`,n=new AbortController,r=setTimeout(()=>n.abort(),this.config.timeoutMs),i;try{i=await this.originalFetch(t,{method:"GET",headers:{Authorization:`Bearer ${this.config.apiKey}`,Accept:"application/json",...this.versionHeaders()},signal:n.signal})}finally{clearTimeout(r)}if(!i.ok)throw new Error(`ALLOW rules/bundle fetch failed: HTTP ${i.status} ${i.statusText}`);let a=await i.json();return Jn.parse(a)}async sendTelemetry(e){if(e.length===0)return;let t=`${this.config.endpoint}/allow/telemetry`,n=await this.originalFetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify({decisions:e})});if(!n.ok)throw new Error(`ALLOW telemetry delivery failed: HTTP ${n.status} ${n.statusText}`)}async sendCognition(e,t){if(t.length===0)return;let n=`${this.config.endpoint}/allow/cognition`,r=await this.originalFetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify({...e?{session:e}:{},beats:t})});if(!r.ok)throw new Error(`ALLOW cognition delivery failed: HTTP ${r.status} ${r.statusText}`)}async reportExecutionResult(e,t,n){let r=`${this.config.endpoint}/allow/execution-events`;try{let i=await this.originalFetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify({decision_id:e,result:t,details:n})});i.ok||console.warn(`[ALLOW] Execution result report failed: HTTP ${i.status}`)}catch(i){console.warn("[ALLOW] Execution result report failed:",i)}}async registerEnvironment(e){if(!this.config.agentId)return;let t=`${this.config.endpoint}/allow/agents/register`;try{let n=await this.originalFetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify({agent_id:this.config.agentId,os:e.os,hostname:e.hostname,ip:e.ip,username:e.username,...this.config.harnessKind?{kind:this.config.harnessKind}:{},...e.agent_type?{agent_type:e.agent_type}:{},...e.model?{model:e.model}:{},...e.systemPrompt?{system_prompt:e.systemPrompt}:{},...e.toolSchemas&&e.toolSchemas.length>0?{tool_schemas:e.toolSchemas}:{}})});n.ok||console.warn(`[ALLOW] Agent registration failed: HTTP ${n.status} ${n.statusText}`)}catch(n){console.warn("[ALLOW] Agent registration failed:",n)}}async reportToolSurface(e){if(!this.config.agentId||e.length===0)return;let t=`${this.config.endpoint}/allow/agents/tools`;try{let n=await this.originalFetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify({agent_id:this.config.agentId,tools:e})});n.ok||console.warn(`[ALLOW] Tool-surface report failed: HTTP ${n.status} ${n.statusText}`)}catch(n){console.warn("[ALLOW] Tool-surface report failed:",n)}}async waitForApproval(e){if(!e)throw new Error("waitForApproval: decisionId must be a non-empty string");let t=Date.now()+this.config.hitlTimeoutMs;for(;Date.now()<t;){let n=new AbortController,r=setTimeout(()=>n.abort(),this.config.timeoutMs),i;try{i=await this.originalFetch(`${this.config.endpoint}/v1/allow/decisions/${encodeURIComponent(e)}`,{method:"GET",headers:{Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},signal:n.signal})}finally{clearTimeout(r)}if(!i.ok)throw new Error(`ALLOW decisions poll failed: HTTP ${i.status} ${i.statusText}`);let a=await i.json();if(typeof a!="object"||a===null)throw new Error("ALLOW decisions poll returned unexpected non-object response");let o=a,s=o.hitl_result;if(s==="approved")return{decision_id:e,decision:"permit",reason:"Approved by human reviewer"};if(s==="rejected")return{decision_id:e,decision:"deny",reason:typeof o.reason=="string"?o.reason:"Rejected by human reviewer"};if(s==="timeout"||s==="expired")return{decision_id:e,decision:"deny",reason:"HITL approval timed out"};await Qn(Zn)}return{decision_id:e,decision:"deny",reason:"HITL approval timed out"}}};function Qn(e){return new Promise(t=>setTimeout(t,e))}function re(){let e={};try{let t=`${v.platform()} ${v.release()}`.trim();t&&(e.os=t)}catch{}try{let t=v.hostname();t&&(e.hostname=t)}catch{}try{let{username:t}=v.userInfo();t&&(e.username=t)}catch{}try{let t=Xn();t&&(e.ip=t)}catch{}return e}function Xn(){let e=v.networkInterfaces();for(let t of Object.keys(e))for(let n of e[t]??[])if((n.family==="IPv4"||n.family===4)&&!n.internal&&n.address)return n.address}var Je=new Map;function tr(e){let t=(Je.get(e)??0)+1;return Je.set(e,t),t}function ie(e,t,n){if(!e||typeof e.isCognitionEnabled!="function"||!e.isCognitionEnabled())return;let r=t.sessionId&&t.sessionId.length>0?t.sessionId:t.agentId;e.emitCognition({clientEventId:er(),agentId:t.agentId,sessionId:r,threadId:t.agentId,parentId:t.agentId,seq:tr(r),ts:Date.now(),kind:"spawn",visibility:"shown",provenance:"parsed",...t.framework?{framework:t.framework}:{},spawn:{childAgentId:n.childAgentId,childName:n.childName,kind:n.kind,...n.model?{model:n.model}:{},...n.task?{prompt:n.task}:{}}})}import{z as d}from"zod";import{createHash as nr}from"crypto";import{createHash as vr}from"crypto";var rt=new Map;function it(e){return e.map(t=>t.trim()).filter(t=>t.length>0&&t!=="true")}function ct(e){let t=nr("sha256").update(e).digest("hex"),n=rt.get(t);if(n)return n;let r=new Map,i=[],a=e.split(`
|
|
6
|
+
`).map(l=>rr(l)).filter(l=>l.trim().length>0),o=0;for(;o<a.length;){let l=a[o].trim();if(l.startsWith("package ")||l.startsWith("import ")){o++;continue}let u=l.match(/^default\s+(\w+)\s*:?=\s*(.+)$/);if(u){let h=u[1],m=u[2].trim();r.set(h,$(m)),o++;continue}let p=l.match(/^(\w+)\s*:?=\s*(.+?)(?:\s+if)?\s*\{(.*)$/);if(p){let h=p[1],m=p[2].trim(),g=p[3].trim(),y=[];if(g&&g!=="}"){let x=g.endsWith("}")?g.slice(0,-1).trim():g;x&&y.push(x),g.endsWith("}")||(o++,o=q(a,o,y))}else g==="}"||(o++,o=q(a,o,y));let b=at(y);i.push({variable:h,value:$(m),conditions:b,rawConditions:it(y)}),o++;continue}let f=l.match(/^(\w+)(?:\s+if)?\s*\{(.*)$/);if(f){let h=f[1],m=f[2].trim(),g=[];if(m&&m!=="}"){let b=m.endsWith("}")?m.slice(0,-1).trim():m;b&&g.push(b),m.endsWith("}")||(o++,o=q(a,o,g))}else m==="}"||(o++,o=q(a,o,g));let y=at(g);i.push({variable:h,value:"true",conditions:y,rawConditions:it(g)}),o++;continue}o++}let s={defaults:r,rules:i};return rt.set(t,s),s}function rr(e){let t=!1,n="";for(let r=0;r<e.length;r++){let i=e[r];if(t)i===n&&e[r-1]!=="\\"&&(t=!1);else if(i==='"'||i==="'")t=!0,n=i;else if(i==="#")return e.slice(0,r)}return e}function q(e,t,n){let r=1,i=t;for(;i<e.length&&r>0;){let a=e[i].trim();for(let o of a)o==="{"&&r++,o==="}"&&r--;if(r>0)n.push(a),i++;else{let o=a.slice(0,a.lastIndexOf("}")).trim();return o&&n.push(o),i}}return i}function $(e){return e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function ir(e){return e.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\")}function at(e){let t=[];for(let n of e){let r=n.split(";").map(i=>i.trim()).filter(i=>i.length>0);for(let i of r){let a=ar(i);a&&t.push(a)}}return t}function ar(e){let t=!1,n=e.trim();if(n.startsWith("not ")&&(t=!0,n=n.slice(4).trim()),n==="true"||n==="false")return{type:"literal_bool",negated:t,field:"",value:n==="true"};if(n.includes("[_]"))return{type:"truthy",negated:!1,field:ae,value:e.trim()};let r=n.match(/^count\(([^)]+)\)\s*(>=|<=|>|<)\s*(\d+)$/);if(r)return{type:"count_gt",negated:t,field:r[1].trim(),operator:r[2],value:parseInt(r[3],10)};let i=n.match(/^startswith\(([^,]+),\s*"([^"]*)"\)$/);if(i)return{type:"startswith",negated:t,field:i[1].trim(),value:i[2]};let a=n.match(/^endswith\(([^,]+),\s*"([^"]*)"\)$/);if(a)return{type:"endswith",negated:t,field:a[1].trim(),value:a[2]};let o=n.match(/^contains\(([^,]+),\s*"([^"]*)"\)$/);if(o)return{type:"contains",negated:t,field:o[1].trim(),value:o[2]};let s=n.match(/^regex\.match\(\s*("(?:[^"\\]|\\.)*")\s*,\s*((?:input|data)[^\s)]*)\s*\)$/);if(s)return{type:"regex_match",negated:t,field:s[2].trim(),value:ir(s[1])};let l=n.match(/^("(?:[^"\\]|\\.)*"|-?\d+(?:\.\d+)?|true|false)\s+in\s+((?:input|data)[^\s]*)$/);if(l)return{type:"array_includes",negated:t,field:l[2].trim(),value:dt(l[1])};let u=n.match(/^([^\s]+)\s+in\s+(\[.*\])$/);if(u){let y=sr(u[2]);if(y!==null)return{type:"in_set",negated:t,field:u[1].trim(),values:y}}let p=n.match(/^([^\s=!<>]+)\s*(>=|<=|>|<)\s*(-?\d+(?:\.\d+)?)$/);if(p)return{type:"comparison",negated:t,field:p[1].trim(),operator:p[2],value:parseFloat(p[3])};let f=n.match(/^("(?:[^"\\]|\\.)*"|-?\d+(?:\.\d+)?|true|false)\s*==\s*((?:input|data)\S*)$/);if(f)return{type:"equality",negated:t,field:f[2].trim(),value:$(f[1].trim())};let h=n.match(/^([^\s=!]+)\s*==\s*(.+)$/);if(h)return{type:"equality",negated:t,field:h[1].trim(),value:$(h[2].trim())};let m=n.match(/^([^\s=!]+)\s*!=\s*(.+)$/);if(m)return{type:"inequality",negated:t,field:m[1].trim(),value:$(m[2].trim())};let g=n.match(/^(input(?:\.[a-zA-Z0-9_]+|\["[^"]+"\]|\['[^']+'\])+)$/);return g?{type:"truthy",negated:t,field:g[1].trim()}:{type:"truthy",negated:!1,field:ae,value:e.trim()}}var ae="__unrecognized_condition_forces_deny__";var or=/[A-Za-z_][A-Za-z0-9_.]*\s*\(/;function ut(e){let t=[];for(let n of e.rules)for(let r of n.conditions)typeof r.field=="string"&&r.field!==ae&&or.test(r.field)&&t.push(r.field);return t}function dt(e){let t=e.trim();return t==="true"?!0:t==="false"?!1:/^-?\d+(?:\.\d+)?$/.test(t)?parseFloat(t):t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1):t}function sr(e){let t=e.trim().replace(/^\[/,"").replace(/\]$/,"").trim();if(t.length===0)return[];let n=[],r="",i=!1,a="";for(let s=0;s<t.length;s++){let l=t[s];i?(r+=l,l===a&&t[s-1]!=="\\"&&(i=!1)):l==='"'||l==="'"?(r+=l,i=!0,a=l):l===","?(n.push(r.trim()),r=""):r+=l}if(i)return null;r.trim().length>0&&n.push(r.trim());let o=[];for(let s of n){let l=s.startsWith('"')&&s.endsWith('"')&&s.length>=2||s.startsWith("'")&&s.endsWith("'")&&s.length>=2,u=/^-?\d+(?:\.\d+)?$/.test(s);if(!l&&!u&&!(s==="true"||s==="false"))return null;o.push(dt(s))}return o}var lr=["tier1","tier2","tier3"];function pt(e){return typeof e=="string"&&lr.includes(e)}var cr=["read_only","transactional","data_processor","external_comms","code_exec","privileged"],ur=["internal","customer_facing","experimental","third_party"],ft=[...cr,...ur];function dr(e){return typeof e=="string"&&ft.includes(e)}function mt(e){let t=new Set;for(let n of e)dr(n)&&t.add(n);return ft.filter(n=>t.has(n))}var pr=["read_only","record_create","record_update","record_delete","data_export","data_share","data_subject_request","consent_change","funds_transfer","funds_disbursement","payroll_run","trade_execution","ledger_mutation","credit_decision","decision_adverse","account_restriction","account_closure","card_management","purchase_commitment","vendor_management","deal_management","pricing_change","contract_execution","legal_hold","regulatory_filing","personnel_action","employment_termination","compensation_change","campaign_send","content_publish","inventory_adjustment","order_fulfillment","account_servicing","credential_reset","access_grant","permission_change","credential_management","auth_policy_change","security_config_change","logging_change","alert_management","code_change","infrastructure_provision","deployment_change","communication_send","other"];function fr(e){if(typeof e!="string"&&typeof e!="number")return null;let t=String(e).trim().replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"");return t.length>0?t:null}var ot={github:"version_control",gitlab:"version_control",bitbucket:"version_control",stripe:"payments",adyen:"payments",braintree:"payments",paypal:"payments",square:"payments",salesforce:"crm",hubspot:"crm",pipedrive:"crm",slack:"communication",teams:"communication",twilio:"communication",sendgrid:"communication",mailgun:"communication",gmail:"communication",outlook:"communication",zoom:"communication",aws:"cloud_infra",gcp:"cloud_infra",azure:"cloud_infra",okta:"identity",auth0:"identity",entra:"identity",onelogin:"identity",duo:"identity",snowflake:"data_warehouse",bigquery:"data_warehouse",databricks:"data_warehouse",redshift:"data_warehouse",jira:"ticketing",zendesk:"ticketing",servicenow:"ticketing",freshdesk:"ticketing",linear:"ticketing",workday:"hr",bamboohr:"hr",gusto:"hr",netsuite:"finance_erp",quickbooks:"finance_erp",sap:"finance_erp",xero:"finance_erp",s3:"storage",gcs:"storage",dropbox:"storage",box:"storage",postgres:"database",postgresql:"database",mysql:"database",mongodb:"database",redis:"database"};function mr(e){let t=fr(e);return t===null?"other":ot[t]??ot[t.replace(/_/g,"")]??"other"}function gt(e,t){let n={...e};if(t.targetApp!==void 0&&t.targetApp!==null){let r=n.context&&typeof n.context=="object"&&!Array.isArray(n.context)?{...n.context}:{};r.app_category===void 0&&(r.app_category=mr(t.targetApp)),n.context=r}return n}var st=64,gr=64,P={retrieved_data_categories:[],retrieved_classifications:[],taint:[],action_classes:[],action_counts:{},denied_count:0,inhibited_count:0,event_count:0,target_apps:[]};function ht(){return{retrieved_data_categories:[],retrieved_classifications:[],taint:[],action_classes:[],action_counts:{},denied_count:0,inhibited_count:0,event_count:0,target_apps:[]}}var hr=new Set(["deny","approval_required","escalate"]);function R(e,t){if(t.length===0)return[...e];let n=new Set(e);for(let i of t)n.add(i);let r=[...n].sort();return r.length>st?r.slice(0,st):r}function lt(e){return e?e.filter(t=>typeof t=="string"&&t.length>0):[]}function z(e){return typeof e=="string"&&e.length>0?e:null}function _t(e,t){let n=lt(t.data_categories),r=z(t.classification),i=lt(t.taint),a=z(t.action_class),o=a&&pr.includes(a)?a:null,s=z(t.target_app),l=z(t.decision),u={...e.action_counts};if(o)if(o in u)u[o]=(u[o]??0)+1;else if(Object.keys(u).length<gr)u[o]=1;else{let p=Object.keys(u).sort(),f=p[p.length-1];f!==void 0&&o<f&&(delete u[f],u[o]=1)}return{retrieved_data_categories:R(e.retrieved_data_categories,n),retrieved_classifications:R(e.retrieved_classifications,r?[r]:[]),taint:R(e.taint,i),action_classes:R(e.action_classes,o?[o]:[]),action_counts:u,denied_count:e.denied_count+(l==="deny"?1:0),inhibited_count:e.inhibited_count+(l&&hr.has(l)?1:0),event_count:e.event_count+1,target_apps:R(e.target_apps,s?[s]:[])}}var yt="generic",bt=[{id:"finance_accounting",name:"Finance & Accounting",icon:"Landmark",description:"Payments, invoicing, ledgers, transactions, refunds, financial reporting, SOX/AML/KYC controls."},{id:"hr",name:"Human Resources",icon:"Users",description:"Employee records, payroll, hiring/recruiting, benefits, personnel actions and PII of staff."},{id:"engineering",name:"Engineering",icon:"Code",description:"Source code, build/deploy pipelines, infrastructure changes, production systems and developer tooling."},{id:"it_security",name:"IT & Security",icon:"ShieldCheck",description:"Credentials, secrets, access control, configuration, threat/exfiltration prevention and security operations."},{id:"legal",name:"Legal",icon:"Scale",description:"Contracts, NDAs, litigation, counsel communications and legal-hold material."},{id:"privacy_compliance",name:"Privacy & Compliance",icon:"BadgeCheck",description:"GDPR/CCPA/HIPAA, consent, data-subject rights, special-category data and regulatory data handling."},{id:"sales",name:"Sales",icon:"TrendingUp",description:"CRM, leads, deals, quotes, pipeline and customer commercial relationships."},{id:"marketing",name:"Marketing",icon:"Megaphone",description:"Campaigns, content, brand, social channels and prospect/audience data."},{id:"operations",name:"Operations",icon:"Cog",description:"Business operations, logistics, internal workflows, vendor/ops tooling and process automation."},{id:"customer_support",name:"Customer Support",icon:"LifeBuoy",description:"Support tickets, customer communications, account servicing and help-desk actions."},{id:"procurement",name:"Procurement",icon:"ShoppingCart",description:"Purchasing, supplier management, purchase orders, sourcing and spend approvals."},{id:yt,name:"Generic",icon:"Shapes",description:"Catch-all for cross-cutting rules or rules that do not fit a specific function. Assign when no specific function clearly applies."}],_r=bt.map(e=>e.id),Mi=new Map(bt.map(e=>[e.id,e])),ji=new Set(_r);function vt(e){return Array.isArray(e)&&e.length>0?[...e]:[yt]}var yr=/^[a-z][a-z0-9_]*$/;function wt(e){if(!Array.isArray(e))return[];let t=[],n=new Set;for(let r of e)typeof r=="string"&&yr.test(r)&&!n.has(r)&&(n.add(r),t.push(r));return t}var br=["narrow","moderate","broad","unbounded","unknown"];function At(e){return typeof e=="string"&&br.includes(e)}function kt(e){return e==="open"||e==="closed"?e:null}var wr=["tool_name","function","name","action"];function G(e,t,n){if(Array.isArray(e)){if(e.length===0){n.push([`${t}[]`,void 0]);return}for(let r of e)G(r,`${t}[]`,n);return}if(e!==null&&typeof e=="object"){let r=Object.entries(e);if(r.length===0){t&&n.push([t,void 0]);return}for(let[i,a]of r)G(a,t?`${t}.${i}`:i,n);return}t&&n.push([t,e])}function Ar(e){let t=[];return G(e,"",t),[...new Set(t.map(([n])=>n))].sort()}function kr(e){let t=e.slice(e.lastIndexOf(".")+1);return t.endsWith("[]")?t.slice(0,-2):t}function Ir(e){if(typeof e!="string"&&typeof e!="number")return null;let t=String(e).trim().toLowerCase();return t.length>0?t:null}function Sr(e,t={}){if(t.discriminatorField===null)return null;let n=[];G(e,"",n);let r=t.discriminatorField?[t.discriminatorField]:t.discriminatorFields??wr;for(let i of r){let a=null;for(let[o,s]of n){if(kr(o)!==i)continue;let l=Ir(s);l!==null&&(a===null||o<a.path)&&(a={path:o,value:l})}if(a)return a.value}return null}function It(e,t={}){let n=vr("sha256").update(Ar(e).join(",")).digest("hex").slice(0,16),r=Sr(e,t);return r!==null?`${n}:${r}`:n}var Er=["action","retrieval","delegation"];function Cr(e){return typeof e=="string"&&Er.includes(e)}var Tr=new Set(["rules"]);function St(e){if(typeof e.id!="string"||typeof e.vendor_id!="string")return null;let t=typeof e.origin_table=="string"?e.origin_table:"";if(!Tr.has(t))return null;let n=Array.isArray(e.applies_to)?e.applies_to.filter(Cr):[];return n.length===0?null:{id:e.id,originTable:t,vendorId:e.vendor_id,name:typeof e.name=="string"?e.name:"",description:typeof e.description=="string"?e.description:null,regoSource:typeof e.rego_source=="string"?e.rego_source:null,priority:typeof e.priority=="number"?e.priority:0,enabled:e.enabled===!0,appliesTo:n,targetApp:typeof e.target_app=="string"?e.target_app:null,actionPattern:typeof e.action_pattern=="string"?e.action_pattern:null,trustTier:typeof e.trust_tier=="string"?e.trust_tier:null,surface:typeof e.surface=="string"?e.surface:null,principalExclusions:Array.isArray(e.principal_exclusions)?e.principal_exclusions.filter(r=>typeof r=="string"):null,bypassActive:e.bypass_active===!0,bypassReason:typeof e.bypass_reason=="string"?e.bypass_reason:null,bypassExpiresAt:typeof e.bypass_expires_at=="string"?e.bypass_expires_at:null,redactionSpec:e.redaction_spec??null,failClosedOnEmptySpec:e.fail_closed_on_empty_spec===!0,hitlFallback:e.hitl_fallback==="mask"?"mask":"deny",ruleCode:typeof e.rule_code=="string"?e.rule_code:null}}import{z as V}from"zod";var Et=e=>e!==void 0&&e.length>5120?e.slice(0,5120):e;function Or(e){let t={...e};return t.content?.text!==void 0&&(t.content={...t.content,text:Et(t.content.text)}),t.spawn?.prompt!==void 0&&(t.spawn={...t.spawn,prompt:Et(t.spawn.prompt)}),t}function xr(e,t=process.env){if(typeof e=="number"&&Number.isFinite(e)&&e>0)return e;let n=t.ALLOW_TIMEOUT_MS;if(n!==void 0){let r=Number.parseInt(n,10);if(Number.isFinite(r)&&r>0)return r}return 5e3}var Nr=1440*60*1e3,Rr="VISIQ_BUNDLE_GRACE_TTL_MS",$r="VISIQ_BUNDLE_CACHE_DISABLED",Pr="VISIQ_CACHE_DIR",Lr=V.object({graceTtlMs:V.number().int().nonnegative().optional(),disabled:V.boolean().optional(),cacheDir:V.string().min(1).optional()}).strict();function Dr(e){return e==null?{}:Lr.parse(e)}function Mr(e,t=process.env){if(typeof e=="number"&&Number.isInteger(e)&&e>=0)return e;let n=t[Rr];if(n!==void 0){let r=Number(n);if(Number.isInteger(r)&&r>=0)return r}return Nr}function jr(e,t=process.env){if(typeof e=="boolean")return e;let n=(t[$r]??"").trim().toLowerCase();return n==="1"||n==="true"||n==="yes"}var Ct;function Fr(){if(Ct!==void 0)return Ct;try{return typeof process<"u"&&!!process.versions&&!!process.versions.node}catch{return!1}}function Ur(e){return JSON.stringify(se(e))}function se(e){if(Array.isArray(e))return e.map(se);if(e!==null&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=se(t[r]);return n}return e}function Br(e,t,n){let r=n-e.fetchedAt;return r<0?!1:r<=t}function qr(e){if(e!==null&&typeof e=="object"&&typeof e.fetchedAt=="number"&&typeof e.contentHash=="string"&&"body"in e){let t=e;return{fetchedAt:t.fetchedAt,version:typeof t.version=="string"?t.version:null,contentHash:t.contentHash,body:t.body}}return null}async function Pt(){if(!Fr())return null;try{let[e,t,n,r]=await Promise.all([import("node:fs/promises"),import("node:path"),import("node:os"),import("node:crypto")]);return{fs:e,path:t,os:n,crypto:r}}catch{return null}}function Lt(e,t){return e.createHash("sha256").update(Ur(t)).digest("hex")}function zr(e,t){let n=t.cacheDir?.trim();if(n)return n;let r=process.env[Pr]?.trim();if(r)return r;let i=process.env.XDG_CACHE_HOME?.trim();if(i)return e.path.join(i,"visiq");let a="";try{a=e.os.homedir()}catch{a=""}return a?e.path.join(a,".cache","visiq"):e.path.join(e.os.tmpdir(),"visiq-cache")}function Gr(e,t){return e.crypto.createHash("sha256").update(`${t.endpoint}\0${t.agentId}\0${t.apiKey}`).digest("hex")}function Dt(e,t,n){return e.path.join(zr(e,n),"bundles",`${Gr(e,t)}.json`)}async function Vr(e,t,n,r={}){let i=await Pt();if(i)try{let a=Dt(i,e,r),o=i.path.dirname(a);await i.fs.mkdir(o,{recursive:!0,mode:448});let s={fetchedAt:r.now??Date.now(),version:n,contentHash:Lt(i.crypto,t),body:t},l=`${a}.tmp-${process.pid}-${i.crypto.randomBytes(6).toString("hex")}`;await i.fs.writeFile(l,JSON.stringify(s),{mode:384});try{await i.fs.rename(l,a)}catch(u){throw await i.fs.rm(l,{force:!0}).catch(()=>{}),u}}catch{}}async function Wr(e,t={}){let n=await Pt();if(!n)return null;try{let r=await n.fs.readFile(Dt(n,e,t),"utf-8"),i=qr(JSON.parse(r));return!i||Lt(n.crypto,i.body)!==i.contentHash?null:i}catch{return null}}var L;async function Hr(){if(L!==void 0)return L;try{let e=await import("@visiq/core-wasm"),t=e.evaluate??e.default?.evaluate;L=typeof t=="function"?t:null}catch{L=null}return L}function Kr(e){let t=[];for(let n of e){if(typeof n!="object"||n===null)continue;let r=n,i=r.rego_source;if(typeof i!="string"||i.length===0)continue;let a;try{a=ct(i)}catch{continue}let o=typeof r.id=="string"?r.id:"<rule>";for(let s of ut(a))t.push(`${o}: ${s}`)}return t}var Yr=5e3,Jr=1e4,Zr=25,Tt=1e3,Qr=5e3,Xr=100,Ot=2e3,ei=512,ti=1800*1e3,ni=.7,ri="monitor",ii="Agent has been shut down by an operator \u2014 all actions are blocked (G001)",xt="Rules bundle requires a newer SDK wire-contract dialect than this SDK supports \u2014 refusing the bundle and blocking all actions (fail-closed, G001). Upgrade the VisIQ SDK.",ai="open";function Nt(e){if(typeof e!="string")return;let t=e.trim().toLowerCase();return t==="open"||t==="closed"?t:void 0}function oi(e,t){return Ge({content:e,resourceMetadata:t})}var si=d.object({operations:d.array(d.enum(["retrieval","action","delegation"])).min(1,"at least one operation is required"),agentId:d.string().min(1,"agentId is required"),sessionId:d.string().min(1).max(255).optional(),toolName:d.string().optional(),toolArgs:d.record(d.unknown()).optional(),targetResource:d.string().optional(),resourceType:d.string().optional(),resourceMetadata:d.record(d.unknown()).optional(),normalized:d.record(d.unknown()).optional(),query:d.string().optional(),contentPreview:d.string().optional(),telemetry:d.record(d.unknown()).optional(),context:d.record(d.unknown()).optional(),mcpServer:d.string().min(1).max(255).optional()}),li=d.object({version:d.string().min(1),dialect_version:d.number().int().optional(),min_dialect:d.number().int().optional(),shutdown:d.boolean().optional(),agent_mode:d.enum(["enforce","monitor","off"]).optional(),cognition_capture:d.boolean().optional(),agent_mode_by_operation:d.object({action:d.string().optional(),retrieval:d.string().optional(),delegation:d.string().optional()}).partial().optional(),agent_attributes:d.object({trust_tier:d.string().nullable().optional(),categories:d.array(d.string()).optional(),business_function:d.string().nullable().optional(),business_functions:d.array(d.string()).nullable().optional(),blast_radius_tier:d.string().nullable().optional(),no_coverage:d.string().nullable().optional(),fail_mode:d.string().nullable().optional()}).optional(),rules:d.array(d.record(d.unknown())),action_schemas:d.array(d.object({id:d.string(),plane:d.string().optional(),field_mappings:d.array(d.record(d.unknown())).optional(),derived_fields:d.array(d.record(d.unknown())).optional(),action_class:d.string().nullable().optional(),action_class_confidence:d.number().optional()})).optional(),no_coverage:d.object({no_coverage_defaults:d.record(d.string()),autopilot_enabled:d.boolean(),enduser_hitl_enabled:d.boolean(),hitl_timeout_seconds:d.number().optional()}).optional()});function ci(e){let t=e.trust_tier??null,n=[];Array.isArray(e.business_functions)&&e.business_functions.length>0?n=e.business_functions:typeof e.business_function=="string"&&e.business_function!==""&&(n=[e.business_function]);let r=vt(wt(n));return{trust_tier:pt(t)?t:null,categories:mt(e.categories??[]),business_functions:r,business_function:r[0]??null,blast_radius_tier:typeof e.blast_radius_tier=="string"&&At(e.blast_radius_tier)?e.blast_radius_tier:null}}function ui(e){if(!e)return null;let t={};for(let n of["action","retrieval","delegation"]){let r=e[n];(r==="enforce"||r==="monitor"||r==="off")&&(t[n]=r)}return Object.keys(t).length>0?t:null}function di(e){return e==="permit"?"permit":e==="mask"||e==="redact"?"mask":e==="approval_required"||e==="escalate"?"approval_required":"deny"}var le=new Set,Rt=!1;async function $t(e){let t=[];for(let n of le){if(n.pendingTelemetryCount()>0&&!n.hasBackend()){console.warn(`[UnifiedRuntime] exiting with ${n.pendingTelemetryCount()} un-sent decision(s) and no backend \u2014 telemetry lost.`);continue}let r=n.flush();e&&t.push(r)}t.length>0&&await Promise.allSettled(t)}function pi(){if(!Rt&&!(typeof process>"u"||typeof process.once!="function")){Rt=!0,process.once("beforeExit",()=>{$t(!1)});for(let e of["SIGINT","SIGTERM"])process.once(e,()=>{(async()=>{try{await $t(!0)}finally{process.kill(process.pid,e)}})()})}}var Mt=class{client;originalFetch;resolvedApiKey;resolvedEndpoint;resolvedAgentId;harnessKind;sdkVersion;sdkDialect;rules=[];agentAttributes=null;agentNoCoverage=null;sessions=new Map;noCoverage=null;bundleVersion=null;bundleEtag=null;bundleLoaded=!1;bundleFetchInProgress=!1;initialBundlePromise=null;refreshTimer=null;cacheIdentity;bundleCacheDisabled;bundleGraceTtlMs;bundleCacheDirOverride;diskFallbackServed=!1;agentMode=ri;agentModeByOperation=null;rawBundle=null;agentModeConfirmed=!1;operatorShutdown=!1;bundleApplyFailed=!1;dialectRefused=!1;failMode=Nt(typeof process<"u"?process.env?.VISIQ_FAIL_MODE:void 0)??ai;governedFailMode=null;telemetryBuffer=[];telemetryTimer=null;cognitionBuffer=[];cognitionTimer=null;cognitionEnabled=process.env.VISIQ_COGNITION_CAPTURE==="1";envRegistered=!1;registerPromise=null;lastToolSurfaceSig=null;lastCloneCaptureSig=null;toolDescriptions=new Map;constructor(e,t,n,r,i,a,o,s){let l=e??process.env.VISIQ_API_KEY??process.env.ALLOW_API_KEY??process.env.VISIQ_ALLOW_API_KEY,u=t??process.env.VISIQ_ENDPOINT??process.env.ALLOW_ENDPOINT,p=n??process.env.VISIQ_AGENT_ID??process.env.ALLOW_AGENT_ID??"";this.resolvedApiKey=l,this.resolvedEndpoint=u,this.resolvedAgentId=p,this.harnessKind=r,this.sdkVersion=a,this.sdkDialect=o,this.originalFetch=globalThis.fetch.bind(globalThis);let f=Dr(s);if(this.bundleCacheDisabled=jr(f.disabled),this.bundleGraceTtlMs=Mr(f.graceTtlMs),this.bundleCacheDirOverride=f.cacheDir,this.cacheIdentity=l&&u&&!this.bundleCacheDisabled?{endpoint:u,agentId:p,apiKey:l}:null,l&&u){let h={apiKey:l,agentId:p,endpoint:u,mode:"enforce",timeoutMs:xr(i),hitlTimeoutMs:12e4,failBehavior:"closed",...r?{harnessKind:r}:{},...a!==void 0?{sdkVersion:a}:{},...o!==void 0?{sdkDialect:o}:{}};this.client=new nt(h,this.originalFetch),this.initialBundlePromise=this.initialBundleLoad(),this.refreshTimer=setInterval(()=>{this.fetchBundleBackground()},Yr),oe(this.refreshTimer),this.telemetryTimer=setInterval(()=>{this.flushTelemetry()},Jr),oe(this.telemetryTimer),this.cognitionTimer=setInterval(()=>{this.flushCognition()},Qr),oe(this.cognitionTimer),le.add(this),pi()}else this.client=null}async evaluate(e){let t=si.parse(e),n=Date.now();if(this.operatorShutdown){let f=this.denyAll(t,ii);return this.applyAgentMode(f,"enforce",t,n)}if(this.dialectRefused){if(this.failMode==="open")return this.failOpen(t,xt,n);let f=this.denyAll(t,xt);return this.applyAgentMode(f,"enforce",t,n)}if(t.operations.every(f=>this.modeFor(f)==="off"))return this.offDecision(t);if(!this.bundleLoaded){let f;if(this.agentModeConfirmed?f=this.agentMode:this.bundleApplyFailed?f="enforce":f="monitor",f==="enforce"&&this.failMode==="open")return this.failOpen(t,"no unified bundle loaded and no local rules",n);let h=this.denyAll(t,"No unified bundle loaded and no local rules \u2014 fail-closed (G001)");return this.applyAgentMode(h,f,t,n)}let r=this.readSession(t.sessionId),i=await Hr();if(!i||!this.rawBundle){if(this.failMode==="open")return this.failOpen(t,"governance core (@visiq/core-wasm) unavailable",n);throw new Error("governance core (@visiq/core-wasm) unavailable \u2014 failing closed (G001)")}let a=t.operations.includes("action")||t.operations.includes("delegation")?gt(t.normalized??{},{targetApp:t.targetResource??t.toolName??""}):t.normalized,o=this.buildActionSchemaEvent(t),s=t.mcpServer?{...a??{},mcp_server:t.mcpServer}:a,l={...t,normalized:s,session:r,at:Date.now(),action_schema_id:o.id,action_schema_raw:o.canonical},u={...this.rawBundle,agent_mode:this.agentMode,...this.agentModeByOperation?{agent_mode_by_operation:this.agentModeByOperation}:{}},p;try{p=i(l,u)}catch(f){if(this.failMode==="open")return this.failOpen(t,`governance core evaluation threw: ${f instanceof Error?f.message:String(f)}`,n);throw f}return this.foldSession(t,p.enforced?p.decision:"permit"),p.enforced&&p.action.decision==="approval_required"&&await this.registerHitl(t,p),this.bufferTelemetry(t,p,Date.now()-n,p.enforced),p}modeFor(e){return this.agentModeByOperation?.[e]??this.agentMode}readSession(e){if(!e)return P;let t=this.sessions.get(e);return t?Date.now()-t.touchedAt>ti?(this.sessions.delete(e),P):t.state:P}foldActionClass(e){let t=e.normalized?.action_class;if(typeof t=="string"&&t.length>0)return t;let n=this.rawBundle?.action_schemas;if(!Array.isArray(n))return;let{id:r}=this.buildActionSchemaEvent(e),i=n.find(s=>s?.id===r);if(!i)return;let a=i.action_class,o=typeof i.action_class_confidence=="number"?i.action_class_confidence:0;if(typeof a=="string"&&a.length>0&&o>=ni)return a}foldSession(e,t){let{sessionId:n}=e;if(!n)return;let r=this.readSession(n),i=e.resourceMetadata??{},a=e.operations.includes("retrieval"),o=e.operations.includes("action")||e.operations.includes("delegation"),s=_t(r===P?ht():r,{data_categories:a&&Array.isArray(i.data_categories)?i.data_categories:void 0,classification:a?i.classification:void 0,taint:a?oi(e.contentPreview,i):void 0,action_class:o?this.foldActionClass(e):void 0,target_app:o?e.targetResource??e.toolName:void 0,decision:t});if(this.sessions.delete(n),this.sessions.set(n,{state:s,touchedAt:Date.now()}),this.sessions.size>ei){let l=this.sessions.keys().next().value;l!==void 0&&this.sessions.delete(l)}}applyAgentMode(e,t,n,r){let i=Date.now()-r;if(t==="enforce"){let o={...e,enforced:!0,agentMode:"enforce"};return this.bufferTelemetry(n,o,i,!0),o}let a={...e,allowed:!0,enforced:!1,agentMode:"monitor"};return this.bufferTelemetry(n,a,i,!1),a}setFailMode(e){this.failMode=e}getFailMode(){return this.failMode}getGovernedFailMode(){return this.governedFailMode}failOpen(e,t,n){let r=`fail-open: ${t} \u2014 proceeding UNGOVERNED (set VISIQ_FAIL_MODE=closed to block instead)`;console.error(`[VisIQ] FAIL-OPEN: ${t} \u2014 proceeding UNGOVERNED. Set VISIQ_FAIL_MODE=closed to block instead.`);let i=e.operations.includes("action")||e.operations.includes("delegation"),a=e.operations.includes("retrieval"),o={decision:"permit",allowed:!0,reason:r,ruleId:null,ruleCode:null,enforced:!1,agentMode:this.agentMode,action:i?{decision:"permit",allowed:!0}:{decision:null,allowed:!0},retrieval:a?{action:"allow"}:{action:null},failOpen:!0};return this.bufferTelemetry(e,o,Date.now()-n,!1,!0),o}reportFailOpen(e,t){try{let n={operations:["action"],agentId:this.resolvedAgentId,...t?.toolName?{toolName:t.toolName}:{},...t?.sessionId?{sessionId:t.sessionId}:{}},r={decision:"permit",allowed:!0,reason:`fail-open: ${e} \u2014 proceeding UNGOVERNED (set VISIQ_FAIL_MODE=closed to block instead)`,ruleId:null,ruleCode:null,enforced:!1,agentMode:this.agentMode,action:{decision:"permit",allowed:!0},retrieval:{action:null},failOpen:!0};this.bufferTelemetry(n,r,0,!1,!0)}catch{}}offDecision(e){let t=e.operations.includes("action")||e.operations.includes("delegation"),n=e.operations.includes("retrieval");return{decision:"permit",allowed:!0,reason:"agent_mode=off \u2014 evaluation bypassed",ruleId:null,ruleCode:null,enforced:!1,agentMode:"off",action:t?{decision:"permit",allowed:!0}:{decision:null,allowed:!0},retrieval:n?{action:"allow"}:{action:null}}}denyAll(e,t){let n=e.operations.includes("action")||e.operations.includes("delegation"),r=e.operations.includes("retrieval");return{decision:"deny",allowed:!1,reason:t,ruleId:null,ruleCode:null,enforced:!0,agentMode:"enforce",action:n?{decision:"deny",allowed:!1}:{decision:null,allowed:!0},retrieval:r?{action:"deny"}:{action:null}}}async registerHitl(e,t){if(this.client)try{let n={agent_id:e.agentId,target_app:e.targetResource??e.toolName??"",action:e.toolName??"",context:e.toolName?{[e.toolName]:e.toolArgs??{}}:{},action_schema_id:this.buildActionSchemaEvent(e).id,...e.sessionId?{session_id:e.sessionId}:{},...e.telemetry?{telemetry:e.telemetry}:{}},r=await this.client.evaluate(n);r.decision_id&&(t.action.decisionId=r.decision_id)}catch(n){console.warn("[UNIFIED] HITL registration failed \u2014 staying fail-closed (G001):",n)}}applyBundle(e){this.bundleApplyFailed=!0;let t=li.parse(e);this.bundleApplyFailed=!1;let n=this.sdkDialect??1;if(t.min_dialect!==void 0&&t.min_dialect>n){this.dialectRefused=!0,this.bundleApplyFailed=!0,console.warn(`[UNIFIED] rules bundle requires dialect ${t.min_dialect} but this SDK speaks ${n} \u2014 refusing the bundle and failing closed (deny-all, G001). Upgrade the VisIQ SDK.`);return}let r=Kr(t.rules);if(r.length>0){this.dialectRefused=!0,this.bundleApplyFailed=!0,console.warn(`[UNIFIED] rules bundle contains rego_source using a builtin the engine cannot evaluate (would silently never match \u2192 fail open): ${r.join("; ")}. Refusing the bundle and failing closed (G001). Recompile the rule without case-folding wrappers like upper()/lower().`);return}this.dialectRefused=!1,!(this.bundleLoaded&&t.version===this.bundleVersion)&&(this.rules=t.rules.map(i=>St(i)).filter(i=>i!==null),this.agentAttributes=t.agent_attributes?ci(t.agent_attributes):null,this.agentNoCoverage=kt(t.agent_attributes?.no_coverage),this.governedFailMode=Nt(t.agent_attributes?.fail_mode)??null,this.bundleVersion=t.version,this.bundleLoaded=!0,this.noCoverage=t.no_coverage?{no_coverage_defaults:t.no_coverage.no_coverage_defaults,autopilot_enabled:t.no_coverage.autopilot_enabled,enduser_hitl_enabled:t.no_coverage.enduser_hitl_enabled}:null,t.agent_mode!==void 0&&(this.agentMode=t.agent_mode,this.agentModeConfirmed=!0),this.agentModeByOperation=ui(t.agent_mode_by_operation),process.env.VISIQ_COGNITION_CAPTURE==="1"?this.cognitionEnabled=!0:typeof t.cognition_capture=="boolean"&&(this.cognitionEnabled=t.cognition_capture),this.operatorShutdown=t.shutdown===!0,this.rawBundle=e)}async awaitBundleReady(e=5e3){if(!this.initialBundlePromise||this.bundleLoaded)return;let t,n=new Promise(r=>{t=setTimeout(r,e)});try{await Promise.race([this.initialBundlePromise,n])}catch{}finally{t&&clearTimeout(t)}}async fetchBundleBackground(){if(!(this.bundleFetchInProgress||!this.resolvedEndpoint||!this.resolvedApiKey)){this.bundleFetchInProgress=!0;try{let e=this.resolvedAgentId?`?agent_id=${encodeURIComponent(this.resolvedAgentId)}`:"",t={Authorization:`Bearer ${this.resolvedApiKey}`,Accept:"application/json",...ne(this.sdkVersion,this.sdkDialect)};this.bundleEtag&&(t["If-None-Match"]=this.bundleEtag);let n=await this.originalFetch(`${this.resolvedEndpoint}/rules/bundle${e}`,{method:"GET",headers:t});if(n.status===304)return;if(!n.ok)throw new Error(`unified bundle fetch failed: HTTP ${n.status}`);let r=n.headers.get("ETag"),i=await n.json();this.applyBundle(i);let a=this.bundleLoaded&&!this.dialectRefused&&!this.bundleApplyFailed;r&&a?this.bundleEtag=r:a||(this.bundleEtag=null),a&&await this.persistBundleToDisk(i)}catch(e){this.bundleLoaded?console.warn("[UNIFIED] Bundle refresh failed (using cached rules):",e):console.warn("[UNIFIED] Initial bundle fetch failed (fail-closed until loaded):",e)}finally{this.bundleFetchInProgress=!1}}}async initialBundleLoad(){await this.fetchBundleBackground(),this.bundleLoaded||await this.tryLoadFromDiskCache()}async tryLoadFromDiskCache(){if(this.bundleLoaded||this.bundleCacheDisabled||!this.cacheIdentity||this.dialectRefused)return;let e;try{e=await Wr(this.cacheIdentity,{...this.bundleCacheDirOverride?{cacheDir:this.bundleCacheDirOverride}:{}})}catch{return}if(!e)return;let t=Date.now();if(Br(e,this.bundleGraceTtlMs,t)){try{this.applyBundle(e.body)}catch{return}if(this.bundleLoaded&&!this.dialectRefused&&!this.diskFallbackServed){this.diskFallbackServed=!0;let n=Math.max(0,Math.round((t-e.fetchedAt)/1e3)),r=Math.round(this.bundleGraceTtlMs/1e3);console.warn(`[UnifiedRuntime] serving cached rules bundle (age ${n}s) \u2014 control plane unreachable on cold start; will keep retrying and fail closed once the cache exceeds the ${r}s grace window.`)}}}async persistBundleToDisk(e){this.bundleCacheDisabled||!this.cacheIdentity||await Vr(this.cacheIdentity,e,this.bundleVersion,{...this.bundleCacheDirOverride?{cacheDir:this.bundleCacheDirOverride}:{}})}hasRules(){return this.bundleLoaded&&this.rules.length>0}hasClient(){return this.client!==null}getEndpoint(){return this.resolvedEndpoint}getApiKey(){return this.resolvedApiKey}getBundleVersion(){return this.bundleVersion}isBundleLoaded(){return this.bundleLoaded}getAgentMode(){return this.agentMode}getAgentAttributes(){return this.agentAttributes}getSessionState(e){return this.readSession(e)}registerEnvironment(e){!this.client||this.envRegistered||!this.resolvedAgentId||(this.envRegistered=!0,this.registerPromise=this.client.registerEnvironment(e))}registerHostEnvironment(e,t){this.registerEnvironment({...re(),...e?{agent_type:e}:{},...t?.model?{model:t.model}:{},...t?.systemPrompt?{systemPrompt:t.systemPrompt}:{},...t?.toolSchemas&&t.toolSchemas.length>0?{toolSchemas:t.toolSchemas}:{}})}reportToolSurface(e){if(!this.client||!this.resolvedAgentId||e.length===0)return;let t=JSON.stringify([...e].map(n=>({n:n.name,d:n.description??"",s:n.input_schema??null})).sort((n,r)=>n.n.localeCompare(r.n)));for(let n of e)n.description&&this.toolDescriptions.set(n.name,n.description);t!==this.lastToolSurfaceSig&&(this.lastToolSurfaceSig=t,this.client.reportToolSurface(e))}captureCloneMetadata(e){if(!this.client||!this.resolvedAgentId||!(e.model||e.systemPrompt||(e.toolSchemas?.length??0)>0))return;let t=JSON.stringify({m:e.model??"",s:e.systemPrompt??"",t:e.toolSchemas??[]});t!==this.lastCloneCaptureSig&&(this.lastCloneCaptureSig=t,this.client.registerEnvironment({...re(),...e.agentType?{agent_type:e.agentType}:{},...e.model?{model:e.model}:{},...e.systemPrompt?{systemPrompt:e.systemPrompt}:{},...e.toolSchemas&&e.toolSchemas.length>0?{toolSchemas:e.toolSchemas}:{}}))}buildActionSchemaEvent(e){let t=e.toolName?this.toolDescriptions.get(e.toolName):void 0,n={agent_id:e.agentId,operations:e.operations,...e.toolName?{tool_name:e.toolName}:{},...e.targetResource?{target_resource:e.targetResource}:{},...e.resourceType?{resource_type:e.resourceType}:{},...e.toolArgs?{tool_args:e.toolArgs}:{},...t?{tool_description:t}:{}},r=It(n),i={...n};return e.toolArgs&&(i.tool_args=Le(e.toolArgs)),{canonical:n,id:r,rawEventForWire:i}}bufferTelemetry(e,t,n,r,i=!1){let a=this.buildActionSchemaEvent(e);this.telemetryBuffer.push({decision_id:crypto.randomUUID(),agent_id:e.agentId,target_app:e.targetResource??e.toolName??"",action:e.toolName??e.operations.join("+"),...e.sessionId?{session_id:e.sessionId}:{},decision:r?di(t.decision):"permit",reason:t.reason,evaluated_at:new Date().toISOString(),rule_id:t.ruleId,rule_code:t.ruleCode,enforced:r,agent_mode:this.agentMode,latency_ms:n,evaluation_mode:"local",raw_event:a.rawEventForWire,action_schema_id:a.id,...this.harnessKind||e.context||i?{context:{...this.harnessKind?{[et]:this.harnessKind}:{},...e.context??{},...i?{fail_open:!0}:{}}}:{}}),this.enforceTelemetryCap(),this.telemetryBuffer.length>=Zr&&this.flushTelemetry()}pendingTelemetryCount(){return this.telemetryBuffer.length}hasBackend(){return this.client!==null}async flushTelemetry(){if(this.telemetryBuffer.length===0||!this.client)return;let e=this.telemetryBuffer.splice(0);try{await this.client.sendTelemetry(e)}catch(t){console.error("[UnifiedRuntime] telemetry flush failed (non-fatal):",t)}}enforceTelemetryCap(){let e=this.telemetryBuffer.length-Tt;e>0&&(this.telemetryBuffer.splice(0,e),console.warn(`[UnifiedRuntime] telemetry buffer full \u2014 dropped ${e} oldest entries (cap ${Tt})`))}isCognitionEnabled(){return this.cognitionEnabled}emitCognition(e){!this.cognitionEnabled||!this.client||(this.cognitionBuffer.push(Or(e)),this.enforceCognitionCap(),this.cognitionBuffer.length>=Xr&&this.flushCognition())}async flushCognition(){if(this.cognitionBuffer.length===0||!this.client)return;let e=this.cognitionBuffer.splice(0);try{await this.client.sendCognition(void 0,e)}catch(t){console.error("[UnifiedRuntime] cognition flush failed (non-fatal):",t)}}enforceCognitionCap(){let e=this.cognitionBuffer.length-Ot;e>0&&(this.cognitionBuffer.splice(0,e),console.warn(`[UnifiedRuntime] cognition buffer full \u2014 dropped ${e} oldest beats (cap ${Ot})`))}async flush(){if(this.registerPromise)try{await this.registerPromise}catch{}await this.flushTelemetry(),await this.flushCognition()}async shutdown(){await this.flush(),this.dispose(),le.delete(this)}dispose(){this.refreshTimer&&(clearInterval(this.refreshTimer),this.refreshTimer=null),this.telemetryTimer&&(clearInterval(this.telemetryTimer),this.telemetryTimer=null),this.cognitionTimer&&(clearInterval(this.cognitionTimer),this.cognitionTimer=null),this.flushTelemetry(),this.flushCognition()}};function oe(e){e&&typeof e=="object"&&"unref"in e&&e.unref()}function W(e){return typeof e=="string"&&e.trim().length>0?e:void 0}function jt(e,t){if(e!=="Task"&&e!=="Agent")return null;let n=W(t.description),r=W(t.subagent_type),i=W(t.prompt),a=n??r??"sub-agent";return{childAgentId:a,childName:a,kind:"subagent",agentType:r,description:n,task:i,goal:i,model:W(t.model),source:"structural"}}function Ft(e,t){return{delegation:{is_delegated:!0,role:"parent",parent_agent_id:t,target_agent:e.childAgentId,source:e.source,spawn:{childAgentId:e.childAgentId,childName:e.childName,kind:e.kind,...e.model?{model:e.model}:{},...e.task?{prompt:e.task}:{},...e.description?{description:e.description}:{},...e.goal?{goal:e.goal}:{},...e.agentType?{agentType:e.agentType}:{}}}}}function ce(e){let t=[],n=[],r,i=[];for(let o of e){if(o.mode==="partial"||o.mode==="email"||o.mode==="custom"){let l={mode:o.mode};o.field&&(l.field=o.field),o.pattern&&(l.pattern=o.pattern),typeof o.keepFirst=="number"&&(l.keepFirst=o.keepFirst),typeof o.keepLast=="number"&&(l.keepLast=o.keepLast),o.maskChar&&(l.maskChar=o.maskChar),o.keepPattern&&(l.keepPattern=o.keepPattern),o.replacement!==void 0&&(l.replacement=o.replacement),i.push(l);continue}o.field&&t.push(o.field),o.pattern&&n.push(o.pattern);let{replacement:s}=o;s&&r===void 0&&(r=s)}let a={};return t.length>0&&(a.fields=t),n.length>0&&(a.patterns=n),r!==void 0&&(a.replacement=r),i.length>0&&(a.directives=i),a}var fi="[VisIQ: retrieval withheld by policy]";function H(e){return ue(e)}function ue(e){if(e==null)return e;if(typeof e=="string")return e.length>0?fi:e;if(typeof e=="number")return 0;if(typeof e=="boolean")return!1;if(Array.isArray(e))return e.map(ue);if(typeof e=="object"){let t=Object.create(null);for(let n of Object.keys(e))t[n]=ue(e[n]);return t}return e}function Ut(e){return e.fields&&e.fields.length>0||e.patterns&&e.patterns.length>0?!0:!!e.directives?.some(t=>t.field&&t.field.length>0||t.pattern&&t.pattern.length>0)}function Bt(e,t){if(!e.enforced)return null;let{action:n,retrieval:r}=e,i=I(e.reason,e.ruleCode);if(n.decision==="deny"||r.action==="deny")return F(i);if(n.decision==="approval_required"||r.action==="escalate")return ve(i);if(n.decision==="mask"&&n.argRedactionRules&&n.argRedactionRules.length>0){let a=ce(n.argRedactionRules);if(Ut(a)){let o=te(t,a)??t;if(JSON.stringify(o)!==JSON.stringify(t))return be(o)}return null}return null}function qt(e,t){if(!e.enforced)return null;let{retrieval:n}=e,r=I(e.reason,e.ruleCode);if(n.action==="redact"){let i=ce(n.redactionRules??[]);if(!Ut(i))return S(H(t),r);let a=te(t,i);return JSON.stringify(a)===JSON.stringify(t)?null:S(a,r)}return n.action==="deny"?S(H(t),r):null}var mi="cli_harness";function C(e){let t=new Mt(e.apiKey,e.baseUrl,e.agentId,mi);return t.setFailMode(e.failMode),t}function K(e){let t={operations:e.operations,agentId:e.agentId,toolName:e.toolName,toolArgs:e.toolInput,resourceType:"tool_result",resourceMetadata:{toolName:e.toolName,...e.toolUseId?{toolCallId:e.toolUseId}:{},...e.sessionId?{sessionId:e.sessionId}:{},...e.cwd?{cwd:e.cwd}:{}}};return e.query&&(t.query=e.query),e.context&&(t.context=e.context),t}async function T(e,t,n=pe){let{agentId:r}=t,i=await me(r);if(i&&fe(i,n,Date.now())&&de(e,i.body))return!0;let a=e.getEndpoint();if(a){let o=await he(a,t.apiKey,r);if(o&&de(e,o.body))return await ge(r,o.body,o.version),!0}if(i&&de(e,i.body))return!0;try{await e.awaitBundleReady(2500)}catch{}return e.isBundleLoaded()}function de(e,t){try{return e.applyBundle(t),!0}catch{return!1}}async function O(e){try{await e.flush()}catch{}try{e.dispose()}catch{}}async function ca(e,t){let n=C(t),r=e.tool_input??{};try{if(await _e(e.session_id)||(n.registerHostEnvironment(),await D(e.session_id)),!await T(n,t)&&t.failMode!=="closed")return await k({stage:"no-bundle",detail:"no rule bundle available (cache empty + fetch failed)",toolName:e.tool_name,sessionId:e.session_id}),null;let a=jt(e.tool_name,r),o=ye(e.tool_name),s;a&&(ie(n,{agentId:t.agentId,sessionId:e.session_id,framework:"claude-code"},a),o=Array.from(new Set([...o,"delegation"])),s=Ft(a,t.agentId));let l=K({operations:o,agentId:t.agentId,toolName:e.tool_name,toolInput:r,sessionId:e.session_id,cwd:e.cwd,toolUseId:e.tool_use_id,query:j(r),...s?{context:s}:{}}),u=await n.evaluate(l);return await M(u,{toolName:e.tool_name,sessionId:e.session_id}),Bt(u,r)}catch(i){return t.failMode==="closed"?F(I("evaluation error \u2014 blocked (VISIQ_FAIL_MODE=closed)",null)):(await k({stage:"pre-eval-error",detail:i instanceof Error?i.message:String(i),toolName:e.tool_name,sessionId:e.session_id}),null)}finally{await O(n)}}async function ha(e,t){if(!J(e.tool_name))return null;let n=C(t);try{if(!await T(n,t)&&t.failMode!=="closed")return await k({stage:"no-bundle",detail:"no rule bundle available (cache empty + fetch failed)",toolName:e.tool_name,sessionId:e.session_id}),null;let i=e.tool_input??{},a=K({operations:["retrieval"],agentId:t.agentId,toolName:e.tool_name,toolInput:i,sessionId:e.session_id,cwd:e.cwd,toolUseId:e.tool_use_id,query:j(i)}),o=await n.evaluate(a);return await M(o,{toolName:e.tool_name,sessionId:e.session_id}),qt(o,e.tool_response)}catch(r){return t.failMode==="closed"?S(H(e.tool_response),I("evaluation error \u2014 withheld (VISIQ_FAIL_MODE=closed)",null)):(await k({stage:"post-eval-error",detail:r instanceof Error?r.message:String(r),toolName:e.tool_name,sessionId:e.session_id}),null)}finally{await O(n)}}async function va(e,t){let n=C(t);try{n.registerHostEnvironment(),await T(n,t,0),await D(e.session_id)}finally{await O(n)}return null}export{Ht as a,k as b,Jt as c,J as d,ye as e,j as f,I as g,be as h,F as i,ve as j,S as k,vi as l,fi as m,H as n,Bt as o,qt as p,mi as q,C as r,K as s,T as t,O as u,ca as v,ha as w,va as x};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readFile as P}from"node:fs/promises";import{homedir as g}from"node:os";import{join as f,isAbsolute as w,resolve as C}from"node:path";var S="https://api.visiqlabs.com",M="@visiq/claude-code-harness",p="open";function m(n){if(typeof n!="string")return;let e=n.trim().toLowerCase();return e==="open"||e==="closed"?e:void 0}function s(){let n=process.env.VISIQ_HOME;return n&&n.trim().length>0?n:f(g(),".visiq","claude-code")}function x(){return f(s(),"config.json")}function A(n){return n==="~"||n.startsWith("~/")?f(g(),n.slice(1).replace(/^\//,"")):n}async function F(n){try{let e=w(n)?n:C(n),t=await P(e,"utf-8");return JSON.parse(t)}catch{return null}}function c(n,...e){for(let t of e){let i=n[t];if(typeof i=="string"&&i.length>0)return i}}function l(n){if(!n||typeof n!="object")return{};let e=n,t={},i=c(e,"apiKey","api_key"),r=c(e,"agentId","agent_id"),o=c(e,"baseUrl","base_url"),a=m(c(e,"failMode","fail_mode"));return i&&(t.apiKey=i),r&&(t.agentId=r),o&&(t.baseUrl=o),a&&(t.failMode=a),t}async function d(n){if(!n)return{};let e=await F(A(n));if(!e||typeof e!="object")return{};let t=e,i=t.plugins?.entries,r=i&&typeof i=="object"?i[M]:void 0;return r&&typeof r=="object"&&r.config?l(r.config):l(t)}function k(n=process.env){let e={};n.VISIQ_API_KEY&&(e.apiKey=n.VISIQ_API_KEY),n.VISIQ_AGENT_ID&&(e.agentId=n.VISIQ_AGENT_ID),n.VISIQ_BASE_URL?e.baseUrl=n.VISIQ_BASE_URL:n.VISIQ_ENDPOINT&&(e.baseUrl=n.VISIQ_ENDPOINT);let t=m(n.VISIQ_FAIL_MODE);return t&&(e.failMode=t),e}function E(n,e,t){let i={...n,...e,...t};if(!i.apiKey||!i.agentId)return null;let r={apiKey:i.apiKey,agentId:i.agentId,failMode:i.failMode??p};return r.baseUrl=i.baseUrl||S,r}async function U(){let n=k(),e=await d(process.env.VISIQ_CONFIG_PATH),t=await d(x()),i={...t,...e,...n};return{config:E(t,e,n),failMode:i.failMode??p}}async function K(){return(await U()).config}import{mkdir as I,readFile as D,writeFile as y,stat as N}from"node:fs/promises";import{createHash as V}from"node:crypto";import{join as u}from"node:path";var G=3e4,T=4e3;function v(n){return n.replace(/[^a-zA-Z0-9._-]/g,"_").slice(0,200)||"default"}function _(n){let e=V("sha1").update(n).digest("hex").slice(0,10);return`${v(n)}-${e}`}function J(n,e,t){return t-n.fetchedAt<e}function b(n){return u(s(),"bundles",`${_(n)}.json`)}function h(n){return u(s(),"sessions",`${_(n)}.registered`)}async function z(n){try{let e=await D(b(n),"utf-8"),t=JSON.parse(e);return t&&typeof t.fetchedAt=="number"&&"body"in t?t:null}catch{return null}}async function Y(n,e,t){try{let i=b(n);await I(u(s(),"bundles"),{recursive:!0});let r={fetchedAt:Date.now(),version:t,body:e};await y(i,JSON.stringify(r),{mode:384})}catch{}}async function W(n,e,t){try{let r=`${n.replace(/\/+$/,"")}/rules/bundle?agent_id=${encodeURIComponent(t)}`,o=await fetch(r,{method:"GET",headers:{Authorization:`Bearer ${e}`,Accept:"application/json"},signal:AbortSignal.timeout(T)});if(!o.ok)return null;let a=o.headers.get("etag");return{body:await o.json(),version:a}}catch{return null}}async function Z(n){try{return await N(h(n)),!0}catch{return!1}}async function X(n){try{await I(u(s(),"sessions"),{recursive:!0}),await y(h(n),String(Date.now()),{mode:384})}catch{}}export{p as a,m as b,s as c,x as d,k as e,E as f,U as g,K as h,G as i,v as j,J as k,z as l,Y as m,W as n,Z as o,X as p};
|
package/dist/cli/hook.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{
|
|
3
|
-
`)}:()=>{},
|
|
2
|
+
import{b as a,i,l as p,v as f,w as m,x as I}from"../chunk-CBUHAEGD.js";import{a as d,b as c,g as u}from"../chunk-XEWB3NIN.js";var g=process.env.VISIQ_DEBUG==="1",_=g?(...e)=>{process.stderr.write(`${e.map(String).join(" ")}
|
|
3
|
+
`)}:()=>{},S=console;for(let e of["log","info","debug","warn","error"])S[e]=_;var k={handlePre:(e,o)=>f(e,o),handlePost:(e,o)=>m(e,o),handleSession:(e,o)=>I(e,o),write:e=>{process.stdout.write(e)},reportFailOpen:e=>a(e)};async function h(e,o,s=k){let t=e.hook_event_name==="PreToolUse",r=n=>{t&&s.write(JSON.stringify(i(n)))};try{let n=null;switch(e.hook_event_name){case"PreToolUse":n=await s.handlePre(e,o);break;case"PostToolUse":n=await s.handlePost(e,o);break;case"SessionStart":n=await s.handleSession(e,o);break;default:n=null}n&&s.write(JSON.stringify(n))}catch(n){let l=n instanceof Error?n.message:String(n);o.failMode==="closed"?r(`[VisIQ] harness error \u2014 blocked (VISIQ_FAIL_MODE=closed): ${l}`):await s.reportFailOpen({stage:"handler-crash",detail:l,toolName:e.tool_name,sessionId:e.session_id})}}function v(e,o=process.env){return c(o.VISIQ_FAIL_MODE)??e}function w(e,o,s){let t=e instanceof Error?e.message:String(e),r=v(o,s.env??process.env);try{r==="closed"?s.writeOut(JSON.stringify(i("[VisIQ] harness crashed before evaluating the call \u2014 blocked (VISIQ_FAIL_MODE=closed)."))):s.writeErr(`[VisIQ] FAIL-OPEN (dispatch-crash): ${t} \u2014 tool call proceeding UNGOVERNED. Set VISIQ_FAIL_MODE=closed to block instead.
|
|
4
|
+
`)}catch{}return r}var P=d;function E(){return new Promise(e=>{if(process.stdin.isTTY){e("");return}let o=[],s=!1,t=()=>{s||(s=!0,e(Buffer.concat(o).toString("utf-8")))};setTimeout(t,15e3).unref?.(),process.stdin.on("data",n=>o.push(n)),process.stdin.on("end",t),process.stdin.on("error",t)})}async function D(){let e=p(await E());if(!e)return;let o=e.hook_event_name==="PreToolUse",s=n=>{o&&process.stdout.write(JSON.stringify(i(n)))},{config:t,failMode:r}=await u();if(P=r,!t){r==="closed"?s("[VisIQ] Claude Code harness is loaded but NOT configured \u2014 set VISIQ_API_KEY + VISIQ_AGENT_ID (and optionally VISIQ_ENDPOINT), or run `visiq-claude-code configure`. Blocked because VISIQ_FAIL_MODE=closed."):o&&await a({stage:"unconfigured",detail:"no VisIQ credentials resolved (need VISIQ_API_KEY + VISIQ_AGENT_ID)",toolName:e.tool_name,sessionId:e.session_id},!1);return}await h(e,t)}D().then(()=>process.exit(0)).catch(e=>{w(e,P,{writeOut:o=>process.stdout.write(o),writeErr:o=>process.stderr.write(o)}),process.exit(0)});
|
package/dist/cli/main.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as f,e as m,f as w,g as d}from"../chunk-6DMSMBWM.js";import{
|
|
2
|
+
import{a as f,e as m,f as w,g as d}from"../chunk-6DMSMBWM.js";import{c as l,d as u,e as g,h as p,l as y}from"../chunk-XEWB3NIN.js";import{mkdir as I,readFile as v,writeFile as h}from"node:fs/promises";import{existsSync as j}from"node:fs";import{homedir as k}from"node:os";import{dirname as $,isAbsolute as C,join as a,resolve as Q}from"node:path";import{parseArgs as V}from"node:util";function N(){let{positionals:e,values:n}=V({args:process.argv.slice(2),options:{user:{type:"boolean"},project:{type:"boolean"},settings:{type:"string"},command:{type:"string"},"api-key":{type:"string"},"agent-id":{type:"string"},"base-url":{type:"string"}},strict:!1,allowPositionals:!0});return{positionals:e,values:n}}function S(e){let n=e.settings;return typeof n=="string"&&n.length>0?C(n)?n:Q(n):e.project?a(process.cwd(),".claude","settings.json"):a(k(),".claude","settings.json")}async function c(e){if(!j(e))return{};try{let n=await v(e,"utf-8"),t=JSON.parse(n);return t&&typeof t=="object"?t:{}}catch{return{}}}async function P(e,n){await I($(e),{recursive:!0}),await h(e,`${JSON.stringify(n,null,2)}
|
|
3
3
|
`,"utf-8")}async function U(e){let n=S(e),t=typeof e.command=="string"?e.command:f,s=await c(n);return await P(n,m(s,t)),process.stdout.write(`[VisIQ] Installed Claude Code governance hooks \u2192 ${n}
|
|
4
4
|
SessionStart + PreToolUse + PostToolUse \u2192 \`${t}\`
|
|
5
5
|
Next: set credentials (\`visiq-claude-code configure\`) then start Claude Code.
|
package/dist/index.d.ts
CHANGED
|
@@ -19,16 +19,33 @@ import { z } from 'zod';
|
|
|
19
19
|
* null when creds are absent; hooks treat null as "unconfigured → fail-open
|
|
20
20
|
* no-op" so an installed-but-unconfigured harness never breaks Claude Code.
|
|
21
21
|
*/
|
|
22
|
+
/**
|
|
23
|
+
* What the harness does when IT (not policy) fails — missing config, endpoint
|
|
24
|
+
* unreachable, no bundle, evaluator crash. `open` (DEFAULT, owner decision
|
|
25
|
+
* 2026-07-15): allow the call + loud fail-open telemetry — a VisIQ bug must
|
|
26
|
+
* never disrupt the agent. `closed`: strict G001 blocking (opt-in via
|
|
27
|
+
* VISIQ_FAIL_MODE=closed or `failMode` in the config file).
|
|
28
|
+
*/
|
|
29
|
+
export type FailMode = "open" | "closed";
|
|
30
|
+
export declare const DEFAULT_FAIL_MODE: FailMode;
|
|
22
31
|
export interface VisiqConfig {
|
|
23
32
|
apiKey: string;
|
|
24
33
|
agentId: string;
|
|
25
34
|
baseUrl?: string;
|
|
35
|
+
failMode: FailMode;
|
|
26
36
|
}
|
|
27
37
|
export interface PartialConfig {
|
|
28
38
|
apiKey?: string;
|
|
29
39
|
agentId?: string;
|
|
30
40
|
baseUrl?: string;
|
|
41
|
+
failMode?: FailMode;
|
|
31
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Normalize a raw failMode value. Only the exact (case-insensitive) strings
|
|
45
|
+
* `open`/`closed` count; anything else → undefined so the default applies. A
|
|
46
|
+
* typo'd value must degrade to the DEFAULT, never invent strictness.
|
|
47
|
+
*/
|
|
48
|
+
export declare function normalizeFailMode(raw: unknown): FailMode | undefined;
|
|
32
49
|
/**
|
|
33
50
|
* The VisIQ harness state directory (config + bundle cache + session markers).
|
|
34
51
|
* Overridable via VISIQ_HOME (used by tests + the conformance harness to
|
|
@@ -44,50 +61,22 @@ export declare function envConfig(env?: NodeJS.ProcessEnv): PartialConfig;
|
|
|
44
61
|
* config). Pure — split out so it can be unit-tested without disk I/O.
|
|
45
62
|
*/
|
|
46
63
|
export declare function mergeConfig(home: PartialConfig, configPath: PartialConfig, env: PartialConfig): VisiqConfig | null;
|
|
64
|
+
/** Credentials (null when unresolvable) + the failMode that applies either way. */
|
|
65
|
+
export interface HarnessState {
|
|
66
|
+
config: VisiqConfig | null;
|
|
67
|
+
failMode: FailMode;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Resolve credentials AND failMode in one pass. failMode must be resolvable
|
|
71
|
+
* even when credentials are absent (the unconfigured guard consults it), so it
|
|
72
|
+
* is surfaced separately from the nullable config. Never throws.
|
|
73
|
+
*/
|
|
74
|
+
export declare function loadHarnessState(): Promise<HarnessState>;
|
|
47
75
|
/**
|
|
48
76
|
* Resolve harness credentials following the precedence chain. Returns null when
|
|
49
77
|
* apiKey/agentId cannot be resolved. Never throws.
|
|
50
78
|
*/
|
|
51
79
|
export declare function loadConfig(): Promise<VisiqConfig | null>;
|
|
52
|
-
/**
|
|
53
|
-
* Claude Code tool taxonomy — action vs retrieval classification.
|
|
54
|
-
*
|
|
55
|
-
* VisIQ governs two facets per tool call:
|
|
56
|
-
* - ACTION — side-effecting tools (shell, file writes, MCP mutations)
|
|
57
|
-
* - RETRIEVAL — tools that pull external/foreign content INTO the model's
|
|
58
|
-
* context (web fetch/search, file/dir reads, MCP resource reads)
|
|
59
|
-
*
|
|
60
|
-
* The set below is the canonical Claude Code built-in tool list (verified
|
|
61
|
-
* against the running CLI, v2.1.x — the `tool_name` values a hook receives).
|
|
62
|
-
* Retrieval tools are tagged with BOTH facets (`['retrieval','action']`) so an
|
|
63
|
-
* action rule (e.g. "block all web egress") also governs them, mirroring the
|
|
64
|
-
* OpenClaw plugin's dual-facet tagging. Everything else is a pure action.
|
|
65
|
-
*
|
|
66
|
-
* Fail-safe posture (G001): an UNKNOWN tool is treated as an ACTION (governed,
|
|
67
|
-
* never silently ungoverned). MCP tools whose bare name looks like a read are
|
|
68
|
-
* ALSO run through the retrieval facet (fails SAFE toward more governance).
|
|
69
|
-
*/
|
|
70
|
-
/**
|
|
71
|
-
* Reduce a possibly-namespaced MCP tool name to its leaf: `mcp__brave__web_search`
|
|
72
|
-
* → `web_search`. Non-MCP (and non-string, defensively) names are returned as-is.
|
|
73
|
-
*/
|
|
74
|
-
export declare function bareToolName(toolName: string): string;
|
|
75
|
-
/** Does this tool call pull foreign content into the model's context? */
|
|
76
|
-
export declare function isRetrievalTool(toolName: string): boolean;
|
|
77
|
-
/** Governance facets to evaluate for a given tool. */
|
|
78
|
-
export type Operation = "action" | "retrieval" | "delegation";
|
|
79
|
-
/**
|
|
80
|
-
* The `operations[]` to hand `UnifiedRuntime.evaluate`. Retrieval tools carry
|
|
81
|
-
* BOTH facets (an action rule can still govern a fetch); everything else is a
|
|
82
|
-
* pure action.
|
|
83
|
-
*/
|
|
84
|
-
export declare function toolOperations(toolName: string): Operation[];
|
|
85
|
-
/**
|
|
86
|
-
* Extract a human-meaningful query string from a tool's input for retrieval
|
|
87
|
-
* evaluation + telemetry. Joins the first-present query-shaped fields; returns
|
|
88
|
-
* `undefined` when none are present (so the caller omits `query`).
|
|
89
|
-
*/
|
|
90
|
-
export declare function extractQuery(toolInput: unknown): string | undefined;
|
|
91
80
|
/**
|
|
92
81
|
* Server-side per-agent mode. Lives on `allow_agents.mode` and is delivered
|
|
93
82
|
* to the SDK as `agent_mode` in the rules bundle. The SDK branches on this
|
|
@@ -206,6 +195,25 @@ export interface SessionEvalState {
|
|
|
206
195
|
retrieved_data_categories: string[];
|
|
207
196
|
/** Union of resource_metadata.classification tokens over prior retrievals. */
|
|
208
197
|
retrieved_classifications: string[];
|
|
198
|
+
/**
|
|
199
|
+
* Two-axis DATA-FLOW TAINT label (deep-dive 05) — a small CLOSED vocab folded
|
|
200
|
+
* from prior retrieval events, exposed as `input.session.taint` so egress/sink
|
|
201
|
+
* rules can gate on what sensitive/untrusted data actually entered the session:
|
|
202
|
+
* - confidentiality (content-derived): `c:secret` `c:financial` `c:pii`
|
|
203
|
+
* `c:identifier` — emitted by the value-shape FLOOR DETECTORS running over
|
|
204
|
+
* the retrieved CONTENT (not the tool's self-declared metadata), which
|
|
205
|
+
* closes the "a lazy/malicious tool omits data_categories" trust hole.
|
|
206
|
+
* - integrity: `i:untrusted` — the retrieval came from an untrusted origin;
|
|
207
|
+
* `i:injection` — the retrieved CONTENT matched a deterministic
|
|
208
|
+
* hidden-instruction / indirect prompt-injection signature (added
|
|
209
|
+
* 2026-07-21; see `@visiq/redact`'s `detectHiddenInstructions`). Neither
|
|
210
|
+
* integrity token is an LLM/model verdict — both are pattern-derived.
|
|
211
|
+
* Closed 6-token vocab ⇒ the SESSION_SET_CAP truncation can never bind (no
|
|
212
|
+
* silent taint loss). The fold NEVER derives taint itself — it unions a
|
|
213
|
+
* pre-computed label array, so no detector logic lives in the (byte-parity)
|
|
214
|
+
* core; derivation is the SDK/backend's job (deriveRetrievalTaint).
|
|
215
|
+
*/
|
|
216
|
+
taint: string[];
|
|
209
217
|
/** Distinct action_class buckets attempted earlier in the session. */
|
|
210
218
|
action_classes: string[];
|
|
211
219
|
/** Per-action-class attempt counters (prior events only). */
|
|
@@ -275,6 +283,12 @@ export interface AgentEnvironment {
|
|
|
275
283
|
* default `unknown` — never overwriting a management/human-set value.
|
|
276
284
|
*/
|
|
277
285
|
agent_type?: string;
|
|
286
|
+
/** The captured model id the agent runs (e.g. `claude-sonnet-5`). */
|
|
287
|
+
model?: string;
|
|
288
|
+
/** The resolved system prompt, where the framework/CLI hook exposes it. */
|
|
289
|
+
systemPrompt?: string;
|
|
290
|
+
/** The tool schemas (name + description + JSON-schema shape — never values). */
|
|
291
|
+
toolSchemas?: unknown[];
|
|
278
292
|
}
|
|
279
293
|
/**
|
|
280
294
|
* Cognition beats — the Agent Cortex capture payload (thoughts, actions,
|
|
@@ -286,7 +300,9 @@ export interface AgentEnvironment {
|
|
|
286
300
|
* The shape mirrors the framework-agnostic `MindEvent` SSOT the Cortex UI reads
|
|
287
301
|
* (products/project-y/apps/web/src/components/allow/agents/cortex/types.ts).
|
|
288
302
|
*/
|
|
289
|
-
export type CognitionBeatKind = "thought" | "speech" | "action" | "observation" | "intervention" | "spawn" | "phase" | "handoff" | "lifecycle" | "error"
|
|
303
|
+
export type CognitionBeatKind = "thought" | "speech" | "action" | "observation" | "intervention" | "spawn" | "phase" | "handoff" | "lifecycle" | "error"
|
|
304
|
+
/** Long/short-term MEMORY access (read/write/search/delete on an agent store). */
|
|
305
|
+
| "memory";
|
|
290
306
|
export type CognitionVisibility = "shown" | "hidden";
|
|
291
307
|
export type CognitionProvenance = "signed" | "parsed" | "proxy" | "narration";
|
|
292
308
|
/** A recognized sub-agent spawn — the Mode-B delegation edge. */
|
|
@@ -297,6 +313,45 @@ export interface CognitionSpawn {
|
|
|
297
313
|
model?: string;
|
|
298
314
|
prompt?: string;
|
|
299
315
|
}
|
|
316
|
+
/**
|
|
317
|
+
* A recognized MEMORY access — the "memory access" clause of the execution-trace
|
|
318
|
+
* contract. STRUCTURAL ENVELOPE ONLY: like {@link CognitionCost}, this is
|
|
319
|
+
* persisted verbatim (the server schema is default-strip, so nothing is left to
|
|
320
|
+
* floor-redact), which means NO free text may ride through it. The human-readable
|
|
321
|
+
* label — the memory key, the search query — travels in the floor-redacted
|
|
322
|
+
* `tool.argSummary` / `content.text` instead.
|
|
323
|
+
*
|
|
324
|
+
* DISPLAY/TRACE ONLY. A memory beat never changes a decision, never adds an
|
|
325
|
+
* `operations[]` tag, and never touches the evaluation core: the same tool call
|
|
326
|
+
* evaluates byte-identically with or without it.
|
|
327
|
+
*/
|
|
328
|
+
export interface CognitionMemory {
|
|
329
|
+
op: "read" | "write" | "search" | "delete";
|
|
330
|
+
/** The store the operation targets (`mem0`, `letta-archival`, `mcp-memory`, …). */
|
|
331
|
+
store: string;
|
|
332
|
+
scope?: "session" | "agent" | "user" | "org";
|
|
333
|
+
/** Items returned (search/read) or written (write) — count only, never content. */
|
|
334
|
+
itemCount?: number;
|
|
335
|
+
bytes?: number;
|
|
336
|
+
/** Whether a read/search found anything (a miss is as diagnostic as a hit). */
|
|
337
|
+
hit?: boolean;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Per-model-turn token usage attached to the beat that closes the turn.
|
|
341
|
+
* NUMBERS ONLY — `cost` is persisted verbatim (not floor-redacted at rest), so
|
|
342
|
+
* free text must never ride through it; the server schema strips unknown keys.
|
|
343
|
+
* Dollars are never computed harness-side (field-deployed price tables go
|
|
344
|
+
* stale): consumers price at read time from the token buckets + `beat.model`.
|
|
345
|
+
*/
|
|
346
|
+
export interface CognitionCost {
|
|
347
|
+
/** Uncached input tokens (Anthropic `input_tokens` semantics). */
|
|
348
|
+
tokensIn?: number;
|
|
349
|
+
tokensOut?: number;
|
|
350
|
+
cacheRead?: number;
|
|
351
|
+
cacheWrite?: number;
|
|
352
|
+
/** Legal on the wire for forward-compat; no VisIQ producer writes it. */
|
|
353
|
+
usd?: number;
|
|
354
|
+
}
|
|
300
355
|
export interface CognitionBeat {
|
|
301
356
|
/** Stable harness-minted id → server dedup key (idempotent re-sends). */
|
|
302
357
|
clientEventId: string;
|
|
@@ -324,7 +379,8 @@ export interface CognitionBeat {
|
|
|
324
379
|
phase?: Record<string, unknown>;
|
|
325
380
|
handoff?: Record<string, unknown>;
|
|
326
381
|
attribution?: Record<string, unknown>;
|
|
327
|
-
cost?:
|
|
382
|
+
cost?: CognitionCost;
|
|
383
|
+
memory?: CognitionMemory;
|
|
328
384
|
model?: string;
|
|
329
385
|
agentRole?: string;
|
|
330
386
|
framework?: string;
|
|
@@ -346,9 +402,8 @@ declare const bundleCacheOptionsSchema: z.ZodObject<{
|
|
|
346
402
|
cacheDir?: string | undefined;
|
|
347
403
|
}>;
|
|
348
404
|
export type BundleCacheOptions = z.infer<typeof bundleCacheOptionsSchema>;
|
|
349
|
-
|
|
405
|
+
type FailMode$1 = "open" | "closed";
|
|
350
406
|
export type UnifiedOperation = "retrieval" | "action" | "delegation";
|
|
351
|
-
/** One governed agent event, tagged with the facets it participates in. */
|
|
352
407
|
export interface UnifiedEvaluateEvent {
|
|
353
408
|
/** Which facets this event participates in (≥1). */
|
|
354
409
|
operations: UnifiedOperation[];
|
|
@@ -391,6 +446,18 @@ export interface UnifiedEvaluateEvent {
|
|
|
391
446
|
* the decision itself; display/graph data only.
|
|
392
447
|
*/
|
|
393
448
|
context?: Record<string, unknown>;
|
|
449
|
+
/**
|
|
450
|
+
* Surface P: the MCP SERVER this call is attributed to (the tool's origin
|
|
451
|
+
* server). When tagged, it is threaded to `input.normalized.mcp_server` so a
|
|
452
|
+
* synthetic MCP-block deny rule the bundle ships fires IN-PROCESS through the one
|
|
453
|
+
* Rust core before the tool runs. (It is deliberately NOT keyed on `input.context`:
|
|
454
|
+
* the core rebuilds `input.context` as {toolName: toolArgs} on the action leg, so a
|
|
455
|
+
* context-keyed rule would be silently hollow through the real SDK path.)
|
|
456
|
+
* Optional — v1 bites only on TAGGED calls;
|
|
457
|
+
* automatic tool→server attribution across frameworks is the operator-deferred
|
|
458
|
+
* apex. Absent ⇒ the MCP-server plane simply doesn't fire for this event.
|
|
459
|
+
*/
|
|
460
|
+
mcpServer?: string;
|
|
394
461
|
}
|
|
395
462
|
/** The action-facet sub-decision (null leg when the event had no action op). */
|
|
396
463
|
export interface UnifiedActionSubDecision {
|
|
@@ -449,6 +516,17 @@ export interface UnifiedDecision {
|
|
|
449
516
|
agentMode: AgentMode;
|
|
450
517
|
action: UnifiedActionSubDecision;
|
|
451
518
|
retrieval: UnifiedRetrievalSubDecision;
|
|
519
|
+
/**
|
|
520
|
+
* True ONLY for a fail-open PERMIT — a harness-INTERNAL failure (dialect
|
|
521
|
+
* refusal, no bundle, core unavailable) that ran ungoverned under
|
|
522
|
+
* failMode=open. The runtime also echoes this to stderr via `console.error`,
|
|
523
|
+
* but a host that has silenced `console` (e.g. the Claude Code hook harness,
|
|
524
|
+
* which must keep stdout/stderr clean for its JSON protocol) MUST inspect
|
|
525
|
+
* this structured flag to satisfy the "mandatory loud telemetry" contract —
|
|
526
|
+
* console.error alone is not observable there. Absent/false on every other
|
|
527
|
+
* decision (real policy verdicts, agent_mode=off, cold-start deny).
|
|
528
|
+
*/
|
|
529
|
+
failOpen?: boolean;
|
|
452
530
|
}
|
|
453
531
|
declare class UnifiedRuntime {
|
|
454
532
|
private readonly client;
|
|
@@ -538,6 +616,28 @@ declare class UnifiedRuntime {
|
|
|
538
616
|
* apply a subset. Cleared the instant a bundle we CAN speak applies.
|
|
539
617
|
*/
|
|
540
618
|
private dialectRefused;
|
|
619
|
+
/**
|
|
620
|
+
* Error posture (owner decision 2026-07-15). Resolved from VISIQ_FAIL_MODE at
|
|
621
|
+
* construction (default `open`); harnesses override via `setFailMode()` with
|
|
622
|
+
* their own resolved config.
|
|
623
|
+
*/
|
|
624
|
+
private failMode;
|
|
625
|
+
/**
|
|
626
|
+
* X-FAILMODE: the GOVERNED fail-mode the control plane resolved for this agent,
|
|
627
|
+
* hydrated from the bundle's `agent_attributes.fail_mode` on each apply (null =
|
|
628
|
+
* not present → fall back to the local `failMode`). Stored + exposed
|
|
629
|
+
* (getGovernedFailMode) so the harness can adopt it.
|
|
630
|
+
*
|
|
631
|
+
* FOLLOW-ON (deliberately NOT wired into the decision branches yet): making the
|
|
632
|
+
* EFFECTIVE posture prefer the governed value requires a precedence policy —
|
|
633
|
+
* recommended CLOSED-WINS monotonicity (either a local `VISIQ_FAIL_MODE=closed`
|
|
634
|
+
* break-glass OR a governed `closed` forces closed; neither can force open
|
|
635
|
+
* against the other's closed) — plus the harness leaving `failMode` unset when
|
|
636
|
+
* unconfigured. That change touches the conformance-tested fail-open/closed
|
|
637
|
+
* branches and is its own PR; today `failMode` still comes solely from local
|
|
638
|
+
* env/config.
|
|
639
|
+
*/
|
|
640
|
+
private governedFailMode;
|
|
541
641
|
private telemetryBuffer;
|
|
542
642
|
private telemetryTimer;
|
|
543
643
|
private cognitionBuffer;
|
|
@@ -551,6 +651,17 @@ declare class UnifiedRuntime {
|
|
|
551
651
|
/** Content signature of the last reported tool surface — so a repeat visiq()
|
|
552
652
|
* wrap (same tools) doesn't re-POST. Null until the first report. */
|
|
553
653
|
private lastToolSurfaceSig;
|
|
654
|
+
/** Content signature of the last clone capture posted — so a CLI hook that
|
|
655
|
+
* surfaces the same model/prompt/tools on every turn doesn't re-POST
|
|
656
|
+
* ([D-15]). Null until the first capture. */
|
|
657
|
+
private lastCloneCaptureSig;
|
|
658
|
+
/** tool name → description, harvested from the captured tool surface
|
|
659
|
+
* ({@link reportToolSurface}). The mapper learns `action_class` from a tool's
|
|
660
|
+
* NAME + DESCRIPTION (honest-max — no governance-metadata args are
|
|
661
|
+
* spoon-fed), so the runtime rides the description alongside the floor-masked
|
|
662
|
+
* args on the telemetry `raw_event`. Best-effort: absent ⇒ the mapper falls
|
|
663
|
+
* back to name + args only. */
|
|
664
|
+
private toolDescriptions;
|
|
554
665
|
constructor(apiKey?: string, endpoint?: string, agentId?: string, harnessKind?: AgentKind, timeoutMs?: number, sdkVersion?: string, sdkDialect?: number, bundleCache?: BundleCacheOptions);
|
|
555
666
|
/**
|
|
556
667
|
* Evaluate one governed agent event across ALL its tagged operations and
|
|
@@ -563,6 +674,16 @@ declare class UnifiedRuntime {
|
|
|
563
674
|
private modeFor;
|
|
564
675
|
/** Read the session's PRIOR-events state; fresh/absent/expired ⇒ empty. */
|
|
565
676
|
private readSession;
|
|
677
|
+
/** The action_class the SDK-local session fold accumulates (Phase 3). Source-3
|
|
678
|
+
* fed the fold, NOT verb-derivation (retired). Precedence mirrors the Rust
|
|
679
|
+
* decision path:
|
|
680
|
+
* (1) a caller-supplied `event.normalized.action_class` wins (source-1);
|
|
681
|
+
* (2) else the bundle's LEARNED action_class for the event's
|
|
682
|
+
* `action_schema_id` (id lookup on `rawBundle.action_schemas`, NO
|
|
683
|
+
* recompute — same key the decision leg uses), applied only at
|
|
684
|
+
* confidence ≥ threshold (byte-identical 0.7 to the Rust leg).
|
|
685
|
+
* No hit / low-confidence ⇒ undefined (unlearned tool contributes none). */
|
|
686
|
+
private foldActionClass;
|
|
566
687
|
/** Fold one decided event into its session (LRU touch + bounds enforcement). */
|
|
567
688
|
private foldSession;
|
|
568
689
|
/**
|
|
@@ -571,6 +692,34 @@ declare class UnifiedRuntime {
|
|
|
571
692
|
* the would-be `decision` + sub-decisions, with enforced=false.
|
|
572
693
|
*/
|
|
573
694
|
private applyAgentMode;
|
|
695
|
+
/** Override the error posture (harnesses pass their resolved config's failMode). */
|
|
696
|
+
setFailMode(mode: FailMode$1): void;
|
|
697
|
+
getFailMode(): FailMode$1;
|
|
698
|
+
/** The GOVERNED fail-mode last hydrated from the bundle (null if the bundle
|
|
699
|
+
* carried none). See the governedFailMode field for the pending precedence
|
|
700
|
+
* follow-on. */
|
|
701
|
+
getGovernedFailMode(): FailMode$1 | null;
|
|
702
|
+
/**
|
|
703
|
+
* The LOUD fail-open outcome for a harness-internal failure in `open` mode:
|
|
704
|
+
* a non-enforced permit whose reason names the cause, buffered into
|
|
705
|
+
* telemetry (so the platform can audit every ungoverned call) and echoed to
|
|
706
|
+
* stderr via console.error. Also carries a structured `failOpen: true` flag
|
|
707
|
+
* so a host that has silenced `console` (the Claude Code hook harness) can
|
|
708
|
+
* still surface the mandatory loud telemetry. Policy outcomes never route here.
|
|
709
|
+
*/
|
|
710
|
+
private failOpen;
|
|
711
|
+
/**
|
|
712
|
+
* Report a HOOK-LEVEL fail-open — a harness failure that bypassed
|
|
713
|
+
* `evaluate()` entirely (hook wiring threw, config half-resolved, …).
|
|
714
|
+
* Buffers the same `context.fail_open=true` audit row the internal fail-open
|
|
715
|
+
* path produces, so the platform's ungoverned-call audit covers hook-level
|
|
716
|
+
* failures too. Does NOT print (the reporting hook already emitted its own
|
|
717
|
+
* loud stderr line). Fire-and-forget; never throws.
|
|
718
|
+
*/
|
|
719
|
+
reportFailOpen(cause: string, ctx?: {
|
|
720
|
+
toolName?: string;
|
|
721
|
+
sessionId?: string;
|
|
722
|
+
}): void;
|
|
574
723
|
/** The agent_mode=off short-circuit — permit everything, no telemetry. */
|
|
575
724
|
private offDecision;
|
|
576
725
|
/** Build a fail-closed deny-all decision for cold start / no-config paths. */
|
|
@@ -625,6 +774,13 @@ declare class UnifiedRuntime {
|
|
|
625
774
|
/** The resolved API key, for callers driving the HITL wait loop. */
|
|
626
775
|
getApiKey(): string | undefined;
|
|
627
776
|
getBundleVersion(): string | null;
|
|
777
|
+
/**
|
|
778
|
+
* Has a rule bundle actually been applied? (getBundleVersion() can be null
|
|
779
|
+
* even when loaded.) Callers use this to tell "governed, rules present" from
|
|
780
|
+
* "cold — evaluate() would take the cold-start posture", e.g. to apply a
|
|
781
|
+
* failMode decision instead of surfacing a VisIQ outage as a spurious deny.
|
|
782
|
+
*/
|
|
783
|
+
isBundleLoaded(): boolean;
|
|
628
784
|
getAgentMode(): AgentMode;
|
|
629
785
|
/** The bundle-shipped server-authoritative agent attributes (null until shipped). */
|
|
630
786
|
getAgentAttributes(): AgentEvalAttributes | null;
|
|
@@ -637,8 +793,17 @@ declare class UnifiedRuntime {
|
|
|
637
793
|
* `agentType` is the harness-detected framework slug (F5) — merged into the
|
|
638
794
|
* registration handshake so the backend can classify a self-provisioned agent
|
|
639
795
|
* (omitted when unknown, so it never overwrites a good value).
|
|
796
|
+
*
|
|
797
|
+
* `capture` is the OPTIONAL clone capture ([D-15]) — the model / resolved system
|
|
798
|
+
* prompt / tool schemas the harness could introspect at wrap time. Each field is
|
|
799
|
+
* forwarded only when present, so a harness that can introspect none behaves
|
|
800
|
+
* exactly as before and any missing field keeps the agent honestly non-clonable.
|
|
640
801
|
*/
|
|
641
|
-
registerHostEnvironment(agentType?: string
|
|
802
|
+
registerHostEnvironment(agentType?: string, capture?: {
|
|
803
|
+
model?: string;
|
|
804
|
+
systemPrompt?: string;
|
|
805
|
+
toolSchemas?: unknown[];
|
|
806
|
+
}): void;
|
|
642
807
|
/**
|
|
643
808
|
* Report the agent's captured tool surface (fire-and-forget). Drives backend
|
|
644
809
|
* blast-radius inference. Re-reports ONLY when the surface changes (content
|
|
@@ -647,6 +812,43 @@ declare class UnifiedRuntime {
|
|
|
647
812
|
* on an empty set. Never throws (best-effort, must not affect the host).
|
|
648
813
|
*/
|
|
649
814
|
reportToolSurface(tools: CapturedToolSpec[]): void;
|
|
815
|
+
/**
|
|
816
|
+
* Post an OPTIONAL clone capture ([D-15]) surfaced by a CLI hook AFTER the
|
|
817
|
+
* initial registration — the OpenClaw `llm-input` hook sees the resolved model
|
|
818
|
+
* + system prompt + tool schemas only on the first model call, well after
|
|
819
|
+
* registerHostEnvironment already fired. Unlike registerHostEnvironment (once
|
|
820
|
+
* per runtime), this fires when NEW capture arrives.
|
|
821
|
+
*
|
|
822
|
+
* It re-sends the SAME host environment alongside the capture (so the register
|
|
823
|
+
* route's env write refreshes the columns rather than nulling them) and DEDUPES
|
|
824
|
+
* by content signature so a hook that surfaces the same fields on every turn
|
|
825
|
+
* posts exactly once. Fire-and-forget: no-ops without a client / agent id or an
|
|
826
|
+
* empty capture; never throws (best-effort, must not affect the host).
|
|
827
|
+
*/
|
|
828
|
+
captureCloneMetadata(capture: {
|
|
829
|
+
model?: string;
|
|
830
|
+
systemPrompt?: string;
|
|
831
|
+
toolSchemas?: unknown[];
|
|
832
|
+
agentType?: string;
|
|
833
|
+
}): void;
|
|
834
|
+
/**
|
|
835
|
+
* Build the ONE canonical action-schema event for a decision and compute its
|
|
836
|
+
* identity (F1). The SDK is the single producer of `action_schema_id`: it
|
|
837
|
+
* hashes the canonical event (via `computeActionSchemaId`) so the backend
|
|
838
|
+
* (`allow_telemetry`/`/evaluate`) and the in-core apply all key off an
|
|
839
|
+
* IDENTICAL id — parity is definitional, not recomputed from a divergent
|
|
840
|
+
* server-side event shape.
|
|
841
|
+
*
|
|
842
|
+
* The id is computed over the REAL args (the discriminator + key-path
|
|
843
|
+
* fingerprint must reflect what the agent actually sent); the wire copy masks
|
|
844
|
+
* `tool_args` with the value-shape floor {@link redactByValueShape} AFTER
|
|
845
|
+
* hashing, so PII-shaped leaves never leave the process while business values
|
|
846
|
+
* (an `amount`, a record id) survive as the mapper's value-learning signal
|
|
847
|
+
* and the key paths are preserved (masking is key-path-preserving ⇒ the id is
|
|
848
|
+
* stable either way, but hashing-before-masking removes even the theoretical
|
|
849
|
+
* discriminator-on-a-masked-value hazard).
|
|
850
|
+
*/
|
|
851
|
+
private buildActionSchemaEvent;
|
|
650
852
|
private bufferTelemetry;
|
|
651
853
|
/** Buffered-but-unsent decision count (for the exit-drain warning). */
|
|
652
854
|
pendingTelemetryCount(): number;
|
|
@@ -676,6 +878,60 @@ declare class UnifiedRuntime {
|
|
|
676
878
|
shutdown(): Promise<void>;
|
|
677
879
|
dispose(): void;
|
|
678
880
|
}
|
|
881
|
+
/** Where fail-open events are appended (one JSON line per event). */
|
|
882
|
+
export declare function failOpenLogPath(): string;
|
|
883
|
+
export interface FailOpenEvent {
|
|
884
|
+
/** Which guard failed open (e.g. `unconfigured`, `no-bundle`, `pre-eval-error`). */
|
|
885
|
+
stage: string;
|
|
886
|
+
detail: string;
|
|
887
|
+
toolName?: string;
|
|
888
|
+
sessionId?: string;
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Record a fail-open event: stderr always; the on-disk log for runtime
|
|
892
|
+
* failures (`logToDisk=false` for the steady-state `unconfigured` case, which
|
|
893
|
+
* would otherwise grow the log unboundedly on a machine that never configures).
|
|
894
|
+
*/
|
|
895
|
+
export declare function reportFailOpen(event: FailOpenEvent, logToDisk?: boolean): Promise<void>;
|
|
896
|
+
/**
|
|
897
|
+
* Claude Code tool taxonomy — action vs retrieval classification.
|
|
898
|
+
*
|
|
899
|
+
* VisIQ governs two facets per tool call:
|
|
900
|
+
* - ACTION — side-effecting tools (shell, file writes, MCP mutations)
|
|
901
|
+
* - RETRIEVAL — tools that pull external/foreign content INTO the model's
|
|
902
|
+
* context (web fetch/search, file/dir reads, MCP resource reads)
|
|
903
|
+
*
|
|
904
|
+
* The set below is the canonical Claude Code built-in tool list (verified
|
|
905
|
+
* against the running CLI, v2.1.x — the `tool_name` values a hook receives).
|
|
906
|
+
* Retrieval tools are tagged with BOTH facets (`['retrieval','action']`) so an
|
|
907
|
+
* action rule (e.g. "block all web egress") also governs them, mirroring the
|
|
908
|
+
* OpenClaw plugin's dual-facet tagging. Everything else is a pure action.
|
|
909
|
+
*
|
|
910
|
+
* Fail-safe posture (G001): an UNKNOWN tool is treated as an ACTION (governed,
|
|
911
|
+
* never silently ungoverned). MCP tools whose bare name looks like a read are
|
|
912
|
+
* ALSO run through the retrieval facet (fails SAFE toward more governance).
|
|
913
|
+
*/
|
|
914
|
+
/**
|
|
915
|
+
* Reduce a possibly-namespaced MCP tool name to its leaf: `mcp__brave__web_search`
|
|
916
|
+
* → `web_search`. Non-MCP (and non-string, defensively) names are returned as-is.
|
|
917
|
+
*/
|
|
918
|
+
export declare function bareToolName(toolName: string): string;
|
|
919
|
+
/** Does this tool call pull foreign content into the model's context? */
|
|
920
|
+
export declare function isRetrievalTool(toolName: string): boolean;
|
|
921
|
+
/** Governance facets to evaluate for a given tool. */
|
|
922
|
+
export type Operation = "action" | "retrieval" | "delegation";
|
|
923
|
+
/**
|
|
924
|
+
* The `operations[]` to hand `UnifiedRuntime.evaluate`. Retrieval tools carry
|
|
925
|
+
* BOTH facets (an action rule can still govern a fetch); everything else is a
|
|
926
|
+
* pure action.
|
|
927
|
+
*/
|
|
928
|
+
export declare function toolOperations(toolName: string): Operation[];
|
|
929
|
+
/**
|
|
930
|
+
* Extract a human-meaningful query string from a tool's input for retrieval
|
|
931
|
+
* evaluation + telemetry. Joins the first-present query-shaped fields; returns
|
|
932
|
+
* `undefined` when none are present (so the caller omits `query`).
|
|
933
|
+
*/
|
|
934
|
+
export declare function extractQuery(toolInput: unknown): string | undefined;
|
|
679
935
|
/**
|
|
680
936
|
* Claude Code hook I/O contract — types + pure builders.
|
|
681
937
|
*
|
|
@@ -858,11 +1114,12 @@ export declare function buildEvaluateEvent(opts: {
|
|
|
858
1114
|
* 2. stale/absent → raw fetch → applyBundle + persist;
|
|
859
1115
|
* 3. fetch failed but a STALE cache exists → applyBundle(stale) (a stale
|
|
860
1116
|
* bundle is strictly better than a cold-start deny flake);
|
|
861
|
-
* 4. nothing on disk + fetch failed → awaitBundleReady (last resort
|
|
862
|
-
*
|
|
1117
|
+
* 4. nothing on disk + fetch failed → awaitBundleReady (last resort).
|
|
1118
|
+
* Returns true when a usable bundle was applied (or became ready), false when
|
|
1119
|
+
* the whole ladder failed — the caller maps false to its failMode posture.
|
|
863
1120
|
* Best-effort; never throws.
|
|
864
1121
|
*/
|
|
865
|
-
export declare function warmFromCache(runtime: UnifiedRuntime, config: VisiqConfig, ttlMs?: number): Promise<
|
|
1122
|
+
export declare function warmFromCache(runtime: UnifiedRuntime, config: VisiqConfig, ttlMs?: number): Promise<boolean>;
|
|
866
1123
|
/** Drain telemetry + registration then release timers. Bounded; never throws. */
|
|
867
1124
|
export declare function finishRuntime(runtime: UnifiedRuntime): Promise<void>;
|
|
868
1125
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as x,b as C,c as u,d as H,e as _,f as c,g}from"./chunk-6DMSMBWM.js";import{a as l,b as p,c as m,d,e as f,f as E,g as K,h as V,i as w,j as z,k as G,l as Q,m as T,n as h,o as O,p as S,q as A,r as v,s as P,t as U,u as k,v as B,w as b,x as q}from"./chunk-CBUHAEGD.js";import{a as e,b as o,c as t,d as r,e as i,f as a,g as n,h as s,i as D,j as F,k as R,l as L,m as y,n as I,o as M,p as N}from"./chunk-XEWB3NIN.js";export{D as DEFAULT_BUNDLE_TTL_MS,e as DEFAULT_FAIL_MODE,A as HARNESS_KIND,x as HOOK_COMMAND,C as HOOK_TIMEOUT_SECONDS,u as RETRIEVAL_MATCHER,T as WITHHELD_SENTINEL,m as bareToolName,h as blankContent,P as buildEvaluateEvent,G as buildPostRedact,V as buildPreAllow,z as buildPreAsk,w as buildPreDeny,r as configFilePath,v as createRuntime,i as envConfig,E as extractQuery,l as failOpenLogPath,I as fetchBundle,k as finishRuntime,K as formatReason,b as handlePostToolUse,B as handlePreToolUse,q as handleSessionStart,g as hooksInstalled,_ as installHooks,R as isFresh,d as isRetrievalTool,M as isSessionRegistered,H as isVisiqGroup,s as loadConfig,n as loadHarnessState,S as mapPostRedaction,O as mapPreDecision,N as markSessionRegistered,a as mergeConfig,o as normalizeFailMode,Q as parseHookInput,L as readBundleCache,p as reportFailOpen,F as sanitizeId,f as toolOperations,c as uninstallHooks,t as visiqHomeDir,U as warmFromCache,y as writeBundleCache};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visiq/claude-code-harness",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "VisIQ governance harness for the Claude Code CLI — action monitor/block + retrieval monitor/block/redact via Claude Code hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
package/dist/chunk-3GWLCI47.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{readFile as h}from"node:fs/promises";import{homedir as g}from"node:os";import{join as u,isAbsolute as _,resolve as w}from"node:path";var P="@visiq/claude-code-harness";function s(){let n=process.env.VISIQ_HOME;return n&&n.trim().length>0?n:u(g(),".visiq","claude-code")}function C(){return u(s(),"config.json")}function S(n){return n==="~"||n.startsWith("~/")?u(g(),n.slice(1).replace(/^\//,"")):n}async function k(n){try{let e=_(n)?n:w(n),t=await h(e,"utf-8");return JSON.parse(t)}catch{return null}}function c(n,...e){for(let t of e){let r=n[t];if(typeof r=="string"&&r.length>0)return r}}function f(n){if(!n||typeof n!="object")return{};let e=n,t={},r=c(e,"apiKey","api_key"),i=c(e,"agentId","agent_id"),o=c(e,"baseUrl","base_url");return r&&(t.apiKey=r),i&&(t.agentId=i),o&&(t.baseUrl=o),t}async function l(n){if(!n)return{};let e=await k(S(n));if(!e||typeof e!="object")return{};let t=e,r=t.plugins?.entries,i=r&&typeof r=="object"?r[P]:void 0;return i&&typeof i=="object"&&i.config?f(i.config):f(t)}function x(n=process.env){let e={};return n.VISIQ_API_KEY&&(e.apiKey=n.VISIQ_API_KEY),n.VISIQ_AGENT_ID&&(e.agentId=n.VISIQ_AGENT_ID),n.VISIQ_BASE_URL?e.baseUrl=n.VISIQ_BASE_URL:n.VISIQ_ENDPOINT&&(e.baseUrl=n.VISIQ_ENDPOINT),e}function U(n,e,t){let r={...n,...e,...t};if(!r.apiKey||!r.agentId)return null;let i={apiKey:r.apiKey,agentId:r.agentId};return r.baseUrl&&(i.baseUrl=r.baseUrl),i}async function F(){let n=x(),e=await l(process.env.VISIQ_CONFIG_PATH),t=await l(C());return U(t,e,n)}import{mkdir as d,readFile as A,writeFile as p,stat as E}from"node:fs/promises";import{createHash as N}from"node:crypto";import{join as a}from"node:path";var $=3e4,V=4e3;function v(n){return n.replace(/[^a-zA-Z0-9._-]/g,"_").slice(0,200)||"default"}function m(n){let e=N("sha1").update(n).digest("hex").slice(0,10);return`${v(n)}-${e}`}function L(n,e,t){return t-n.fetchedAt<e}function I(n){return a(s(),"bundles",`${m(n)}.json`)}function y(n){return a(s(),"sessions",`${m(n)}.registered`)}async function H(n){try{let e=await A(I(n),"utf-8"),t=JSON.parse(e);return t&&typeof t.fetchedAt=="number"&&"body"in t?t:null}catch{return null}}async function G(n,e,t){try{let r=I(n);await d(a(s(),"bundles"),{recursive:!0});let i={fetchedAt:Date.now(),version:t,body:e};await p(r,JSON.stringify(i),{mode:384})}catch{}}async function J(n,e,t){try{let i=`${n.replace(/\/+$/,"")}/rules/bundle?agent_id=${encodeURIComponent(t)}`,o=await fetch(i,{method:"GET",headers:{Authorization:`Bearer ${e}`,Accept:"application/json"},signal:AbortSignal.timeout(V)});if(!o.ok)return null;let b=o.headers.get("etag");return{body:await o.json(),version:b}}catch{return null}}async function M(n){try{return await E(y(n)),!0}catch{return!1}}async function z(n){try{await d(a(s(),"sessions"),{recursive:!0}),await p(y(n),String(Date.now()),{mode:384})}catch{}}export{s as a,C as b,x as c,U as d,F as e,$ as f,v as g,L as h,H as i,G as j,J as k,M as l,z as m};
|
package/dist/chunk-42FZPLOF.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{f as W,h as H,i as V,j as G,k as K,l as Z,m as I}from"./chunk-3GWLCI47.js";var qe=new Set(["WebFetch","WebSearch","Read","Grep","Glob","LSP","NotebookRead","ListMcpResourcesTool","ReadMcpResourceTool"]),ze=/(^|_)(search|fetch|read|list|get|query|retrieve|lookup|find|describe|download|export|dump)(_|$)/i;function We(e){if(typeof e!="string"||!e.startsWith("mcp__"))return typeof e=="string"?e:"";let t=e.lastIndexOf("__");return t>=0?e.slice(t+2):e}function L(e){return typeof e!="string"?!1:qe.has(e)?!0:e.startsWith("mcp__")?ze.test(We(e)):!1}function Y(e){return L(e)?["retrieval","action"]:["action"]}var He=["query","q","url","prompt","pattern","file_path","path"];function S(e){if(!e||typeof e!="object")return;let t=e,n=[];for(let r of He){let i=t[r];typeof i=="string"&&i.length>0&&n.push(i)}return n.length>0?n.join(" "):void 0}function h(e,t){let n=t?`VisIQ ${t}`:"VisIQ",r=e&&e.trim().length>0?e.trim():"blocked by policy";return`[${n}] ${r}`}function J(e){let t={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}};return e&&(t.hookSpecificOutput.updatedInput=e),t}function E(e){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:e}}}function Q(e){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"ask",permissionDecisionReason:e}}}function _(e,t){let n={hookSpecificOutput:{hookEventName:"PostToolUse",updatedToolOutput:e}};return t&&(n.hookSpecificOutput.additionalContext=t),n}function hn(e){try{let t=JSON.parse(e);return t&&typeof t=="object"&&typeof t.hook_event_name=="string"?t:null}catch{return null}}var Ve=[{name:"private_key",re:/-----BEGIN (?:[A-Z]+ )?PRIVATE KEY-----[\s\S]*?-----END (?:[A-Z]+ )?PRIVATE KEY-----/g},{name:"jwt",re:/\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{6,}\b/g},{name:"aws_access_key",re:/\b(?:AKIA|ASIA|AGPA|AIDA|AROA|ANPA|ANVA|AIPA)[0-9A-Z]{16}\b/g},{name:"github_token",re:/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36}\b|\bgithub_pat_[A-Za-z0-9_]{22,}\b/g},{name:"slack_token",re:/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g},{name:"stripe_secret",re:/\b(?:sk|rk)_live_[A-Za-z0-9]{16,}\b/g},{name:"google_api_key",re:/\bAIza[0-9A-Za-z_-]{35}\b/g},{name:"llm_api_key",re:/\bsk-(?:ant-|proj-)?[A-Za-z0-9_-]{20,}\b/g},{name:"bearer_token",re:/\bBearer\s+[A-Za-z0-9._~+/=-]{20,}/g},{name:"connection_string",re:/\b(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis|amqps?):\/\/[^\s/@:]+:[^\s/@:]+@[^\s'"]+/g},{name:"us_ein",re:/\b\d{2}-\d{7}\b/g},{name:"ssn",re:/\b\d{3}[- ]\d{2}[- ]\d{4}\b/g},{name:"email",re:/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g},{name:"swift_bic",re:/\b[A-Z]{6}[A-Z0-9]{2}(?:[A-Z0-9]{3})?\b/g},{name:"us_phone",re:/\b(?:\+?1[ .-]?)?\(?\d{3}\)?[ .-]?\d{3}[ .-]?\d{4}\b/g},{name:"ipv4",re:/\b(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)\b/g},{name:"mac_address",re:/\b(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}\b/g}];var f=Object.fromEntries(Ve.map(e=>[e.name,e.re.source])),Ge=["private_key","jwt","aws_access_key","github_token","slack_token","stripe_secret","google_api_key","llm_api_key","bearer_token","connection_string","pan","iban","aba_routing","us_ein","swift_bic","ssn","email","us_phone","ipv4","mac_address"],Ke={private_key:{id:"private_key",label:"Private keys (PEM)",description:"PEM-encoded private keys (RSA / EC / EdDSA / OpenSSH).",category:"secret",example:`-----BEGIN PRIVATE KEY-----
|
|
2
|
-
MIIEv\u2026
|
|
3
|
-
-----END PRIVATE KEY-----`,template:{pattern:f.private_key,mode:"full"},defaultEnabled:!0},jwt:{id:"jwt",label:"JWT / bearer tokens",description:"JSON Web Tokens (base64url header.payload.signature).",category:"secret",example:"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIn0.dBjftJeZ4CVP",template:{pattern:f.jwt,mode:"full"},defaultEnabled:!0},aws_access_key:{id:"aws_access_key",label:"AWS access key IDs",description:"AWS access / identity key ids (AKIA / ASIA / AROA \u2026).",category:"secret",example:"AKIAIOSFODNN7EXAMPLE",template:{pattern:f.aws_access_key,mode:"full"},defaultEnabled:!0},github_token:{id:"github_token",label:"GitHub tokens",description:"GitHub personal / OAuth tokens (classic ghp_\u2026 + fine-grained).",category:"secret",example:"ghp_0123456789abcdef0123456789abcdef0123",template:{pattern:f.github_token,mode:"full"},defaultEnabled:!0},slack_token:{id:"slack_token",label:"Slack tokens",description:"Slack bot / user / app tokens (xoxb- / xoxp- \u2026).",category:"secret",example:"xoxb-1234567890-abcdefghijkl",template:{pattern:f.slack_token,mode:"full"},defaultEnabled:!0},stripe_secret:{id:"stripe_secret",label:"Stripe secret keys",description:"Stripe live secret / restricted keys (sk_live_ / rk_live_).",category:"secret",example:"sk_live_0123456789abcdefABCDEF",template:{pattern:f.stripe_secret,mode:"full"},defaultEnabled:!0},google_api_key:{id:"google_api_key",label:"Google API keys",description:"Google API keys (AIza\u2026).",category:"secret",example:"AIzaSyA1234567890abcdefghijklmnopqrstuv",template:{pattern:f.google_api_key,mode:"full"},defaultEnabled:!0},llm_api_key:{id:"llm_api_key",label:"LLM provider API keys",description:"OpenAI / Anthropic secret keys (sk-\u2026, sk-proj-\u2026, sk-ant-\u2026).",category:"secret",example:"sk-ant-api03-AbCdEf0123456789AbCdEf01",template:{pattern:f.llm_api_key,mode:"full"},defaultEnabled:!0},bearer_token:{id:"bearer_token",label:"Authorization bearer tokens",description:"Credentials following an HTTP `Authorization: Bearer \u2026` header.",category:"secret",example:"Bearer abcdef0123456789abcdef0123456789",template:{pattern:f.bearer_token,mode:"full"},defaultEnabled:!0},connection_string:{id:"connection_string",label:"Connection strings (with password)",description:"Database / broker DSNs carrying an inline password (scheme://user:pass@host).",category:"secret",example:"postgres://app:s3cr3t@db.internal:5432/main",template:{pattern:f.connection_string,mode:"full"},defaultEnabled:!0},pan:{id:"pan",label:"Payment card numbers (PAN)",description:"Luhn-valid 13\u201319 digit primary account numbers (PCI-DSS).",category:"financial",example:"4242 4242 4242 4242",template:{pattern:"\\b\\d{13,19}\\b",mode:"partial",keepLast:4},defaultEnabled:!0},iban:{id:"iban",label:"IBAN bank account numbers",description:"ISO 13616 IBANs (mod-97 validated); keeps the last 4 visible.",category:"financial",example:"DE89 3704 0044 0532 0130 00",template:{pattern:"\\b[A-Z]{2}\\d{2}(?:[ ]?[A-Z0-9]){10,30}\\b",mode:"partial",keepLast:4},defaultEnabled:!0},aba_routing:{id:"aba_routing",label:"ABA routing numbers",description:"US bank routing-transit numbers (9-digit, checksum-validated). DEFAULT-OFF (9-digit false-positive surface).",category:"financial",example:"021000021",template:{pattern:"\\b\\d{9}\\b",mode:"full"},defaultEnabled:!1},us_ein:{id:"us_ein",label:"US Employer ID (EIN)",description:"US tax Employer Identification Numbers (XX-XXXXXXX).",category:"financial",example:"12-3456789",template:{pattern:f.us_ein,mode:"full"},defaultEnabled:!0},swift_bic:{id:"swift_bic",label:"SWIFT / BIC codes",description:"Bank SWIFT/BIC codes (8 or 11 chars). DEFAULT-OFF (matches uppercase tokens).",category:"financial",example:"DEUTDEFF500",template:{pattern:f.swift_bic,mode:"full"},defaultEnabled:!1},ssn:{id:"ssn",label:"US Social Security numbers",description:"Dashed / spaced US SSNs (e.g. 123-45-6789).",category:"pii",example:"123-45-6789",template:{pattern:f.ssn,mode:"partial",keepLast:4},defaultEnabled:!0},email:{id:"email",label:"Email addresses",description:"Email addresses (the mailbox is masked, the domain kept).",category:"pii",example:"alice@acme.com",template:{pattern:f.email,mode:"email"},defaultEnabled:!0},us_phone:{id:"us_phone",label:"US phone numbers",description:"US phone numbers in common formats. DEFAULT-OFF (10-digit false-positive surface).",category:"pii",example:"(415) 555-0132",template:{pattern:f.us_phone,mode:"partial",keepLast:4},defaultEnabled:!1},ipv4:{id:"ipv4",label:"IPv4 addresses",description:"Dotted-quad IPv4 addresses. DEFAULT-OFF (common + usually benign).",category:"identifier",example:"203.0.113.42",template:{pattern:f.ipv4,mode:"full"},defaultEnabled:!1},mac_address:{id:"mac_address",label:"MAC addresses",description:"Hardware MAC addresses. DEFAULT-OFF.",category:"identifier",example:"3c:22:fb:1a:2b:3c",template:{pattern:f.mac_address,mode:"full"},defaultEnabled:!1}},yn=new Set(Ge.filter(e=>!Ke[e].defaultEnabled));var P="[REDACTED]",y="\u2022",C=e=>/[A-Za-z0-9]/.test(e);function X(e,t,n,r){let i=Array.from(e),a=i.length,o=Math.max(0,Math.floor(t)||0),c=Math.max(0,Math.floor(n)||0),l=r.length>0?r:y,d=o+c>=a;return i.map((p,g)=>!d&&(g<o||g>=a-c)?p:C(p)?l:p).join("")}function Ze(e,t){let n=e.indexOf("@");if(n<=0||n>=e.length-1)return X(e,0,0,t);let r=e.slice(0,n),i=e.slice(n),a=t.length>0?t:y;return(r.length<=1?a:r[0]+Array.from(r.slice(1)).map(o=>C(o)?a:o).join(""))+i}function Ye(e,t,n){let r=n.length>0?n:y,i=new Array(e.length).fill(!1);if(typeof t=="string"&&t.length>0)try{let d=new RegExp(t,"g"),p;for(;(p=d.exec(e))!==null;){if(p[0].length===0){d.lastIndex++;continue}for(let g=p.index;g<p.index+p[0].length;g++)i[g]=!0}}catch{}let a=!1,o=!0;for(let d=0;d<e.length;d++)if(C(e[d])&&(a=!0,!i[d])){o=!1;break}let c=a&&o,l="";for(let d=0;d<e.length;d++){let p=e[d];!c&&i[d]||!C(p)?l+=p:l+=r}return l}function ee(e,t){let n=t.mode??"full";return n==="partial"?X(e,t.keepFirst??0,t.keepLast??0,t.maskChar??y):n==="email"?Ze(e,t.maskChar??y):n==="custom"?Ye(e,t.keepPattern,t.maskChar??y):t.replacement??P}function Je(e,t){return typeof e=="string"?ee(e,t):t.replacement??P}function te(e){let t=[],n=e.replacement??P;for(let r of e.patterns??[])typeof r!="string"||r.length===0||t.push({source:r,replacer:()=>n});for(let r of e.directives??[]){let{pattern:i}=r;typeof i!="string"||i.length===0||t.push({source:i,replacer:a=>ee(a,r)})}return t}function ne(e,t){let n=e;for(let{source:r,replacer:i}of t){let a;try{a=new RegExp(r,"g")}catch(o){let c=o instanceof Error?o.message:String(o);throw new Error(`[visiq-redact] Invalid redaction pattern "${r}": ${c}`)}n=n.replace(a,o=>i(o))}return n}function D(e,t){return e==null?e:typeof e=="string"?Qe(e,t):typeof e=="object"?Xe(e,t):e}function Qe(e,t){if(typeof e!="string")return e;let n=te(t);return n.length===0?e:ne(e,n)}function Xe(e,t){let n=new Map;for(let c of t.fields??[])typeof c=="string"&&c.length>0&&n.set(c,{field:c,mode:"full",replacement:t.replacement});for(let c of t.directives??[])typeof c.field=="string"&&c.field.length>0&&n.set(c.field,c);let r=te(t),i=n.size>0,a=r.length>0,o=c=>{if(c==null)return c;if(Array.isArray(c))return c.map(l=>o(l));if(typeof c=="object"){let l=c,d=Object.create(Object.getPrototypeOf(l));for(let p of Object.keys(l)){let g=i?n.get(p):void 0;if(g){d[p]=Je(l[p],g);continue}d[p]=o(l[p])}return d}return typeof c=="string"&&a?ne(c,r):c};return o(e)}import{z as s}from"zod";import*as m from"node:os";var re="X-VisIQ-SDK",ie="X-VisIQ-Dialect",ae="unknown";function F(e,t=1){return{[re]:e&&e.length>0?e:ae,[ie]:String(t)}}var oe="interceptor_source",et=s.enum(["enforce","audit","off"]),tt=s.enum(["closed","open"]),se=s.enum(["enforce","monitor","off"]),nt=s.object({apiKey:s.string().min(1,"apiKey is required"),agentId:s.string().min(1,"agentId is required"),endpoint:s.string().url().optional(),mode:et.optional(),timeoutMs:s.number().int().positive().optional(),hitlTimeoutMs:s.number().int().positive().optional(),failBehavior:tt.optional()}),wn=s.object({agent_id:s.string().min(1),target_app:s.string().min(1),action:s.string().min(1),context:s.record(s.unknown()).optional(),session_id:s.string().min(1).max(255).optional(),telemetry:s.record(s.unknown()).optional()}),rt=s.object({field:s.string().optional(),pattern:s.string().optional(),replacement:s.string().optional(),mode:s.enum(["full","partial","email"]).optional(),keepFirst:s.number().optional(),keepLast:s.number().optional(),maskChar:s.string().optional()}),it=s.object({decision_id:s.string().min(1),decision:s.enum(["permit","deny","approval_required","mask"]),reason:s.string().optional(),rule_code:s.string().nullable().optional(),enforced:s.boolean().optional(),agent_mode:se.optional(),arg_redaction_rules:s.array(rt).optional(),plane:s.string().nullable().optional(),operation:s.string().nullable().optional(),is_retrieval:s.boolean().optional(),metadata:s.record(s.unknown()).optional()}),at=s.object({field:s.string().min(1),operator:s.enum(["equals","in","not_equals","not_in","glob","gt","lt","gte","lte","contains","not_contains"]),value:s.union([s.string(),s.number(),s.array(s.string())])}),ot=s.object({id:s.string().min(1),rule_code:s.string().default(""),name:s.string().min(1),description:s.string().nullable().default(null),effect:s.enum(["allow","deny","hitl","mask"]),resource_type:s.string().min(1),rego_source:s.string().default(""),target_app:s.string().nullable().default(null),action_pattern:s.string().nullable().default(null),conditions:s.array(at).default([]),priority:s.number().int().default(0)}),st=s.object({version:s.string().min(1),agent_mode:se.optional(),rules:s.array(ot),no_coverage:s.object({no_coverage_defaults:s.record(s.string()),autopilot_enabled:s.boolean(),enduser_hitl_enabled:s.boolean(),hitl_timeout_seconds:s.number()}).optional()}),lt=2e3,le=class{config;originalFetch;constructor(e,t){this.config=e,this.originalFetch=t}versionHeaders(){return F(this.config.sdkVersion,this.config.sdkDialect)}async evaluate(e){let t=new AbortController,n=setTimeout(()=>t.abort(),this.config.timeoutMs),r;try{r=await this.originalFetch(`${this.config.endpoint}/allow/evaluate`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify(e),signal:t.signal})}finally{clearTimeout(n)}if(!r.ok)throw new Error(`ALLOW evaluate request failed: HTTP ${r.status} ${r.statusText}`);let i=await r.json();return it.parse(i)}async fetchBundle(){let e=this.config.agentId?`?agent_id=${encodeURIComponent(this.config.agentId)}`:"",t=`${this.config.endpoint}/allow/rules/bundle${e}`,n=new AbortController,r=setTimeout(()=>n.abort(),this.config.timeoutMs),i;try{i=await this.originalFetch(t,{method:"GET",headers:{Authorization:`Bearer ${this.config.apiKey}`,Accept:"application/json",...this.versionHeaders()},signal:n.signal})}finally{clearTimeout(r)}if(!i.ok)throw new Error(`ALLOW rules/bundle fetch failed: HTTP ${i.status} ${i.statusText}`);let a=await i.json();return st.parse(a)}async sendTelemetry(e){if(e.length===0)return;let t=`${this.config.endpoint}/allow/telemetry`,n=await this.originalFetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify({decisions:e})});if(!n.ok)throw new Error(`ALLOW telemetry delivery failed: HTTP ${n.status} ${n.statusText}`)}async sendCognition(e,t){if(t.length===0)return;let n=`${this.config.endpoint}/allow/cognition`,r=await this.originalFetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify({...e?{session:e}:{},beats:t})});if(!r.ok)throw new Error(`ALLOW cognition delivery failed: HTTP ${r.status} ${r.statusText}`)}async reportExecutionResult(e,t,n){let r=`${this.config.endpoint}/allow/execution-events`;try{let i=await this.originalFetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify({decision_id:e,result:t,details:n})});i.ok||console.warn(`[ALLOW] Execution result report failed: HTTP ${i.status}`)}catch(i){console.warn("[ALLOW] Execution result report failed:",i)}}async registerEnvironment(e){if(!this.config.agentId)return;let t=`${this.config.endpoint}/allow/agents/register`;try{let n=await this.originalFetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify({agent_id:this.config.agentId,os:e.os,hostname:e.hostname,ip:e.ip,username:e.username,...this.config.harnessKind?{kind:this.config.harnessKind}:{},...e.agent_type?{agent_type:e.agent_type}:{}})});n.ok||console.warn(`[ALLOW] Agent registration failed: HTTP ${n.status} ${n.statusText}`)}catch(n){console.warn("[ALLOW] Agent registration failed:",n)}}async reportToolSurface(e){if(!this.config.agentId||e.length===0)return;let t=`${this.config.endpoint}/allow/agents/tools`;try{let n=await this.originalFetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},body:JSON.stringify({agent_id:this.config.agentId,tools:e})});n.ok||console.warn(`[ALLOW] Tool-surface report failed: HTTP ${n.status} ${n.statusText}`)}catch(n){console.warn("[ALLOW] Tool-surface report failed:",n)}}async waitForApproval(e){if(!e)throw new Error("waitForApproval: decisionId must be a non-empty string");let t=Date.now()+this.config.hitlTimeoutMs;for(;Date.now()<t;){let n=new AbortController,r=setTimeout(()=>n.abort(),this.config.timeoutMs),i;try{i=await this.originalFetch(`${this.config.endpoint}/v1/allow/decisions/${encodeURIComponent(e)}`,{method:"GET",headers:{Authorization:`Bearer ${this.config.apiKey}`,...this.versionHeaders()},signal:n.signal})}finally{clearTimeout(r)}if(!i.ok)throw new Error(`ALLOW decisions poll failed: HTTP ${i.status} ${i.statusText}`);let a=await i.json();if(typeof a!="object"||a===null)throw new Error("ALLOW decisions poll returned unexpected non-object response");let o=a,c=o.hitl_result;if(c==="approved")return{decision_id:e,decision:"permit",reason:"Approved by human reviewer"};if(c==="rejected")return{decision_id:e,decision:"deny",reason:typeof o.reason=="string"?o.reason:"Rejected by human reviewer"};if(c==="timeout"||c==="expired")return{decision_id:e,decision:"deny",reason:"HITL approval timed out"};await ct(lt)}return{decision_id:e,decision:"deny",reason:"HITL approval timed out"}}};function ct(e){return new Promise(t=>setTimeout(t,e))}function ce(){let e={};try{let t=`${m.platform()} ${m.release()}`.trim();t&&(e.os=t)}catch{}try{let t=m.hostname();t&&(e.hostname=t)}catch{}try{let{username:t}=m.userInfo();t&&(e.username=t)}catch{}try{let t=ut();t&&(e.ip=t)}catch{}return e}function ut(){let e=m.networkInterfaces();for(let t of Object.keys(e))for(let n of e[t]??[])if((n.family==="IPv4"||n.family===4)&&!n.internal&&n.address)return n.address}import{z as u}from"zod";import{createHash as Sn}from"crypto";import{createHash as On}from"crypto";var dt=["tier1","tier2","tier3"];function pe(e){return typeof e=="string"&&dt.includes(e)}var pt=["read_only","transactional","data_processor","external_comms","code_exec","privileged"],ft=["internal","customer_facing","experimental","third_party"],fe=[...pt,...ft];function gt(e){return typeof e=="string"&&fe.includes(e)}function ge(e){let t=new Set;for(let n of e)gt(n)&&t.add(n);return fe.filter(n=>t.has(n))}var mt=["read_only","record_create","record_update","record_delete","data_export","data_share","data_subject_request","consent_change","funds_transfer","funds_disbursement","payroll_run","trade_execution","ledger_mutation","credit_decision","decision_adverse","account_restriction","account_closure","card_management","purchase_commitment","vendor_management","deal_management","pricing_change","contract_execution","legal_hold","regulatory_filing","personnel_action","employment_termination","compensation_change","campaign_send","content_publish","inventory_adjustment","order_fulfillment","account_servicing","credential_reset","access_grant","permission_change","credential_management","auth_policy_change","security_config_change","logging_change","alert_management","code_change","infrastructure_provision","deployment_change","communication_send","other"];function me(e){if(typeof e!="string"&&typeof e!="number")return null;let t=String(e).trim().replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"");return t.length>0?t:null}var ht={wire_transfer:"funds_transfer",international_transfer:"funds_transfer",cross_border_payment:"funds_transfer",send_swift:"funds_transfer",send_wire:"funds_transfer",transfer_funds:"funds_transfer",update_wire_instructions:"funds_transfer",add_beneficiary:"funds_transfer",modify_payee:"funds_transfer",disburse_funds:"funds_disbursement",initiate_ach:"funds_disbursement",issue_refund:"funds_disbursement",execute_trade:"trade_execution",place_order:"trade_execution",post_journal_entry:"ledger_mutation",adjust_ledger:"ledger_mutation",modify_general_ledger:"ledger_mutation",raise_limit:"credit_decision",increase_credit_limit:"credit_decision",extend_credit:"credit_decision",decline_credit:"decision_adverse",deny_application:"decision_adverse",adverse_action:"decision_adverse",block_card:"card_management",cancel_card:"card_management",place_hold:"account_restriction",freeze_account:"account_restriction",restrict_account:"account_restriction",close_account:"account_closure",export_data:"data_export",export_customer_list:"data_export",download_report:"data_export",download_customer_list:"data_export",bulk_export:"data_export",share_data:"data_share",send_to_partner:"data_share",delete_records:"record_delete",delete_user:"record_delete",drop_table:"record_delete",grant_role:"access_grant",change_permissions:"permission_change",modify_access:"permission_change",rotate_keys:"credential_management",disable_mfa:"auth_policy_change",modify_security_config:"security_config_change",disable_logging:"logging_change",purge_logs:"logging_change",suppress_alert:"alert_management",dismiss_alert:"alert_management",rollback:"deployment_change",modify_billing:"record_update",close_sar:"record_update",send_email:"communication_send",send_sms:"communication_send",fulfill_dsar:"data_subject_request",process_dsar:"data_subject_request",fulfill_data_request:"data_subject_request",process_erasure_request:"data_subject_request",honor_deletion_request:"data_subject_request",export_subject_data:"data_subject_request",erase_subject_data:"data_subject_request",delete_subject_data:"data_subject_request",record_consent:"consent_change",capture_consent:"consent_change",update_consent:"consent_change",withdraw_consent:"consent_change",revoke_consent:"consent_change",opt_out:"consent_change",opt_in:"consent_change",run_payroll:"payroll_run",process_payroll:"payroll_run",submit_payroll:"payroll_run",approve_payroll:"payroll_run",create_purchase_order:"purchase_commitment",issue_purchase_order:"purchase_commitment",approve_purchase_order:"purchase_commitment",submit_purchase_order:"purchase_commitment",approve_purchase:"purchase_commitment",approve_requisition:"purchase_commitment",commit_spend:"purchase_commitment",onboard_vendor:"vendor_management",add_vendor:"vendor_management",create_supplier:"vendor_management",approve_vendor:"vendor_management",update_vendor_bank:"vendor_management",update_supplier_bank:"vendor_management",modify_supplier:"vendor_management",create_opportunity:"deal_management",update_opportunity:"deal_management",advance_deal_stage:"deal_management",update_deal_stage:"deal_management",close_deal:"deal_management",mark_closed_won:"deal_management",mark_closed_lost:"deal_management",issue_quote:"pricing_change",send_quote:"pricing_change",approve_discount:"pricing_change",apply_discount:"pricing_change",override_price:"pricing_change",update_pricing:"pricing_change",approve_special_pricing:"pricing_change",execute_contract:"contract_execution",sign_contract:"contract_execution",countersign_contract:"contract_execution",sign_agreement:"contract_execution",execute_agreement:"contract_execution",sign_nda:"contract_execution",execute_nda:"contract_execution",sign_document:"contract_execution",esign_document:"contract_execution",place_legal_hold:"legal_hold",place_litigation_hold:"legal_hold",apply_legal_hold:"legal_hold",release_legal_hold:"legal_hold",file_regulatory_report:"regulatory_filing",file_sar:"regulatory_filing",submit_regulatory_filing:"regulatory_filing",file_compliance_report:"regulatory_filing",file_disclosure:"regulatory_filing",onboard_employee:"personnel_action",hire_employee:"personnel_action",change_employee_role:"personnel_action",promote_employee:"personnel_action",transfer_employee:"personnel_action",update_job_title:"personnel_action",terminate_employee:"employment_termination",offboard_employee:"employment_termination",deactivate_employee:"employment_termination",separate_employee:"employment_termination",adjust_salary:"compensation_change",change_compensation:"compensation_change",approve_raise:"compensation_change",grant_equity:"compensation_change",grant_stock:"compensation_change",issue_bonus:"compensation_change",update_pay_rate:"compensation_change",send_campaign:"campaign_send",launch_campaign:"campaign_send",schedule_campaign:"campaign_send",send_bulk_email:"campaign_send",send_marketing_email:"campaign_send",send_newsletter:"campaign_send",blast_email:"campaign_send",publish_post:"content_publish",publish_content:"content_publish",publish_blog:"content_publish",post_to_social:"content_publish",schedule_post:"content_publish",adjust_inventory:"inventory_adjustment",write_off_inventory:"inventory_adjustment",update_stock_level:"inventory_adjustment",reconcile_inventory:"inventory_adjustment",fulfill_order:"order_fulfillment",ship_order:"order_fulfillment",dispatch_order:"order_fulfillment",mark_order_shipped:"order_fulfillment",update_customer_account:"account_servicing",modify_customer_account:"account_servicing",update_customer_contact:"account_servicing",change_customer_settings:"account_servicing",reset_customer_password:"credential_reset",reset_password:"credential_reset",force_password_reset:"credential_reset",reset_mfa:"credential_reset",unlock_account:"credential_reset",reset_customer_credentials:"credential_reset",merge_pull_request:"code_change",merge_pr:"code_change",merge_branch:"code_change",push_to_branch:"code_change",push_to_main:"code_change",push_code:"code_change",commit_code:"code_change",force_push:"code_change",provision_infrastructure:"infrastructure_provision",provision_resource:"infrastructure_provision",create_instance:"infrastructure_provision",terminate_instance:"infrastructure_provision",spin_up_server:"infrastructure_provision",tear_down_server:"infrastructure_provision",destroy_resource:"infrastructure_provision",create_cluster:"infrastructure_provision"};function _t(e){let t=me(e);return t===null?"other":ht[t]||(/^(delete|remove|purge|drop|destroy|wipe)_/.test(t)?"record_delete":/^(export|download|extract|dump)_/.test(t)?"data_export":/^(create|add|insert)_/.test(t)?"record_create":/^(update|edit|modify|patch|set)_/.test(t)?"record_update":t==="send_email"||t==="send_sms"||/^(notify|email|sms)_/.test(t)?"communication_send":/^(read|get|list|search|fetch|view|query)_/.test(t)||t==="read"||t==="get"?"read_only":"other")}var ue={github:"version_control",gitlab:"version_control",bitbucket:"version_control",stripe:"payments",adyen:"payments",braintree:"payments",paypal:"payments",square:"payments",salesforce:"crm",hubspot:"crm",pipedrive:"crm",slack:"communication",teams:"communication",twilio:"communication",sendgrid:"communication",mailgun:"communication",gmail:"communication",outlook:"communication",zoom:"communication",aws:"cloud_infra",gcp:"cloud_infra",azure:"cloud_infra",okta:"identity",auth0:"identity",entra:"identity",onelogin:"identity",duo:"identity",snowflake:"data_warehouse",bigquery:"data_warehouse",databricks:"data_warehouse",redshift:"data_warehouse",jira:"ticketing",zendesk:"ticketing",servicenow:"ticketing",freshdesk:"ticketing",linear:"ticketing",workday:"hr",bamboohr:"hr",gusto:"hr",netsuite:"finance_erp",quickbooks:"finance_erp",sap:"finance_erp",xero:"finance_erp",s3:"storage",gcs:"storage",dropbox:"storage",box:"storage",postgres:"database",postgresql:"database",mysql:"database",mongodb:"database",redis:"database"};function yt(e){let t=me(e);return t===null?"other":ue[t]??ue[t.replace(/_/g,"")]??"other"}function he(e,t){let n={...e};if(t.action!==void 0&&t.action!==null&&n.action_class===void 0&&(n.action_class=_t(t.action)),t.targetApp!==void 0&&t.targetApp!==null){let r=n.context&&typeof n.context=="object"&&!Array.isArray(n.context)?{...n.context}:{};r.app_category===void 0&&(r.app_category=yt(t.targetApp)),n.context=r}return n}var de=64,bt=64,k={retrieved_data_categories:[],retrieved_classifications:[],action_classes:[],action_counts:{},denied_count:0,inhibited_count:0,event_count:0,target_apps:[]};function _e(){return{retrieved_data_categories:[],retrieved_classifications:[],action_classes:[],action_counts:{},denied_count:0,inhibited_count:0,event_count:0,target_apps:[]}}var vt=new Set(["deny","approval_required","escalate"]);function T(e,t){if(t.length===0)return[...e];let n=new Set(e);for(let i of t)n.add(i);let r=[...n].sort();return r.length>de?r.slice(0,de):r}function wt(e){return e?e.filter(t=>typeof t=="string"&&t.length>0):[]}function O(e){return typeof e=="string"&&e.length>0?e:null}function ye(e,t){let n=wt(t.data_categories),r=O(t.classification),i=O(t.action_class),a=i&&mt.includes(i)?i:null,o=O(t.target_app),c=O(t.decision),l={...e.action_counts};if(a)if(a in l)l[a]=(l[a]??0)+1;else if(Object.keys(l).length<bt)l[a]=1;else{let d=Object.keys(l).sort(),p=d[d.length-1];p!==void 0&&a<p&&(delete l[p],l[a]=1)}return{retrieved_data_categories:T(e.retrieved_data_categories,n),retrieved_classifications:T(e.retrieved_classifications,r?[r]:[]),action_classes:T(e.action_classes,a?[a]:[]),action_counts:l,denied_count:e.denied_count+(c==="deny"?1:0),inhibited_count:e.inhibited_count+(c&&vt.has(c)?1:0),event_count:e.event_count+1,target_apps:T(e.target_apps,o?[o]:[])}}var kt="generic",be=[{id:"finance_accounting",name:"Finance & Accounting",icon:"Landmark",description:"Payments, invoicing, ledgers, transactions, refunds, financial reporting, SOX/AML/KYC controls."},{id:"hr",name:"Human Resources",icon:"Users",description:"Employee records, payroll, hiring/recruiting, benefits, personnel actions and PII of staff."},{id:"engineering",name:"Engineering",icon:"Code",description:"Source code, build/deploy pipelines, infrastructure changes, production systems and developer tooling."},{id:"it_security",name:"IT & Security",icon:"ShieldCheck",description:"Credentials, secrets, access control, configuration, threat/exfiltration prevention and security operations."},{id:"legal",name:"Legal",icon:"Scale",description:"Contracts, NDAs, litigation, counsel communications and legal-hold material."},{id:"privacy_compliance",name:"Privacy & Compliance",icon:"BadgeCheck",description:"GDPR/CCPA/HIPAA, consent, data-subject rights, special-category data and regulatory data handling."},{id:"sales",name:"Sales",icon:"TrendingUp",description:"CRM, leads, deals, quotes, pipeline and customer commercial relationships."},{id:"marketing",name:"Marketing",icon:"Megaphone",description:"Campaigns, content, brand, social channels and prospect/audience data."},{id:"operations",name:"Operations",icon:"Cog",description:"Business operations, logistics, internal workflows, vendor/ops tooling and process automation."},{id:"customer_support",name:"Customer Support",icon:"LifeBuoy",description:"Support tickets, customer communications, account servicing and help-desk actions."},{id:"procurement",name:"Procurement",icon:"ShoppingCart",description:"Purchasing, supplier management, purchase orders, sourcing and spend approvals."},{id:kt,name:"Generic",icon:"Shapes",description:"Catch-all for cross-cutting rules or rules that do not fit a specific function. Assign when no specific function clearly applies."}],At=be.map(e=>e.id),En=new Map(be.map(e=>[e.id,e])),Cn=new Set(At);var It=/^[a-z][a-z0-9_]*$/;function ve(e){if(!Array.isArray(e))return[];let t=[],n=new Set;for(let r of e)typeof r=="string"&&It.test(r)&&!n.has(r)&&(n.add(r),t.push(r));return t}var St=["narrow","moderate","broad","unbounded","unknown"];function we(e){return typeof e=="string"&&St.includes(e)}function ke(e){return e==="open"||e==="closed"?e:null}var Et=["action","retrieval","delegation"];function Ct(e){return typeof e=="string"&&Et.includes(e)}var Tt=new Set(["rules"]);function Ae(e){if(typeof e.id!="string"||typeof e.vendor_id!="string")return null;let t=typeof e.origin_table=="string"?e.origin_table:"";if(!Tt.has(t))return null;let n=Array.isArray(e.applies_to)?e.applies_to.filter(Ct):[];return n.length===0?null:{id:e.id,originTable:t,vendorId:e.vendor_id,name:typeof e.name=="string"?e.name:"",description:typeof e.description=="string"?e.description:null,regoSource:typeof e.rego_source=="string"?e.rego_source:null,priority:typeof e.priority=="number"?e.priority:0,enabled:e.enabled===!0,appliesTo:n,targetApp:typeof e.target_app=="string"?e.target_app:null,actionPattern:typeof e.action_pattern=="string"?e.action_pattern:null,trustTier:typeof e.trust_tier=="string"?e.trust_tier:null,surface:typeof e.surface=="string"?e.surface:null,principalExclusions:Array.isArray(e.principal_exclusions)?e.principal_exclusions.filter(r=>typeof r=="string"):null,bypassActive:e.bypass_active===!0,bypassReason:typeof e.bypass_reason=="string"?e.bypass_reason:null,bypassExpiresAt:typeof e.bypass_expires_at=="string"?e.bypass_expires_at:null,redactionSpec:e.redaction_spec??null,failClosedOnEmptySpec:e.fail_closed_on_empty_spec===!0,hitlFallback:e.hitl_fallback==="mask"?"mask":"deny",ruleCode:typeof e.rule_code=="string"?e.rule_code:null}}import{z as x}from"zod";import{randomUUID as dn}from"node:crypto";var Ie=e=>e!==void 0&&e.length>5120?e.slice(0,5120):e;function Ot(e){let t={...e};return t.content?.text!==void 0&&(t.content={...t.content,text:Ie(t.content.text)}),t.spawn?.prompt!==void 0&&(t.spawn={...t.spawn,prompt:Ie(t.spawn.prompt)}),t}function xt(e,t=process.env){if(typeof e=="number"&&Number.isFinite(e)&&e>0)return e;let n=t.ALLOW_TIMEOUT_MS;if(n!==void 0){let r=Number.parseInt(n,10);if(Number.isFinite(r)&&r>0)return r}return 5e3}var Rt=1440*60*1e3,Nt="VISIQ_BUNDLE_GRACE_TTL_MS",Lt="VISIQ_BUNDLE_CACHE_DISABLED",Pt="VISIQ_CACHE_DIR",Dt=x.object({graceTtlMs:x.number().int().nonnegative().optional(),disabled:x.boolean().optional(),cacheDir:x.string().min(1).optional()}).strict();function Ft(e){return e==null?{}:Dt.parse(e)}function Ut(e,t=process.env){if(typeof e=="number"&&Number.isInteger(e)&&e>=0)return e;let n=t[Nt];if(n!==void 0){let r=Number(n);if(Number.isInteger(r)&&r>=0)return r}return Rt}function Bt(e,t=process.env){if(typeof e=="boolean")return e;let n=(t[Lt]??"").trim().toLowerCase();return n==="1"||n==="true"||n==="yes"}var Se;function jt(){if(Se!==void 0)return Se;try{return typeof process<"u"&&!!process.versions&&!!process.versions.node}catch{return!1}}function Mt(e){return JSON.stringify(j(e))}function j(e){if(Array.isArray(e))return e.map(j);if(e!==null&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=j(t[r]);return n}return e}function $t(e,t,n){let r=n-e.fetchedAt;return r<0?!1:r<=t}function qt(e){if(e!==null&&typeof e=="object"&&typeof e.fetchedAt=="number"&&typeof e.contentHash=="string"&&"body"in e){let t=e;return{fetchedAt:t.fetchedAt,version:typeof t.version=="string"?t.version:null,contentHash:t.contentHash,body:t.body}}return null}async function Re(){if(!jt())return null;try{let[e,t,n,r]=await Promise.all([import("node:fs/promises"),import("node:path"),import("node:os"),import("node:crypto")]);return{fs:e,path:t,os:n,crypto:r}}catch{return null}}function Ne(e,t){return e.createHash("sha256").update(Mt(t)).digest("hex")}function zt(e,t){let n=t.cacheDir?.trim();if(n)return n;let r=process.env[Pt]?.trim();if(r)return r;let i=process.env.XDG_CACHE_HOME?.trim();if(i)return e.path.join(i,"visiq");let a="";try{a=e.os.homedir()}catch{a=""}return a?e.path.join(a,".cache","visiq"):e.path.join(e.os.tmpdir(),"visiq-cache")}function Wt(e,t){return e.crypto.createHash("sha256").update(`${t.endpoint}\0${t.agentId}\0${t.apiKey}`).digest("hex")}function Le(e,t,n){return e.path.join(zt(e,n),"bundles",`${Wt(e,t)}.json`)}async function Ht(e,t,n,r={}){let i=await Re();if(i)try{let a=Le(i,e,r),o=i.path.dirname(a);await i.fs.mkdir(o,{recursive:!0,mode:448});let c={fetchedAt:r.now??Date.now(),version:n,contentHash:Ne(i.crypto,t),body:t},l=`${a}.tmp-${process.pid}-${i.crypto.randomBytes(6).toString("hex")}`;await i.fs.writeFile(l,JSON.stringify(c),{mode:384});try{await i.fs.rename(l,a)}catch(d){throw await i.fs.rm(l,{force:!0}).catch(()=>{}),d}}catch{}}async function Vt(e,t={}){let n=await Re();if(!n)return null;try{let r=await n.fs.readFile(Le(n,e,t),"utf-8"),i=qt(JSON.parse(r));return!i||Ne(n.crypto,i.body)!==i.contentHash?null:i}catch{return null}}var A;async function Gt(){if(A!==void 0)return A;try{let e=await import("@visiq/core-wasm"),t=e.evaluate??e.default?.evaluate;A=typeof t=="function"?t:null}catch{A=null}return A}var Kt=5e3,Zt=1e4,Yt=25,Ee=1e3,Jt=5e3,Qt=100,Ce=2e3,Xt=512,en=1800*1e3,tn="monitor",nn="Agent has been shut down by an operator \u2014 all actions are blocked (G001)",rn="Rules bundle requires a newer SDK wire-contract dialect than this SDK supports \u2014 refusing the bundle and blocking all actions (fail-closed, G001). Upgrade the VisIQ SDK.",an=u.object({operations:u.array(u.enum(["retrieval","action","delegation"])).min(1,"at least one operation is required"),agentId:u.string().min(1,"agentId is required"),sessionId:u.string().min(1).max(255).optional(),toolName:u.string().optional(),toolArgs:u.record(u.unknown()).optional(),targetResource:u.string().optional(),resourceType:u.string().optional(),resourceMetadata:u.record(u.unknown()).optional(),normalized:u.record(u.unknown()).optional(),query:u.string().optional(),contentPreview:u.string().optional(),telemetry:u.record(u.unknown()).optional(),context:u.record(u.unknown()).optional()}),on=u.object({version:u.string().min(1),dialect_version:u.number().int().optional(),min_dialect:u.number().int().optional(),shutdown:u.boolean().optional(),agent_mode:u.enum(["enforce","monitor","off"]).optional(),cognition_capture:u.boolean().optional(),agent_mode_by_operation:u.object({action:u.string().optional(),retrieval:u.string().optional(),delegation:u.string().optional()}).partial().optional(),agent_attributes:u.object({trust_tier:u.string().nullable().optional(),categories:u.array(u.string()).optional(),business_function:u.string().nullable().optional(),business_functions:u.array(u.string()).nullable().optional(),blast_radius_tier:u.string().nullable().optional(),no_coverage:u.string().nullable().optional()}).optional(),rules:u.array(u.record(u.unknown())),no_coverage:u.object({no_coverage_defaults:u.record(u.string()),autopilot_enabled:u.boolean(),enduser_hitl_enabled:u.boolean(),hitl_timeout_seconds:u.number().optional()}).optional()});function sn(e){let t=e.trust_tier??null,n=[];Array.isArray(e.business_functions)&&e.business_functions.length>0?n=e.business_functions:typeof e.business_function=="string"&&e.business_function!==""&&(n=[e.business_function]);let r=ve(n);return{trust_tier:pe(t)?t:null,categories:ge(e.categories??[]),business_functions:r,business_function:r[0]??null,blast_radius_tier:typeof e.blast_radius_tier=="string"&&we(e.blast_radius_tier)?e.blast_radius_tier:null}}function ln(e){if(!e)return null;let t={};for(let n of["action","retrieval","delegation"]){let r=e[n];(r==="enforce"||r==="monitor"||r==="off")&&(t[n]=r)}return Object.keys(t).length>0?t:null}function cn(e){return e==="permit"?"permit":e==="mask"||e==="redact"?"mask":e==="approval_required"||e==="escalate"?"approval_required":"deny"}var M=new Set,Te=!1;async function Oe(e){let t=[];for(let n of M){if(n.pendingTelemetryCount()>0&&!n.hasBackend()){console.warn(`[UnifiedRuntime] exiting with ${n.pendingTelemetryCount()} un-sent decision(s) and no backend \u2014 telemetry lost.`);continue}let r=n.flush();e&&t.push(r)}t.length>0&&await Promise.allSettled(t)}function un(){if(!Te&&!(typeof process>"u"||typeof process.once!="function")){Te=!0,process.once("beforeExit",()=>{Oe(!1)});for(let e of["SIGINT","SIGTERM"])process.once(e,()=>{(async()=>{try{await Oe(!0)}finally{process.kill(process.pid,e)}})()})}}var Pe=class{client;originalFetch;resolvedApiKey;resolvedEndpoint;resolvedAgentId;harnessKind;sdkVersion;sdkDialect;rules=[];agentAttributes=null;agentNoCoverage=null;sessions=new Map;noCoverage=null;bundleVersion=null;bundleEtag=null;bundleLoaded=!1;bundleFetchInProgress=!1;initialBundlePromise=null;refreshTimer=null;cacheIdentity;bundleCacheDisabled;bundleGraceTtlMs;bundleCacheDirOverride;diskFallbackServed=!1;agentMode=tn;agentModeByOperation=null;rawBundle=null;agentModeConfirmed=!1;operatorShutdown=!1;bundleApplyFailed=!1;dialectRefused=!1;telemetryBuffer=[];telemetryTimer=null;cognitionBuffer=[];cognitionTimer=null;cognitionEnabled=process.env.VISIQ_COGNITION_CAPTURE==="1";envRegistered=!1;registerPromise=null;lastToolSurfaceSig=null;constructor(e,t,n,r,i,a,o,c){let l=e??process.env.VISIQ_API_KEY??process.env.ALLOW_API_KEY??process.env.VISIQ_ALLOW_API_KEY,d=t??process.env.VISIQ_ENDPOINT??process.env.ALLOW_ENDPOINT,p=n??process.env.VISIQ_AGENT_ID??process.env.ALLOW_AGENT_ID??"";this.resolvedApiKey=l,this.resolvedEndpoint=d,this.resolvedAgentId=p,this.harnessKind=r,this.sdkVersion=a,this.sdkDialect=o,this.originalFetch=globalThis.fetch.bind(globalThis);let g=Ft(c);if(this.bundleCacheDisabled=Bt(g.disabled),this.bundleGraceTtlMs=Ut(g.graceTtlMs),this.bundleCacheDirOverride=g.cacheDir,this.cacheIdentity=l&&d&&!this.bundleCacheDisabled?{endpoint:d,agentId:p,apiKey:l}:null,l&&d){let $e={apiKey:l,agentId:p,endpoint:d,mode:"enforce",timeoutMs:xt(i),hitlTimeoutMs:12e4,failBehavior:"closed",...r?{harnessKind:r}:{},...a!==void 0?{sdkVersion:a}:{},...o!==void 0?{sdkDialect:o}:{}};this.client=new le($e,this.originalFetch),this.initialBundlePromise=this.initialBundleLoad(),this.refreshTimer=setInterval(()=>{this.fetchBundleBackground()},Kt),U(this.refreshTimer),this.telemetryTimer=setInterval(()=>{this.flushTelemetry()},Zt),U(this.telemetryTimer),this.cognitionTimer=setInterval(()=>{this.flushCognition()},Jt),U(this.cognitionTimer),M.add(this),un()}else this.client=null}async evaluate(e){let t=an.parse(e),n=Date.now();if(this.operatorShutdown){let l=this.denyAll(t,nn);return this.applyAgentMode(l,"enforce",t,n)}if(this.dialectRefused){let l=this.denyAll(t,rn);return this.applyAgentMode(l,"enforce",t,n)}if(t.operations.every(l=>this.modeFor(l)==="off"))return this.offDecision(t);if(!this.bundleLoaded){let l;this.agentModeConfirmed?l=this.agentMode:this.bundleApplyFailed?l="enforce":l="monitor";let d=this.denyAll(t,"No unified bundle loaded and no local rules \u2014 fail-closed (G001)");return this.applyAgentMode(d,l,t,n)}let r=this.readSession(t.sessionId),i=await Gt();if(!i||!this.rawBundle)throw new Error("governance core (@visiq/core-wasm) unavailable \u2014 failing closed (G001)");let a={...t,session:r,at:Date.now()},o={...this.rawBundle,agent_mode:this.agentMode,...this.agentModeByOperation?{agent_mode_by_operation:this.agentModeByOperation}:{}},c=i(a,o);return this.foldSession(t,c.enforced?c.decision:"permit"),c.enforced&&c.action.decision==="approval_required"&&await this.registerHitl(t,c),this.bufferTelemetry(t,c,Date.now()-n,c.enforced),c}modeFor(e){return this.agentModeByOperation?.[e]??this.agentMode}readSession(e){if(!e)return k;let t=this.sessions.get(e);return t?Date.now()-t.touchedAt>en?(this.sessions.delete(e),k):t.state:k}foldSession(e,t){let{sessionId:n}=e;if(!n)return;let r=this.readSession(n),i=e.resourceMetadata??{},a=e.operations.includes("retrieval"),o=e.operations.includes("action")||e.operations.includes("delegation"),c=o?he(e.normalized??{},{action:e.toolName??"",targetApp:e.targetResource??e.toolName??""}):e.normalized??{},l=ye(r===k?_e():r,{data_categories:a&&Array.isArray(i.data_categories)?i.data_categories:void 0,classification:a?i.classification:void 0,action_class:o?c.action_class:void 0,target_app:o?e.targetResource??e.toolName:void 0,decision:t});if(this.sessions.delete(n),this.sessions.set(n,{state:l,touchedAt:Date.now()}),this.sessions.size>Xt){let d=this.sessions.keys().next().value;d!==void 0&&this.sessions.delete(d)}}applyAgentMode(e,t,n,r){let i=Date.now()-r;if(t==="enforce"){let o={...e,enforced:!0,agentMode:"enforce"};return this.bufferTelemetry(n,o,i,!0),o}let a={...e,allowed:!0,enforced:!1,agentMode:"monitor"};return this.bufferTelemetry(n,a,i,!1),a}offDecision(e){let t=e.operations.includes("action")||e.operations.includes("delegation"),n=e.operations.includes("retrieval");return{decision:"permit",allowed:!0,reason:"agent_mode=off \u2014 evaluation bypassed",ruleId:null,ruleCode:null,enforced:!1,agentMode:"off",action:t?{decision:"permit",allowed:!0}:{decision:null,allowed:!0},retrieval:n?{action:"allow"}:{action:null}}}denyAll(e,t){let n=e.operations.includes("action")||e.operations.includes("delegation"),r=e.operations.includes("retrieval");return{decision:"deny",allowed:!1,reason:t,ruleId:null,ruleCode:null,enforced:!0,agentMode:"enforce",action:n?{decision:"deny",allowed:!1}:{decision:null,allowed:!0},retrieval:r?{action:"deny"}:{action:null}}}async registerHitl(e,t){if(this.client)try{let n={agent_id:e.agentId,target_app:e.targetResource??e.toolName??"",action:e.toolName??"",context:e.toolName?{[e.toolName]:e.toolArgs??{}}:{},...e.sessionId?{session_id:e.sessionId}:{},...e.telemetry?{telemetry:e.telemetry}:{}},r=await this.client.evaluate(n);r.decision_id&&(t.action.decisionId=r.decision_id)}catch(n){console.warn("[UNIFIED] HITL registration failed \u2014 staying fail-closed (G001):",n)}}applyBundle(e){this.bundleApplyFailed=!0;let t=on.parse(e);this.bundleApplyFailed=!1;let n=this.sdkDialect??1;if(t.min_dialect!==void 0&&t.min_dialect>n){this.dialectRefused=!0,this.bundleApplyFailed=!0,console.warn(`[UNIFIED] rules bundle requires dialect ${t.min_dialect} but this SDK speaks ${n} \u2014 refusing the bundle and failing closed (deny-all, G001). Upgrade the VisIQ SDK.`);return}this.dialectRefused=!1,!(this.bundleLoaded&&t.version===this.bundleVersion)&&(this.rules=t.rules.map(r=>Ae(r)).filter(r=>r!==null),this.agentAttributes=t.agent_attributes?sn(t.agent_attributes):null,this.agentNoCoverage=ke(t.agent_attributes?.no_coverage),this.bundleVersion=t.version,this.bundleLoaded=!0,this.noCoverage=t.no_coverage?{no_coverage_defaults:t.no_coverage.no_coverage_defaults,autopilot_enabled:t.no_coverage.autopilot_enabled,enduser_hitl_enabled:t.no_coverage.enduser_hitl_enabled}:null,t.agent_mode!==void 0&&(this.agentMode=t.agent_mode,this.agentModeConfirmed=!0),this.agentModeByOperation=ln(t.agent_mode_by_operation),process.env.VISIQ_COGNITION_CAPTURE==="1"?this.cognitionEnabled=!0:typeof t.cognition_capture=="boolean"&&(this.cognitionEnabled=t.cognition_capture),this.operatorShutdown=t.shutdown===!0,this.rawBundle=e)}async awaitBundleReady(e=5e3){if(!this.initialBundlePromise||this.bundleLoaded)return;let t,n=new Promise(r=>{t=setTimeout(r,e)});try{await Promise.race([this.initialBundlePromise,n])}catch{}finally{t&&clearTimeout(t)}}async fetchBundleBackground(){if(!(this.bundleFetchInProgress||!this.resolvedEndpoint||!this.resolvedApiKey)){this.bundleFetchInProgress=!0;try{let e=this.resolvedAgentId?`?agent_id=${encodeURIComponent(this.resolvedAgentId)}`:"",t={Authorization:`Bearer ${this.resolvedApiKey}`,Accept:"application/json",...F(this.sdkVersion,this.sdkDialect)};this.bundleEtag&&(t["If-None-Match"]=this.bundleEtag);let n=await this.originalFetch(`${this.resolvedEndpoint}/rules/bundle${e}`,{method:"GET",headers:t});if(n.status===304)return;if(!n.ok)throw new Error(`unified bundle fetch failed: HTTP ${n.status}`);let r=n.headers.get("ETag"),i=await n.json();this.applyBundle(i);let a=this.bundleLoaded&&!this.dialectRefused&&!this.bundleApplyFailed;r&&a?this.bundleEtag=r:a||(this.bundleEtag=null),a&&await this.persistBundleToDisk(i)}catch(e){this.bundleLoaded?console.warn("[UNIFIED] Bundle refresh failed (using cached rules):",e):console.warn("[UNIFIED] Initial bundle fetch failed (fail-closed until loaded):",e)}finally{this.bundleFetchInProgress=!1}}}async initialBundleLoad(){await this.fetchBundleBackground(),this.bundleLoaded||await this.tryLoadFromDiskCache()}async tryLoadFromDiskCache(){if(this.bundleLoaded||this.bundleCacheDisabled||!this.cacheIdentity||this.dialectRefused)return;let e;try{e=await Vt(this.cacheIdentity,{...this.bundleCacheDirOverride?{cacheDir:this.bundleCacheDirOverride}:{}})}catch{return}if(!e)return;let t=Date.now();if($t(e,this.bundleGraceTtlMs,t)){try{this.applyBundle(e.body)}catch{return}if(this.bundleLoaded&&!this.dialectRefused&&!this.diskFallbackServed){this.diskFallbackServed=!0;let n=Math.max(0,Math.round((t-e.fetchedAt)/1e3)),r=Math.round(this.bundleGraceTtlMs/1e3);console.warn(`[UnifiedRuntime] serving cached rules bundle (age ${n}s) \u2014 control plane unreachable on cold start; will keep retrying and fail closed once the cache exceeds the ${r}s grace window.`)}}}async persistBundleToDisk(e){this.bundleCacheDisabled||!this.cacheIdentity||await Ht(this.cacheIdentity,e,this.bundleVersion,{...this.bundleCacheDirOverride?{cacheDir:this.bundleCacheDirOverride}:{}})}hasRules(){return this.bundleLoaded&&this.rules.length>0}hasClient(){return this.client!==null}getEndpoint(){return this.resolvedEndpoint}getApiKey(){return this.resolvedApiKey}getBundleVersion(){return this.bundleVersion}getAgentMode(){return this.agentMode}getAgentAttributes(){return this.agentAttributes}getSessionState(e){return this.readSession(e)}registerEnvironment(e){!this.client||this.envRegistered||!this.resolvedAgentId||(this.envRegistered=!0,this.registerPromise=this.client.registerEnvironment(e))}registerHostEnvironment(e){this.registerEnvironment({...ce(),...e?{agent_type:e}:{}})}reportToolSurface(e){if(!this.client||!this.resolvedAgentId||e.length===0)return;let t=JSON.stringify([...e].map(n=>({n:n.name,d:n.description??"",s:n.input_schema??null})).sort((n,r)=>n.n.localeCompare(r.n)));t!==this.lastToolSurfaceSig&&(this.lastToolSurfaceSig=t,this.client.reportToolSurface(e))}bufferTelemetry(e,t,n,r){this.telemetryBuffer.push({decision_id:crypto.randomUUID(),agent_id:e.agentId,target_app:e.targetResource??e.toolName??"",action:e.toolName??e.operations.join("+"),...e.sessionId?{session_id:e.sessionId}:{},decision:r?cn(t.decision):"permit",reason:t.reason,evaluated_at:new Date().toISOString(),rule_id:t.ruleId,rule_code:t.ruleCode,enforced:r,agent_mode:this.agentMode,latency_ms:n,evaluation_mode:"local",raw_event:{agent_id:e.agentId,operations:e.operations,...e.toolName?{tool_name:e.toolName}:{},...e.targetResource?{target_resource:e.targetResource}:{},...e.resourceType?{resource_type:e.resourceType}:{}},...this.harnessKind||e.context?{context:{...this.harnessKind?{[oe]:this.harnessKind}:{},...e.context??{}}}:{}}),this.enforceTelemetryCap(),this.telemetryBuffer.length>=Yt&&this.flushTelemetry()}pendingTelemetryCount(){return this.telemetryBuffer.length}hasBackend(){return this.client!==null}async flushTelemetry(){if(this.telemetryBuffer.length===0||!this.client)return;let e=this.telemetryBuffer.splice(0);try{await this.client.sendTelemetry(e)}catch(t){console.error("[UnifiedRuntime] telemetry flush failed (non-fatal):",t)}}enforceTelemetryCap(){let e=this.telemetryBuffer.length-Ee;e>0&&(this.telemetryBuffer.splice(0,e),console.warn(`[UnifiedRuntime] telemetry buffer full \u2014 dropped ${e} oldest entries (cap ${Ee})`))}isCognitionEnabled(){return this.cognitionEnabled}emitCognition(e){!this.cognitionEnabled||!this.client||(this.cognitionBuffer.push(Ot(e)),this.enforceCognitionCap(),this.cognitionBuffer.length>=Qt&&this.flushCognition())}async flushCognition(){if(this.cognitionBuffer.length===0||!this.client)return;let e=this.cognitionBuffer.splice(0);try{await this.client.sendCognition(void 0,e)}catch(t){console.error("[UnifiedRuntime] cognition flush failed (non-fatal):",t)}}enforceCognitionCap(){let e=this.cognitionBuffer.length-Ce;e>0&&(this.cognitionBuffer.splice(0,e),console.warn(`[UnifiedRuntime] cognition buffer full \u2014 dropped ${e} oldest beats (cap ${Ce})`))}async flush(){if(this.registerPromise)try{await this.registerPromise}catch{}await this.flushTelemetry(),await this.flushCognition()}async shutdown(){await this.flush(),this.dispose(),M.delete(this)}dispose(){this.refreshTimer&&(clearInterval(this.refreshTimer),this.refreshTimer=null),this.telemetryTimer&&(clearInterval(this.telemetryTimer),this.telemetryTimer=null),this.cognitionTimer&&(clearInterval(this.cognitionTimer),this.cognitionTimer=null),this.flushTelemetry(),this.flushCognition()}};function U(e){e&&typeof e=="object"&&"unref"in e&&e.unref()}function B(e){return typeof e=="string"&&e.trim().length>0?e:void 0}function De(e,t){if(e!=="Task"&&e!=="Agent")return null;let n=B(t.description),r=B(t.subagent_type),i=B(t.prompt),a=n??r??"sub-agent";return{childAgentId:a,childName:a,kind:"subagent",agentType:r,description:n,task:i,goal:i,source:"structural"}}function Fe(e,t){return{delegation:{is_delegated:!0,role:"parent",parent_agent_id:t,target_agent:e.childAgentId,source:e.source,spawn:{childAgentId:e.childAgentId,childName:e.childName,kind:e.kind,...e.model?{model:e.model}:{},...e.task?{prompt:e.task}:{},...e.description?{description:e.description}:{},...e.goal?{goal:e.goal}:{},...e.agentType?{agentType:e.agentType}:{}}}}}var xe=new Map;function pn(e){let t=(xe.get(e)??0)+1;return xe.set(e,t),t}function Ue(e,t,n){if(!e||typeof e.isCognitionEnabled!="function"||!e.isCognitionEnabled())return;let r=t.sessionId&&t.sessionId.length>0?t.sessionId:t.agentId;e.emitCognition({clientEventId:dn(),agentId:t.agentId,sessionId:r,threadId:t.agentId,parentId:t.agentId,seq:pn(r),ts:Date.now(),kind:"spawn",visibility:"shown",provenance:"parsed",...t.framework?{framework:t.framework}:{},spawn:{childAgentId:n.childAgentId,childName:n.childName,kind:n.kind,...n.model?{model:n.model}:{},...n.task?{prompt:n.task}:{}}})}function $(e){let t=[],n=[],r,i=[];for(let o of e){if(o.mode==="partial"||o.mode==="email"||o.mode==="custom"){let l={mode:o.mode};o.field&&(l.field=o.field),o.pattern&&(l.pattern=o.pattern),typeof o.keepFirst=="number"&&(l.keepFirst=o.keepFirst),typeof o.keepLast=="number"&&(l.keepLast=o.keepLast),o.maskChar&&(l.maskChar=o.maskChar),o.keepPattern&&(l.keepPattern=o.keepPattern),o.replacement!==void 0&&(l.replacement=o.replacement),i.push(l);continue}o.field&&t.push(o.field),o.pattern&&n.push(o.pattern);let{replacement:c}=o;c&&r===void 0&&(r=c)}let a={};return t.length>0&&(a.fields=t),n.length>0&&(a.patterns=n),r!==void 0&&(a.replacement=r),i.length>0&&(a.directives=i),a}var fn="[VisIQ: retrieval withheld by policy]";function R(e){return q(e)}function q(e){if(e==null)return e;if(typeof e=="string")return e.length>0?fn:e;if(typeof e=="number")return 0;if(typeof e=="boolean")return!1;if(Array.isArray(e))return e.map(q);if(typeof e=="object"){let t=Object.create(null);for(let n of Object.keys(e))t[n]=q(e[n]);return t}return e}function Be(e){return e.fields&&e.fields.length>0||e.patterns&&e.patterns.length>0?!0:!!e.directives?.some(t=>t.field&&t.field.length>0||t.pattern&&t.pattern.length>0)}function je(e,t){if(!e.enforced)return null;let{action:n,retrieval:r}=e,i=h(e.reason,e.ruleCode);if(n.decision==="deny"||r.action==="deny")return E(i);if(n.decision==="approval_required"||r.action==="escalate")return Q(i);if(n.decision==="mask"&&n.argRedactionRules&&n.argRedactionRules.length>0){let a=$(n.argRedactionRules);if(Be(a)){let o=D(t,a)??t;if(JSON.stringify(o)!==JSON.stringify(t))return J(o)}return null}return null}function Me(e,t){if(!e.enforced)return null;let{retrieval:n}=e,r=h(e.reason,e.ruleCode);if(n.action==="redact"){let i=$(n.redactionRules??[]);if(!Be(i))return _(R(t),r);let a=D(t,i);return JSON.stringify(a)===JSON.stringify(t)?null:_(a,r)}return n.action==="deny"?_(R(t),r):null}var gn="cli_harness";function b(e){return new Pe(e.apiKey,e.baseUrl,e.agentId,gn)}function N(e){let t={operations:e.operations,agentId:e.agentId,toolName:e.toolName,toolArgs:e.toolInput,resourceType:"tool_result",resourceMetadata:{toolName:e.toolName,...e.toolUseId?{toolCallId:e.toolUseId}:{},...e.sessionId?{sessionId:e.sessionId}:{},...e.cwd?{cwd:e.cwd}:{}}};return e.query&&(t.query=e.query),e.context&&(t.context=e.context),t}async function v(e,t,n=W){let{agentId:r}=t,i=await V(r);if(i&&H(i,n,Date.now())&&z(e,i.body))return;let a=e.getEndpoint();if(a){let o=await K(a,t.apiKey,r);if(o&&z(e,o.body)){await G(r,o.body,o.version);return}}if(!(i&&z(e,i.body)))try{await e.awaitBundleReady(2500)}catch{}}function z(e,t){try{return e.applyBundle(t),!0}catch{return!1}}async function w(e){try{await e.flush()}catch{}try{e.dispose()}catch{}}async function Qn(e,t){let n=b(t),r=e.tool_input??{};try{await Z(e.session_id)||(n.registerHostEnvironment(),await I(e.session_id)),await v(n,t);let i=De(e.tool_name,r),a=Y(e.tool_name),o;i&&(Ue(n,{agentId:t.agentId,sessionId:e.session_id,framework:"claude-code"},i),a=Array.from(new Set([...a,"delegation"])),o=Fe(i,t.agentId));let c=N({operations:a,agentId:t.agentId,toolName:e.tool_name,toolInput:r,sessionId:e.session_id,cwd:e.cwd,toolUseId:e.tool_use_id,query:S(r),...o?{context:o}:{}}),l=await n.evaluate(c);return je(l,r)}catch{return E(h("evaluation error (fail-closed)",null))}finally{await w(n)}}async function ir(e,t){if(!L(e.tool_name))return null;let n=b(t);try{await v(n,t);let r=e.tool_input??{},i=N({operations:["retrieval"],agentId:t.agentId,toolName:e.tool_name,toolInput:r,sessionId:e.session_id,cwd:e.cwd,toolUseId:e.tool_use_id,query:S(r)}),a=await n.evaluate(i);return Me(a,e.tool_response)}catch{return _(R(e.tool_response),h("evaluation error (fail-closed)",null))}finally{await w(n)}}async function lr(e,t){let n=b(t);try{n.registerHostEnvironment(),await v(n,t,0),await I(e.session_id)}finally{await w(n)}return null}export{We as a,L as b,Y as c,S as d,h as e,J as f,E as g,Q as h,_ as i,hn as j,fn as k,R as l,je as m,Me as n,gn as o,b as p,N as q,v as r,w as s,Qn as t,ir as u,lr as v};
|