@visiq/claude-code-harness 0.1.1 → 0.1.3

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 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
- - **Configured, evaluation error / cold-start with no bundle** (enforce mode):
73
- **fail-closed** — actions are denied and retrieval content is withheld (G001).
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,5 @@
1
+ import{c as V,i as ce,k as ue,l as de,m as pe,n as fe,o as me,p as L}from"./chunk-XEWB3NIN.js";import{appendFile as Nt,mkdir as Rt}from"node:fs/promises";import{join as $t}from"node:path";function Lt(){return $t(V(),"fail-open.log")}async function v(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 Rt(V(),{recursive:!0}),await Nt(Lt(),`${JSON.stringify({at:new Date().toISOString(),...e})}
3
+ `,{mode:384})}catch{}}async function P(e,t={}){e.failOpen===!0&&await v({stage:"runtime-fail-open",detail:e.reason,...t.toolName?{toolName:t.toolName}:{},...t.sessionId?{sessionId:t.sessionId}:{}})}var Pt=new Set(["WebFetch","WebSearch","Read","Grep","Glob","LSP","NotebookRead","ListMcpResourcesTool","ReadMcpResourceTool"]),Dt=/(^|_)(search|fetch|read|list|get|query|retrieve|lookup|find|describe|download|export|dump)(_|$)/i;function Mt(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 W(e){return typeof e!="string"?!1:Pt.has(e)?!0:e.startsWith("mcp__")?Dt.test(Mt(e)):!1}function ge(e){return W(e)?["retrieval","action"]:["action"]}var Ft=["query","q","url","prompt","pattern","file_path","path"];function D(e){if(!e||typeof e!="object")return;let t=e,n=[];for(let r of Ft){let i=t[r];typeof i=="string"&&i.length>0&&n.push(i)}return n.length>0?n.join(" "):void 0}function w(e,t){let n=t?`VisIQ ${t}`:"VisIQ",r=e&&e.trim().length>0?e.trim():"blocked by policy";return`[${n}] ${r}`}function he(e){let t={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}};return e&&(t.hookSpecificOutput.updatedInput=e),t}function M(e){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:e}}}function _e(e){return{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"ask",permissionDecisionReason:e}}}function k(e,t){let n={hookSpecificOutput:{hookEventName:"PostToolUse",updatedToolOutput:e}};return t&&(n.hookSpecificOutput.additionalContext=t),n}function Yr(e){try{let t=JSON.parse(e);return t&&typeof t=="object"&&typeof t.hook_event_name=="string"?t:null}catch{return null}}var jt="[REDACTED]",Ee=[{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 Ce(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 Ut(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 l=0;l<o.length;l++)r=(r*10+(o.charCodeAt(l)-48))%97}return r===1}function Bt(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 qt=[{name:"pan",re:/\d(?:[ -]?\d){12,18}/g,normalize:e=>e.replace(/[ -]/g,""),validate:e=>e.length>=13&&e.length<=19&&Ce(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:Ut},{name:"aba_routing",re:/\b\d{9}\b/g,normalize:e=>e,validate:Bt}],m=Object.fromEntries(Ee.map(e=>[e.name,e.re.source])),Te=["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"],J={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:m.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:m.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:m.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:m.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:m.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:m.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:m.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:m.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:m.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:m.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:m.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:m.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:m.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:m.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:m.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:m.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:m.mac_address,mode:"full"},defaultEnabled:!1}},Zr=new Set(Te.filter(e=>!J[e].defaultEnabled));function zt(e,t){let n=new Set;for(let r of Te)(J[r].defaultEnabled?!e?.has(r):t?.has(r))||n.add(r);return n}function Gt(e,t,n,r){if(typeof e!="string"||e.length===0)return e;let i=e;for(let{name:a,re:o}of Ee){let l=a;n.has(l)||(i=i.replace(o,()=>(r?.(l),t)))}for(let{name:a,re:o,normalize:l,validate:u}of qt)n.has(a)||(i=i.replace(o,s=>u(l(s))?(r?.(a),t):s));return i}function Vt(e,t=jt,n,r){let i=new Set,a=zt(n,r),o=!a.has("pan"),l=s=>{i.add(s)},u=s=>{if(typeof s=="string")return Gt(s,t,a,l);if(typeof s=="number"&&Number.isInteger(s)&&s>0){if(!o)return s;let p=String(s);return p.length>=13&&p.length<=19&&Ce(p)?(i.add("pan"),t):s}if(Array.isArray(s))return s.map(p=>u(p));if(s!==null&&typeof s=="object"){let p=s,f={};for(let h of Object.keys(p))f[h]=u(p[h]);return f}return s};return{value:u(e),detectors:[...i].sort()}}var Wt=/[\u00AD\u200B-\u200F\u202A-\u202E\u2060\u2066-\u2069\uFEFF]/g,xe=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"}),Ht=new RegExp(`[${Object.keys(xe).join("")}]`,"gu"),Kt=Object.freeze({4:"a","@":"a",3:"e",1:"i","!":"i",0:"o",5:"s",$:"s",7:"t",9:"g","(":"c",8:"b"}),Oe="\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",Yt=Object.freeze(Object.fromEntries([...Oe].map((e,t)=>[e,String.fromCharCode(97+t)]))),Jt=new RegExp(`[${Oe}\u2800]`,"g"),Ne=/[⠀-⣿]/;function Zt(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 Qt(e){return e.replace(Wt,"")}function Re(e){return e.replace(Ht,t=>xe[t]??t)}function Xt(e){return e.replace(/[4@31!05$79(8]/g,t=>Kt[t]??t)}function en(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 tn(e){return Ne.test(e)?e.replace(Jt,t=>t==="\u2800"?" ":Yt[t]??t):e}function ye(e){let t;try{t=Zt(e)}catch{t=e}try{t=t.normalize("NFKC")}catch{}return t=Qt(t),t=Re(t),t}var nn=/^[A-Za-z0-9+/]{16,}={0,2}$/,rn=/^(?:[0-9a-fA-F]{2}\s*){8,}$/,be=/[A-Za-z0-9+/]{20,}={0,2}/g;function Y(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 $e=new TextDecoder("utf-8",{fatal:!1});function Le(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=$e.decode(n);return t===r?[t]:[r,t]}function an(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=$e.decode(n);return r===i?[r]:[i,r]}function ve(e){let t=e.trim(),n=[];if(rn.test(t))for(let r of an(t))n.push({decoded:r,textiness:Y(r)});if(nn.test(t)&&t.length%4===0)for(let r of Le(t))n.push({decoded:r,textiness:Y(r)});return n}function we(e,t){let n=[],r;for(be.lastIndex=0;(r=be.exec(e))!==null&&n.length<t;){let i=r[0];if(i.length%4===0)for(let a of Le(i))n.push({decoded:a,textiness:Y(a)})}return n}var on=Object.freeze({maxDepth:3,byteCap:262144,maxNodes:256,maxBlobsPerNode:8});function Pe(e,t=on){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,l=A=>{A.length>0&&A.length<=r&&o.add(A)},u=!1,s=!1,p=0,f=0,h=[{s:e,depth:0}];for(;h.length>0;){if(p>=i){s=!0;break}let A=h.pop();if(A===void 0)break;let{s:R,depth:$}=A;if(R.length>r){s=!0;continue}p++,$>f&&(f=$);let _=ye(R);l(_);let le=Xt(_);if(le!==_&&l(le),l(en(_)),Ne.test(R)&&l(tn(_)),$>=n){let y=ye(R);(ve(y).length>0||we(y,a).length>0)&&(s=!0);continue}let Ot=[...ve(_),...we(_,a)];for(let y of Ot){if(u=!0,y.decoded.length>r){s=!0;continue}y.textiness>=.85&&y.decoded!==_?h.push({s:y.decoded,depth:$+1}):l(y.decoded)}}return{views:[...o],anyDecoded:u,truncated:s,nodes:p,maxDepthSeen:f}}var De=["hidden_text_carrier","injected_turn_boundary","mixed_script_token","nested_encoding_payload"],sn=Object.freeze(["hidden_text_carrier","injected_turn_boundary","mixed_script_token"]),ln=8,cn=new Set([173,8203,8204,8205,8206,8207,8288,65279,8234,8235,8236,8237,8238,8294,8295,8296,8297]),Ae=e=>e!==void 0&&(e>=65&&e<=90||e>=97&&e<=122);function un(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||cn.has(i)&&Ae(t[r-1])&&Ae(t[r+1])&&(n++,n>=ln))return!0}return!1}var dn=/^[ \t]*(?:system|assistant|developer|user)[ \t]*:/i;function pn(e){let t=e.split(/\r?\n/),n=!1;for(let r of t){if(dn.test(r)){if(n)return!0;continue}r.trim().length>0&&(n=!0)}return!1}var fn=[{name:"latin",lo:65,hi:591},{name:"greek",lo:880,hi:1023},{name:"cyrillic",lo:1024,hi:1279}];function mn(e){for(let t of fn)if(e>=t.lo&&e<=t.hi)return t.name;return null}function gn(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=mn(a.codePointAt(0));if(o===null){i=!1;break}o==="latin"?n++:Re(a)!==a&&r++}if(i&&n>0&&r>0)return!0}return!1}var ke=Object.freeze({signals:[],contributes:!1});function hn(e){if(typeof e!="string"||e.length===0)return{...ke,signals:[]};let t=new Set;try{un(e)&&t.add("hidden_text_carrier"),pn(e)&&t.add("injected_turn_boundary"),gn(e)&&t.add("mixed_script_token");let{anyDecoded:n,maxDepthSeen:r,truncated:i}=Pe(e);n&&(r>=2||i)&&t.add("nested_encoding_payload")}catch{return{...ke,signals:[]}}return{signals:[...De.filter(n=>t.has(n))],contributes:sn.some(n=>t.has(n))}}var j=[{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 Ie(e){return typeof e!="string"||e.length===0?[]:j.filter(({re:t})=>t.test(e)).map(({name:t})=>t)}function _n(e){if(typeof e!="string"||e.length===0)return[];let t=new Set(Ie(e)),{views:n}=Pe(e);for(let r of n)for(let i of Ie(r))t.add(i);return j.filter(r=>t.has(r.name)).map(r=>r.name)}function yn(e){let t=new Set,n=new Set,r=!1,i=a=>{if(a!=null){if(typeof a=="string"){for(let l of _n(a))t.add(l);let o=hn(a);for(let l of o.signals)n.add(l);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:j.filter(a=>t.has(a.name)).map(a=>a.name),structural:De.filter(a=>n.has(a))}}function bn(e){return yn(e).matched}var Qr=j.map(e=>e.name);var vn=new Set(["untrusted","external","public","public_internet","external_third_party","web"]);var wn="i:injection";function Me(e){let t=new Set;if(e.content!==void 0&&e.content!==null){let{detectors:i}=Vt(e.content);for(let a of i){let o=J[a]?.category;o&&t.add(`c:${o}`)}bn(e.content)&&t.add(wn)}let n=e.resourceMetadata??{},r=n.source_trust;return(n.untrusted_source===!0||typeof r=="string"&&vn.has(r.toLowerCase()))&&t.add("i:untrusted"),[...t].sort()}var H="(?: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))",Xr=[{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${H}\\b`,"i")},{name:"what_is_prompt",re:new RegExp(`\\bwhat\\s+(?:is|are|were)\\b[\\s\\S]{0,20}?\\b${H}\\b`,"i")},{name:"tell_me_prompt",re:new RegExp(`\\b(?:tell|give|send|show)\\s+me\\b[\\s\\S]{0,30}?\\b${H}\\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}],Se="(?:instructions?|prompts?|rules?|directives?|guidelines?|constraints?|guardrails?)",An=`(?:(?:all\\s+|any\\s+|the\\s+|these\\s+|those\\s+)*(?:previous|prior|preceding|earlier|above|foregoing|initial|original|system|developer)\\s+${Se}|your\\s+(?:(?:system|initial|original|previous|prior|current)\\s+)?(?:${Se}|programming|training))`,kn="(?:(?:all|any|every|the|of|and|now|please|completely|entirely|totally|immediately)\\s+){0,3}",K="(?:\\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|\\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)",In="(?:ignore|disregard|forget|override|overrule|bypass|act|behave|respond|reply|answer|pretend|roleplay|role-play|assume|impersonate|only|always|never|no\\s+longer|instead|obey|comply\\s+with|follow\\s+(?:only|my|these))",ei=[{name:"override_instructions",re:new RegExp(`\\b(?:ignore|disregard|forget|discard|override|overrule|bypass|delete|erase)\\s+${kn}${An}\\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}?${K}`,"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)\\s+(?:${In}|(?:a|an|the)\\b[\\s\\S]{0,40}?${K}|${K})`,"i")},{name:"new_instructions_header",re:/^\s*(?:[#*>-]+\s*)?(?:new|real|actual|true|secret|hidden|override)\s+(?:system\s+)?(?:instructions?|prompts?|directives?)\s*:/im}];var ti=Object.freeze({"\u2019":"'",\u02BC:"'","\uFF07":"'","\u02B9":"'","\u2032":"'"});var b=e=>`[^.!?;\\n]{0,${e}}?`,Sn=["\\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("|"),Fe="(?: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)",ni=Object.freeze([{id:"capability_denial",class:"strong",re:new RegExp([`(?:${Sn})\\s${b(40)}\\b${Fe}\\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${b(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${b(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${b(24)}\\b(?:do(?:es)?\\s+not\\s+(?:allow|permit)|prohibit|forbid|prevent)\\b`,`\\bnot\\s+(?:permitted|allowed|authori[sz]ed)\\s+(?:under|by)\\s${b(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${b(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")}]),ri=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${b(60)}\\b(?:i\\s+(?:can|could)(?!'t)\\s${b(30)}\\b${Fe}\\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 T=e=>`[^.!?;\\n]{0,${e}}?`,ii=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${T(20)}\\b(?:payment|refund|invoice|transfer|purchase\\s+order)s?\\b`,"i"),new RegExp(`\\b(?:move|transfer)\\s${T(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${T(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${T(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${T(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 Z="[REDACTED]",I="\u2022",F=e=>/[A-Za-z0-9]/.test(e);function je(e,t,n,r){let i=Array.from(e),a=i.length,o=Math.max(0,Math.floor(t)||0),l=Math.max(0,Math.floor(n)||0),u=r.length>0?r:I,s=o+l>=a;return i.map((p,f)=>!s&&(f<o||f>=a-l)?p:F(p)?u:p).join("")}function En(e,t){let n=e.indexOf("@");if(n<=0||n>=e.length-1)return je(e,0,0,t);let r=e.slice(0,n),i=e.slice(n),a=t.length>0?t:I;return(r.length<=1?a:r[0]+Array.from(r.slice(1)).map(o=>F(o)?a:o).join(""))+i}function Cn(e,t,n){let r=n.length>0?n:I,i=new Array(e.length).fill(!1);if(typeof t=="string"&&t.length>0)try{let s=new RegExp(t,"g"),p;for(;(p=s.exec(e))!==null;){if(p[0].length===0){s.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 s=0;s<e.length;s++)if(F(e[s])&&(a=!0,!i[s])){o=!1;break}let l=a&&o,u="";for(let s=0;s<e.length;s++){let p=e[s];!l&&i[s]||!F(p)?u+=p:u+=r}return u}function Ue(e,t){let n=t.mode??"full";return n==="partial"?je(e,t.keepFirst??0,t.keepLast??0,t.maskChar??I):n==="email"?En(e,t.maskChar??I):n==="custom"?Cn(e,t.keepPattern,t.maskChar??I):t.replacement??Z}function Tn(e,t){return typeof e=="string"?Ue(e,t):t.replacement??Z}function Be(e){let t=[],n=e.replacement??Z;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=>Ue(a,r)})}return t}function qe(e,t){let n=e;for(let{source:r,replacer:i}of t){let a;try{a=new RegExp(r,"g")}catch(o){let l=o instanceof Error?o.message:String(o);throw new Error(`[visiq-redact] Invalid redaction pattern "${r}": ${l}`)}n=n.replace(a,o=>i(o))}return n}function Q(e,t){return e==null?e:typeof e=="string"?xn(e,t):typeof e=="object"?On(e,t):e}function xn(e,t){if(typeof e!="string")return e;let n=Be(t);return n.length===0?e:qe(e,n)}function On(e,t){let n=new Map;for(let l of t.fields??[])typeof l=="string"&&l.length>0&&n.set(l,{field:l,mode:"full",replacement:t.replacement});for(let l of t.directives??[])typeof l.field=="string"&&l.field.length>0&&n.set(l.field,l);let r=Be(t),i=n.size>0,a=r.length>0,o=l=>{if(l==null)return l;if(Array.isArray(l))return l.map(u=>o(u));if(typeof l=="object"){let u=l,s=Object.create(Object.getPrototypeOf(u));for(let p of Object.keys(u)){let f=i?n.get(p):void 0;if(f){s[p]=Tn(u[p],f);continue}s[p]=o(u[p])}return s}return typeof l=="string"&&a?qe(l,r):l};return o(e)}import{z as c}from"zod";import*as g from"node:os";import{randomUUID as qn}from"node:crypto";var Ge="X-VisIQ-SDK",Ve="X-VisIQ-Dialect",We="unknown";function X(e,t=1){return{[Ge]:e&&e.length>0?e:We,[Ve]:String(t)}}var He="interceptor_source",Nn=c.enum(["enforce","audit","off"]),Rn=c.enum(["closed","open"]),Ke=c.enum(["enforce","monitor","off"]),$n=c.object({apiKey:c.string().min(1,"apiKey is required"),agentId:c.string().min(1,"agentId is required"),endpoint:c.string().url().optional(),mode:Nn.optional(),timeoutMs:c.number().int().positive().optional(),hitlTimeoutMs:c.number().int().positive().optional(),failBehavior:Rn.optional()}),si=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(),telemetry:c.record(c.unknown()).optional()}),Ln=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()}),Pn=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:Ke.optional(),arg_redaction_rules:c.array(Ln).optional(),plane:c.string().nullable().optional(),operation:c.string().nullable().optional(),is_retrieval:c.boolean().optional(),metadata:c.record(c.unknown()).optional()}),Dn=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())])}),Mn=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(Dn).default([]),priority:c.number().int().default(0)}),Fn=c.object({version:c.string().min(1),agent_mode:Ke.optional(),rules:c.array(Mn),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()}),jn=2e3,Ye=class{config;originalFetch;constructor(e,t){this.config=e,this.originalFetch=t}versionHeaders(){return X(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 Pn.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 Fn.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,l=o.hitl_result;if(l==="approved")return{decision_id:e,decision:"permit",reason:"Approved by human reviewer"};if(l==="rejected")return{decision_id:e,decision:"deny",reason:typeof o.reason=="string"?o.reason:"Rejected by human reviewer"};if(l==="timeout"||l==="expired")return{decision_id:e,decision:"deny",reason:"HITL approval timed out"};await Un(jn)}return{decision_id:e,decision:"deny",reason:"HITL approval timed out"}}};function Un(e){return new Promise(t=>setTimeout(t,e))}function Je(){let e={};try{let t=`${g.platform()} ${g.release()}`.trim();t&&(e.os=t)}catch{}try{let t=g.hostname();t&&(e.hostname=t)}catch{}try{let{username:t}=g.userInfo();t&&(e.username=t)}catch{}try{let t=Bn();t&&(e.ip=t)}catch{}return e}function Bn(){let e=g.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 ze=new Map;function zn(e){let t=(ze.get(e)??0)+1;return ze.set(e,t),t}function ee(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:qn(),agentId:t.agentId,sessionId:r,threadId:t.agentId,parentId:t.agentId,seq:zn(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 pi}from"crypto";import{createHash as hi}from"crypto";var Gn=["tier1","tier2","tier3"];function et(e){return typeof e=="string"&&Gn.includes(e)}var Vn=["read_only","transactional","data_processor","external_comms","code_exec","privileged"],Wn=["internal","customer_facing","experimental","third_party"],tt=[...Vn,...Wn];function Hn(e){return typeof e=="string"&&tt.includes(e)}function nt(e){let t=new Set;for(let n of e)Hn(n)&&t.add(n);return tt.filter(n=>t.has(n))}var Kn=["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 rt(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 Yn={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 Jn(e){let t=rt(e);return t===null?"other":Yn[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 Ze={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 Zn(e){let t=rt(e);return t===null?"other":Ze[t]??Ze[t.replace(/_/g,"")]??"other"}function te(e,t){let n={...e};if(t.action!==void 0&&t.action!==null&&n.action_class===void 0&&(n.action_class=Jn(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=Zn(t.targetApp)),n.context=r}return n}var Qe=64,Qn=64,O={retrieved_data_categories:[],retrieved_classifications:[],taint:[],action_classes:[],action_counts:{},denied_count:0,inhibited_count:0,event_count:0,target_apps:[]};function it(){return{retrieved_data_categories:[],retrieved_classifications:[],taint:[],action_classes:[],action_counts:{},denied_count:0,inhibited_count:0,event_count:0,target_apps:[]}}var Xn=new Set(["deny","approval_required","escalate"]);function x(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>Qe?r.slice(0,Qe):r}function Xe(e){return e?e.filter(t=>typeof t=="string"&&t.length>0):[]}function U(e){return typeof e=="string"&&e.length>0?e:null}function at(e,t){let n=Xe(t.data_categories),r=U(t.classification),i=Xe(t.taint),a=U(t.action_class),o=a&&Kn.includes(a)?a:null,l=U(t.target_app),u=U(t.decision),s={...e.action_counts};if(o)if(o in s)s[o]=(s[o]??0)+1;else if(Object.keys(s).length<Qn)s[o]=1;else{let p=Object.keys(s).sort(),f=p[p.length-1];f!==void 0&&o<f&&(delete s[f],s[o]=1)}return{retrieved_data_categories:x(e.retrieved_data_categories,n),retrieved_classifications:x(e.retrieved_classifications,r?[r]:[]),taint:x(e.taint,i),action_classes:x(e.action_classes,o?[o]:[]),action_counts:s,denied_count:e.denied_count+(u==="deny"?1:0),inhibited_count:e.inhibited_count+(u&&Xn.has(u)?1:0),event_count:e.event_count+1,target_apps:x(e.target_apps,l?[l]:[])}}var ot="generic",st=[{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:ot,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."}],er=st.map(e=>e.id),fi=new Map(st.map(e=>[e.id,e])),mi=new Set(er);function lt(e){return Array.isArray(e)&&e.length>0?[...e]:[ot]}var tr=/^[a-z][a-z0-9_]*$/;function ct(e){if(!Array.isArray(e))return[];let t=[],n=new Set;for(let r of e)typeof r=="string"&&tr.test(r)&&!n.has(r)&&(n.add(r),t.push(r));return t}var nr=["narrow","moderate","broad","unbounded","unknown"];function ut(e){return typeof e=="string"&&nr.includes(e)}function dt(e){return e==="open"||e==="closed"?e:null}var rr=["action","retrieval","delegation"];function ir(e){return typeof e=="string"&&rr.includes(e)}var ar=new Set(["rules"]);function pt(e){if(typeof e.id!="string"||typeof e.vendor_id!="string")return null;let t=typeof e.origin_table=="string"?e.origin_table:"";if(!ar.has(t))return null;let n=Array.isArray(e.applies_to)?e.applies_to.filter(ir):[];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 B}from"zod";var ft=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:ft(t.content.text)}),t.spawn?.prompt!==void 0&&(t.spawn={...t.spawn,prompt:ft(t.spawn.prompt)}),t}function sr(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 lr=1440*60*1e3,cr="VISIQ_BUNDLE_GRACE_TTL_MS",ur="VISIQ_BUNDLE_CACHE_DISABLED",dr="VISIQ_CACHE_DIR",pr=B.object({graceTtlMs:B.number().int().nonnegative().optional(),disabled:B.boolean().optional(),cacheDir:B.string().min(1).optional()}).strict();function fr(e){return e==null?{}:pr.parse(e)}function mr(e,t=process.env){if(typeof e=="number"&&Number.isInteger(e)&&e>=0)return e;let n=t[cr];if(n!==void 0){let r=Number(n);if(Number.isInteger(r)&&r>=0)return r}return lr}function gr(e,t=process.env){if(typeof e=="boolean")return e;let n=(t[ur]??"").trim().toLowerCase();return n==="1"||n==="true"||n==="yes"}var mt;function hr(){if(mt!==void 0)return mt;try{return typeof process<"u"&&!!process.versions&&!!process.versions.node}catch{return!1}}function _r(e){return JSON.stringify(re(e))}function re(e){if(Array.isArray(e))return e.map(re);if(e!==null&&typeof e=="object"){let t=e,n={};for(let r of Object.keys(t).sort())n[r]=re(t[r]);return n}return e}function yr(e,t,n){let r=n-e.fetchedAt;return r<0?!1:r<=t}function br(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 wt(){if(!hr())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 At(e,t){return e.createHash("sha256").update(_r(t)).digest("hex")}function vr(e,t){let n=t.cacheDir?.trim();if(n)return n;let r=process.env[dr]?.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 wr(e,t){return e.crypto.createHash("sha256").update(`${t.endpoint}\0${t.agentId}\0${t.apiKey}`).digest("hex")}function kt(e,t,n){return e.path.join(vr(e,n),"bundles",`${wr(e,t)}.json`)}async function Ar(e,t,n,r={}){let i=await wt();if(i)try{let a=kt(i,e,r),o=i.path.dirname(a);await i.fs.mkdir(o,{recursive:!0,mode:448});let l={fetchedAt:r.now??Date.now(),version:n,contentHash:At(i.crypto,t),body:t},u=`${a}.tmp-${process.pid}-${i.crypto.randomBytes(6).toString("hex")}`;await i.fs.writeFile(u,JSON.stringify(l),{mode:384});try{await i.fs.rename(u,a)}catch(s){throw await i.fs.rm(u,{force:!0}).catch(()=>{}),s}}catch{}}async function kr(e,t={}){let n=await wt();if(!n)return null;try{let r=await n.fs.readFile(kt(n,e,t),"utf-8"),i=br(JSON.parse(r));return!i||At(n.crypto,i.body)!==i.contentHash?null:i}catch{return null}}var N;async function Ir(){if(N!==void 0)return N;try{let e=await import("@visiq/core-wasm"),t=e.evaluate??e.default?.evaluate;N=typeof t=="function"?t:null}catch{N=null}return N}var Sr=5e3,Er=1e4,Cr=25,gt=1e3,Tr=5e3,xr=100,ht=2e3,Or=512,Nr=1800*1e3,Rr="monitor",$r="Agent has been shut down by an operator \u2014 all actions are blocked (G001)",_t="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.",Lr="open";function yt(e){if(typeof e!="string")return;let t=e.trim().toLowerCase();return t==="open"||t==="closed"?t:void 0}function Pr(e,t){return Me({content:e,resourceMetadata:t})}var Dr=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()}),Mr=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())),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 Fr(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=lt(ct(n));return{trust_tier:et(t)?t:null,categories:nt(e.categories??[]),business_functions:r,business_function:r[0]??null,blast_radius_tier:typeof e.blast_radius_tier=="string"&&ut(e.blast_radius_tier)?e.blast_radius_tier:null}}function jr(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 Ur(e){return e==="permit"?"permit":e==="mask"||e==="redact"?"mask":e==="approval_required"||e==="escalate"?"approval_required":"deny"}var ie=new Set,bt=!1;async function vt(e){let t=[];for(let n of ie){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 Br(){if(!bt&&!(typeof process>"u"||typeof process.once!="function")){bt=!0,process.once("beforeExit",()=>{vt(!1)});for(let e of["SIGINT","SIGTERM"])process.once(e,()=>{(async()=>{try{await vt(!0)}finally{process.kill(process.pid,e)}})()})}}var It=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=Rr;agentModeByOperation=null;rawBundle=null;agentModeConfirmed=!1;operatorShutdown=!1;bundleApplyFailed=!1;dialectRefused=!1;failMode=yt(typeof process<"u"?process.env?.VISIQ_FAIL_MODE:void 0)??Lr;governedFailMode=null;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,l){let u=e??process.env.VISIQ_API_KEY??process.env.ALLOW_API_KEY??process.env.VISIQ_ALLOW_API_KEY,s=t??process.env.VISIQ_ENDPOINT??process.env.ALLOW_ENDPOINT,p=n??process.env.VISIQ_AGENT_ID??process.env.ALLOW_AGENT_ID??"";this.resolvedApiKey=u,this.resolvedEndpoint=s,this.resolvedAgentId=p,this.harnessKind=r,this.sdkVersion=a,this.sdkDialect=o,this.originalFetch=globalThis.fetch.bind(globalThis);let f=fr(l);if(this.bundleCacheDisabled=gr(f.disabled),this.bundleGraceTtlMs=mr(f.graceTtlMs),this.bundleCacheDirOverride=f.cacheDir,this.cacheIdentity=u&&s&&!this.bundleCacheDisabled?{endpoint:s,agentId:p,apiKey:u}:null,u&&s){let h={apiKey:u,agentId:p,endpoint:s,mode:"enforce",timeoutMs:sr(i),hitlTimeoutMs:12e4,failBehavior:"closed",...r?{harnessKind:r}:{},...a!==void 0?{sdkVersion:a}:{},...o!==void 0?{sdkDialect:o}:{}};this.client=new Ye(h,this.originalFetch),this.initialBundlePromise=this.initialBundleLoad(),this.refreshTimer=setInterval(()=>{this.fetchBundleBackground()},Sr),ne(this.refreshTimer),this.telemetryTimer=setInterval(()=>{this.flushTelemetry()},Er),ne(this.telemetryTimer),this.cognitionTimer=setInterval(()=>{this.flushCognition()},Tr),ne(this.cognitionTimer),ie.add(this),Br()}else this.client=null}async evaluate(e){let t=Dr.parse(e),n=Date.now();if(this.operatorShutdown){let s=this.denyAll(t,$r);return this.applyAgentMode(s,"enforce",t,n)}if(this.dialectRefused){if(this.failMode==="open")return this.failOpen(t,_t,n);let s=this.denyAll(t,_t);return this.applyAgentMode(s,"enforce",t,n)}if(t.operations.every(s=>this.modeFor(s)==="off"))return this.offDecision(t);if(!this.bundleLoaded){let s;if(this.agentModeConfirmed?s=this.agentMode:this.bundleApplyFailed?s="enforce":s="monitor",s==="enforce"&&this.failMode==="open")return this.failOpen(t,"no unified bundle loaded and no local rules",n);let p=this.denyAll(t,"No unified bundle loaded and no local rules \u2014 fail-closed (G001)");return this.applyAgentMode(p,s,t,n)}let r=this.readSession(t.sessionId),i=await Ir();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")?te(t.normalized??{},{action:t.toolName??"",targetApp:t.targetResource??t.toolName??""}):t.normalized,o={...t,normalized:a,session:r,at:Date.now()},l={...this.rawBundle,agent_mode:this.agentMode,...this.agentModeByOperation?{agent_mode_by_operation:this.agentModeByOperation}:{}},u;try{u=i(o,l)}catch(s){if(this.failMode==="open")return this.failOpen(t,`governance core evaluation threw: ${s instanceof Error?s.message:String(s)}`,n);throw s}return this.foldSession(t,u.enforced?u.decision:"permit"),u.enforced&&u.action.decision==="approval_required"&&await this.registerHitl(t,u),this.bufferTelemetry(t,u,Date.now()-n,u.enforced),u}modeFor(e){return this.agentModeByOperation?.[e]??this.agentMode}readSession(e){if(!e)return O;let t=this.sessions.get(e);return t?Date.now()-t.touchedAt>Nr?(this.sessions.delete(e),O):t.state:O}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"),l=o?te(e.normalized??{},{action:e.toolName??"",targetApp:e.targetResource??e.toolName??""}):e.normalized??{},u=at(r===O?it():r,{data_categories:a&&Array.isArray(i.data_categories)?i.data_categories:void 0,classification:a?i.classification:void 0,taint:a?Pr(e.contentPreview,i):void 0,action_class:o?l.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:u,touchedAt:Date.now()}),this.sessions.size>Or){let s=this.sessions.keys().next().value;s!==void 0&&this.sessions.delete(s)}}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??{}}:{},...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=Mr.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=>pt(r)).filter(r=>r!==null),this.agentAttributes=t.agent_attributes?Fr(t.agent_attributes):null,this.agentNoCoverage=dt(t.agent_attributes?.no_coverage),this.governedFailMode=yt(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=jr(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",...X(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 kr(this.cacheIdentity,{...this.bundleCacheDirOverride?{cacheDir:this.bundleCacheDirOverride}:{}})}catch{return}if(!e)return;let t=Date.now();if(yr(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 Ar(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){this.registerEnvironment({...Je(),...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,i=!1){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?Ur(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||i?{context:{...this.harnessKind?{[He]:this.harnessKind}:{},...e.context??{},...i?{fail_open:!0}:{}}}:{}}),this.enforceTelemetryCap(),this.telemetryBuffer.length>=Cr&&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-gt;e>0&&(this.telemetryBuffer.splice(0,e),console.warn(`[UnifiedRuntime] telemetry buffer full \u2014 dropped ${e} oldest entries (cap ${gt})`))}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-ht;e>0&&(this.cognitionBuffer.splice(0,e),console.warn(`[UnifiedRuntime] cognition buffer full \u2014 dropped ${e} oldest beats (cap ${ht})`))}async flush(){if(this.registerPromise)try{await this.registerPromise}catch{}await this.flushTelemetry(),await this.flushCognition()}async shutdown(){await this.flush(),this.dispose(),ie.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 ne(e){e&&typeof e=="object"&&"unref"in e&&e.unref()}function q(e){return typeof e=="string"&&e.trim().length>0?e:void 0}function St(e,t){if(e!=="Task"&&e!=="Agent")return null;let n=q(t.description),r=q(t.subagent_type),i=q(t.prompt),a=n??r??"sub-agent";return{childAgentId:a,childName:a,kind:"subagent",agentType:r,description:n,task:i,goal:i,model:q(t.model),source:"structural"}}function Et(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 ae(e){let t=[],n=[],r,i=[];for(let o of e){if(o.mode==="partial"||o.mode==="email"||o.mode==="custom"){let u={mode:o.mode};o.field&&(u.field=o.field),o.pattern&&(u.pattern=o.pattern),typeof o.keepFirst=="number"&&(u.keepFirst=o.keepFirst),typeof o.keepLast=="number"&&(u.keepLast=o.keepLast),o.maskChar&&(u.maskChar=o.maskChar),o.keepPattern&&(u.keepPattern=o.keepPattern),o.replacement!==void 0&&(u.replacement=o.replacement),i.push(u);continue}o.field&&t.push(o.field),o.pattern&&n.push(o.pattern);let{replacement:l}=o;l&&r===void 0&&(r=l)}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 qr="[VisIQ: retrieval withheld by policy]";function z(e){return oe(e)}function oe(e){if(e==null)return e;if(typeof e=="string")return e.length>0?qr:e;if(typeof e=="number")return 0;if(typeof e=="boolean")return!1;if(Array.isArray(e))return e.map(oe);if(typeof e=="object"){let t=Object.create(null);for(let n of Object.keys(e))t[n]=oe(e[n]);return t}return e}function Ct(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 Tt(e,t){if(!e.enforced)return null;let{action:n,retrieval:r}=e,i=w(e.reason,e.ruleCode);if(n.decision==="deny"||r.action==="deny")return M(i);if(n.decision==="approval_required"||r.action==="escalate")return _e(i);if(n.decision==="mask"&&n.argRedactionRules&&n.argRedactionRules.length>0){let a=ae(n.argRedactionRules);if(Ct(a)){let o=Q(t,a)??t;if(JSON.stringify(o)!==JSON.stringify(t))return he(o)}return null}return null}function xt(e,t){if(!e.enforced)return null;let{retrieval:n}=e,r=w(e.reason,e.ruleCode);if(n.action==="redact"){let i=ae(n.redactionRules??[]);if(!Ct(i))return k(z(t),r);let a=Q(t,i);return JSON.stringify(a)===JSON.stringify(t)?null:k(a,r)}return n.action==="deny"?k(z(t),r):null}var zr="cli_harness";function S(e){let t=new It(e.apiKey,e.baseUrl,e.agentId,zr);return t.setFailMode(e.failMode),t}function G(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 E(e,t,n=ce){let{agentId:r}=t,i=await de(r);if(i&&ue(i,n,Date.now())&&se(e,i.body))return!0;let a=e.getEndpoint();if(a){let o=await fe(a,t.apiKey,r);if(o&&se(e,o.body))return await pe(r,o.body,o.version),!0}if(i&&se(e,i.body))return!0;try{await e.awaitBundleReady(2500)}catch{}return e.isBundleLoaded()}function se(e,t){try{return e.applyBundle(t),!0}catch{return!1}}async function C(e){try{await e.flush()}catch{}try{e.dispose()}catch{}}async function Ui(e,t){let n=S(t),r=e.tool_input??{};try{if(await me(e.session_id)||(n.registerHostEnvironment(),await L(e.session_id)),!await E(n,t)&&t.failMode!=="closed")return await v({stage:"no-bundle",detail:"no rule bundle available (cache empty + fetch failed)",toolName:e.tool_name,sessionId:e.session_id}),null;let a=St(e.tool_name,r),o=ge(e.tool_name),l;a&&(ee(n,{agentId:t.agentId,sessionId:e.session_id,framework:"claude-code"},a),o=Array.from(new Set([...o,"delegation"])),l=Et(a,t.agentId));let u=G({operations:o,agentId:t.agentId,toolName:e.tool_name,toolInput:r,sessionId:e.session_id,cwd:e.cwd,toolUseId:e.tool_use_id,query:D(r),...l?{context:l}:{}}),s=await n.evaluate(u);return await P(s,{toolName:e.tool_name,sessionId:e.session_id}),Tt(s,r)}catch(i){return t.failMode==="closed"?M(w("evaluation error \u2014 blocked (VISIQ_FAIL_MODE=closed)",null)):(await v({stage:"pre-eval-error",detail:i instanceof Error?i.message:String(i),toolName:e.tool_name,sessionId:e.session_id}),null)}finally{await C(n)}}async function Hi(e,t){if(!W(e.tool_name))return null;let n=S(t);try{if(!await E(n,t)&&t.failMode!=="closed")return await v({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=G({operations:["retrieval"],agentId:t.agentId,toolName:e.tool_name,toolInput:i,sessionId:e.session_id,cwd:e.cwd,toolUseId:e.tool_use_id,query:D(i)}),o=await n.evaluate(a);return await P(o,{toolName:e.tool_name,sessionId:e.session_id}),xt(o,e.tool_response)}catch(r){return t.failMode==="closed"?k(z(e.tool_response),w("evaluation error \u2014 withheld (VISIQ_FAIL_MODE=closed)",null)):(await v({stage:"post-eval-error",detail:r instanceof Error?r.message:String(r),toolName:e.tool_name,sessionId:e.session_id}),null)}finally{await C(n)}}async function Zi(e,t){let n=S(t);try{n.registerHostEnvironment(),await E(n,t,0),await L(e.session_id)}finally{await C(n)}return null}export{Lt as a,v as b,Mt as c,W as d,ge as e,D as f,w as g,he as h,M as i,_e as j,k,Yr as l,qr as m,z as n,Tt as o,xt as p,zr as q,S as r,G as s,E as t,C as u,Ui as v,Hi as w,Zi 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{g as r,j as u,t as c,u as l,v as d}from"../chunk-IT2RXQ74.js";import{e as a}from"../chunk-3GWLCI47.js";var p=process.env.VISIQ_DEBUG==="1",m=p?(...o)=>{process.stderr.write(`${o.map(String).join(" ")}
3
- `)}:()=>{},P=console;for(let o of["log","info","debug","warn","error"])P[o]=m;var h={handlePre:(o,e)=>c(o,e),handlePost:(o,e)=>l(o,e),handleSession:(o,e)=>d(o,e),write:o=>{process.stdout.write(o)}};async function f(o,e,s=h){let t=o.hook_event_name==="PreToolUse",i=n=>{t&&s.write(JSON.stringify(r(n)))};try{let n=null;switch(o.hook_event_name){case"PreToolUse":n=await s.handlePre(o,e);break;case"PostToolUse":n=await s.handlePost(o,e);break;case"SessionStart":n=await s.handleSession(o,e);break;default:n=null}n&&s.write(JSON.stringify(n))}catch(n){i(`[VisIQ] harness error (fail-closed): ${n instanceof Error?n.message:String(n)}`)}}function g(){return new Promise(o=>{if(process.stdin.isTTY){o("");return}let e=[],s=!1,t=()=>{s||(s=!0,o(Buffer.concat(e).toString("utf-8")))};setTimeout(t,15e3).unref?.(),process.stdin.on("data",n=>e.push(n)),process.stdin.on("end",t),process.stdin.on("error",t)})}async function w(){let o=u(await g());if(!o)return;let e=o.hook_event_name==="PreToolUse",s=i=>{e&&process.stdout.write(JSON.stringify(r(i)))},t=await a();if(!t){s("[VisIQ] Claude Code harness is loaded but NOT configured \u2014 set VISIQ_API_KEY + VISIQ_ENDPOINT so VisIQ can govern this tool call. Blocked (fail-closed) until configured.");return}await f(o,t)}w().then(()=>process.exit(0)).catch(()=>{try{process.stdout.write(JSON.stringify(r("[VisIQ] harness crashed before evaluating the call \u2014 blocked (fail-closed).")))}catch{}process.exit(0)});
2
+ import{b as a,i,l as p,v as f,w as m,x as I}from"../chunk-HI63J7G3.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{a as l,b as u,c as g,e as p,i as y}from"../chunk-3GWLCI47.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)}
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
@@ -1,3 +1,5 @@
1
+ import { z } from 'zod';
2
+
1
3
  /**
2
4
  * Credential + config-dir resolution for the VisIQ Claude Code harness.
3
5
  *
@@ -17,16 +19,33 @@
17
19
  * null when creds are absent; hooks treat null as "unconfigured → fail-open
18
20
  * no-op" so an installed-but-unconfigured harness never breaks Claude Code.
19
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;
20
31
  export interface VisiqConfig {
21
32
  apiKey: string;
22
33
  agentId: string;
23
34
  baseUrl?: string;
35
+ failMode: FailMode;
24
36
  }
25
37
  export interface PartialConfig {
26
38
  apiKey?: string;
27
39
  agentId?: string;
28
40
  baseUrl?: string;
41
+ failMode?: FailMode;
29
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;
30
49
  /**
31
50
  * The VisIQ harness state directory (config + bundle cache + session markers).
32
51
  * Overridable via VISIQ_HOME (used by tests + the conformance harness to
@@ -42,50 +61,22 @@ export declare function envConfig(env?: NodeJS.ProcessEnv): PartialConfig;
42
61
  * config). Pure — split out so it can be unit-tested without disk I/O.
43
62
  */
44
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>;
45
75
  /**
46
76
  * Resolve harness credentials following the precedence chain. Returns null when
47
77
  * apiKey/agentId cannot be resolved. Never throws.
48
78
  */
49
79
  export declare function loadConfig(): Promise<VisiqConfig | null>;
50
- /**
51
- * Claude Code tool taxonomy — action vs retrieval classification.
52
- *
53
- * VisIQ governs two facets per tool call:
54
- * - ACTION — side-effecting tools (shell, file writes, MCP mutations)
55
- * - RETRIEVAL — tools that pull external/foreign content INTO the model's
56
- * context (web fetch/search, file/dir reads, MCP resource reads)
57
- *
58
- * The set below is the canonical Claude Code built-in tool list (verified
59
- * against the running CLI, v2.1.x — the `tool_name` values a hook receives).
60
- * Retrieval tools are tagged with BOTH facets (`['retrieval','action']`) so an
61
- * action rule (e.g. "block all web egress") also governs them, mirroring the
62
- * OpenClaw plugin's dual-facet tagging. Everything else is a pure action.
63
- *
64
- * Fail-safe posture (G001): an UNKNOWN tool is treated as an ACTION (governed,
65
- * never silently ungoverned). MCP tools whose bare name looks like a read are
66
- * ALSO run through the retrieval facet (fails SAFE toward more governance).
67
- */
68
- /**
69
- * Reduce a possibly-namespaced MCP tool name to its leaf: `mcp__brave__web_search`
70
- * → `web_search`. Non-MCP (and non-string, defensively) names are returned as-is.
71
- */
72
- export declare function bareToolName(toolName: string): string;
73
- /** Does this tool call pull foreign content into the model's context? */
74
- export declare function isRetrievalTool(toolName: string): boolean;
75
- /** Governance facets to evaluate for a given tool. */
76
- export type Operation = "action" | "retrieval" | "delegation";
77
- /**
78
- * The `operations[]` to hand `UnifiedRuntime.evaluate`. Retrieval tools carry
79
- * BOTH facets (an action rule can still govern a fetch); everything else is a
80
- * pure action.
81
- */
82
- export declare function toolOperations(toolName: string): Operation[];
83
- /**
84
- * Extract a human-meaningful query string from a tool's input for retrieval
85
- * evaluation + telemetry. Joins the first-present query-shaped fields; returns
86
- * `undefined` when none are present (so the caller omits `query`).
87
- */
88
- export declare function extractQuery(toolInput: unknown): string | undefined;
89
80
  /**
90
81
  * Server-side per-agent mode. Lives on `allow_agents.mode` and is delivered
91
82
  * to the SDK as `agent_mode` in the rules bundle. The SDK branches on this
@@ -204,6 +195,25 @@ export interface SessionEvalState {
204
195
  retrieved_data_categories: string[];
205
196
  /** Union of resource_metadata.classification tokens over prior retrievals. */
206
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[];
207
217
  /** Distinct action_class buckets attempted earlier in the session. */
208
218
  action_classes: string[];
209
219
  /** Per-action-class attempt counters (prior events only). */
@@ -284,7 +294,9 @@ export interface AgentEnvironment {
284
294
  * The shape mirrors the framework-agnostic `MindEvent` SSOT the Cortex UI reads
285
295
  * (products/project-y/apps/web/src/components/allow/agents/cortex/types.ts).
286
296
  */
287
- export type CognitionBeatKind = "thought" | "speech" | "action" | "observation" | "intervention" | "spawn" | "phase" | "handoff" | "lifecycle" | "error";
297
+ export type CognitionBeatKind = "thought" | "speech" | "action" | "observation" | "intervention" | "spawn" | "phase" | "handoff" | "lifecycle" | "error"
298
+ /** Long/short-term MEMORY access (read/write/search/delete on an agent store). */
299
+ | "memory";
288
300
  export type CognitionVisibility = "shown" | "hidden";
289
301
  export type CognitionProvenance = "signed" | "parsed" | "proxy" | "narration";
290
302
  /** A recognized sub-agent spawn — the Mode-B delegation edge. */
@@ -295,6 +307,45 @@ export interface CognitionSpawn {
295
307
  model?: string;
296
308
  prompt?: string;
297
309
  }
310
+ /**
311
+ * A recognized MEMORY access — the "memory access" clause of the execution-trace
312
+ * contract. STRUCTURAL ENVELOPE ONLY: like {@link CognitionCost}, this is
313
+ * persisted verbatim (the server schema is default-strip, so nothing is left to
314
+ * floor-redact), which means NO free text may ride through it. The human-readable
315
+ * label — the memory key, the search query — travels in the floor-redacted
316
+ * `tool.argSummary` / `content.text` instead.
317
+ *
318
+ * DISPLAY/TRACE ONLY. A memory beat never changes a decision, never adds an
319
+ * `operations[]` tag, and never touches the evaluation core: the same tool call
320
+ * evaluates byte-identically with or without it.
321
+ */
322
+ export interface CognitionMemory {
323
+ op: "read" | "write" | "search" | "delete";
324
+ /** The store the operation targets (`mem0`, `letta-archival`, `mcp-memory`, …). */
325
+ store: string;
326
+ scope?: "session" | "agent" | "user" | "org";
327
+ /** Items returned (search/read) or written (write) — count only, never content. */
328
+ itemCount?: number;
329
+ bytes?: number;
330
+ /** Whether a read/search found anything (a miss is as diagnostic as a hit). */
331
+ hit?: boolean;
332
+ }
333
+ /**
334
+ * Per-model-turn token usage attached to the beat that closes the turn.
335
+ * NUMBERS ONLY — `cost` is persisted verbatim (not floor-redacted at rest), so
336
+ * free text must never ride through it; the server schema strips unknown keys.
337
+ * Dollars are never computed harness-side (field-deployed price tables go
338
+ * stale): consumers price at read time from the token buckets + `beat.model`.
339
+ */
340
+ export interface CognitionCost {
341
+ /** Uncached input tokens (Anthropic `input_tokens` semantics). */
342
+ tokensIn?: number;
343
+ tokensOut?: number;
344
+ cacheRead?: number;
345
+ cacheWrite?: number;
346
+ /** Legal on the wire for forward-compat; no VisIQ producer writes it. */
347
+ usd?: number;
348
+ }
298
349
  export interface CognitionBeat {
299
350
  /** Stable harness-minted id → server dedup key (idempotent re-sends). */
300
351
  clientEventId: string;
@@ -322,14 +373,31 @@ export interface CognitionBeat {
322
373
  phase?: Record<string, unknown>;
323
374
  handoff?: Record<string, unknown>;
324
375
  attribution?: Record<string, unknown>;
325
- cost?: Record<string, unknown>;
376
+ cost?: CognitionCost;
377
+ memory?: CognitionMemory;
326
378
  model?: string;
327
379
  agentRole?: string;
328
380
  framework?: string;
329
381
  }
330
- /** The facets an event participates in (the unified `operations` tag). */
382
+ declare const bundleCacheOptionsSchema: z.ZodObject<{
383
+ /** Grace window in ms; ≥0. 0 ⇒ never serve a stale cache (fallback disabled). */
384
+ graceTtlMs: z.ZodOptional<z.ZodNumber>;
385
+ /** Disable the on-disk cache entirely. */
386
+ disabled: z.ZodOptional<z.ZodBoolean>;
387
+ /** Base cache directory override. */
388
+ cacheDir: z.ZodOptional<z.ZodString>;
389
+ }, "strict", z.ZodTypeAny, {
390
+ graceTtlMs?: number | undefined;
391
+ disabled?: boolean | undefined;
392
+ cacheDir?: string | undefined;
393
+ }, {
394
+ graceTtlMs?: number | undefined;
395
+ disabled?: boolean | undefined;
396
+ cacheDir?: string | undefined;
397
+ }>;
398
+ export type BundleCacheOptions = z.infer<typeof bundleCacheOptionsSchema>;
399
+ type FailMode$1 = "open" | "closed";
331
400
  export type UnifiedOperation = "retrieval" | "action" | "delegation";
332
- /** One governed agent event, tagged with the facets it participates in. */
333
401
  export interface UnifiedEvaluateEvent {
334
402
  /** Which facets this event participates in (≥1). */
335
403
  operations: UnifiedOperation[];
@@ -430,6 +498,17 @@ export interface UnifiedDecision {
430
498
  agentMode: AgentMode;
431
499
  action: UnifiedActionSubDecision;
432
500
  retrieval: UnifiedRetrievalSubDecision;
501
+ /**
502
+ * True ONLY for a fail-open PERMIT — a harness-INTERNAL failure (dialect
503
+ * refusal, no bundle, core unavailable) that ran ungoverned under
504
+ * failMode=open. The runtime also echoes this to stderr via `console.error`,
505
+ * but a host that has silenced `console` (e.g. the Claude Code hook harness,
506
+ * which must keep stdout/stderr clean for its JSON protocol) MUST inspect
507
+ * this structured flag to satisfy the "mandatory loud telemetry" contract —
508
+ * console.error alone is not observable there. Absent/false on every other
509
+ * decision (real policy verdicts, agent_mode=off, cold-start deny).
510
+ */
511
+ failOpen?: boolean;
433
512
  }
434
513
  declare class UnifiedRuntime {
435
514
  private readonly client;
@@ -438,6 +517,10 @@ declare class UnifiedRuntime {
438
517
  private readonly resolvedEndpoint;
439
518
  private readonly resolvedAgentId;
440
519
  private readonly harnessKind;
520
+ /** Human-readable SDK version for the `X-VisIQ-SDK` header (undefined → DEFAULT_SDK_VERSION). */
521
+ private readonly sdkVersion;
522
+ /** Wire-contract capability integer for the `X-VisIQ-Dialect` header (undefined → SDK_DIALECT). */
523
+ private readonly sdkDialect;
441
524
  private rules;
442
525
  /** Server-authoritative agent attributes from the bundle (null until shipped). */
443
526
  private agentAttributes;
@@ -464,6 +547,19 @@ declare class UnifiedRuntime {
464
547
  private bundleFetchInProgress;
465
548
  private initialBundlePromise;
466
549
  private refreshTimer;
550
+ /**
551
+ * On-disk bundle cache (grace-TTL outage survival). Persist every successful
552
+ * bundle; on a COLD-START fetch failure, serve the most recent cached bundle
553
+ * IF younger than {@link bundleGraceTtlMs}. Beyond grace / corrupt / absent ⇒
554
+ * the pre-existing cold-start fail-closed deny is preserved EXACTLY (G001).
555
+ * Identity is null (cache off) when no backend creds are configured.
556
+ */
557
+ private readonly cacheIdentity;
558
+ private readonly bundleCacheDisabled;
559
+ private readonly bundleGraceTtlMs;
560
+ private readonly bundleCacheDirOverride;
561
+ /** Guard so the one-time cold-start disk fallback warning isn't re-logged. */
562
+ private diskFallbackServed;
467
563
  private agentMode;
468
564
  /** Optional per-operation mode override, shipped resolved in the bundle:
469
565
  * `{action?, retrieval?, delegation?}` → enforce|monitor|off. An operation
@@ -484,14 +580,46 @@ declare class UnifiedRuntime {
484
580
  * has shut this agent down (notebook item 1). Every {@link evaluate} then
485
581
  * returns an immediate, always-enforced deny-all BEFORE any mode bypass / rule
486
582
  * eval / core call. Set from the bundle on every version change (a normal
487
- * bundle ⇒ false), so reactivation (a fresh non-shutdown bundle) clears it. */
488
- private shutdown;
583
+ * bundle ⇒ false), so reactivation (a fresh non-shutdown bundle) clears it.
584
+ * (Named `operatorShutdown` to leave the public `shutdown()` graceful-drain
585
+ * method — added for HS-4 — an unambiguous name.) */
586
+ private operatorShutdown;
489
587
  /** True when a bundle body was RECEIVED but FAILED to apply (malformed /
490
588
  * schema-drifted / corrupt cache) — an ERROR, distinct from a genuinely
491
589
  * absent bundle. On cold start this fails CLOSED (enforce the deny-all) so a
492
590
  * corrupt or poisoned bundle can never downgrade an agent to the permissive
493
591
  * monitor onboarding fail-safe (G001). Cleared once a body validates. */
494
592
  private bundleApplyFailed;
593
+ /**
594
+ * True when the last bundle required a wire dialect NEWER than this SDK speaks
595
+ * (`min_dialect` > our dialect). Like {@link operatorShutdown} it forces an
596
+ * enforced deny-all on EVERY evaluate — the bundle may carry constructs we
597
+ * cannot honour, so we refuse it wholesale (MUST-UNDERSTAND, G001) rather than
598
+ * apply a subset. Cleared the instant a bundle we CAN speak applies.
599
+ */
600
+ private dialectRefused;
601
+ /**
602
+ * Error posture (owner decision 2026-07-15). Resolved from VISIQ_FAIL_MODE at
603
+ * construction (default `open`); harnesses override via `setFailMode()` with
604
+ * their own resolved config.
605
+ */
606
+ private failMode;
607
+ /**
608
+ * X-FAILMODE: the GOVERNED fail-mode the control plane resolved for this agent,
609
+ * hydrated from the bundle's `agent_attributes.fail_mode` on each apply (null =
610
+ * not present → fall back to the local `failMode`). Stored + exposed
611
+ * (getGovernedFailMode) so the harness can adopt it.
612
+ *
613
+ * FOLLOW-ON (deliberately NOT wired into the decision branches yet): making the
614
+ * EFFECTIVE posture prefer the governed value requires a precedence policy —
615
+ * recommended CLOSED-WINS monotonicity (either a local `VISIQ_FAIL_MODE=closed`
616
+ * break-glass OR a governed `closed` forces closed; neither can force open
617
+ * against the other's closed) — plus the harness leaving `failMode` unset when
618
+ * unconfigured. That change touches the conformance-tested fail-open/closed
619
+ * branches and is its own PR; today `failMode` still comes solely from local
620
+ * env/config.
621
+ */
622
+ private governedFailMode;
495
623
  private telemetryBuffer;
496
624
  private telemetryTimer;
497
625
  private cognitionBuffer;
@@ -505,7 +633,7 @@ declare class UnifiedRuntime {
505
633
  /** Content signature of the last reported tool surface — so a repeat visiq()
506
634
  * wrap (same tools) doesn't re-POST. Null until the first report. */
507
635
  private lastToolSurfaceSig;
508
- constructor(apiKey?: string, endpoint?: string, agentId?: string, harnessKind?: AgentKind, timeoutMs?: number);
636
+ constructor(apiKey?: string, endpoint?: string, agentId?: string, harnessKind?: AgentKind, timeoutMs?: number, sdkVersion?: string, sdkDialect?: number, bundleCache?: BundleCacheOptions);
509
637
  /**
510
638
  * Evaluate one governed agent event across ALL its tagged operations and
511
639
  * return the merged unified decision with both facet sub-decisions.
@@ -525,6 +653,34 @@ declare class UnifiedRuntime {
525
653
  * the would-be `decision` + sub-decisions, with enforced=false.
526
654
  */
527
655
  private applyAgentMode;
656
+ /** Override the error posture (harnesses pass their resolved config's failMode). */
657
+ setFailMode(mode: FailMode$1): void;
658
+ getFailMode(): FailMode$1;
659
+ /** The GOVERNED fail-mode last hydrated from the bundle (null if the bundle
660
+ * carried none). See the governedFailMode field for the pending precedence
661
+ * follow-on. */
662
+ getGovernedFailMode(): FailMode$1 | null;
663
+ /**
664
+ * The LOUD fail-open outcome for a harness-internal failure in `open` mode:
665
+ * a non-enforced permit whose reason names the cause, buffered into
666
+ * telemetry (so the platform can audit every ungoverned call) and echoed to
667
+ * stderr via console.error. Also carries a structured `failOpen: true` flag
668
+ * so a host that has silenced `console` (the Claude Code hook harness) can
669
+ * still surface the mandatory loud telemetry. Policy outcomes never route here.
670
+ */
671
+ private failOpen;
672
+ /**
673
+ * Report a HOOK-LEVEL fail-open — a harness failure that bypassed
674
+ * `evaluate()` entirely (hook wiring threw, config half-resolved, …).
675
+ * Buffers the same `context.fail_open=true` audit row the internal fail-open
676
+ * path produces, so the platform's ungoverned-call audit covers hook-level
677
+ * failures too. Does NOT print (the reporting hook already emitted its own
678
+ * loud stderr line). Fire-and-forget; never throws.
679
+ */
680
+ reportFailOpen(cause: string, ctx?: {
681
+ toolName?: string;
682
+ sessionId?: string;
683
+ }): void;
528
684
  /** The agent_mode=off short-circuit — permit everything, no telemetry. */
529
685
  private offDecision;
530
686
  /** Build a fail-closed deny-all decision for cold start / no-config paths. */
@@ -550,6 +706,28 @@ declare class UnifiedRuntime {
550
706
  */
551
707
  awaitBundleReady(timeoutMs?: number): Promise<void>;
552
708
  private fetchBundleBackground;
709
+ /**
710
+ * The initial bundle load driven at construction: attempt the network fetch
711
+ * first (the authoritative, freshest source), and ONLY if that leaves us with
712
+ * no bundle on a cold start fall back to the on-disk grace cache. This keeps
713
+ * the periodic refresh path ({@link fetchBundleBackground}) network-only, and
714
+ * confines the one-time disk fallback to startup — a warm process never reads
715
+ * the disk cache. Awaited by {@link awaitBundleReady}.
716
+ */
717
+ private initialBundleLoad;
718
+ /**
719
+ * Cold-start fallback: if the initial network fetch failed, serve the most
720
+ * recent on-disk bundle IF it exists, passes its integrity check, AND is
721
+ * younger than the grace window. The disk body is applied through the SAME
722
+ * {@link applyBundle} (Zod envelope validation + min_dialect refusal), so a
723
+ * stale/corrupt/too-new cached bundle can never be applied more permissively
724
+ * than a fresh one. Beyond grace / absent / corrupt ⇒ NOTHING is loaded and
725
+ * the runtime's cold-start fail-closed deny is preserved EXACTLY (G001).
726
+ * Best-effort; never throws.
727
+ */
728
+ private tryLoadFromDiskCache;
729
+ /** Persist the applied bundle body to the on-disk grace cache. Best-effort. */
730
+ private persistBundleToDisk;
553
731
  hasRules(): boolean;
554
732
  hasClient(): boolean;
555
733
  /** The resolved backend endpoint, for callers driving the HITL wait loop. */
@@ -557,6 +735,13 @@ declare class UnifiedRuntime {
557
735
  /** The resolved API key, for callers driving the HITL wait loop. */
558
736
  getApiKey(): string | undefined;
559
737
  getBundleVersion(): string | null;
738
+ /**
739
+ * Has a rule bundle actually been applied? (getBundleVersion() can be null
740
+ * even when loaded.) Callers use this to tell "governed, rules present" from
741
+ * "cold — evaluate() would take the cold-start posture", e.g. to apply a
742
+ * failMode decision instead of surfacing a VisIQ outage as a spurious deny.
743
+ */
744
+ isBundleLoaded(): boolean;
560
745
  getAgentMode(): AgentMode;
561
746
  /** The bundle-shipped server-authoritative agent attributes (null until shipped). */
562
747
  getAgentAttributes(): AgentEvalAttributes | null;
@@ -599,8 +784,69 @@ declare class UnifiedRuntime {
599
784
  private enforceCognitionCap;
600
785
  /** Drain pending registration + telemetry + cognition and await it (graceful shutdown). */
601
786
  flush(): Promise<void>;
787
+ /**
788
+ * Graceful shutdown for a long-running host: drain every pending batch, stop
789
+ * the background timers, and deregister from the process exit-drain set so the
790
+ * runtime can be GC'd. Idempotent; short-lived scripts are covered
791
+ * automatically by the beforeExit / SIGINT / SIGTERM hooks.
792
+ */
793
+ shutdown(): Promise<void>;
602
794
  dispose(): void;
603
795
  }
796
+ /** Where fail-open events are appended (one JSON line per event). */
797
+ export declare function failOpenLogPath(): string;
798
+ export interface FailOpenEvent {
799
+ /** Which guard failed open (e.g. `unconfigured`, `no-bundle`, `pre-eval-error`). */
800
+ stage: string;
801
+ detail: string;
802
+ toolName?: string;
803
+ sessionId?: string;
804
+ }
805
+ /**
806
+ * Record a fail-open event: stderr always; the on-disk log for runtime
807
+ * failures (`logToDisk=false` for the steady-state `unconfigured` case, which
808
+ * would otherwise grow the log unboundedly on a machine that never configures).
809
+ */
810
+ export declare function reportFailOpen(event: FailOpenEvent, logToDisk?: boolean): Promise<void>;
811
+ /**
812
+ * Claude Code tool taxonomy — action vs retrieval classification.
813
+ *
814
+ * VisIQ governs two facets per tool call:
815
+ * - ACTION — side-effecting tools (shell, file writes, MCP mutations)
816
+ * - RETRIEVAL — tools that pull external/foreign content INTO the model's
817
+ * context (web fetch/search, file/dir reads, MCP resource reads)
818
+ *
819
+ * The set below is the canonical Claude Code built-in tool list (verified
820
+ * against the running CLI, v2.1.x — the `tool_name` values a hook receives).
821
+ * Retrieval tools are tagged with BOTH facets (`['retrieval','action']`) so an
822
+ * action rule (e.g. "block all web egress") also governs them, mirroring the
823
+ * OpenClaw plugin's dual-facet tagging. Everything else is a pure action.
824
+ *
825
+ * Fail-safe posture (G001): an UNKNOWN tool is treated as an ACTION (governed,
826
+ * never silently ungoverned). MCP tools whose bare name looks like a read are
827
+ * ALSO run through the retrieval facet (fails SAFE toward more governance).
828
+ */
829
+ /**
830
+ * Reduce a possibly-namespaced MCP tool name to its leaf: `mcp__brave__web_search`
831
+ * → `web_search`. Non-MCP (and non-string, defensively) names are returned as-is.
832
+ */
833
+ export declare function bareToolName(toolName: string): string;
834
+ /** Does this tool call pull foreign content into the model's context? */
835
+ export declare function isRetrievalTool(toolName: string): boolean;
836
+ /** Governance facets to evaluate for a given tool. */
837
+ export type Operation = "action" | "retrieval" | "delegation";
838
+ /**
839
+ * The `operations[]` to hand `UnifiedRuntime.evaluate`. Retrieval tools carry
840
+ * BOTH facets (an action rule can still govern a fetch); everything else is a
841
+ * pure action.
842
+ */
843
+ export declare function toolOperations(toolName: string): Operation[];
844
+ /**
845
+ * Extract a human-meaningful query string from a tool's input for retrieval
846
+ * evaluation + telemetry. Joins the first-present query-shaped fields; returns
847
+ * `undefined` when none are present (so the caller omits `query`).
848
+ */
849
+ export declare function extractQuery(toolInput: unknown): string | undefined;
604
850
  /**
605
851
  * Claude Code hook I/O contract — types + pure builders.
606
852
  *
@@ -783,11 +1029,12 @@ export declare function buildEvaluateEvent(opts: {
783
1029
  * 2. stale/absent → raw fetch → applyBundle + persist;
784
1030
  * 3. fetch failed but a STALE cache exists → applyBundle(stale) (a stale
785
1031
  * bundle is strictly better than a cold-start deny flake);
786
- * 4. nothing on disk + fetch failed → awaitBundleReady (last resort; may
787
- * cold-start fail-closed deny in enforce, which is the correct posture).
1032
+ * 4. nothing on disk + fetch failed → awaitBundleReady (last resort).
1033
+ * Returns true when a usable bundle was applied (or became ready), false when
1034
+ * the whole ladder failed — the caller maps false to its failMode posture.
788
1035
  * Best-effort; never throws.
789
1036
  */
790
- export declare function warmFromCache(runtime: UnifiedRuntime, config: VisiqConfig, ttlMs?: number): Promise<void>;
1037
+ export declare function warmFromCache(runtime: UnifiedRuntime, config: VisiqConfig, ttlMs?: number): Promise<boolean>;
791
1038
  /** Drain telemetry + registration then release timers. Bounded; never throws. */
792
1039
  export declare function finishRuntime(runtime: UnifiedRuntime): Promise<void>;
793
1040
  /**
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{a as E,b as T,c as h,d as C,e as u,f as x,g as S}from"./chunk-6DMSMBWM.js";import{a as n,b as s,c as a,d as l,e as P,f as U,g as F,h as b,i as q,j as K,k as m,l as p,m as f,n as d,o as I,p as L,q as k,r as v,s as y,t as A,u as B,v as M}from"./chunk-IT2RXQ74.js";import{a as e,b as o,c as t,d as r,e as i,f as c,g as R,h as g,i as H,j as O,k as _,l as D,m as N}from"./chunk-3GWLCI47.js";export{c as DEFAULT_BUNDLE_TTL_MS,I as HARNESS_KIND,E as HOOK_COMMAND,T as HOOK_TIMEOUT_SECONDS,h as RETRIEVAL_MATCHER,m as WITHHELD_SENTINEL,n as bareToolName,p as blankContent,k as buildEvaluateEvent,q as buildPostRedact,U as buildPreAllow,b as buildPreAsk,F as buildPreDeny,o as configFilePath,L as createRuntime,t as envConfig,l as extractQuery,_ as fetchBundle,y as finishRuntime,P as formatReason,B as handlePostToolUse,A as handlePreToolUse,M as handleSessionStart,S as hooksInstalled,u as installHooks,g as isFresh,s as isRetrievalTool,D as isSessionRegistered,C as isVisiqGroup,i as loadConfig,d as mapPostRedaction,f as mapPreDecision,N as markSessionRegistered,r as mergeConfig,K as parseHookInput,H as readBundleCache,R as sanitizeId,a as toolOperations,x as uninstallHooks,e as visiqHomeDir,v as warmFromCache,O as writeBundleCache};
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-HI63J7G3.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.1",
3
+ "version": "0.1.3",
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",
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "zod": "^3.23.8",
20
- "@visiq/core-wasm": "^0.1.0"
20
+ "@visiq/core-wasm": "^0.1.3"
21
21
  },
22
22
  "engines": {
23
23
  "node": ">=20"
@@ -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};
@@ -1,3 +0,0 @@
1
- import{f as M,h as $,i as q,j as z,k as W,l as H,m as I}from"./chunk-3GWLCI47.js";var Oe=new Set(["WebFetch","WebSearch","Read","Grep","Glob","LSP","NotebookRead","ListMcpResourcesTool","ReadMcpResourceTool"]),Re=/(^|_)(search|fetch|read|list|get|query|retrieve|lookup|find|describe|download|export|dump)(_|$)/i;function Ne(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 N(e){return typeof e!="string"?!1:Oe.has(e)?!0:e.startsWith("mcp__")?Re.test(Ne(e)):!1}function V(e){return N(e)?["retrieval","action"]:["action"]}var Pe=["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 Pe){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 G(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 K(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 Mt(e){try{let t=JSON.parse(e);return t&&typeof t=="object"&&typeof t.hook_event_name=="string"?t:null}catch{return null}}var Le=[{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(Le.map(e=>[e.name,e.re.source])),Fe=["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"],De={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}},qt=new Set(Fe.filter(e=>!De[e].defaultEnabled));var P="[REDACTED]",y="\u2022",C=e=>/[A-Za-z0-9]/.test(e);function Z(e,t,n,r){let i=Array.from(e),o=i.length,a=Math.max(0,Math.floor(t)||0),l=Math.max(0,Math.floor(n)||0),u=r.length>0?r:y,d=a+l>=o;return i.map((p,m)=>!d&&(m<a||m>=o-l)?p:C(p)?u:p).join("")}function Ue(e,t){let n=e.indexOf("@");if(n<=0||n>=e.length-1)return Z(e,0,0,t);let r=e.slice(0,n),i=e.slice(n),o=t.length>0?t:y;return(r.length<=1?o:r[0]+Array.from(r.slice(1)).map(a=>C(a)?o:a).join(""))+i}function je(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 m=p.index;m<p.index+p[0].length;m++)i[m]=!0}}catch{}let o=!1,a=!0;for(let d=0;d<e.length;d++)if(C(e[d])&&(o=!0,!i[d])){a=!1;break}let l=o&&a,u="";for(let d=0;d<e.length;d++){let p=e[d];!l&&i[d]||!C(p)?u+=p:u+=r}return u}function Y(e,t){let n=t.mode??"full";return n==="partial"?Z(e,t.keepFirst??0,t.keepLast??0,t.maskChar??y):n==="email"?Ue(e,t.maskChar??y):n==="custom"?je(e,t.keepPattern,t.maskChar??y):t.replacement??P}function Be(e,t){return typeof e=="string"?Y(e,t):t.replacement??P}function J(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:o=>Y(o,r)})}return t}function Q(e,t){let n=e;for(let{source:r,replacer:i}of t){let o;try{o=new RegExp(r,"g")}catch(a){let l=a instanceof Error?a.message:String(a);throw new Error(`[visiq-redact] Invalid redaction pattern "${r}": ${l}`)}n=n.replace(o,a=>i(a))}return n}function L(e,t){return e==null?e:typeof e=="string"?Me(e,t):typeof e=="object"?$e(e,t):e}function Me(e,t){if(typeof e!="string")return e;let n=J(t);return n.length===0?e:Q(e,n)}function $e(e,t){let n=new Map;for(let l of t.fields??[])typeof l=="string"&&l.length>0&&n.set(l,{field:l,mode:"full",replacement:t.replacement});for(let l of t.directives??[])typeof l.field=="string"&&l.field.length>0&&n.set(l.field,l);let r=J(t),i=n.size>0,o=r.length>0,a=l=>{if(l==null)return l;if(Array.isArray(l))return l.map(u=>a(u));if(typeof l=="object"){let u=l,d=Object.create(Object.getPrototypeOf(u));for(let p of Object.keys(u)){let m=i?n.get(p):void 0;if(m){d[p]=Be(u[p],m);continue}d[p]=a(u[p])}return d}return typeof l=="string"&&o?Q(l,r):l};return a(e)}import{z as s}from"zod";import*as g from"node:os";var X="interceptor_source",qe=s.enum(["enforce","audit","off"]),ze=s.enum(["closed","open"]),ee=s.enum(["enforce","monitor","off"]),We=s.object({apiKey:s.string().min(1,"apiKey is required"),agentId:s.string().min(1,"agentId is required"),endpoint:s.string().url().optional(),mode:qe.optional(),timeoutMs:s.number().int().positive().optional(),hitlTimeoutMs:s.number().int().positive().optional(),failBehavior:ze.optional()}),Ht=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()}),He=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()}),Ve=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:ee.optional(),arg_redaction_rules:s.array(He).optional(),plane:s.string().nullable().optional(),operation:s.string().nullable().optional(),is_retrieval:s.boolean().optional(),metadata:s.record(s.unknown()).optional()}),Ge=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())])}),Ke=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(Ge).default([]),priority:s.number().int().default(0)}),Ze=s.object({version:s.string().min(1),agent_mode:ee.optional(),rules:s.array(Ke),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()}),Ye=2e3,te=class{config;originalFetch;constructor(e,t){this.config=e,this.originalFetch=t}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}`},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 Ve.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"},signal:n.signal})}finally{clearTimeout(r)}if(!i.ok)throw new Error(`ALLOW rules/bundle fetch failed: HTTP ${i.status} ${i.statusText}`);let o=await i.json();return Ze.parse(o)}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}`},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}`},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}`},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}`},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}`},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}`},signal:n.signal})}finally{clearTimeout(r)}if(!i.ok)throw new Error(`ALLOW decisions poll failed: HTTP ${i.status} ${i.statusText}`);let o=await i.json();if(typeof o!="object"||o===null)throw new Error("ALLOW decisions poll returned unexpected non-object response");let a=o,l=a.hitl_result;if(l==="approved")return{decision_id:e,decision:"permit",reason:"Approved by human reviewer"};if(l==="rejected")return{decision_id:e,decision:"deny",reason:typeof a.reason=="string"?a.reason:"Rejected by human reviewer"};if(l==="timeout"||l==="expired")return{decision_id:e,decision:"deny",reason:"HITL approval timed out"};await Je(Ye)}return{decision_id:e,decision:"deny",reason:"HITL approval timed out"}}};function Je(e){return new Promise(t=>setTimeout(t,e))}function ne(){let e={};try{let t=`${g.platform()} ${g.release()}`.trim();t&&(e.os=t)}catch{}try{let t=g.hostname();t&&(e.hostname=t)}catch{}try{let{username:t}=g.userInfo();t&&(e.username=t)}catch{}try{let t=Qe();t&&(e.ip=t)}catch{}return e}function Qe(){let e=g.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 c}from"zod";import{createHash as Zt}from"crypto";import{createHash as Xt}from"crypto";var Xe=["tier1","tier2","tier3"];function ae(e){return typeof e=="string"&&Xe.includes(e)}var et=["read_only","transactional","data_processor","external_comms","code_exec","privileged"],tt=["internal","customer_facing","experimental","third_party"],oe=[...et,...tt];function nt(e){return typeof e=="string"&&oe.includes(e)}function se(e){let t=new Set;for(let n of e)nt(n)&&t.add(n);return oe.filter(n=>t.has(n))}var rt=["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 le(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 it={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 at(e){let t=le(e);return t===null?"other":it[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 re={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 ot(e){let t=le(e);return t===null?"other":re[t]??re[t.replace(/_/g,"")]??"other"}function ce(e,t){let n={...e};if(t.action!==void 0&&t.action!==null&&n.action_class===void 0&&(n.action_class=at(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=ot(t.targetApp)),n.context=r}return n}var ie=64,st=64,k={retrieved_data_categories:[],retrieved_classifications:[],action_classes:[],action_counts:{},denied_count:0,inhibited_count:0,event_count:0,target_apps:[]};function ue(){return{retrieved_data_categories:[],retrieved_classifications:[],action_classes:[],action_counts:{},denied_count:0,inhibited_count:0,event_count:0,target_apps:[]}}var lt=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>ie?r.slice(0,ie):r}function ct(e){return e?e.filter(t=>typeof t=="string"&&t.length>0):[]}function x(e){return typeof e=="string"&&e.length>0?e:null}function de(e,t){let n=ct(t.data_categories),r=x(t.classification),i=x(t.action_class),o=i&&rt.includes(i)?i:null,a=x(t.target_app),l=x(t.decision),u={...e.action_counts};if(o)if(o in u)u[o]=(u[o]??0)+1;else if(Object.keys(u).length<st)u[o]=1;else{let d=Object.keys(u).sort(),p=d[d.length-1];p!==void 0&&o<p&&(delete u[p],u[o]=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,o?[o]:[]),action_counts:u,denied_count:e.denied_count+(l==="deny"?1:0),inhibited_count:e.inhibited_count+(l&&lt.has(l)?1:0),event_count:e.event_count+1,target_apps:T(e.target_apps,a?[a]:[])}}var ut="generic",pe=[{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:ut,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."}],dt=pe.map(e=>e.id),Yt=new Map(pe.map(e=>[e.id,e])),Jt=new Set(dt);var pt=/^[a-z][a-z0-9_]*$/;function fe(e){if(!Array.isArray(e))return[];let t=[],n=new Set;for(let r of e)typeof r=="string"&&pt.test(r)&&!n.has(r)&&(n.add(r),t.push(r));return t}var ft=["narrow","moderate","broad","unbounded","unknown"];function ge(e){return typeof e=="string"&&ft.includes(e)}function me(e){return e==="open"||e==="closed"?e:null}var gt=["action","retrieval","delegation"];function mt(e){return typeof e=="string"&&gt.includes(e)}var ht=new Set(["rules"]);function he(e){if(typeof e.id!="string"||typeof e.vendor_id!="string")return null;let t=typeof e.origin_table=="string"?e.origin_table:"";if(!ht.has(t))return null;let n=Array.isArray(e.applies_to)?e.applies_to.filter(mt):[];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{randomUUID as Ft}from"node:crypto";var _e=e=>e!==void 0&&e.length>5120?e.slice(0,5120):e;function _t(e){let t={...e};return t.content?.text!==void 0&&(t.content={...t.content,text:_e(t.content.text)}),t.spawn?.prompt!==void 0&&(t.spawn={...t.spawn,prompt:_e(t.spawn.prompt)}),t}function yt(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 A;async function bt(){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 vt=5e3,wt=1e4,kt=25,ye=1e3,At=5e3,It=100,be=2e3,St=512,Et=1800*1e3,Ct="monitor",Tt="Agent has been shut down by an operator \u2014 all actions are blocked (G001)",xt=c.object({operations:c.array(c.enum(["retrieval","action","delegation"])).min(1,"at least one operation is required"),agentId:c.string().min(1,"agentId is required"),sessionId:c.string().min(1).max(255).optional(),toolName:c.string().optional(),toolArgs:c.record(c.unknown()).optional(),targetResource:c.string().optional(),resourceType:c.string().optional(),resourceMetadata:c.record(c.unknown()).optional(),normalized:c.record(c.unknown()).optional(),query:c.string().optional(),contentPreview:c.string().optional(),telemetry:c.record(c.unknown()).optional(),context:c.record(c.unknown()).optional()}),Ot=c.object({version:c.string().min(1),shutdown:c.boolean().optional(),agent_mode:c.enum(["enforce","monitor","off"]).optional(),cognition_capture:c.boolean().optional(),agent_mode_by_operation:c.object({action:c.string().optional(),retrieval:c.string().optional(),delegation:c.string().optional()}).partial().optional(),agent_attributes:c.object({trust_tier:c.string().nullable().optional(),categories:c.array(c.string()).optional(),business_function:c.string().nullable().optional(),business_functions:c.array(c.string()).nullable().optional(),blast_radius_tier:c.string().nullable().optional(),no_coverage:c.string().nullable().optional()}).optional(),rules:c.array(c.record(c.unknown())),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()}).optional()});function Rt(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=fe(n);return{trust_tier:ae(t)?t:null,categories:se(e.categories??[]),business_functions:r,business_function:r[0]??null,blast_radius_tier:typeof e.blast_radius_tier=="string"&&ge(e.blast_radius_tier)?e.blast_radius_tier:null}}function Nt(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 Pt(e){return e==="permit"?"permit":e==="mask"||e==="redact"?"mask":e==="approval_required"||e==="escalate"?"approval_required":"deny"}var ke=new Set,ve=!1;function Lt(){ve||typeof process>"u"||typeof process.once!="function"||(ve=!0,process.once("beforeExit",()=>{for(let e of ke)if(e.pendingTelemetryCount()>0){if(!e.hasBackend()){console.warn(`[UnifiedRuntime] exiting with ${e.pendingTelemetryCount()} un-sent decision(s) and no backend \u2014 telemetry lost.`);continue}e.flush()}}))}var Ae=class{client;originalFetch;resolvedApiKey;resolvedEndpoint;resolvedAgentId;harnessKind;rules=[];agentAttributes=null;agentNoCoverage=null;sessions=new Map;noCoverage=null;bundleVersion=null;bundleEtag=null;bundleLoaded=!1;bundleFetchInProgress=!1;initialBundlePromise=null;refreshTimer=null;agentMode=Ct;agentModeByOperation=null;rawBundle=null;agentModeConfirmed=!1;shutdown=!1;bundleApplyFailed=!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){let o=e??process.env.VISIQ_API_KEY??process.env.ALLOW_API_KEY??process.env.VISIQ_ALLOW_API_KEY,a=t??process.env.VISIQ_ENDPOINT??process.env.ALLOW_ENDPOINT,l=n??process.env.VISIQ_AGENT_ID??process.env.ALLOW_AGENT_ID??"";if(this.resolvedApiKey=o,this.resolvedEndpoint=a,this.resolvedAgentId=l,this.harnessKind=r,this.originalFetch=globalThis.fetch.bind(globalThis),o&&a){let u={apiKey:o,agentId:l,endpoint:a,mode:"enforce",timeoutMs:yt(i),hitlTimeoutMs:12e4,failBehavior:"closed",...r?{harnessKind:r}:{}};this.client=new te(u,this.originalFetch),this.initialBundlePromise=this.fetchBundleBackground(),this.refreshTimer=setInterval(()=>{this.fetchBundleBackground()},vt),F(this.refreshTimer),this.telemetryTimer=setInterval(()=>{this.flushTelemetry()},wt),F(this.telemetryTimer),this.cognitionTimer=setInterval(()=>{this.flushCognition()},At),F(this.cognitionTimer),ke.add(this),Lt()}else this.client=null}async evaluate(e){let t=xt.parse(e),n=Date.now();if(this.shutdown){let u=this.denyAll(t,Tt);return this.applyAgentMode(u,"enforce",t,n)}if(t.operations.every(u=>this.modeFor(u)==="off"))return this.offDecision(t);if(!this.bundleLoaded){let u;this.agentModeConfirmed?u=this.agentMode:this.bundleApplyFailed?u="enforce":u="monitor";let d=this.denyAll(t,"No unified bundle loaded and no local rules \u2014 fail-closed (G001)");return this.applyAgentMode(d,u,t,n)}let r=this.readSession(t.sessionId),i=await bt();if(!i||!this.rawBundle)throw new Error("governance core (@visiq/core-wasm) unavailable \u2014 failing closed (G001)");let o={...t,session:r,at:Date.now()},a={...this.rawBundle,agent_mode:this.agentMode,...this.agentModeByOperation?{agent_mode_by_operation:this.agentModeByOperation}:{}},l=i(o,a);return this.foldSession(t,l.enforced?l.decision:"permit"),l.enforced&&l.action.decision==="approval_required"&&await this.registerHitl(t,l),this.bufferTelemetry(t,l,Date.now()-n,l.enforced),l}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>Et?(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??{},o=e.operations.includes("retrieval"),a=e.operations.includes("action")||e.operations.includes("delegation"),l=a?ce(e.normalized??{},{action:e.toolName??"",targetApp:e.targetResource??e.toolName??""}):e.normalized??{},u=de(r===k?ue():r,{data_categories:o&&Array.isArray(i.data_categories)?i.data_categories:void 0,classification:o?i.classification:void 0,action_class:a?l.action_class:void 0,target_app:a?e.targetResource??e.toolName:void 0,decision:t});if(this.sessions.delete(n),this.sessions.set(n,{state:u,touchedAt:Date.now()}),this.sessions.size>St){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 a={...e,enforced:!0,agentMode:"enforce"};return this.bufferTelemetry(n,a,i,!0),a}let o={...e,allowed:!0,enforced:!1,agentMode:"monitor"};return this.bufferTelemetry(n,o,i,!1),o}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=Ot.parse(e);this.bundleApplyFailed=!1,!(this.bundleLoaded&&t.version===this.bundleVersion)&&(this.rules=t.rules.map(n=>he(n)).filter(n=>n!==null),this.agentAttributes=t.agent_attributes?Rt(t.agent_attributes):null,this.agentNoCoverage=me(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=Nt(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.shutdown=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"};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");r&&(this.bundleEtag=r);let i=await n.json();this.applyBundle(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}}}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({...ne(),...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?Pt(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?{[X]:this.harnessKind}:{},...e.context??{}}}:{}}),this.enforceTelemetryCap(),this.telemetryBuffer.length>=kt&&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-ye;e>0&&(this.telemetryBuffer.splice(0,e),console.warn(`[UnifiedRuntime] telemetry buffer full \u2014 dropped ${e} oldest entries (cap ${ye})`))}isCognitionEnabled(){return this.cognitionEnabled}emitCognition(e){!this.cognitionEnabled||!this.client||(this.cognitionBuffer.push(_t(e)),this.enforceCognitionCap(),this.cognitionBuffer.length>=It&&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-be;e>0&&(this.cognitionBuffer.splice(0,e),console.warn(`[UnifiedRuntime] cognition buffer full \u2014 dropped ${e} oldest beats (cap ${be})`))}async flush(){if(this.registerPromise)try{await this.registerPromise}catch{}await this.flushTelemetry(),await this.flushCognition()}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 F(e){e&&typeof e=="object"&&"unref"in e&&e.unref()}function D(e){return typeof e=="string"&&e.trim().length>0?e:void 0}function Ie(e,t){if(e!=="Task"&&e!=="Agent")return null;let n=D(t.description),r=D(t.subagent_type),i=D(t.prompt),o=n??r??"sub-agent";return{childAgentId:o,childName:o,kind:"subagent",agentType:r,description:n,task:i,goal:i,source:"structural"}}function Se(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 we=new Map;function Dt(e){let t=(we.get(e)??0)+1;return we.set(e,t),t}function Ee(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:Ft(),agentId:t.agentId,sessionId:r,threadId:t.agentId,parentId:t.agentId,seq:Dt(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 U(e){let t=[],n=[],r,i=[];for(let a of e){if(a.mode==="partial"||a.mode==="email"||a.mode==="custom"){let u={mode:a.mode};a.field&&(u.field=a.field),a.pattern&&(u.pattern=a.pattern),typeof a.keepFirst=="number"&&(u.keepFirst=a.keepFirst),typeof a.keepLast=="number"&&(u.keepLast=a.keepLast),a.maskChar&&(u.maskChar=a.maskChar),a.keepPattern&&(u.keepPattern=a.keepPattern),a.replacement!==void 0&&(u.replacement=a.replacement),i.push(u);continue}a.field&&t.push(a.field),a.pattern&&n.push(a.pattern);let{replacement:l}=a;l&&r===void 0&&(r=l)}let o={};return t.length>0&&(o.fields=t),n.length>0&&(o.patterns=n),r!==void 0&&(o.replacement=r),i.length>0&&(o.directives=i),o}var Ut="[VisIQ: retrieval withheld by policy]";function O(e){return j(e)}function j(e){if(e==null)return e;if(typeof e=="string")return e.length>0?Ut:e;if(typeof e=="number")return 0;if(typeof e=="boolean")return!1;if(Array.isArray(e))return e.map(j);if(typeof e=="object"){let t=Object.create(null);for(let n of Object.keys(e))t[n]=j(e[n]);return t}return e}function Ce(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 Te(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 K(i);if(n.decision==="mask"&&n.argRedactionRules&&n.argRedactionRules.length>0){let o=U(n.argRedactionRules);if(Ce(o)){let a=L(t,o)??t;if(JSON.stringify(a)!==JSON.stringify(t))return G(a)}return null}return null}function xe(e,t){if(!e.enforced)return null;let{retrieval:n}=e,r=h(e.reason,e.ruleCode);if(n.action==="redact"){let i=U(n.redactionRules??[]);if(!Ce(i))return _(O(t),r);let o=L(t,i);return JSON.stringify(o)===JSON.stringify(t)?null:_(o,r)}return n.action==="deny"?_(O(t),r):null}var jt="cli_harness";function b(e){return new Ae(e.apiKey,e.baseUrl,e.agentId,jt)}function R(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=M){let{agentId:r}=t,i=await q(r);if(i&&$(i,n,Date.now())&&B(e,i.body))return;let o=e.getEndpoint();if(o){let a=await W(o,t.apiKey,r);if(a&&B(e,a.body)){await z(r,a.body,a.version);return}}if(!(i&&B(e,i.body)))try{await e.awaitBundleReady(2500)}catch{}}function B(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 wn(e,t){let n=b(t),r=e.tool_input??{};try{await H(e.session_id)||(n.registerHostEnvironment(),await I(e.session_id)),await v(n,t);let i=Ie(e.tool_name,r),o=V(e.tool_name),a;i&&(Ee(n,{agentId:t.agentId,sessionId:e.session_id,framework:"claude-code"},i),o=Array.from(new Set([...o,"delegation"])),a=Se(i,t.agentId));let l=R({operations:o,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?{context:a}:{}}),u=await n.evaluate(l);return Te(u,r)}catch{return E(h("evaluation error (fail-closed)",null))}finally{await w(n)}}async function Cn(e,t){if(!N(e.tool_name))return null;let n=b(t);try{await v(n,t);let r=e.tool_input??{},i=R({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)}),o=await n.evaluate(i);return xe(o,e.tool_response)}catch{return _(O(e.tool_response),h("evaluation error (fail-closed)",null))}finally{await w(n)}}async function Rn(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{Ne as a,N as b,V as c,S as d,h as e,G as f,E as g,K as h,_ as i,Mt as j,Ut as k,O as l,Te as m,xe as n,jt as o,b as p,R as q,v as r,w as s,wn as t,Cn as u,Rn as v};