@i4ctime/q-ring 0.17.0 → 0.17.5

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.
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  PACKAGE_VERSION,
4
+ buildSessions,
4
5
  checkDecay,
5
6
  collapseEnvironment,
6
7
  detectAnomalies,
@@ -14,14 +15,14 @@ import {
14
15
  readProjectConfig,
15
16
  tunnelList,
16
17
  verifyAuditChain
17
- } from "./chunk-SQKTDYSO.js";
18
+ } from "./chunk-VMDD5QTJ.js";
18
19
 
19
20
  // src/core/dashboard.ts
20
21
  import { createServer } from "http";
21
22
  import { randomBytes, timingSafeEqual } from "crypto";
22
23
 
23
24
  // src/core/dashboard-client.ts
24
- var DASHBOARD_CLIENT = '"use strict";(()=>{var J,b,we,tt,q,ge,Ce,Me,se,W,I,Se,ie,ae,oe,nt,O={},Y=[],st=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,Q=Array.isArray;function T(t,e){for(var n in e)t[n]=e[n];return t}function le(t){t&&t.parentNode&&t.parentNode.removeChild(t)}function re(t,e,n){var s,o,a,l={};for(a in e)a=="key"?s=e[a]:a=="ref"?o=e[a]:l[a]=e[a];if(arguments.length>2&&(l.children=arguments.length>3?J.call(arguments,2):n),typeof t=="function"&&t.defaultProps!=null)for(a in t.defaultProps)l[a]===void 0&&(l[a]=t.defaultProps[a]);return K(t,l,s,o,null)}function K(t,e,n,s,o){var a={type:t,props:e,key:n,ref:s,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o==null?++we:o,__i:-1,__u:0};return o==null&&b.vnode!=null&&b.vnode(a),a}function X(t){return t.children}function z(t,e){this.props=t,this.context=e}function D(t,e){if(e==null)return t.__?D(t.__,t.__i+1):null;for(var n;e<t.__k.length;e++)if((n=t.__k[e])!=null&&n.__e!=null)return n.__e;return typeof t.type=="function"?D(t):null}function at(t){if(t.__P&&t.__d){var e=t.__v,n=e.__e,s=[],o=[],a=T({},e);a.__v=e.__v+1,b.vnode&&b.vnode(a),ce(t.__P,a,e,t.__n,t.__P.namespaceURI,32&e.__u?[n]:null,s,n==null?D(e):n,!!(32&e.__u),o),a.__v=e.__v,a.__.__k[a.__i]=a,Te(s,a,o),e.__e=e.__=null,a.__e!=n&&Ae(a)}}function Ae(t){if((t=t.__)!=null&&t.__c!=null)return t.__e=t.__c.base=null,t.__k.some(function(e){if(e!=null&&e.__e!=null)return t.__e=t.__c.base=e.__e}),Ae(t)}function ke(t){(!t.__d&&(t.__d=!0)&&q.push(t)&&!G.__r++||ge!=b.debounceRendering)&&((ge=b.debounceRendering)||Ce)(G)}function G(){try{for(var t,e=1;q.length;)q.length>e&&q.sort(Me),t=q.shift(),e=q.length,at(t)}finally{q.length=G.__r=0}}function Ee(t,e,n,s,o,a,l,u,_,c,r){var p,i,v,f,h,y,m=s&&s.__k||Y,$=e.length;for(_=ot(n,e,m,_,$),p=0;p<$;p++)(v=n.__k[p])!=null&&(i=v.__i!=-1&&m[v.__i]||O,v.__i=p,y=ce(t,v,i,o,a,l,u,_,c,r),f=v.__e,v.ref&&i.ref!=v.ref&&(i.ref&&de(i.ref,null,v),r.push(v.ref,v.__c||f,v)),h==null&&f!=null&&(h=f),4&v.__u?(_=Pe(v,_,t),i.__e&&(i.__e=null)):typeof v.type=="function"&&y!==void 0?_=y:f&&(_=f.nextSibling),v.__u&=-7);return n.__e=h,_}function ot(t,e,n,s,o){var a,l,u,_,c,r=n.length,p=r,i=0;for(t.__k=new Array(o),a=0;a<o;a++)(l=e[a])!=null&&typeof l!="boolean"&&typeof l!="function"?(typeof l=="string"||typeof l=="number"||typeof l=="bigint"||l.constructor==String?l=t.__k[a]=K(null,l,null,null,null):Q(l)?l=t.__k[a]=K(X,{children:l},null,null,null):l.constructor===void 0&&l.__b>0?l=t.__k[a]=K(l.type,l.props,l.key,l.ref?l.ref:null,l.__v):t.__k[a]=l,_=a+i,l.__=t,l.__b=t.__b+1,u=null,(c=l.__i=it(l,n,_,p))!=-1&&(p--,(u=n[c])&&(u.__u|=2)),u==null||u.__v==null?(c==-1&&(o>r?i--:o<r&&i++),typeof l.type!="function"&&(l.__u|=4)):c!=_&&(c==_-1?i--:c==_+1?i++:(c>_?i--:i++,l.__u|=4))):t.__k[a]=null;if(p)for(a=0;a<r;a++)(u=n[a])!=null&&(2&u.__u)==0&&(u.__e==s&&(s=D(u)),Ne(u,u));return s}function Pe(t,e,n){var s,o;if(typeof t.type=="function"){for(s=t.__k,o=0;s&&o<s.length;o++)s[o]&&(s[o].__=t,e=Pe(s[o],e,n));return e}t.__e!=e&&(e&&t.type&&!e.parentNode&&(e=D(t)),e=n.insertBefore(t.__e,e||null));do e=e&&e.nextSibling;while(e!=null&&e.nodeType==8);return e}function it(t,e,n,s){var o,a,l,u=t.key,_=t.type,c=e[n],r=c!=null&&(2&c.__u)==0;if(c===null&&u==null||r&&u==c.key&&_==c.type)return n;if(s>(r?1:0)){for(o=n-1,a=n+1;o>=0||a<e.length;)if((c=e[l=o>=0?o--:a++])!=null&&(2&c.__u)==0&&u==c.key&&_==c.type)return l}return-1}function be(t,e,n){e[0]=="-"?t.setProperty(e,n==null?"":n):t[e]=n==null?"":typeof n!="number"||st.test(e)?n:n+"px"}function V(t,e,n,s,o){var a,l;e:if(e=="style")if(typeof n=="string")t.style.cssText=n;else{if(typeof s=="string"&&(t.style.cssText=s=""),s)for(e in s)n&&e in n||be(t.style,e,"");if(n)for(e in n)s&&n[e]==s[e]||be(t.style,e,n[e])}else if(e[0]=="o"&&e[1]=="n")a=e!=(e=e.replace(Se,"$1")),l=e.toLowerCase(),e=l in t||e=="onFocusOut"||e=="onFocusIn"?l.slice(2):e.slice(2),t.l||(t.l={}),t.l[e+a]=n,n?s?n[I]=s[I]:(n[I]=ie,t.addEventListener(e,a?oe:ae,a)):t.removeEventListener(e,a?oe:ae,a);else{if(o=="http://www.w3.org/2000/svg")e=e.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(e!="width"&&e!="height"&&e!="href"&&e!="list"&&e!="form"&&e!="tabIndex"&&e!="download"&&e!="rowSpan"&&e!="colSpan"&&e!="role"&&e!="popover"&&e in t)try{t[e]=n==null?"":n;break e}catch{}typeof n=="function"||(n==null||n===!1&&e[4]!="-"?t.removeAttribute(e):t.setAttribute(e,e=="popover"&&n==1?"":n))}}function xe(t){return function(e){if(this.l){var n=this.l[e.type+t];if(e[W]==null)e[W]=ie++;else if(e[W]<n[I])return;return n(b.event?b.event(e):e)}}}function ce(t,e,n,s,o,a,l,u,_,c){var r,p,i,v,f,h,y,m,$,g,w,P,H,me,B,ne,R=e.type;if(e.constructor!==void 0)return null;128&n.__u&&(_=!!(32&n.__u),a=[u=e.__e=n.__e]),(r=b.__b)&&r(e);e:if(typeof R=="function"){p=l.length;try{if($=e.props,g=R.prototype&&R.prototype.render,w=(r=R.contextType)&&s[r.__c],P=r?w?w.props.value:r.__:s,n.__c?m=(i=e.__c=n.__c).__=i.__E:(g?e.__c=i=new R($,P):(e.__c=i=new z($,P),i.constructor=R,i.render=rt),w&&w.sub(i),i.state||(i.state={}),i.__n=s,v=i.__d=!0,i.__h=[],i._sb=[]),g&&i.__s==null&&(i.__s=i.state),g&&R.getDerivedStateFromProps!=null&&(i.__s==i.state&&(i.__s=T({},i.__s)),T(i.__s,R.getDerivedStateFromProps($,i.__s))),f=i.props,h=i.state,i.__v=e,v)g&&R.getDerivedStateFromProps==null&&i.componentWillMount!=null&&i.componentWillMount(),g&&i.componentDidMount!=null&&i.__h.push(i.componentDidMount);else{if(g&&R.getDerivedStateFromProps==null&&$!==f&&i.componentWillReceiveProps!=null&&i.componentWillReceiveProps($,P),e.__v==n.__v||!i.__e&&i.shouldComponentUpdate!=null&&i.shouldComponentUpdate($,i.__s,P)===!1){e.__v!=n.__v&&(i.props=$,i.state=i.__s,i.__d=!1),e.__e=n.__e,e.__k=n.__k,e.__k.some(function(j){j&&(j.__=e)}),Y.push.apply(i.__h,i._sb),i._sb=[],i.__h.length&&l.push(i),u=D(n);break e}i.componentWillUpdate!=null&&i.componentWillUpdate($,i.__s,P),g&&i.componentDidUpdate!=null&&i.__h.push(function(){i.componentDidUpdate(f,h,y)})}if(i.context=P,i.props=$,i.__P=t,i.__e=!1,H=b.__r,me=0,g)i.state=i.__s,i.__d=!1,H&&H(e),r=i.render(i.props,i.state,i.context),Y.push.apply(i.__h,i._sb),i._sb=[];else do i.__d=!1,H&&H(e),r=i.render(i.props,i.state,i.context),i.state=i.__s;while(i.__d&&++me<25);i.state=i.__s,i.getChildContext!=null&&(s=T(T({},s),i.getChildContext())),g&&!v&&i.getSnapshotBeforeUpdate!=null&&(y=i.getSnapshotBeforeUpdate(f,h)),B=r!=null&&r.type===X&&r.key==null?qe(r.props.children):r,u=Ee(t,Q(B)?B:[B],e,n,s,o,a,l,u,_,c),i.base=e.__e,e.__u&=-161,i.__h.length&&l.push(i),m&&(i.__E=i.__=null)}catch(j){if(l.length=p,e.__v=null,_||a!=null){if(j.then){for(e.__u|=_?160:128;u&&u.nodeType==8&&u.nextSibling;)u=u.nextSibling;a!=null&&(a[a.indexOf(u)]=null),e.__e=u}else if(a!=null)for(ne=a.length;ne--;)le(a[ne])}else e.__e=n.__e;e.__k==null&&(e.__k=n.__k||[]),j.then||Re(e),b.__e(j,e,n)}}else a==null&&e.__v==n.__v?(e.__k=n.__k,e.__e=n.__e):u=e.__e=lt(n.__e,e,n,s,o,a,l,_,c);return(r=b.diffed)&&r(e),128&e.__u?void 0:u}function Re(t){t&&(t.__c&&(t.__c.__e=!0),t.__k&&t.__k.some(Re))}function Te(t,e,n){for(var s=0;s<n.length;s++)de(n[s],n[++s],n[++s]);b.__c&&b.__c(e,t),t.some(function(o){try{t=o.__h,o.__h=[],t.some(function(a){a.call(o)})}catch(a){b.__e(a,o.__v)}})}function qe(t){return typeof t!="object"||t==null||t.__b>0?t:Q(t)?t.map(qe):t.constructor!==void 0?null:T({},t)}function lt(t,e,n,s,o,a,l,u,_){var c,r,p,i,v,f,h,y=n.props||O,m=e.props,$=e.type;if($=="svg"?o="http://www.w3.org/2000/svg":$=="math"?o="http://www.w3.org/1998/Math/MathML":o||(o="http://www.w3.org/1999/xhtml"),a!=null){for(c=0;c<a.length;c++)if((v=a[c])&&"setAttribute"in v==!!$&&($?v.localName==$:v.nodeType==3)){t=v,a[c]=null;break}}if(t==null){if($==null)return document.createTextNode(m);t=document.createElementNS(o,$,m.is&&m),u&&(b.__m&&b.__m(e,a),u=!1),a=null}if($==null)y===m||u&&t.data==m||(t.data=m);else{if(a=$=="textarea"&&m.defaultValue!=null?null:a&&J.call(t.childNodes),!u&&a!=null)for(y={},c=0;c<t.attributes.length;c++)y[(v=t.attributes[c]).name]=v.value;for(c in y)v=y[c],c=="dangerouslySetInnerHTML"?p=v:c=="children"||c in m||c=="value"&&"defaultValue"in m||c=="checked"&&"defaultChecked"in m||V(t,c,null,v,o);for(c in m)v=m[c],c=="children"?i=v:c=="dangerouslySetInnerHTML"?r=v:c=="value"?f=v:c=="checked"?h=v:u&&typeof v!="function"||y[c]===v||V(t,c,v,y[c],o);if(r)u||p&&(r.__html==p.__html||r.__html==t.innerHTML)||(t.innerHTML=r.__html),e.__k=[];else if(p&&(t.innerHTML=""),Ee(e.type=="template"?t.content:t,Q(i)?i:[i],e,n,s,$=="foreignObject"?"http://www.w3.org/1999/xhtml":o,a,l,a?a[0]:n.__k&&D(n,0),u,_),a!=null)for(c=a.length;c--;)le(a[c]);u&&$!="textarea"||(c="value",$=="progress"&&f==null?t.removeAttribute("value"):f!=null&&(f!==t[c]||$=="progress"&&!f||$=="option"&&f!=y[c])&&V(t,c,f,y[c],o),c="checked",h!=null&&h!=t[c]&&V(t,c,h,y[c],o))}return t}function de(t,e,n){try{if(typeof t=="function"){var s=typeof t.__u=="function";s&&t.__u(),s&&e==null||(t.__u=t(e))}else t.current=e}catch(o){b.__e(o,n)}}function Ne(t,e,n){var s,o;if(b.unmount&&b.unmount(t),(s=t.ref)&&(s.current&&s.current!=t.__e||de(s,null,e)),(s=t.__c)!=null){if(s.componentWillUnmount)try{s.componentWillUnmount()}catch(a){b.__e(a,e)}s.base=s.__P=s.__n=null}if(s=t.__k)for(o=0;o<s.length;o++)s[o]&&Ne(s[o],e,n||typeof t.type!="function");n||le(t.__e),t.__c=t.__=t.__e=void 0}function rt(t,e,n){return this.constructor(t,n)}function He(t,e,n){var s,o,a,l;e==document&&(e=document.documentElement),b.__&&b.__(t,e),o=(s=typeof n=="function")?null:n&&n.__k||e.__k,a=[],l=[],ce(e,t=(!s&&n||e).__k=re(X,null,[t]),o||O,O,e.namespaceURI,!s&&n?[n]:o?null:e.firstChild?J.call(e.childNodes):null,a,!s&&n?n:o?o.__e:e.firstChild,s,l),Te(a,t,l),t.props.children=null}J=Y.slice,b={__e:function(t,e,n,s){for(var o,a,l;e=e.__;)if((o=e.__c)&&!o.__)try{if((a=o.constructor)&&a.getDerivedStateFromError!=null&&(o.setState(a.getDerivedStateFromError(t)),l=o.__d),o.componentDidCatch!=null&&(o.componentDidCatch(t,s||{}),l=o.__d),l)return o.__E=o}catch(u){t=u}throw t}},we=0,tt=function(t){return t!=null&&t.constructor===void 0},z.prototype.setState=function(t,e){var n;n=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=T({},this.state),typeof t=="function"&&(t=t(T({},n),this.props)),t&&T(n,t),t!=null&&this.__v&&(e&&this._sb.push(e),ke(this))},z.prototype.forceUpdate=function(t){this.__v&&(this.__e=!0,t&&this.__h.push(t),ke(this))},z.prototype.render=X,q=[],Ce=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,Me=function(t,e){return t.__v.__b-e.__v.__b},G.__r=0,se=Math.random().toString(8),W="__d"+se,I="__a"+se,Se=/(PointerCapture)$|Capture$/i,ie=0,ae=xe(!1),oe=xe(!0),nt=0;var U,x,ue,De,F=0,We=[],C=b,je=C.__b,Le=C.__r,Ie=C.diffed,Ue=C.__c,Fe=C.unmount,Be=C.__;function _e(t,e){C.__h&&C.__h(x,t,F||e),F=0;var n=x.__H||(x.__H={__:[],__h:[]});return t>=n.__.length&&n.__.push({}),n.__[t]}function N(t){return F=1,ct(ze,t)}function ct(t,e,n){var s=_e(U++,2);if(s.t=t,!s.__c&&(s.__=[n?n(e):ze(void 0,e),function(u){var _=s.__N?s.__N[0]:s.__[0],c=s.t(_,u);_!==c&&(s.__N=[c,s.__[1]],s.__c.setState({}))}],s.__c=x,!x.__f)){var o=function(u,_,c){if(!s.__c.__H)return!0;var r=!1,p=s.__c.props!==u;if(s.__c.__H.__.some(function(v){if(v.__N){r=!0;var f=v.__[0];v.__=v.__N,v.__N=void 0,f!==v.__[0]&&(p=!0)}}),a){var i=a.call(this,u,_,c);return r?i||p:i}return!r||p};x.__f=!0;var a=x.shouldComponentUpdate,l=x.componentWillUpdate;x.componentWillUpdate=function(u,_,c){if(this.__e){var r=a;a=void 0,o(u,_,c),a=r}l&&l.call(this,u,_,c)},x.shouldComponentUpdate=o}return s.__N||s.__}function ee(t,e){var n=_e(U++,3);!C.__s&&Ke(n.__H,e)&&(n.__=t,n.u=e,x.__H.__h.push(n))}function ve(t){return F=5,te(function(){return{current:t}},[])}function te(t,e){var n=_e(U++,7);return Ke(n.__H,e)&&(n.__=t(),n.__H=e,n.__h=t),n.__}function he(t,e){return F=8,te(function(){return t},e)}function dt(){for(var t;t=We.shift();){var e=t.__H;if(t.__P&&e)try{e.__h.some(Z),e.__h.some(pe),e.__h=[]}catch(n){e.__h=[],C.__e(n,t.__v)}}}C.__b=function(t){x=null,je&&je(t)},C.__=function(t,e){t&&e.__k&&e.__k.__m&&(t.__m=e.__k.__m),Be&&Be(t,e)},C.__r=function(t){Le&&Le(t),U=0;var e=(x=t.__c).__H;e&&(ue===x?(e.__h=[],x.__h=[],e.__.some(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0})):(e.__h.some(Z),e.__h.some(pe),e.__h=[],U=0)),ue=x},C.diffed=function(t){Ie&&Ie(t);var e=t.__c;e&&e.__H&&(e.__H.__h.length&&(We.push(e)!==1&&De===C.requestAnimationFrame||((De=C.requestAnimationFrame)||ut)(dt)),e.__H.__.some(function(n){n.u&&(n.__H=n.u,n.u=void 0)})),ue=x=null},C.__c=function(t,e){e.some(function(n){try{n.__h.some(Z),n.__h=n.__h.filter(function(s){return!s.__||pe(s)})}catch(s){e.some(function(o){o.__h&&(o.__h=[])}),e=[],C.__e(s,n.__v)}}),Ue&&Ue(t,e)},C.unmount=function(t){Fe&&Fe(t);var e,n=t.__c;n&&n.__H&&(n.__H.__.some(function(s){try{Z(s)}catch(o){e=o}}),n.__H=void 0,e&&C.__e(e,n.__v))};var Ve=typeof requestAnimationFrame=="function";function ut(t){var e,n=function(){clearTimeout(s),Ve&&cancelAnimationFrame(e),setTimeout(t)},s=setTimeout(n,35);Ve&&(e=requestAnimationFrame(n))}function Z(t){var e=x,n=t.__c;typeof n=="function"&&(t.__c=void 0,n()),x=e}function pe(t){var e=x;t.__c=t.__(),x=e}function Ke(t,e){return!t||t.length!==e.length||e.some(function(n,s){return n!==t[s]})}function ze(t,e){return typeof e=="function"?e(t):e}var Ye=function(t,e,n,s){var o;e[0]=0;for(var a=1;a<e.length;a++){var l=e[a++],u=e[a]?(e[0]|=l?1:2,n[e[a++]]):e[++a];l===3?s[0]=u:l===4?s[1]=Object.assign(s[1]||{},u):l===5?(s[1]=s[1]||{})[e[++a]]=u:l===6?s[1][e[++a]]+=u+"":l?(o=t.apply(u,Ye(t,u,n,["",null])),s.push(o),u[0]?e[0]|=2:(e[a-2]=0,e[a]=o)):s.push(u)}return s},Oe=new Map;function Ge(t){var e=Oe.get(this);return e||(e=new Map,Oe.set(this,e)),(e=Ye(this,e.get(t)||(e.set(t,e=(function(n){for(var s,o,a=1,l="",u="",_=[0],c=function(i){a===1&&(i||(l=l.replace(/^\\s*\\n\\s*|\\s*\\n\\s*$/g,"")))?_.push(0,i,l):a===3&&(i||l)?(_.push(3,i,l),a=2):a===2&&l==="..."&&i?_.push(4,i,0):a===2&&l&&!i?_.push(5,0,!0,l):a>=5&&((l||!i&&a===5)&&(_.push(a,0,l,o),a=6),i&&(_.push(a,i,0,o),a=6)),l=""},r=0;r<n.length;r++){r&&(a===1&&c(),c(r));for(var p=0;p<n[r].length;p++)s=n[r][p],a===1?s==="<"?(c(),_=[_],a=3):l+=s:a===4?l==="--"&&s===">"?(a=1,l=""):l=s+l[0]:u?s===u?u="":l+=s:s===\'"\'||s==="\'"?u=s:s===">"?(c(),a=1):a&&(s==="="?(a=5,o=l,l=""):s==="/"&&(a<5||n[r][p+1]===">")?(c(),a===3&&(_=_[0]),a=_,(_=_[0]).push(2,0,a),a=0):s===" "||s===" "||s===`\n`||s==="\\r"?(c(),a=2):l+=s),a===3&&l==="!--"&&(a=4,_=_[0])}return c(),_})(t)),e),arguments,[])).length>1?e:e[0]}var d=Ge.bind(re),Je=window.__QRING__&&window.__QRING__.token||"",fe=Je?"?token="+encodeURIComponent(Je):"",A=t=>\'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="url(#neon-grad)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\'+t+"</svg>",k={health:A(\'<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>\'),environment:A(\'<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>\'),decay:A(\'<path d="M5 22h14"/><path d="M5 2h14"/><path d="M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22"/><path d="M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2"/>\'),superposition:A(\'<polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/>\'),entangle:A(\'<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>\'),tunnel:A(\'<path d="M9 10h.01"/><path d="M15 10h.01"/><path d="M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z"/>\'),anomaly:A(\'<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>\'),audit:A(\'<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>\'),key:A(\'<path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/>\'),hook:A(\'<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>\'),approve:A(\'<path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/>\'),manifest:A(\'<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/>\'),policy:A(\'<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="M9 12l2 2 4-4"/>\'),memory:A(\'<rect x="4" y="4" width="16" height="16" rx="2"/><rect x="9" y="9" width="6" height="6"/><line x1="9" y1="2" x2="9" y2="4"/><line x1="15" y1="2" x2="15" y2="4"/><line x1="9" y1="20" x2="9" y2="22"/><line x1="15" y1="20" x2="15" y2="22"/><line x1="20" y1="9" x2="22" y2="9"/><line x1="20" y1="14" x2="22" y2="14"/><line x1="2" y1="9" x2="4" y2="9"/><line x1="2" y1="14" x2="4" y2="14"/>\'),folder:\'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>\',search:\'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>\',lock:\'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>\'};function $e(t){if(!t)return"env-default";let e=t.toLowerCase();return e==="prod"||e==="production"?"env-prod":e==="staging"||e==="stage"?"env-staging":e==="dev"||e==="development"?"env-dev":e==="test"||e==="testing"?"env-test":"env-default"}function Xe(t,e){return e||t>=90?"var(--danger)":t>=75?"var(--warning)":"var(--accent)"}function Ze(t){let e=new Date(t);return String(e.getHours()).padStart(2,"0")+":"+String(e.getMinutes()).padStart(2,"0")+":"+String(e.getSeconds()).padStart(2,"0")}function et(t){if(!t)return"\\u2014";let e=Math.floor((Date.now()-new Date(t).getTime())/1e3);return isNaN(e)?"\\u2014":e<5?"just now":e<60?e+"s ago":e<3600?Math.floor(e/60)+"m ago":e<86400?Math.floor(e/3600)+"h ago":Math.floor(e/86400)+"d ago"}function ye(t){return t==null?"\\u2014":t<0?"expired":t<60?t+"s":t<3600?Math.floor(t/60)+"m":t<86400?Math.floor(t/3600)+"h":Math.floor(t/86400)+"d"}var L=({svg:t})=>d`<span style="display:contents" dangerouslySetInnerHTML=${{__html:t}} />`;function M({icon:t,title:e,aside:n,asideStyle:s}){return d`<div class="card-title">\n <${L} svg=${t} />${e}\n ${n!=null?d`<span class="title-aside" style=${s||""}>${n}</span>`:null}\n </div>`}function S({delay:t=0,wide:e=!1,style:n="",children:s}){let o="card"+(e?" grid-wide":""),a="animation-delay:"+t+"ms"+(n?";"+n:"");return d`<div class=${o} style=${a}>${s}</div>`}function E({children:t,cta:e}){return d`<div class="empty">${t}${e?d`<span class="empty-cta">${e}</span>`:null}</div>`}function Qe({snap:t,paused:e,connState:n,onPause:s,onRefresh:o,lastUpdate:a}){let l=e?"paused":n==="live"?"live":n==="reconnecting"?"reconnecting\\u2026":"connecting\\u2026",u="status-dot"+(e?" paused":n==="reconnecting"?" disconnected":"");return d`\n <header class="header">\n <div class="header-left">\n <h1>\n <span class="q-icon"><svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="url(#neon-grad)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg></span>\n <span class="brand">q-ring</span>\n <span class="sub">quantum status</span>\n </h1>\n <span class="meta-chip" title="q-ring version">\n <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>\n ${" v"+(t?t.version:"")}\n </span>\n <span class="meta-chip" title="Project working directory">\n <${L} svg=${k.folder} /> ${t?t.projectPath:""}\n </span>\n </div>\n <div class="header-right">\n <span class="conn-label" title="Last update from the live stream"><span>${a}</span></span>\n <button class="btn" type="button" title="Pause / resume the live stream (P)" onClick=${s}>\n ${e?d`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>`:d`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="4" width="4" height="16" rx="1"/><rect x="14" y="4" width="4" height="16" rx="1"/></svg>`}\n <span>${e?"Resume":"Pause"}</span>\n </button>\n <button class="btn" type="button" title="Force-refresh now (R)" onClick=${o}>\n <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-3.5-7.1"/><polyline points="21 3 21 9 15 9"/></svg>\n Refresh\n </button>\n <a class="btn" href=${"/api/status"+fe} target="_blank" rel="noopener" title="Open the raw JSON snapshot in a new tab">\n <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>\n JSON\n </a>\n <span class="conn-label"><span class=${u}></span><span>${l}</span></span>\n </div>\n </header>\n `}function pt({snap:t}){let e=t,n=e.auditMetrics||{total:0,byAction:{},topRead:[]},s=n.byAction.read||0,o=(n.byAction.write||0)+(n.byAction.delete||0)+(n.byAction.rotate||0),a=n.byAction.policy_deny||0,l=(e.hooks||[]).filter(r=>r.enabled).length,u=(e.approvals||[]).filter(r=>r.valid).length,_=(e.anomalies||[]).length,c=[{label:"Secrets",icon:k.key,value:e.health.total,sub:e.health.healthy+" healthy \\xB7 "+e.health.stale+" stale \\xB7 "+e.health.expired+" expired",cls:""},{label:"Environment",icon:k.environment,value:e.environment?e.environment.env:"none",sub:e.environment?"via "+e.environment.source:"no env detected",cls:e.environment?"":"dim"},{label:"Protected",icon:k.lock,value:e.protectedCount,sub:"require approval",cls:e.protectedCount>0?"warning":"dim"},{label:"Approvals",icon:k.approve,value:u,sub:"active grants",cls:u>0?"green":"dim"},{label:"Hooks",icon:k.hook,value:l,sub:"enabled / "+(e.hooks||[]).length+" total",cls:l>0?"":"dim"},{label:"Reads (24h)",icon:k.audit,value:s,sub:o+" writes \\xB7 "+a+" denied",cls:""},{label:"Anomalies",icon:k.anomaly,value:_,sub:_?"investigate now":"all clear",cls:_?"danger":"green"}];return d`<section class="kpi-strip">\n ${c.map(r=>d`<div class="kpi" key=${r.label}>\n <div class="kpi-label"><${L} svg=${r.icon} />${r.label}</div>\n <div class="kpi-value ${r.cls}">${r.value}</div>\n <div class="kpi-sub">${r.sub}</div>\n </div>`)}\n </section>`}function _t({snap:t,delay:e}){let n=t.health,s=n.total||1,o=42,a=2*Math.PI*o,l=[{v:n.healthy,c:"var(--accent)"},{v:n.stale,c:"var(--warning)"},{v:n.expired,c:"var(--danger)"},{v:n.noDecay,c:"var(--text-dim)"}],u=0,_=l.map((r,p)=>{let i=r.v/s*a,v=d`<circle key=${p} cx="50" cy="50" r=${o} fill="none" stroke=${r.c} stroke-width="12" stroke-dasharray=${i+" "+(a-i)} stroke-dashoffset=${-u} stroke-linecap="round" opacity="0.85" />`;return u+=i,v}),c=t.scopes||{global:0,project:0,team:0,org:0};return d`<${S} delay=${e}>\n <${M} icon=${k.health} title="Health Summary" aside=${n.healthy+"/"+n.total+" healthy"} />\n <div class="health-row">\n <div class="donut-wrap">\n <svg viewBox="0 0 100 100" width="100" height="100">${_}</svg>\n <div class="donut-label">${n.total}<small>secrets</small></div>\n </div>\n <div class="health-legend">\n <div class="legend-item"><span class="legend-dot" style="background:var(--accent)"></span>Healthy ${n.healthy}</div>\n <div class="legend-item"><span class="legend-dot" style="background:var(--warning)"></span>Stale ${n.stale}</div>\n <div class="legend-item"><span class="legend-dot" style="background:var(--danger)"></span>Expired ${n.expired}</div>\n <div class="legend-item"><span class="legend-dot" style="background:var(--text-dim)"></span>No decay ${n.noDecay}</div>\n </div>\n </div>\n <div class="scope-row">\n ${["global","project","team","org"].filter(r=>c[r]).map(r=>d`<span class="scope-pill" key=${r}><strong>${c[r]}</strong>${r}</span>`)}\n </div>\n <//>`}function vt({snap:t,delay:e}){let n=t.environment;return d`<${S} delay=${e}>\n <${M} icon=${k.environment} title="Environment" />\n ${n?d`<div class="env-status"><span class="env-big env-pill ${$e(n.env)}">${n.env}</span><span class="env-source">detected via ${n.source}</span></div>`:d`<${E} cta="$ qring env --project-path .">No environment detected.<//>`}\n <//>`}function ht({snap:t,delay:e}){let n=t.manifest;if(!n)return d`<${S} delay=${e}>\n <${M} icon=${k.manifest} title="Manifest" />\n <${E} cta=${d`$ qring wizard <name>`}>No <code>.q-ring.json</code> manifest in this project.<//>\n <//>`;let s=n.required-n.missing.length-n.expired.length-n.stale.length,o=n.required?Math.max(0,Math.round(s/n.required*100)):100,a=n.missing.length?"var(--danger)":n.expired.length||n.stale.length?"var(--warning)":"var(--green)",l=(_,c,r)=>d`<div class="label">${_} (${c.length})</div><div>${c.map(p=>d`<span class="key-pill ${r}" key=${p}>${p}</span>`)}</div>`,u=n.missing.length||n.expired.length||n.stale.length;return d`<${S} delay=${e}>\n <${M} icon=${k.manifest} title="Manifest" aside=${n.required+" required / "+n.declared+" declared"} />\n <div class="manifest-bars">\n <div class="manifest-row"><span style="min-width:54px">healthy</span><div class="manifest-bar"><div class="manifest-fill" style=${"width:"+o+"%;background:"+a}></div></div><span>${o}%</span></div>\n </div>\n <div class="manifest-list">\n ${n.missing.length?l("Missing required",n.missing,"miss"):null}\n ${n.expired.length?l("Expired",n.expired,"exp"):null}\n ${n.stale.length?l("Stale",n.stale,"exp"):null}\n ${u?null:d`<div class="label">All required keys present and healthy.</div>`}\n </div>\n <//>`}function ft({snap:t,delay:e}){let n=t.policy||{counts:{}},s=n.counts||{};if(!(n.hasMcpPolicy||n.hasExecPolicy||n.hasSecretPolicy))return d`<${S} delay=${e}>\n <${M} icon=${k.policy} title="Policy" />\n <${E} cta=${d`add <code>policy</code> to <code>.q-ring.json</code>`}>No governance policy declared.<//>\n <//>`;let a=({label:u,value:_})=>d`<div class="policy-row"><span class="policy-label">${u}</span><span class="policy-value ${_?"":"zero"}">${_||"\\u2014"}</span></div>`,l=[n.hasMcpPolicy?"mcp":"",n.hasExecPolicy?"exec":"",n.hasSecretPolicy?"secrets":""].filter(Boolean).join(" \\xB7 ")||"none";return d`<${S} delay=${e}>\n <${M} icon=${k.policy} title="Policy" aside=${l} />\n <div class="policy-rows">\n <${a} label="MCP allow tools" value=${s.allowTools} />\n <${a} label="MCP deny tools" value=${s.denyTools} />\n <${a} label="Denied keys" value=${s.deniedKeys} />\n <${a} label="Denied tags" value=${s.deniedTags} />\n <${a} label="Exec allow" value=${s.allowCommands} />\n <${a} label="Exec deny" value=${s.denyCommands} />\n <${a} label="Tag \u2192 approval" value=${s.requireApprovalForTags} />\n <${a} label="Tag \u2192 rotation" value=${s.requireRotationFormatForTags} />\n ${n.maxTtlSeconds?d`<${a} label="Max TTL" value=${ye(n.maxTtlSeconds)} />`:null}\n ${n.maxRuntimeSeconds?d`<${a} label="Max exec runtime" value=${ye(n.maxRuntimeSeconds)} />`:null}\n </div>\n <//>`}function yt({snap:t,delay:e}){let n=(t.secrets||[]).filter(s=>s.decay&&s.decay.timeRemaining).sort((s,o)=>(s.decay.secondsRemaining||0)-(o.decay.secondsRemaining||0));return d`<${S} delay=${e}>\n <${M} icon=${k.decay} title="Decay Timers" aside=${n.length+" tracked"} />\n ${n.length?d`<div class="decay-list">${n.slice(0,12).map(s=>{let o=Math.min(s.decay.lifetimePercent,100),a=Xe(o,s.decay.isExpired),l=s.decay.isExpired?"expired":s.decay.timeRemaining||"";return d`<div class="decay-item" key=${s.scope+":"+s.key}>\n <span class="decay-key" title=${s.key}>${s.key}</span>\n <div class="decay-bar"><div class="decay-fill" style=${"width:"+o+"%;background:"+a}></div></div>\n <span class="decay-time" style=${"color:"+a}>${l}</span>\n </div>`})}</div>`:d`<${E} cta="$ qring set KEY --ttl 86400">No secrets with decay configured.<//>`}\n <//>`}function $t({snap:t,delay:e}){let n=(t.secrets||[]).filter(s=>s.type==="superposition"&&s.environments&&s.environments.length);return d`<${S} delay=${e}>\n <${M} icon=${k.superposition} title="Superposition" aside=${n.length+" multi-env"} />\n ${n.length?d`<div class="super-list">${n.slice(0,14).map(s=>d`<div class="super-item" key=${s.scope+":"+s.key}>\n <span class="super-key">${s.key}</span>\n ${(s.environments||[]).map(o=>d`<span class="env-pill ${$e(o)}" key=${o}>${o}${o===s.defaultEnv?" \\u2713":""}</span>`)}\n </div>`)}</div>`:d`<${E} cta="$ qring set KEY --env prod">No secrets in superposition.<//>`}\n <//>`}function mt({snap:t,delay:e}){let n=t.entanglements||[],s=new Set,o=n.filter(h=>{let y=[h.source.service,h.source.key,h.target.service,h.target.key].sort().join("|");return s.has(y)?!1:(s.add(y),!0)}),a=[],l=new Map;for(let h of o)for(let y of[h.source.key,h.target.key])l.has(y)||(l.set(y,a.length),a.push(y));let u=o.length>0&&a.length<=14,_=320,c=210,r=_/2,p=c/2,i=Math.min(_,c)/2-34,v=a.map((h,y)=>{let m=2*Math.PI*y/a.length-Math.PI/2;return{x:r+i*Math.cos(m),y:p+i*Math.sin(m)}}),f=h=>h.length>14?h.slice(0,12)+"\\u2026":h;return d`<${S} delay=${e}>\n <${M} icon=${k.entangle} title="Entanglement" aside=${o.length+" pair"+(o.length===1?"":"s")+" \\xB7 "+a.length+" keys"} />\n ${o.length?u?d`<svg class="entangle-graph" viewBox="0 0 ${_} ${c}" role="img" aria-label="Entanglement graph: ${o.length} linked pairs">\n ${o.map((h,y)=>{let m=v[l.get(h.source.key)],$=v[l.get(h.target.key)];return d`<line key=${"e"+y} x1=${m.x} y1=${m.y} x2=${$.x} y2=${$.y} class="entangle-edge" />`})}\n ${a.map((h,y)=>{let m=v[y],$=m.x>=r;return d`<g key=${"n"+y}>\n <circle cx=${m.x} cy=${m.y} r="5" class="entangle-node" />\n <text x=${m.x+($?9:-9)} y=${m.y+3.5} text-anchor=${$?"start":"end"} class="entangle-label">${f(h)}<title>${h}</title></text>\n </g>`})}\n </svg>`:d`<div class="entangle-list">${o.slice(0,12).map((h,y)=>d`<div class="entangle-pair" key=${y}>\n <span>${h.source.key}</span><span class="entangle-arrow">\u2194</span><span>${h.target.key}</span>\n </div>`)}</div>`:d`<${E} cta="$ qring entangle KEY_A KEY_B">No entangled secrets.<//>`}\n <//>`}function gt({snap:t,delay:e}){let n=t.tunnels||[];return d`<${S} delay=${e}>\n <${M} icon=${k.tunnel} title="Quantum Tunnels" aside=${n.length+" live"} />\n ${n.length?d`<div class="tunnel-list">${n.map(s=>{let o=s.expiresAt?Math.max(0,Math.floor((s.expiresAt-Date.now())/1e3)):null;return d`<div class="tunnel-card" key=${s.id}>${s.id}<div class="tunnel-meta">\n <span>reads: ${s.accessCount}${s.maxReads?"/"+s.maxReads:""}</span>\n ${o!==null?d`<span>expires: ${o}s</span>`:d`<span>no expiry</span>`}\n </div></div>`})}</div>`:d`<${E} cta=${d`$ qring tunnel create <value>`}>No active tunnels.<//>`}\n <//>`}function kt({snap:t,delay:e}){let n=t.approvals||[];return d`<${S} delay=${e}>\n <${M} icon=${k.approve} title="Approvals" aside=${n.filter(s=>s.valid).length+" valid"} />\n ${n.length?d`<div class="approval-list">${n.slice(0,8).map(s=>{let o=s.tampered?"tampered":s.secondsRemaining<300?"expiring":"";return d`<div class="approval-card ${o}" key=${s.id}>\n <div class="approval-head"><span>${s.key}${s.tampered?" \\u26A0 TAMPERED":""}</span><span>${ye(s.secondsRemaining)} left</span></div>\n <div class="approval-reason">${s.reason||"(no reason)"}</div>\n <div class="approval-meta"><span>scope:${s.scope}</span><span>by:${s.grantedBy}</span></div>\n </div>`})}</div>`:d`<${E} cta=${\'$ qring approve KEY --for 1800 --reason "..."\'}>No active approvals.<//>`}\n <//>`}function bt({snap:t,delay:e}){let n=t.hooks||[];return d`<${S} delay=${e}>\n <${M} icon=${k.hook} title="Hooks" aside=${n.filter(s=>s.enabled).length+" enabled / "+n.length} />\n ${n.length?d`<div class="hooks-list">${n.slice(0,8).map(s=>d`<div class="hook-row ${s.enabled?"":"disabled"}" key=${s.id}>\n <span class="hook-type ${s.type}">${s.type}</span>\n <span class="hook-summary" title=${s.matchSummary}>${s.description||s.matchSummary}</span>\n <span class="hook-id">${s.id}</span>\n </div>`)}</div>`:d`<${E} cta=${\'$ qring hook add --tag payments --action rotate --exec "..."\'}>No hooks registered.<//>`}\n <//>`}function xt({snap:t,delay:e}){return d`<${S} delay=${e}>\n <${M} icon=${k.memory} title="Agent Memory" />\n <div class="empty" style="display:flex;align-items:baseline;gap:8px;font-style:normal">\n <span style="font-size:1.6rem;font-weight:700;color:var(--text-primary);font-family:var(--font-display)">${t.memoryKeys||0}</span>\n <span>memory key${t.memoryKeys===1?"":"s"} encrypted at <code>~/.config/q-ring/agent-memory.enc</code></span>\n </div>\n <//>`}function wt({snap:t,delay:e}){let n=t.anomalies||[];if(!n.length)return d`<${S} delay=${e} wide=${!0}>\n <${M} icon=${k.anomaly} title="Anomaly Alerts" aside="all clear" asideStyle="color:var(--green)" />\n <${E}>No anomalies detected \u2014 quantum field is stable.<//>\n <//>`;let s=o=>o==="tampered"?"$ qring audit:verify":o==="burst"?"$ qring audit --key \\u2026 --action read":o==="unusual-hour"?\'$ qring audit --action read --since "1am"\':"$ qring audit --limit 100";return d`<${S} delay=${e} wide=${!0}>\n <${M} icon=${k.anomaly} title="Anomaly Alerts" aside=${n.length+" active"} asideStyle="color:var(--danger)" />\n <div class="anomaly-list">${n.map((o,a)=>d`<div class="anomaly-card" key=${a}>\n <div class="anomaly-type">${o.type}</div>\n <div class="anomaly-desc">${o.description}</div>\n <div class="anomaly-hint">${s(o.type)}</div>\n </div>`)}</div>\n <//>`}function Ct(t,e){let n=e.trim().toLowerCase();return n?n==="expired"?t.filter(s=>s.decay&&s.decay.isExpired):n==="stale"?t.filter(s=>s.decay&&s.decay.isStale&&!s.decay.isExpired):n==="protected"?t.filter(s=>s.requiresApproval):t.filter(s=>[s.key,s.scope,s.type,s.provider||"",s.defaultEnv||"",(s.environments||[]).join(" "),(s.tags||[]).join(" ")].join(" ").toLowerCase().indexOf(n)!==-1):t.slice()}function Mt(t,e){let n=e.dir==="asc"?1:-1;return t.sort((s,o)=>{let a,l;switch(e.col){case"key":a=s.key,l=o.key;break;case"scope":a=s.scope,l=o.scope;break;case"env":a=s.defaultEnv||(s.environments||[])[0]||"",l=o.defaultEnv||(o.environments||[])[0]||"";break;case"type":a=s.type,l=o.type;break;case"decay":a=s.decay&&s.decay.secondsRemaining!=null?s.decay.secondsRemaining:1/0,l=o.decay&&o.decay.secondsRemaining!=null?o.decay.secondsRemaining:1/0;break;case"tags":a=(s.tags||[]).join(","),l=(o.tags||[]).join(",");break;default:a=s.lastAccessedAt?new Date(s.lastAccessedAt).getTime():0,l=o.lastAccessedAt?new Date(o.lastAccessedAt).getTime():0}return a<l?-1*n:a>l?1*n:0})}function St({snap:t,query:e,setQuery:n,sort:s,setSort:o,searchRef:a}){let l=t.secrets||[],u=te(()=>Mt(Ct(l,e),s),[l,e,s]),_=[{id:"key",label:"Key"},{id:"scope",label:"Scope"},{id:"env",label:"Env"},{id:"type",label:"Type"},{id:"decay",label:"Decay"},{id:"tags",label:"Tags"},{id:"lastAccessedAt",label:"Last read"}],c=r=>{s.col===r?o({col:r,dir:s.dir==="asc"?"desc":"asc"}):o({col:r,dir:r==="key"?"asc":"desc"})};return d`<section><${S} wide=${!0} style="margin-bottom:16px">\n <${M} icon=${k.key} title="Secrets" aside=${u.length+" of "+l.length} />\n <div class="secrets-toolbar">\n <label class="search"><${L} svg=${k.search} /><input ref=${a} id="secretsSearch" type="search" placeholder="Filter by key, scope, env, tag, provider\u2026" autocomplete="off" value=${e} onInput=${r=>n(r.target.value)} /></label>\n <button class="btn" type="button" onClick=${()=>n("expired")}>${t.health.expired||0} expired</button>\n <button class="btn" type="button" onClick=${()=>n("stale")}>${t.health.stale||0} stale</button>\n <button class="btn" type="button" onClick=${()=>n("protected")}>${t.protectedCount||0} protected</button>\n <button class="btn" type="button" onClick=${()=>n("")}>clear</button>\n </div>\n <div class="secrets-table-wrap">\n ${u.length?d`<table class="secrets-table">\n <thead><tr>${_.map(r=>d`<th key=${r.id} class=${s.col===r.id?"sorted":""} onClick=${()=>c(r.id)}>${r.label}<span class="sort-arrow">${s.dir==="asc"?"\\u25B2":"\\u25BC"}</span></th>`)}</tr></thead>\n <tbody>${u.map(r=>{let p=r.type==="superposition"?(r.environments||[]).map(f=>d`<span class="env-pill ${$e(f)}" style="margin-right:3px" key=${f}>${f}${f===r.defaultEnv?" \\u2713":""}</span>`):d`<span class="env-pill env-default">\u2014</span>`,i=r.decay&&r.decay.timeRemaining?(()=>{let f=Math.min(r.decay.lifetimePercent,100),h=Xe(f,r.decay.isExpired);return d`<span class="mini-decay"><span class="mini-decay-bar"><span class="mini-decay-fill" style=${"width:"+f+"%;background:"+h}></span></span><span class="mini-decay-time" style=${"color:"+h}>${r.decay.isExpired?"expired":r.decay.timeRemaining}</span></span>`})():d`<span class="mini-decay-time">\u2014</span>`,v=r.tags||[];return d`<tr key=${r.scope+":"+r.key}>\n <td class="col-key" title=${r.key}>${r.key}${r.requiresApproval?d`<span class="protected-icon" title="requires approval for MCP read"><${L} svg=${k.lock} /></span>`:null}</td>\n <td><span class="scope-tag ${r.scope}">${r.scope}</span></td>\n <td>${p}</td>\n <td><span class="type-tag ${r.type}">${r.type}</span></td>\n <td class="col-decay">${i}</td>\n <td class="col-tags">${v.slice(0,3).map(f=>d`<span class="tag-pill" key=${f}>${f}</span>`)}${v.length>3?"+"+(v.length-3):""}</td>\n <td>${et(r.lastAccessedAt)}</td>\n </tr>`})}</tbody>\n </table>`:d`<div class="empty" style="padding:18px;text-align:center">No secrets match the filter.</div>`}\n </div>\n <//></section>`}function At({snap:t,delay:e,filter:n,setFilter:s}){let o=t.audit||[],a=t.auditMetrics||{byAction:{},bySource:{}},l=o.filter(p=>{if(n.action&&p.action!==n.action||n.source&&p.source!==n.source)return!1;let i=n.text.trim().toLowerCase();return!(i&&[p.key||"",p.action,p.source,p.detail||"",p.scope||"",p.env||""].join(" ").toLowerCase().indexOf(i)===-1)}),u=["read","write","delete","rotate","generate","entangle","tunnel","teleport","approve","revoke","policy_deny","collapse","export"],_=["cli","mcp","agent","ci","hook","api"],c=(p,i)=>s({...n,[p]:n[p]===i?"":i}),r=t.auditChain;return d`<${S} delay=${e} wide=${!0}>\n <${M} icon=${k.audit} title="Audit Log (24h)" aside=${l.length+" of "+o.length+" shown \\xB7 window "+(a.windowSeconds||86400)/3600+"h"} />\n ${r&&r.totalEvents>0?d`<div class="chain-badge ${r.intact?"ok":"broken"}" title="Hash-chain integrity \u2014 same check as qring audit:verify">\n ${r.intact?d`\u26D3 chain intact \xB7 ${r.totalEvents} events verified`:d`\u26D3 chain BROKEN at event #${r.brokenAt} \xB7 ${r.validEvents}/${r.totalEvents} valid \u2014 run $ qring audit:verify`}\n </div>`:null}\n <div class="audit-actions-strip">\n ${u.filter(p=>a.byAction[p]).length?u.filter(p=>a.byAction[p]).map(p=>d`<span class="audit-chip ${n.action===p?"active":""}" key=${p} onClick=${()=>c("action",p)}>${p}<strong>${a.byAction[p]}</strong></span>`):d`<span class="empty" style="padding:0">no actions</span>`}\n </div>\n ${_.filter(p=>a.bySource[p]).length?d`<div class="audit-actions-strip">${_.filter(p=>a.bySource[p]).map(p=>d`<span class="audit-chip ${n.source===p?"active":""}" key=${p} onClick=${()=>c("source",p)}>${p}<strong>${a.bySource[p]}</strong></span>`)}</div>`:null}\n <div class="audit-toolbar">\n <label class="search"><${L} svg=${k.search} /><input id="auditSearch" type="search" placeholder="Filter by key, detail, scope\u2026" autocomplete="off" value=${n.text} onInput=${p=>s({...n,text:p.target.value})} /></label>\n <button class="btn" type="button" onClick=${()=>s({action:"",source:"",text:""})}>clear</button>\n </div>\n ${l.length?d`<div class="audit-feed">${l.slice(0,80).map((p,i)=>d`<div class="audit-row" key=${i}>\n <span class="audit-ts" title=${p.timestamp}>${Ze(p.timestamp)}</span>\n <span class="audit-action ${p.action}">${p.action}</span>\n <span class="audit-source">${p.source}</span>\n <span><span class="audit-key">${p.key||"\\u2014"}</span> <span class="audit-detail">${p.detail||""}</span></span>\n </div>`)}</div>`:d`<${E}>No audit events match the filter.<//>`}\n <//>`}function Et(){let[t,e]=N(null),[n,s]=N(!1),[o,a]=N("connecting"),[l,u]=N(""),[_,c]=N({col:"lastAccessedAt",dir:"desc"}),[r,p]=N({action:"",source:"",text:""}),[,i]=N(0),v=ve(n);v.current=n;let f=ve(null),h=he(g=>{try{e(typeof g=="string"?JSON.parse(g):g)}catch{}},[]),y=he(()=>{fetch("/api/status"+fe,{cache:"no-store"}).then(g=>g.json()).then(h).catch(()=>{})},[h]);ee(()=>{let g=new EventSource("/events"+fe);return g.onopen=()=>a("live"),g.onmessage=w=>{v.current||h(w.data)},g.onerror=()=>a("reconnecting"),()=>g.close()},[h]),ee(()=>{let g=setInterval(()=>i(w=>w+1),5e3);return()=>clearInterval(g)},[]),ee(()=>{let g=w=>{let P=w.target&&w.target.tagName;if(P==="INPUT"||P==="TEXTAREA"){w.key==="Escape"&&w.target.blur();return}w.key==="/"?(w.preventDefault(),f.current&&f.current.focus()):w.key==="p"||w.key==="P"?s(H=>!H):(w.key==="r"||w.key==="R")&&y()};return document.addEventListener("keydown",g),()=>document.removeEventListener("keydown",g)},[y]);let m=t?"updated "+et(t.timestamp):"\\u2014";if(!t)return d`<div class="container">\n <${Qe} snap=${null} paused=${n} connState=${o} onPause=${()=>s(g=>!g)} onRefresh=${y} lastUpdate=${m} />\n <p class="foot"><span>Connecting to the live quantum stream\u2026</span></p>\n </div>`;let $=t.auditMetrics||{total:0};return d`<div class="container">\n <${Qe} snap=${t} paused=${n} connState=${o} onPause=${()=>s(g=>!g)} onRefresh=${y} lastUpdate=${m} />\n <${pt} snap=${t} />\n <section class="grid">\n <${_t} snap=${t} delay=${0} />\n <${vt} snap=${t} delay=${60} />\n <${ht} snap=${t} delay=${120} />\n <${ft} snap=${t} delay=${180} />\n </section>\n <${St} snap=${t} query=${l} setQuery=${u} sort=${_} setSort=${c} searchRef=${f} />\n <section class="grid">\n <${yt} snap=${t} delay=${0} />\n <${$t} snap=${t} delay=${60} />\n <${mt} snap=${t} delay=${120} />\n <${gt} snap=${t} delay=${180} />\n </section>\n <section class="grid">\n <${kt} snap=${t} delay=${0} />\n <${bt} snap=${t} delay=${60} />\n <${xt} snap=${t} delay=${120} />\n </section>\n <section class="grid">\n <${wt} snap=${t} delay=${0} />\n <${At} snap=${t} delay=${60} filter=${r} setFilter=${p} />\n </section>\n <p class="foot">\n <span>${"q-ring v"+t.version+" \\xB7 snapshot "+Ze(t.timestamp)+" \\xB7 "+($.total||0)+" audit events in last 24h"}</span>\n \xB7 keyboard: <span class="kbd">/</span> search \xB7 <span class="kbd">P</span> pause \xB7 <span class="kbd">R</span> refresh\n </p>\n </div>`}He(d`<${Et} />`,document.getElementById("app"));})();';
25
+ var DASHBOARD_CLIENT = '"use strict";(()=>{var J,b,Me,tt,N,be,Se,Ae,ae,W,I,Ee,le,ie,oe,nt,z={},Y=[],st=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,Q=Array.isArray;function T(t,e){for(var n in e)t[n]=e[n];return t}function re(t){t&&t.parentNode&&t.parentNode.removeChild(t)}function ce(t,e,n){var s,i,a,l={};for(a in e)a=="key"?s=e[a]:a=="ref"?i=e[a]:l[a]=e[a];if(arguments.length>2&&(l.children=arguments.length>3?J.call(arguments,2):n),typeof t=="function"&&t.defaultProps!=null)for(a in t.defaultProps)l[a]===void 0&&(l[a]=t.defaultProps[a]);return K(t,l,s,i,null)}function K(t,e,n,s,i){var a={type:t,props:e,key:n,ref:s,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:i==null?++Me:i,__i:-1,__u:0};return i==null&&b.vnode!=null&&b.vnode(a),a}function X(t){return t.children}function O(t,e){this.props=t,this.context=e}function D(t,e){if(e==null)return t.__?D(t.__,t.__i+1):null;for(var n;e<t.__k.length;e++)if((n=t.__k[e])!=null&&n.__e!=null)return n.__e;return typeof t.type=="function"?D(t):null}function at(t){if(t.__P&&t.__d){var e=t.__v,n=e.__e,s=[],i=[],a=T({},e);a.__v=e.__v+1,b.vnode&&b.vnode(a),de(t.__P,a,e,t.__n,t.__P.namespaceURI,32&e.__u?[n]:null,s,n==null?D(e):n,!!(32&e.__u),i),a.__v=e.__v,a.__.__k[a.__i]=a,Ne(s,a,i),e.__e=e.__=null,a.__e!=n&&Pe(a)}}function Pe(t){if((t=t.__)!=null&&t.__c!=null)return t.__e=t.__c.base=null,t.__k.some(function(e){if(e!=null&&e.__e!=null)return t.__e=t.__c.base=e.__e}),Pe(t)}function xe(t){(!t.__d&&(t.__d=!0)&&N.push(t)&&!G.__r++||be!=b.debounceRendering)&&((be=b.debounceRendering)||Se)(G)}function G(){try{for(var t,e=1;N.length;)N.length>e&&N.sort(Ae),t=N.shift(),e=N.length,at(t)}finally{N.length=G.__r=0}}function Re(t,e,n,s,i,a,l,r,u,d,c){var _,o,v,y,h,f,m=s&&s.__k||Y,$=e.length;for(u=it(n,e,m,u,$),_=0;_<$;_++)(v=n.__k[_])!=null&&(o=v.__i!=-1&&m[v.__i]||z,v.__i=_,f=de(t,v,o,i,a,l,r,u,d,c),y=v.__e,v.ref&&o.ref!=v.ref&&(o.ref&&pe(o.ref,null,v),c.push(v.ref,v.__c||y,v)),h==null&&y!=null&&(h=y),4&v.__u?(u=Te(v,u,t),o.__e&&(o.__e=null)):typeof v.type=="function"&&f!==void 0?u=f:y&&(u=y.nextSibling),v.__u&=-7);return n.__e=h,u}function it(t,e,n,s,i){var a,l,r,u,d,c=n.length,_=c,o=0;for(t.__k=new Array(i),a=0;a<i;a++)(l=e[a])!=null&&typeof l!="boolean"&&typeof l!="function"?(typeof l=="string"||typeof l=="number"||typeof l=="bigint"||l.constructor==String?l=t.__k[a]=K(null,l,null,null,null):Q(l)?l=t.__k[a]=K(X,{children:l},null,null,null):l.constructor===void 0&&l.__b>0?l=t.__k[a]=K(l.type,l.props,l.key,l.ref?l.ref:null,l.__v):t.__k[a]=l,u=a+o,l.__=t,l.__b=t.__b+1,r=null,(d=l.__i=ot(l,n,u,_))!=-1&&(_--,(r=n[d])&&(r.__u|=2)),r==null||r.__v==null?(d==-1&&(i>c?o--:i<c&&o++),typeof l.type!="function"&&(l.__u|=4)):d!=u&&(d==u-1?o--:d==u+1?o++:(d>u?o--:o++,l.__u|=4))):t.__k[a]=null;if(_)for(a=0;a<c;a++)(r=n[a])!=null&&(2&r.__u)==0&&(r.__e==s&&(s=D(r)),De(r,r));return s}function Te(t,e,n){var s,i;if(typeof t.type=="function"){for(s=t.__k,i=0;s&&i<s.length;i++)s[i]&&(s[i].__=t,e=Te(s[i],e,n));return e}t.__e!=e&&(e&&t.type&&!e.parentNode&&(e=D(t)),e=n.insertBefore(t.__e,e||null));do e=e&&e.nextSibling;while(e!=null&&e.nodeType==8);return e}function ot(t,e,n,s){var i,a,l,r=t.key,u=t.type,d=e[n],c=d!=null&&(2&d.__u)==0;if(d===null&&r==null||c&&r==d.key&&u==d.type)return n;if(s>(c?1:0)){for(i=n-1,a=n+1;i>=0||a<e.length;)if((d=e[l=i>=0?i--:a++])!=null&&(2&d.__u)==0&&r==d.key&&u==d.type)return l}return-1}function we(t,e,n){e[0]=="-"?t.setProperty(e,n==null?"":n):t[e]=n==null?"":typeof n!="number"||st.test(e)?n:n+"px"}function V(t,e,n,s,i){var a,l;e:if(e=="style")if(typeof n=="string")t.style.cssText=n;else{if(typeof s=="string"&&(t.style.cssText=s=""),s)for(e in s)n&&e in n||we(t.style,e,"");if(n)for(e in n)s&&n[e]==s[e]||we(t.style,e,n[e])}else if(e[0]=="o"&&e[1]=="n")a=e!=(e=e.replace(Ee,"$1")),l=e.toLowerCase(),e=l in t||e=="onFocusOut"||e=="onFocusIn"?l.slice(2):e.slice(2),t.l||(t.l={}),t.l[e+a]=n,n?s?n[I]=s[I]:(n[I]=le,t.addEventListener(e,a?oe:ie,a)):t.removeEventListener(e,a?oe:ie,a);else{if(i=="http://www.w3.org/2000/svg")e=e.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(e!="width"&&e!="height"&&e!="href"&&e!="list"&&e!="form"&&e!="tabIndex"&&e!="download"&&e!="rowSpan"&&e!="colSpan"&&e!="role"&&e!="popover"&&e in t)try{t[e]=n==null?"":n;break e}catch{}typeof n=="function"||(n==null||n===!1&&e[4]!="-"?t.removeAttribute(e):t.setAttribute(e,e=="popover"&&n==1?"":n))}}function Ce(t){return function(e){if(this.l){var n=this.l[e.type+t];if(e[W]==null)e[W]=le++;else if(e[W]<n[I])return;return n(b.event?b.event(e):e)}}}function de(t,e,n,s,i,a,l,r,u,d){var c,_,o,v,y,h,f,m,$,g,w,P,H,ke,F,se,R=e.type;if(e.constructor!==void 0)return null;128&n.__u&&(u=!!(32&n.__u),a=[r=e.__e=n.__e]),(c=b.__b)&&c(e);e:if(typeof R=="function"){_=l.length;try{if($=e.props,g=R.prototype&&R.prototype.render,w=(c=R.contextType)&&s[c.__c],P=c?w?w.props.value:c.__:s,n.__c?m=(o=e.__c=n.__c).__=o.__E:(g?e.__c=o=new R($,P):(e.__c=o=new O($,P),o.constructor=R,o.render=rt),w&&w.sub(o),o.state||(o.state={}),o.__n=s,v=o.__d=!0,o.__h=[],o._sb=[]),g&&o.__s==null&&(o.__s=o.state),g&&R.getDerivedStateFromProps!=null&&(o.__s==o.state&&(o.__s=T({},o.__s)),T(o.__s,R.getDerivedStateFromProps($,o.__s))),y=o.props,h=o.state,o.__v=e,v)g&&R.getDerivedStateFromProps==null&&o.componentWillMount!=null&&o.componentWillMount(),g&&o.componentDidMount!=null&&o.__h.push(o.componentDidMount);else{if(g&&R.getDerivedStateFromProps==null&&$!==y&&o.componentWillReceiveProps!=null&&o.componentWillReceiveProps($,P),e.__v==n.__v||!o.__e&&o.shouldComponentUpdate!=null&&o.shouldComponentUpdate($,o.__s,P)===!1){e.__v!=n.__v&&(o.props=$,o.state=o.__s,o.__d=!1),e.__e=n.__e,e.__k=n.__k,e.__k.some(function(L){L&&(L.__=e)}),Y.push.apply(o.__h,o._sb),o._sb=[],o.__h.length&&l.push(o),r=D(n);break e}o.componentWillUpdate!=null&&o.componentWillUpdate($,o.__s,P),g&&o.componentDidUpdate!=null&&o.__h.push(function(){o.componentDidUpdate(y,h,f)})}if(o.context=P,o.props=$,o.__P=t,o.__e=!1,H=b.__r,ke=0,g)o.state=o.__s,o.__d=!1,H&&H(e),c=o.render(o.props,o.state,o.context),Y.push.apply(o.__h,o._sb),o._sb=[];else do o.__d=!1,H&&H(e),c=o.render(o.props,o.state,o.context),o.state=o.__s;while(o.__d&&++ke<25);o.state=o.__s,o.getChildContext!=null&&(s=T(T({},s),o.getChildContext())),g&&!v&&o.getSnapshotBeforeUpdate!=null&&(f=o.getSnapshotBeforeUpdate(y,h)),F=c!=null&&c.type===X&&c.key==null?He(c.props.children):c,r=Re(t,Q(F)?F:[F],e,n,s,i,a,l,r,u,d),o.base=e.__e,e.__u&=-161,o.__h.length&&l.push(o),m&&(o.__E=o.__=null)}catch(L){if(l.length=_,e.__v=null,u||a!=null){if(L.then){for(e.__u|=u?160:128;r&&r.nodeType==8&&r.nextSibling;)r=r.nextSibling;a!=null&&(a[a.indexOf(r)]=null),e.__e=r}else if(a!=null)for(se=a.length;se--;)re(a[se])}else e.__e=n.__e;e.__k==null&&(e.__k=n.__k||[]),L.then||qe(e),b.__e(L,e,n)}}else a==null&&e.__v==n.__v?(e.__k=n.__k,e.__e=n.__e):r=e.__e=lt(n.__e,e,n,s,i,a,l,u,d);return(c=b.diffed)&&c(e),128&e.__u?void 0:r}function qe(t){t&&(t.__c&&(t.__c.__e=!0),t.__k&&t.__k.some(qe))}function Ne(t,e,n){for(var s=0;s<n.length;s++)pe(n[s],n[++s],n[++s]);b.__c&&b.__c(e,t),t.some(function(i){try{t=i.__h,i.__h=[],t.some(function(a){a.call(i)})}catch(a){b.__e(a,i.__v)}})}function He(t){return typeof t!="object"||t==null||t.__b>0?t:Q(t)?t.map(He):t.constructor!==void 0?null:T({},t)}function lt(t,e,n,s,i,a,l,r,u){var d,c,_,o,v,y,h,f=n.props||z,m=e.props,$=e.type;if($=="svg"?i="http://www.w3.org/2000/svg":$=="math"?i="http://www.w3.org/1998/Math/MathML":i||(i="http://www.w3.org/1999/xhtml"),a!=null){for(d=0;d<a.length;d++)if((v=a[d])&&"setAttribute"in v==!!$&&($?v.localName==$:v.nodeType==3)){t=v,a[d]=null;break}}if(t==null){if($==null)return document.createTextNode(m);t=document.createElementNS(i,$,m.is&&m),r&&(b.__m&&b.__m(e,a),r=!1),a=null}if($==null)f===m||r&&t.data==m||(t.data=m);else{if(a=$=="textarea"&&m.defaultValue!=null?null:a&&J.call(t.childNodes),!r&&a!=null)for(f={},d=0;d<t.attributes.length;d++)f[(v=t.attributes[d]).name]=v.value;for(d in f)v=f[d],d=="dangerouslySetInnerHTML"?_=v:d=="children"||d in m||d=="value"&&"defaultValue"in m||d=="checked"&&"defaultChecked"in m||V(t,d,null,v,i);for(d in m)v=m[d],d=="children"?o=v:d=="dangerouslySetInnerHTML"?c=v:d=="value"?y=v:d=="checked"?h=v:r&&typeof v!="function"||f[d]===v||V(t,d,v,f[d],i);if(c)r||_&&(c.__html==_.__html||c.__html==t.innerHTML)||(t.innerHTML=c.__html),e.__k=[];else if(_&&(t.innerHTML=""),Re(e.type=="template"?t.content:t,Q(o)?o:[o],e,n,s,$=="foreignObject"?"http://www.w3.org/1999/xhtml":i,a,l,a?a[0]:n.__k&&D(n,0),r,u),a!=null)for(d=a.length;d--;)re(a[d]);r&&$!="textarea"||(d="value",$=="progress"&&y==null?t.removeAttribute("value"):y!=null&&(y!==t[d]||$=="progress"&&!y||$=="option"&&y!=f[d])&&V(t,d,y,f[d],i),d="checked",h!=null&&h!=t[d]&&V(t,d,h,f[d],i))}return t}function pe(t,e,n){try{if(typeof t=="function"){var s=typeof t.__u=="function";s&&t.__u(),s&&e==null||(t.__u=t(e))}else t.current=e}catch(i){b.__e(i,n)}}function De(t,e,n){var s,i;if(b.unmount&&b.unmount(t),(s=t.ref)&&(s.current&&s.current!=t.__e||pe(s,null,e)),(s=t.__c)!=null){if(s.componentWillUnmount)try{s.componentWillUnmount()}catch(a){b.__e(a,e)}s.base=s.__P=s.__n=null}if(s=t.__k)for(i=0;i<s.length;i++)s[i]&&De(s[i],e,n||typeof t.type!="function");n||re(t.__e),t.__c=t.__=t.__e=void 0}function rt(t,e,n){return this.constructor(t,n)}function Le(t,e,n){var s,i,a,l;e==document&&(e=document.documentElement),b.__&&b.__(t,e),i=(s=typeof n=="function")?null:n&&n.__k||e.__k,a=[],l=[],de(e,t=(!s&&n||e).__k=ce(X,null,[t]),i||z,z,e.namespaceURI,!s&&n?[n]:i?null:e.firstChild?J.call(e.childNodes):null,a,!s&&n?n:i?i.__e:e.firstChild,s,l),Ne(a,t,l),t.props.children=null}J=Y.slice,b={__e:function(t,e,n,s){for(var i,a,l;e=e.__;)if((i=e.__c)&&!i.__)try{if((a=i.constructor)&&a.getDerivedStateFromError!=null&&(i.setState(a.getDerivedStateFromError(t)),l=i.__d),i.componentDidCatch!=null&&(i.componentDidCatch(t,s||{}),l=i.__d),l)return i.__E=i}catch(r){t=r}throw t}},Me=0,tt=function(t){return t!=null&&t.constructor===void 0},O.prototype.setState=function(t,e){var n;n=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=T({},this.state),typeof t=="function"&&(t=t(T({},n),this.props)),t&&T(n,t),t!=null&&this.__v&&(e&&this._sb.push(e),xe(this))},O.prototype.forceUpdate=function(t){this.__v&&(this.__e=!0,t&&this.__h.push(t),xe(this))},O.prototype.render=X,N=[],Se=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,Ae=function(t,e){return t.__v.__b-e.__v.__b},G.__r=0,ae=Math.random().toString(8),W="__d"+ae,I="__a"+ae,Ee=/(PointerCapture)$|Capture$/i,le=0,ie=Ce(!1),oe=Ce(!0),nt=0;var U,x,ue,je,B=0,Oe=[],C=b,Ie=C.__b,Ue=C.__r,Be=C.diffed,Fe=C.__c,Ve=C.unmount,We=C.__;function ve(t,e){C.__h&&C.__h(x,t,B||e),B=0;var n=x.__H||(x.__H={__:[],__h:[]});return t>=n.__.length&&n.__.push({}),n.__[t]}function q(t){return B=1,ct(Ye,t)}function ct(t,e,n){var s=ve(U++,2);if(s.t=t,!s.__c&&(s.__=[n?n(e):Ye(void 0,e),function(r){var u=s.__N?s.__N[0]:s.__[0],d=s.t(u,r);u!==d&&(s.__N=[d,s.__[1]],s.__c.setState({}))}],s.__c=x,!x.__f)){var i=function(r,u,d){if(!s.__c.__H)return!0;var c=!1,_=s.__c.props!==r;if(s.__c.__H.__.some(function(v){if(v.__N){c=!0;var y=v.__[0];v.__=v.__N,v.__N=void 0,y!==v.__[0]&&(_=!0)}}),a){var o=a.call(this,r,u,d);return c?o||_:o}return!c||_};x.__f=!0;var a=x.shouldComponentUpdate,l=x.componentWillUpdate;x.componentWillUpdate=function(r,u,d){if(this.__e){var c=a;a=void 0,i(r,u,d),a=c}l&&l.call(this,r,u,d)},x.shouldComponentUpdate=i}return s.__N||s.__}function ee(t,e){var n=ve(U++,3);!C.__s&&ze(n.__H,e)&&(n.__=t,n.u=e,x.__H.__h.push(n))}function he(t){return B=5,te(function(){return{current:t}},[])}function te(t,e){var n=ve(U++,7);return ze(n.__H,e)&&(n.__=t(),n.__H=e,n.__h=t),n.__}function ye(t,e){return B=8,te(function(){return t},e)}function dt(){for(var t;t=Oe.shift();){var e=t.__H;if(t.__P&&e)try{e.__h.some(Z),e.__h.some(_e),e.__h=[]}catch(n){e.__h=[],C.__e(n,t.__v)}}}C.__b=function(t){x=null,Ie&&Ie(t)},C.__=function(t,e){t&&e.__k&&e.__k.__m&&(t.__m=e.__k.__m),We&&We(t,e)},C.__r=function(t){Ue&&Ue(t),U=0;var e=(x=t.__c).__H;e&&(ue===x?(e.__h=[],x.__h=[],e.__.some(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0})):(e.__h.some(Z),e.__h.some(_e),e.__h=[],U=0)),ue=x},C.diffed=function(t){Be&&Be(t);var e=t.__c;e&&e.__H&&(e.__H.__h.length&&(Oe.push(e)!==1&&je===C.requestAnimationFrame||((je=C.requestAnimationFrame)||pt)(dt)),e.__H.__.some(function(n){n.u&&(n.__H=n.u,n.u=void 0)})),ue=x=null},C.__c=function(t,e){e.some(function(n){try{n.__h.some(Z),n.__h=n.__h.filter(function(s){return!s.__||_e(s)})}catch(s){e.some(function(i){i.__h&&(i.__h=[])}),e=[],C.__e(s,n.__v)}}),Fe&&Fe(t,e)},C.unmount=function(t){Ve&&Ve(t);var e,n=t.__c;n&&n.__H&&(n.__H.__.some(function(s){try{Z(s)}catch(i){e=i}}),n.__H=void 0,e&&C.__e(e,n.__v))};var Ke=typeof requestAnimationFrame=="function";function pt(t){var e,n=function(){clearTimeout(s),Ke&&cancelAnimationFrame(e),setTimeout(t)},s=setTimeout(n,35);Ke&&(e=requestAnimationFrame(n))}function Z(t){var e=x,n=t.__c;typeof n=="function"&&(t.__c=void 0,n()),x=e}function _e(t){var e=x;t.__c=t.__(),x=e}function ze(t,e){return!t||t.length!==e.length||e.some(function(n,s){return n!==t[s]})}function Ye(t,e){return typeof e=="function"?e(t):e}var Je=function(t,e,n,s){var i;e[0]=0;for(var a=1;a<e.length;a++){var l=e[a++],r=e[a]?(e[0]|=l?1:2,n[e[a++]]):e[++a];l===3?s[0]=r:l===4?s[1]=Object.assign(s[1]||{},r):l===5?(s[1]=s[1]||{})[e[++a]]=r:l===6?s[1][e[++a]]+=r+"":l?(i=t.apply(r,Je(t,r,n,["",null])),s.push(i),r[0]?e[0]|=2:(e[a-2]=0,e[a]=i)):s.push(r)}return s},Ge=new Map;function Qe(t){var e=Ge.get(this);return e||(e=new Map,Ge.set(this,e)),(e=Je(this,e.get(t)||(e.set(t,e=(function(n){for(var s,i,a=1,l="",r="",u=[0],d=function(o){a===1&&(o||(l=l.replace(/^\\s*\\n\\s*|\\s*\\n\\s*$/g,"")))?u.push(0,o,l):a===3&&(o||l)?(u.push(3,o,l),a=2):a===2&&l==="..."&&o?u.push(4,o,0):a===2&&l&&!o?u.push(5,0,!0,l):a>=5&&((l||!o&&a===5)&&(u.push(a,0,l,i),a=6),o&&(u.push(a,o,0,i),a=6)),l=""},c=0;c<n.length;c++){c&&(a===1&&d(),d(c));for(var _=0;_<n[c].length;_++)s=n[c][_],a===1?s==="<"?(d(),u=[u],a=3):l+=s:a===4?l==="--"&&s===">"?(a=1,l=""):l=s+l[0]:r?s===r?r="":l+=s:s===\'"\'||s==="\'"?r=s:s===">"?(d(),a=1):a&&(s==="="?(a=5,i=l,l=""):s==="/"&&(a<5||n[c][_+1]===">")?(d(),a===3&&(u=u[0]),a=u,(u=u[0]).push(2,0,a),a=0):s===" "||s===" "||s===`\n`||s==="\\r"?(d(),a=2):l+=s),a===3&&l==="!--"&&(a=4,u=u[0])}return d(),u})(t)),e),arguments,[])).length>1?e:e[0]}var p=Qe.bind(ce),Xe=window.__QRING__&&window.__QRING__.token||"",fe=Xe?"?token="+encodeURIComponent(Xe):"",A=t=>\'<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="url(#neon-grad)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">\'+t+"</svg>",k={health:A(\'<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>\'),environment:A(\'<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>\'),decay:A(\'<path d="M5 22h14"/><path d="M5 2h14"/><path d="M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22"/><path d="M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2"/>\'),superposition:A(\'<polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/>\'),entangle:A(\'<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>\'),tunnel:A(\'<path d="M9 10h.01"/><path d="M15 10h.01"/><path d="M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z"/>\'),anomaly:A(\'<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>\'),audit:A(\'<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>\'),key:A(\'<path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/>\'),hook:A(\'<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>\'),approve:A(\'<path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/>\'),manifest:A(\'<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/>\'),policy:A(\'<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="M9 12l2 2 4-4"/>\'),memory:A(\'<rect x="4" y="4" width="16" height="16" rx="2"/><rect x="9" y="9" width="6" height="6"/><line x1="9" y1="2" x2="9" y2="4"/><line x1="15" y1="2" x2="15" y2="4"/><line x1="9" y1="20" x2="9" y2="22"/><line x1="15" y1="20" x2="15" y2="22"/><line x1="20" y1="9" x2="22" y2="9"/><line x1="20" y1="14" x2="22" y2="14"/><line x1="2" y1="9" x2="4" y2="9"/><line x1="2" y1="14" x2="4" y2="14"/>\'),folder:\'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>\',search:\'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>\',lock:\'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>\'};function $e(t){if(!t)return"env-default";let e=t.toLowerCase();return e==="prod"||e==="production"?"env-prod":e==="staging"||e==="stage"?"env-staging":e==="dev"||e==="development"?"env-dev":e==="test"||e==="testing"?"env-test":"env-default"}function et(t,e){return e||t>=90?"var(--danger)":t>=75?"var(--warning)":"var(--accent)"}function me(t){let e=new Date(t);return String(e.getHours()).padStart(2,"0")+":"+String(e.getMinutes()).padStart(2,"0")+":"+String(e.getSeconds()).padStart(2,"0")}function ge(t){if(!t)return"\\u2014";let e=Math.floor((Date.now()-new Date(t).getTime())/1e3);return isNaN(e)?"\\u2014":e<5?"just now":e<60?e+"s ago":e<3600?Math.floor(e/60)+"m ago":e<86400?Math.floor(e/3600)+"h ago":Math.floor(e/86400)+"d ago"}function ne(t){return t==null?"\\u2014":t<0?"expired":t<60?t+"s":t<3600?Math.floor(t/60)+"m":t<86400?Math.floor(t/3600)+"h":Math.floor(t/86400)+"d"}var j=({svg:t})=>p`<span style="display:contents" dangerouslySetInnerHTML=${{__html:t}} />`;function M({icon:t,title:e,aside:n,asideStyle:s}){return p`<div class="card-title">\n <${j} svg=${t} />${e}\n ${n!=null?p`<span class="title-aside" style=${s||""}>${n}</span>`:null}\n </div>`}function S({delay:t=0,wide:e=!1,style:n="",children:s}){let i="card"+(e?" grid-wide":""),a="animation-delay:"+t+"ms"+(n?";"+n:"");return p`<div class=${i} style=${a}>${s}</div>`}function E({children:t,cta:e}){return p`<div class="empty">${t}${e?p`<span class="empty-cta">${e}</span>`:null}</div>`}function Ze({snap:t,paused:e,connState:n,onPause:s,onRefresh:i,lastUpdate:a}){let l=e?"paused":n==="live"?"live":n==="reconnecting"?"reconnecting\\u2026":"connecting\\u2026",r="status-dot"+(e?" paused":n==="reconnecting"?" disconnected":"");return p`\n <header class="header">\n <div class="header-left">\n <h1>\n <span class="q-icon"><svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="url(#neon-grad)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg></span>\n <span class="brand">q-ring</span>\n <span class="sub">quantum status</span>\n </h1>\n <span class="meta-chip" title="q-ring version">\n <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>\n ${" v"+(t?t.version:"")}\n </span>\n <span class="meta-chip" title="Project working directory">\n <${j} svg=${k.folder} /> ${t?t.projectPath:""}\n </span>\n </div>\n <div class="header-right">\n <span class="conn-label" title="Last update from the live stream"><span>${a}</span></span>\n <button class="btn" type="button" title="Pause / resume the live stream (P)" onClick=${s}>\n ${e?p`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>`:p`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="4" width="4" height="16" rx="1"/><rect x="14" y="4" width="4" height="16" rx="1"/></svg>`}\n <span>${e?"Resume":"Pause"}</span>\n </button>\n <button class="btn" type="button" title="Force-refresh now (R)" onClick=${i}>\n <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-3.5-7.1"/><polyline points="21 3 21 9 15 9"/></svg>\n Refresh\n </button>\n <a class="btn" href=${"/api/status"+fe} target="_blank" rel="noopener" title="Open the raw JSON snapshot in a new tab">\n <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>\n JSON\n </a>\n <span class="conn-label"><span class=${r}></span><span>${l}</span></span>\n </div>\n </header>\n `}function ut({snap:t}){let e=t,n=e.auditMetrics||{total:0,byAction:{},topRead:[]},s=n.byAction.read||0,i=(n.byAction.write||0)+(n.byAction.delete||0)+(n.byAction.rotate||0),a=n.byAction.policy_deny||0,l=(e.hooks||[]).filter(c=>c.enabled).length,r=(e.approvals||[]).filter(c=>c.valid).length,u=(e.anomalies||[]).length,d=[{label:"Secrets",icon:k.key,value:e.health.total,sub:e.health.healthy+" healthy \\xB7 "+e.health.stale+" stale \\xB7 "+e.health.expired+" expired",cls:""},{label:"Environment",icon:k.environment,value:e.environment?e.environment.env:"none",sub:e.environment?"via "+e.environment.source:"no env detected",cls:e.environment?"":"dim"},{label:"Protected",icon:k.lock,value:e.protectedCount,sub:"require approval",cls:e.protectedCount>0?"warning":"dim"},{label:"Approvals",icon:k.approve,value:r,sub:"active grants",cls:r>0?"green":"dim"},{label:"Hooks",icon:k.hook,value:l,sub:"enabled / "+(e.hooks||[]).length+" total",cls:l>0?"":"dim"},{label:"Reads (24h)",icon:k.audit,value:s,sub:i+" writes \\xB7 "+a+" denied",cls:""},{label:"Anomalies",icon:k.anomaly,value:u,sub:u?"investigate now":"all clear",cls:u?"danger":"green"}];return p`<section class="kpi-strip">\n ${d.map(c=>p`<div class="kpi" key=${c.label}>\n <div class="kpi-label"><${j} svg=${c.icon} />${c.label}</div>\n <div class="kpi-value ${c.cls}">${c.value}</div>\n <div class="kpi-sub">${c.sub}</div>\n </div>`)}\n </section>`}function _t({snap:t,delay:e}){let n=t.health,s=n.total||1,i=42,a=2*Math.PI*i,l=[{v:n.healthy,c:"var(--accent)"},{v:n.stale,c:"var(--warning)"},{v:n.expired,c:"var(--danger)"},{v:n.noDecay,c:"var(--text-dim)"}],r=0,u=l.map((c,_)=>{let o=c.v/s*a,v=p`<circle key=${_} cx="50" cy="50" r=${i} fill="none" stroke=${c.c} stroke-width="12" stroke-dasharray=${o+" "+(a-o)} stroke-dashoffset=${-r} stroke-linecap="round" opacity="0.85" />`;return r+=o,v}),d=t.scopes||{global:0,project:0,team:0,org:0};return p`<${S} delay=${e}>\n <${M} icon=${k.health} title="Health Summary" aside=${n.healthy+"/"+n.total+" healthy"} />\n <div class="health-row">\n <div class="donut-wrap">\n <svg viewBox="0 0 100 100" width="100" height="100">${u}</svg>\n <div class="donut-label">${n.total}<small>secrets</small></div>\n </div>\n <div class="health-legend">\n <div class="legend-item"><span class="legend-dot" style="background:var(--accent)"></span>Healthy ${n.healthy}</div>\n <div class="legend-item"><span class="legend-dot" style="background:var(--warning)"></span>Stale ${n.stale}</div>\n <div class="legend-item"><span class="legend-dot" style="background:var(--danger)"></span>Expired ${n.expired}</div>\n <div class="legend-item"><span class="legend-dot" style="background:var(--text-dim)"></span>No decay ${n.noDecay}</div>\n </div>\n </div>\n <div class="scope-row">\n ${["global","project","team","org"].filter(c=>d[c]).map(c=>p`<span class="scope-pill" key=${c}><strong>${d[c]}</strong>${c}</span>`)}\n </div>\n <//>`}function vt({snap:t,delay:e}){let n=t.environment;return p`<${S} delay=${e}>\n <${M} icon=${k.environment} title="Environment" />\n ${n?p`<div class="env-status"><span class="env-big env-pill ${$e(n.env)}">${n.env}</span><span class="env-source">detected via ${n.source}</span></div>`:p`<${E} cta="$ qring env --project-path .">No environment detected.<//>`}\n <//>`}function ht({snap:t,delay:e}){let n=t.manifest;if(!n)return p`<${S} delay=${e}>\n <${M} icon=${k.manifest} title="Manifest" />\n <${E} cta=${p`$ qring wizard <name>`}>No <code>.q-ring.json</code> manifest in this project.<//>\n <//>`;let s=n.required-n.missing.length-n.expired.length-n.stale.length,i=n.required?Math.max(0,Math.round(s/n.required*100)):100,a=n.missing.length?"var(--danger)":n.expired.length||n.stale.length?"var(--warning)":"var(--green)",l=(u,d,c)=>p`<div class="label">${u} (${d.length})</div><div>${d.map(_=>p`<span class="key-pill ${c}" key=${_}>${_}</span>`)}</div>`,r=n.missing.length||n.expired.length||n.stale.length;return p`<${S} delay=${e}>\n <${M} icon=${k.manifest} title="Manifest" aside=${n.required+" required / "+n.declared+" declared"} />\n <div class="manifest-bars">\n <div class="manifest-row"><span style="min-width:54px">healthy</span><div class="manifest-bar"><div class="manifest-fill" style=${"width:"+i+"%;background:"+a}></div></div><span>${i}%</span></div>\n </div>\n <div class="manifest-list">\n ${n.missing.length?l("Missing required",n.missing,"miss"):null}\n ${n.expired.length?l("Expired",n.expired,"exp"):null}\n ${n.stale.length?l("Stale",n.stale,"exp"):null}\n ${r?null:p`<div class="label">All required keys present and healthy.</div>`}\n </div>\n <//>`}function yt({snap:t,delay:e}){let n=t.policy||{counts:{}},s=n.counts||{};if(!(n.hasMcpPolicy||n.hasExecPolicy||n.hasSecretPolicy))return p`<${S} delay=${e}>\n <${M} icon=${k.policy} title="Policy" />\n <${E} cta=${p`add <code>policy</code> to <code>.q-ring.json</code>`}>No governance policy declared.<//>\n <//>`;let a=({label:r,value:u})=>p`<div class="policy-row"><span class="policy-label">${r}</span><span class="policy-value ${u?"":"zero"}">${u||"\\u2014"}</span></div>`,l=[n.hasMcpPolicy?"mcp":"",n.hasExecPolicy?"exec":"",n.hasSecretPolicy?"secrets":""].filter(Boolean).join(" \\xB7 ")||"none";return p`<${S} delay=${e}>\n <${M} icon=${k.policy} title="Policy" aside=${l} />\n <div class="policy-rows">\n <${a} label="MCP allow tools" value=${s.allowTools} />\n <${a} label="MCP deny tools" value=${s.denyTools} />\n <${a} label="Denied keys" value=${s.deniedKeys} />\n <${a} label="Denied tags" value=${s.deniedTags} />\n <${a} label="Exec allow" value=${s.allowCommands} />\n <${a} label="Exec deny" value=${s.denyCommands} />\n <${a} label="Tag \u2192 approval" value=${s.requireApprovalForTags} />\n <${a} label="Tag \u2192 rotation" value=${s.requireRotationFormatForTags} />\n ${n.maxTtlSeconds?p`<${a} label="Max TTL" value=${ne(n.maxTtlSeconds)} />`:null}\n ${n.maxRuntimeSeconds?p`<${a} label="Max exec runtime" value=${ne(n.maxRuntimeSeconds)} />`:null}\n </div>\n <//>`}function ft({snap:t,delay:e}){let n=(t.secrets||[]).filter(s=>s.decay&&s.decay.timeRemaining).sort((s,i)=>(s.decay.secondsRemaining||0)-(i.decay.secondsRemaining||0));return p`<${S} delay=${e}>\n <${M} icon=${k.decay} title="Decay Timers" aside=${n.length+" tracked"} />\n ${n.length?p`<div class="decay-list">${n.slice(0,12).map(s=>{let i=Math.min(s.decay.lifetimePercent,100),a=et(i,s.decay.isExpired),l=s.decay.isExpired?"expired":s.decay.timeRemaining||"";return p`<div class="decay-item" key=${s.scope+":"+s.key}>\n <span class="decay-key" title=${s.key}>${s.key}</span>\n <div class="decay-bar"><div class="decay-fill" style=${"width:"+i+"%;background:"+a}></div></div>\n <span class="decay-time" style=${"color:"+a}>${l}</span>\n </div>`})}</div>`:p`<${E} cta="$ qring set KEY --ttl 86400">No secrets with decay configured.<//>`}\n <//>`}function $t({snap:t,delay:e}){let n=(t.secrets||[]).filter(s=>s.type==="superposition"&&s.environments&&s.environments.length);return p`<${S} delay=${e}>\n <${M} icon=${k.superposition} title="Superposition" aside=${n.length+" multi-env"} />\n ${n.length?p`<div class="super-list">${n.slice(0,14).map(s=>p`<div class="super-item" key=${s.scope+":"+s.key}>\n <span class="super-key">${s.key}</span>\n ${(s.environments||[]).map(i=>p`<span class="env-pill ${$e(i)}" key=${i}>${i}${i===s.defaultEnv?" \\u2713":""}</span>`)}\n </div>`)}</div>`:p`<${E} cta="$ qring set KEY --env prod">No secrets in superposition.<//>`}\n <//>`}function mt({snap:t,delay:e}){let n=t.entanglements||[],s=new Set,i=n.filter(h=>{let f=[h.source.service,h.source.key,h.target.service,h.target.key].sort().join("|");return s.has(f)?!1:(s.add(f),!0)}),a=[],l=new Map;for(let h of i)for(let f of[h.source.key,h.target.key])l.has(f)||(l.set(f,a.length),a.push(f));let r=i.length>0&&a.length<=14,u=320,d=210,c=u/2,_=d/2,o=Math.min(u,d)/2-34,v=a.map((h,f)=>{let m=2*Math.PI*f/a.length-Math.PI/2;return{x:c+o*Math.cos(m),y:_+o*Math.sin(m)}}),y=h=>h.length>14?h.slice(0,12)+"\\u2026":h;return p`<${S} delay=${e}>\n <${M} icon=${k.entangle} title="Entanglement" aside=${i.length+" pair"+(i.length===1?"":"s")+" \\xB7 "+a.length+" keys"} />\n ${i.length?r?p`<svg class="entangle-graph" viewBox="0 0 ${u} ${d}" role="img" aria-label="Entanglement graph: ${i.length} linked pairs">\n ${i.map((h,f)=>{let m=v[l.get(h.source.key)],$=v[l.get(h.target.key)];return p`<line key=${"e"+f} x1=${m.x} y1=${m.y} x2=${$.x} y2=${$.y} class="entangle-edge" />`})}\n ${a.map((h,f)=>{let m=v[f],$=m.x>=c;return p`<g key=${"n"+f}>\n <circle cx=${m.x} cy=${m.y} r="5" class="entangle-node" />\n <text x=${m.x+($?9:-9)} y=${m.y+3.5} text-anchor=${$?"start":"end"} class="entangle-label">${y(h)}<title>${h}</title></text>\n </g>`})}\n </svg>`:p`<div class="entangle-list">${i.slice(0,12).map((h,f)=>p`<div class="entangle-pair" key=${f}>\n <span>${h.source.key}</span><span class="entangle-arrow">\u2194</span><span>${h.target.key}</span>\n </div>`)}</div>`:p`<${E} cta="$ qring entangle KEY_A KEY_B">No entangled secrets.<//>`}\n <//>`}function gt({snap:t,delay:e}){let n=t.tunnels||[];return p`<${S} delay=${e}>\n <${M} icon=${k.tunnel} title="Quantum Tunnels" aside=${n.length+" live"} />\n ${n.length?p`<div class="tunnel-list">${n.map(s=>{let i=s.expiresAt?Math.max(0,Math.floor((s.expiresAt-Date.now())/1e3)):null;return p`<div class="tunnel-card" key=${s.id}>${s.id}<div class="tunnel-meta">\n <span>reads: ${s.accessCount}${s.maxReads?"/"+s.maxReads:""}</span>\n ${i!==null?p`<span>expires: ${i}s</span>`:p`<span>no expiry</span>`}\n </div></div>`})}</div>`:p`<${E} cta=${p`$ qring tunnel create <value>`}>No active tunnels.<//>`}\n <//>`}function kt({snap:t,delay:e}){let n=t.approvals||[];return p`<${S} delay=${e}>\n <${M} icon=${k.approve} title="Approvals" aside=${n.filter(s=>s.valid).length+" valid"} />\n ${n.length?p`<div class="approval-list">${n.slice(0,8).map(s=>{let i=s.tampered?"tampered":s.secondsRemaining<300?"expiring":"";return p`<div class="approval-card ${i}" key=${s.id}>\n <div class="approval-head"><span>${s.key}${s.tampered?" \\u26A0 TAMPERED":""}</span><span>${ne(s.secondsRemaining)} left</span></div>\n <div class="approval-reason">${s.reason||"(no reason)"}</div>\n <div class="approval-meta"><span>scope:${s.scope}</span><span>by:${s.grantedBy}</span></div>\n </div>`})}</div>`:p`<${E} cta=${\'$ qring approve KEY --for 1800 --reason "..."\'}>No active approvals.<//>`}\n <//>`}function bt({snap:t,delay:e}){let n=t.hooks||[];return p`<${S} delay=${e}>\n <${M} icon=${k.hook} title="Hooks" aside=${n.filter(s=>s.enabled).length+" enabled / "+n.length} />\n ${n.length?p`<div class="hooks-list">${n.slice(0,8).map(s=>p`<div class="hook-row ${s.enabled?"":"disabled"}" key=${s.id}>\n <span class="hook-type ${s.type}">${s.type}</span>\n <span class="hook-summary" title=${s.matchSummary}>${s.description||s.matchSummary}</span>\n <span class="hook-id">${s.id}</span>\n </div>`)}</div>`:p`<${E} cta=${\'$ qring hook add --tag payments --action rotate --exec "..."\'}>No hooks registered.<//>`}\n <//>`}function xt({snap:t,delay:e}){return p`<${S} delay=${e}>\n <${M} icon=${k.memory} title="Agent Memory" />\n <div class="empty" style="display:flex;align-items:baseline;gap:8px;font-style:normal">\n <span style="font-size:1.6rem;font-weight:700;color:var(--text-primary);font-family:var(--font-display)">${t.memoryKeys||0}</span>\n <span>memory key${t.memoryKeys===1?"":"s"} encrypted at <code>~/.config/q-ring/agent-memory.enc</code></span>\n </div>\n <//>`}function wt({snap:t,delay:e}){let n=t.anomalies||[];if(!n.length)return p`<${S} delay=${e} wide=${!0}>\n <${M} icon=${k.anomaly} title="Anomaly Alerts" aside="all clear" asideStyle="color:var(--green)" />\n <${E}>No anomalies detected \u2014 quantum field is stable.<//>\n <//>`;let s=i=>i==="tampered"?"$ qring audit:verify":i==="burst"?"$ qring audit --key \\u2026 --action read":i==="unusual-hour"?\'$ qring audit --action read --since "1am"\':"$ qring audit --limit 100";return p`<${S} delay=${e} wide=${!0}>\n <${M} icon=${k.anomaly} title="Anomaly Alerts" aside=${n.length+" active"} asideStyle="color:var(--danger)" />\n <div class="anomaly-list">${n.map((i,a)=>p`<div class="anomaly-card" key=${a}>\n <div class="anomaly-type">${i.type}</div>\n <div class="anomaly-desc">${i.description}</div>\n <div class="anomaly-hint">${s(i.type)}</div>\n </div>`)}</div>\n <//>`}function Ct(t,e){let n=e.trim().toLowerCase();return n?n==="expired"?t.filter(s=>s.decay&&s.decay.isExpired):n==="stale"?t.filter(s=>s.decay&&s.decay.isStale&&!s.decay.isExpired):n==="protected"?t.filter(s=>s.requiresApproval):t.filter(s=>[s.key,s.scope,s.type,s.provider||"",s.defaultEnv||"",(s.environments||[]).join(" "),(s.tags||[]).join(" ")].join(" ").toLowerCase().indexOf(n)!==-1):t.slice()}function Mt(t,e){let n=e.dir==="asc"?1:-1;return t.sort((s,i)=>{let a,l;switch(e.col){case"key":a=s.key,l=i.key;break;case"scope":a=s.scope,l=i.scope;break;case"env":a=s.defaultEnv||(s.environments||[])[0]||"",l=i.defaultEnv||(i.environments||[])[0]||"";break;case"type":a=s.type,l=i.type;break;case"decay":a=s.decay&&s.decay.secondsRemaining!=null?s.decay.secondsRemaining:1/0,l=i.decay&&i.decay.secondsRemaining!=null?i.decay.secondsRemaining:1/0;break;case"tags":a=(s.tags||[]).join(","),l=(i.tags||[]).join(",");break;default:a=s.lastAccessedAt?new Date(s.lastAccessedAt).getTime():0,l=i.lastAccessedAt?new Date(i.lastAccessedAt).getTime():0}return a<l?-1*n:a>l?1*n:0})}function St({snap:t,query:e,setQuery:n,sort:s,setSort:i,searchRef:a}){let l=t.secrets||[],r=te(()=>Mt(Ct(l,e),s),[l,e,s]),u=[{id:"key",label:"Key"},{id:"scope",label:"Scope"},{id:"env",label:"Env"},{id:"type",label:"Type"},{id:"decay",label:"Decay"},{id:"tags",label:"Tags"},{id:"lastAccessedAt",label:"Last read"}],d=c=>{s.col===c?i({col:c,dir:s.dir==="asc"?"desc":"asc"}):i({col:c,dir:c==="key"?"asc":"desc"})};return p`<section><${S} wide=${!0} style="margin-bottom:16px">\n <${M} icon=${k.key} title="Secrets" aside=${r.length+" of "+l.length} />\n <div class="secrets-toolbar">\n <label class="search"><${j} svg=${k.search} /><input ref=${a} id="secretsSearch" type="search" placeholder="Filter by key, scope, env, tag, provider\u2026" autocomplete="off" value=${e} onInput=${c=>n(c.target.value)} /></label>\n <button class="btn" type="button" onClick=${()=>n("expired")}>${t.health.expired||0} expired</button>\n <button class="btn" type="button" onClick=${()=>n("stale")}>${t.health.stale||0} stale</button>\n <button class="btn" type="button" onClick=${()=>n("protected")}>${t.protectedCount||0} protected</button>\n <button class="btn" type="button" onClick=${()=>n("")}>clear</button>\n </div>\n <div class="secrets-table-wrap">\n ${r.length?p`<table class="secrets-table">\n <thead><tr>${u.map(c=>p`<th key=${c.id} class=${s.col===c.id?"sorted":""} onClick=${()=>d(c.id)}>${c.label}<span class="sort-arrow">${s.dir==="asc"?"\\u25B2":"\\u25BC"}</span></th>`)}</tr></thead>\n <tbody>${r.map(c=>{let _=c.type==="superposition"?(c.environments||[]).map(y=>p`<span class="env-pill ${$e(y)}" style="margin-right:3px" key=${y}>${y}${y===c.defaultEnv?" \\u2713":""}</span>`):p`<span class="env-pill env-default">\u2014</span>`,o=c.decay&&c.decay.timeRemaining?(()=>{let y=Math.min(c.decay.lifetimePercent,100),h=et(y,c.decay.isExpired);return p`<span class="mini-decay"><span class="mini-decay-bar"><span class="mini-decay-fill" style=${"width:"+y+"%;background:"+h}></span></span><span class="mini-decay-time" style=${"color:"+h}>${c.decay.isExpired?"expired":c.decay.timeRemaining}</span></span>`})():p`<span class="mini-decay-time">\u2014</span>`,v=c.tags||[];return p`<tr key=${c.scope+":"+c.key}>\n <td class="col-key" title=${c.key}>${c.key}${c.requiresApproval?p`<span class="protected-icon" title="requires approval for MCP read"><${j} svg=${k.lock} /></span>`:null}</td>\n <td><span class="scope-tag ${c.scope}">${c.scope}</span></td>\n <td>${_}</td>\n <td><span class="type-tag ${c.type}">${c.type}</span></td>\n <td class="col-decay">${o}</td>\n <td class="col-tags">${v.slice(0,3).map(y=>p`<span class="tag-pill" key=${y}>${y}</span>`)}${v.length>3?"+"+(v.length-3):""}</td>\n <td>${ge(c.lastAccessedAt)}</td>\n </tr>`})}</tbody>\n </table>`:p`<div class="empty" style="padding:18px;text-align:center">No secrets match the filter.</div>`}\n </div>\n <//></section>`}function At({snap:t,delay:e}){let n=t.sessions||[],[s,i]=q({}),a=r=>i(u=>({...u,[r]:!u[r]})),l=r=>{let u=Math.max(0,Math.round((new Date(r.endedAt)-new Date(r.startedAt))/1e3));return ne(u)};return p`<${S} delay=${e} wide=${!0}>\n <${M} icon=${k.audit} title="Agent Sessions (24h)" aside=${n.length+" session"+(n.length===1?"":"s")} />\n ${n.length?p`<div class="sessions-list">${n.slice(0,12).map(r=>p`<div class="session ${s[r.id]?"open":""}" key=${r.id}>\n <button type="button" class="session-row" onClick=${()=>a(r.id)} title=${"session "+r.id}>\n <span class="session-caret">${s[r.id]?"\\u25BE":"\\u25B8"}</span>\n <span class="session-agent">${r.wrapLabel?"airlock":r.agent}</span>\n <span class="hook-type ${r.source==="mcp"?"http":r.source==="agent"?"shell":"signal"}">${r.source}</span>\n ${r.wrapLabel?p`<span class="session-wrap" title=${r.wrapLabel}>${r.wrapLabel}</span>`:null}\n <span class="session-meta">${ge(r.endedAt)} \xB7 ${l(r)} \xB7 ${r.eventCount} events</span>\n <span class="session-denials ${r.denials?"bad":""}">${r.denials?r.denials+" denied":"0 denied"}</span>\n ${r.countsByAction&&r.countsByAction.canary?p`<span class="session-denials bad">${r.countsByAction.canary} canary</span>`:null}\n </button>\n ${s[r.id]?p`<div class="session-detail">\n <div class="session-keys">${r.keys.length?"keys: "+r.keys.join(", "):"no keys touched"}</div>\n <div class="audit-feed">${(r.recent||[]).map((u,d)=>p`<div class="audit-row" key=${d}>\n <span class="audit-ts" title=${u.timestamp}>${me(u.timestamp)}</span>\n <span class="audit-action ${u.action}">${u.action}</span>\n <span></span>\n <span><span class="audit-key">${u.key||"\\u2014"}</span> <span class="audit-detail">${u.detail||""}</span></span>\n </div>`)}</div>\n </div>`:null}\n </div>`)}</div>`:p`<${E} cta=${"$ qring audit:sessions"}>No agent activity in the last 24h. Sessions appear once an MCP client or airlock touches the ring.<//>`}\n <//>`}function Et({snap:t,delay:e,filter:n,setFilter:s}){let i=t.audit||[],a=t.auditMetrics||{byAction:{},bySource:{}},l=i.filter(_=>{if(n.action&&_.action!==n.action||n.source&&_.source!==n.source)return!1;let o=n.text.trim().toLowerCase();return!(o&&[_.key||"",_.action,_.source,_.detail||"",_.scope||"",_.env||""].join(" ").toLowerCase().indexOf(o)===-1)}),r=["read","write","delete","rotate","generate","entangle","tunnel","teleport","approve","revoke","policy_deny","collapse","export"],u=["cli","mcp","agent","ci","hook","api"],d=(_,o)=>s({...n,[_]:n[_]===o?"":o}),c=t.auditChain;return p`<${S} delay=${e} wide=${!0}>\n <${M} icon=${k.audit} title="Audit Log (24h)" aside=${l.length+" of "+i.length+" shown \\xB7 window "+(a.windowSeconds||86400)/3600+"h"} />\n ${c&&c.totalEvents>0?p`<div class="chain-badge ${c.intact?"ok":"broken"}" title="Hash-chain integrity \u2014 same check as qring audit:verify">\n ${c.intact?p`\u26D3 chain intact \xB7 ${c.totalEvents} events verified`:p`\u26D3 chain BROKEN at event #${c.brokenAt} \xB7 ${c.validEvents}/${c.totalEvents} valid \u2014 run $ qring audit:verify`}\n </div>`:null}\n <div class="audit-actions-strip">\n ${r.filter(_=>a.byAction[_]).length?r.filter(_=>a.byAction[_]).map(_=>p`<span class="audit-chip ${n.action===_?"active":""}" key=${_} onClick=${()=>d("action",_)}>${_}<strong>${a.byAction[_]}</strong></span>`):p`<span class="empty" style="padding:0">no actions</span>`}\n </div>\n ${u.filter(_=>a.bySource[_]).length?p`<div class="audit-actions-strip">${u.filter(_=>a.bySource[_]).map(_=>p`<span class="audit-chip ${n.source===_?"active":""}" key=${_} onClick=${()=>d("source",_)}>${_}<strong>${a.bySource[_]}</strong></span>`)}</div>`:null}\n <div class="audit-toolbar">\n <label class="search"><${j} svg=${k.search} /><input id="auditSearch" type="search" placeholder="Filter by key, detail, scope\u2026" autocomplete="off" value=${n.text} onInput=${_=>s({...n,text:_.target.value})} /></label>\n <button class="btn" type="button" onClick=${()=>s({action:"",source:"",text:""})}>clear</button>\n </div>\n ${l.length?p`<div class="audit-feed">${l.slice(0,80).map((_,o)=>p`<div class="audit-row" key=${o}>\n <span class="audit-ts" title=${_.timestamp}>${me(_.timestamp)}</span>\n <span class="audit-action ${_.action}">${_.action}</span>\n <span class="audit-source">${_.source}</span>\n <span><span class="audit-key">${_.key||"\\u2014"}</span> <span class="audit-detail">${_.detail||""}</span></span>\n </div>`)}</div>`:p`<${E}>No audit events match the filter.<//>`}\n <//>`}function Pt(){let[t,e]=q(null),[n,s]=q(!1),[i,a]=q("connecting"),[l,r]=q(""),[u,d]=q({col:"lastAccessedAt",dir:"desc"}),[c,_]=q({action:"",source:"",text:""}),[,o]=q(0),v=he(n);v.current=n;let y=he(null),h=ye(g=>{try{e(typeof g=="string"?JSON.parse(g):g)}catch{}},[]),f=ye(()=>{fetch("/api/status"+fe,{cache:"no-store"}).then(g=>g.json()).then(h).catch(()=>{})},[h]);ee(()=>{let g=new EventSource("/events"+fe);return g.onopen=()=>a("live"),g.onmessage=w=>{v.current||h(w.data)},g.onerror=()=>a("reconnecting"),()=>g.close()},[h]),ee(()=>{let g=setInterval(()=>o(w=>w+1),5e3);return()=>clearInterval(g)},[]),ee(()=>{let g=w=>{let P=w.target&&w.target.tagName;if(P==="INPUT"||P==="TEXTAREA"){w.key==="Escape"&&w.target.blur();return}w.key==="/"?(w.preventDefault(),y.current&&y.current.focus()):w.key==="p"||w.key==="P"?s(H=>!H):(w.key==="r"||w.key==="R")&&f()};return document.addEventListener("keydown",g),()=>document.removeEventListener("keydown",g)},[f]);let m=t?"updated "+ge(t.timestamp):"\\u2014";if(!t)return p`<div class="container">\n <${Ze} snap=${null} paused=${n} connState=${i} onPause=${()=>s(g=>!g)} onRefresh=${f} lastUpdate=${m} />\n <p class="foot"><span>Connecting to the live quantum stream\u2026</span></p>\n </div>`;let $=t.auditMetrics||{total:0};return p`<div class="container">\n <${Ze} snap=${t} paused=${n} connState=${i} onPause=${()=>s(g=>!g)} onRefresh=${f} lastUpdate=${m} />\n <${ut} snap=${t} />\n <section class="grid">\n <${_t} snap=${t} delay=${0} />\n <${vt} snap=${t} delay=${60} />\n <${ht} snap=${t} delay=${120} />\n <${yt} snap=${t} delay=${180} />\n </section>\n <${St} snap=${t} query=${l} setQuery=${r} sort=${u} setSort=${d} searchRef=${y} />\n <section class="grid">\n <${ft} snap=${t} delay=${0} />\n <${$t} snap=${t} delay=${60} />\n <${mt} snap=${t} delay=${120} />\n <${gt} snap=${t} delay=${180} />\n </section>\n <section class="grid">\n <${kt} snap=${t} delay=${0} />\n <${bt} snap=${t} delay=${60} />\n <${xt} snap=${t} delay=${120} />\n </section>\n <section class="grid">\n <${At} snap=${t} delay=${0} />\n </section>\n <section class="grid">\n <${wt} snap=${t} delay=${0} />\n <${Et} snap=${t} delay=${60} filter=${c} setFilter=${_} />\n </section>\n <p class="foot">\n <span>${"q-ring v"+t.version+" \\xB7 snapshot "+me(t.timestamp)+" \\xB7 "+($.total||0)+" audit events in last 24h"}</span>\n \xB7 keyboard: <span class="kbd">/</span> search \xB7 <span class="kbd">P</span> pause \xB7 <span class="kbd">R</span> refresh\n </p>\n </div>`}Le(p`<${Pt} />`,document.getElementById("app"));})();';
25
26
 
26
27
  // src/core/dashboard-html.ts
27
28
  function jsString(value) {
@@ -257,6 +258,21 @@ body{min-height:100vh;overflow-x:hidden;position:relative}
257
258
  .hook-summary{flex:1;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
258
259
  .hook-id{color:var(--text-dim);font-size:.72rem}
259
260
 
261
+ /* Agent sessions */
262
+ .sessions-list{display:flex;flex-direction:column;gap:6px;max-height:420px;overflow-y:auto}
263
+ .session{background:rgba(255,255,255,.03);border:1px solid var(--border);border-radius:var(--radius-sm)}
264
+ .session.open{border-color:rgba(14,165,233,.35)}
265
+ .session-row{display:flex;align-items:center;gap:8px;width:100%;padding:6px 10px;background:none;border:0;color:inherit;font:inherit;font-family:var(--font-mono);font-size:.8rem;text-align:left;cursor:pointer}
266
+ .session-row:hover{background:rgba(255,255,255,.03)}
267
+ .session-caret{color:var(--text-dim);width:10px}
268
+ .session-agent{color:var(--accent-bright);font-weight:600}
269
+ .session-wrap{color:var(--text-secondary);max-width:28ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
270
+ .session-meta{flex:1;color:var(--text-dim);font-size:.74rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
271
+ .session-denials{font-size:.7rem;padding:1px 6px;border-radius:99px;background:rgba(34,197,94,.1);color:var(--green)}
272
+ .session-denials.bad{background:rgba(255,94,91,.12);color:var(--danger)}
273
+ .session-detail{padding:4px 10px 8px 28px;border-top:1px solid var(--border)}
274
+ .session-keys{color:var(--text-secondary);font-family:var(--font-mono);font-size:.74rem;padding:4px 0 6px}
275
+
260
276
  /* Secrets table */
261
277
  .secrets-toolbar{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px;align-items:center}
262
278
  .search{flex:1;min-width:180px;display:flex;align-items:center;gap:6px;background:rgba(255,255,255,.04);border:1px solid var(--border);border-radius:var(--radius-sm);padding:5px 10px;transition:border-color .2s}
@@ -338,6 +354,7 @@ body{min-height:100vh;overflow-x:hidden;position:relative}
338
354
  }
339
355
 
340
356
  // src/core/dashboard.ts
357
+ var SESSION_RECENT_EVENTS = 10;
341
358
  var AUDIT_WINDOW_SECONDS = 24 * 60 * 60;
342
359
  function toSecretSnapshot(entry) {
343
360
  const envelope = entry.envelope;
@@ -475,6 +492,17 @@ function collectSnapshot() {
475
492
  since: new Date(Date.now() - AUDIT_WINDOW_SECONDS * 1e3).toISOString()
476
493
  }).filter((e) => e.action !== "list");
477
494
  const recent = auditWindow.slice(0, 80);
495
+ const sessions = buildSessions(auditWindow, SESSION_RECENT_EVENTS).map(
496
+ ({ events, ...summary }) => ({
497
+ ...summary,
498
+ recent: events.map((e) => ({
499
+ timestamp: e.timestamp,
500
+ action: e.action,
501
+ ...e.key ? { key: e.key } : {},
502
+ ...e.detail ? { detail: e.detail } : {}
503
+ }))
504
+ })
505
+ );
478
506
  const approvals = listApprovals().map((a) => ({
479
507
  id: a.id,
480
508
  key: a.key,
@@ -483,9 +511,7 @@ function collectSnapshot() {
483
511
  grantedBy: a.grantedBy,
484
512
  grantedAt: a.grantedAt,
485
513
  expiresAt: a.expiresAt,
486
- secondsRemaining: Math.floor(
487
- (new Date(a.expiresAt).getTime() - Date.now()) / 1e3
488
- ),
514
+ secondsRemaining: Math.floor((new Date(a.expiresAt).getTime() - Date.now()) / 1e3),
489
515
  valid: a.valid && !a.tampered,
490
516
  tampered: a.tampered
491
517
  }));
@@ -510,6 +536,7 @@ function collectSnapshot() {
510
536
  audit: recent,
511
537
  auditMetrics: buildAuditMetrics(auditWindow),
512
538
  anomalies: detectAnomalies(),
539
+ sessions,
513
540
  environment: collapseEnvironment({ projectPath }),
514
541
  manifest: buildManifest(projectPath, secrets),
515
542
  policy: buildPolicySnapshot(projectPath),
@@ -655,4 +682,4 @@ export {
655
682
  collectSnapshot,
656
683
  startDashboardServer
657
684
  };
658
- //# sourceMappingURL=dashboard-2MLSJZQR.js.map
685
+ //# sourceMappingURL=dashboard-K7LYTWSL.js.map