agentflow-dashboard 0.8.0 → 0.8.2

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 +1 @@
1
- :root{--bg:#0d1117;--bg2:#161b22;--bg3:#1c2129;--bgh:#21262d;--bd:#30363d;--bdm:#21262d;--t1:#e6edf3;--t2:#8b949e;--t3:#6e7681;--ok:#3fb950;--warn:#d29922;--fail:#f85149;--info:#58a6ff;--f:sans-serif;--fm:"SF Mono",Menlo,monospace;--xs:.85rem;--sm:.9rem;--base:1rem;--lg:1.15rem;--xl:1.35rem;--s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:24px;--r:5px}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--f);font-size:var(--base);color:var(--t1);background:var(--bg);line-height:1.4;-webkit-font-smoothing:antialiased}.dashboard{display:flex;flex-direction:column;height:100vh;overflow:hidden}.workspace{display:flex;flex:1;min-height:0;overflow:hidden;border-top:1px solid var(--bd)}.workspace__main{flex:1;overflow-y:auto;overflow-x:hidden}.workspace__empty{display:flex;align-items:center;justify-content:center;height:100%;color:var(--t3);font-size:var(--sm)}.health-banner{display:flex;align-items:center;gap:var(--s4);padding:0 var(--s4);height:42px;background:var(--bg2);border-bottom:1px solid var(--bd);flex-shrink:0}.health-banner__title{font-family:var(--fm);font-size:var(--base);font-weight:700;margin-right:var(--s1)}.hb-version{font-size:11px;color:var(--t3);font-family:var(--fm);margin-right:var(--s3)}.hb-live{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:700;letter-spacing:.06em;padding:1px 6px;border-radius:3px;margin-right:var(--s3)}.hb-live--on{color:var(--ok);background:#3fb9501a}.hb-live--off{color:var(--fail);background:#f851491a}.hb-live__dot{width:6px;height:6px;border-radius:50%;background:currentColor}.hb-live__dot--pulse{animation:livePulse 2s ease-in-out infinite}@keyframes livePulse{0%,to{opacity:1}50%{opacity:.3}}.health-banner__stats{display:flex;gap:var(--s4);align-items:center}.stat-cell{display:flex;flex-direction:column;align-items:center}.stat-cell__value{font-family:var(--fm);font-size:var(--sm);font-weight:700;line-height:1}.stat-cell__label{font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:.06em}.stat-cell__sparkline{display:flex;gap:1px;margin-top:2px}.spark{width:2px;height:6px;border-radius:1px}.spark--ok{background:var(--ok);opacity:.4}.spark--fail{background:var(--fail)}.dot{display:inline-block;width:7px;height:7px;border-radius:50%;flex-shrink:0}.dot--ok{background:var(--ok)}.dot--fail{background:var(--fail)}.dot--warn{background:var(--warn)}.top-section{flex-shrink:0;max-height:33vh;overflow-y:auto;background:var(--bg2);border-bottom:2px solid var(--bd)}.chip-row{display:flex;gap:var(--s1);flex-wrap:wrap;padding:var(--s1) var(--s4);border-bottom:1px solid var(--bd);background:#161b2299;align-items:center}.chip-row__label{font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:.05em;font-weight:600;margin-right:var(--s2);white-space:nowrap}.schip{display:inline-flex;align-items:center;gap:3px;font-size:11px;font-family:var(--fm);padding:2px 6px;border-radius:10px;border:1px solid var(--bd);color:var(--t2)}.schip--ok{border-color:#3fb95033}.schip--fail{border-color:#f851494d;color:var(--fail)}.schip--off{opacity:.5}.schip--infra{border-color:#58a6ff33}.schip--worker{padding:1px 6px;border-radius:var(--r)}.schip__name{font-weight:600;color:var(--t1)}.schip__detail{color:var(--t3)}.schip__state{color:var(--t3);font-style:italic}.chip{font-size:12px;font-family:var(--fm);padding:1px 8px;border-radius:10px;border:1px solid var(--bd);color:var(--t2)}.chip--ok{border-color:#3fb9504d}.chip--fail{border-color:#f851494d;color:var(--fail)}.chip--off{opacity:.5}.chip--infra{border-color:#58a6ff4d}.agroup{border-bottom:1px solid var(--bd)}.agroup__head{display:flex;width:100%;align-items:center;gap:var(--s2);padding:var(--s1) var(--s4);background:transparent;border:none;color:var(--t1);cursor:pointer;font-size:var(--xs);text-align:left}.agroup__head:hover{background:var(--bgh)}.agroup__expand{font-size:11px;color:var(--t3);width:12px}.agroup__name{font-weight:600}.agroup__stats{color:var(--t2);font-family:var(--fm)}.agroup__fail{color:var(--fail);font-weight:600}.agroup__svc{font-size:11px;color:var(--t3);font-family:var(--fm)}.agroup__svc--ok{color:var(--ok)}.agroup__count{margin-left:auto;color:var(--t3)}.agroup__body{padding:var(--s1) var(--s4);display:flex;flex-wrap:wrap;gap:var(--s3);align-items:flex-start}.asubgroup{flex:1;min-width:200px}.asubgroup__label{font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:.06em;padding:var(--s1) 0;font-weight:600}.asubgroup__cards{display:flex;gap:var(--s1);flex-wrap:wrap}.acard__merged{font-size:12px;color:var(--info);font-style:italic}.agent-row{display:flex;gap:var(--s2);flex-wrap:wrap;padding:var(--s2) var(--s4)}.acard{background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r);padding:var(--s1) var(--s2);cursor:pointer;text-align:left;min-width:120px;flex:1 1 140px;max-width:220px;transition:border-color .1s;font-size:var(--xs)}.acard:hover{border-color:var(--info)}.acard--sel{border-color:var(--info);background:#58a6ff0f}.acard--fail{border-left:3px solid var(--fail)}.acard__r1{display:flex;align-items:center;gap:3px;margin-bottom:1px}.acard__name{font-family:var(--fm);font-size:var(--xs);font-weight:600;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.acard__source{font-size:12px;padding:0 4px;border-radius:2px;background:#58a6ff26;color:var(--info);text-transform:uppercase;letter-spacing:.04em;flex-shrink:0}.acard__pct{font-family:var(--fm);font-size:var(--xs);color:var(--ok)}.acard__pct--warn{color:var(--warn)}.acard__r2{display:flex;gap:var(--s2);font-size:12px;color:var(--t3)}.acard__failn{color:var(--fail);font-weight:700}.acard__spark{display:flex;gap:1px;align-items:flex-end;height:8px;margin-top:2px;overflow:hidden}.sk{width:2px;min-height:2px;border-radius:1px;flex-shrink:0}.sk--ok{background:var(--ok);opacity:.4}.sk--fail{background:var(--fail)}.exec-sidebar{width:270px;overflow-y:auto;border-right:2px solid var(--bd);flex-shrink:0;background:var(--bg2)}.exec-sidebar__head{display:flex;justify-content:space-between;padding:var(--s2) var(--s3);font-size:var(--xs);font-weight:600;color:var(--t3);text-transform:uppercase;letter-spacing:.06em;border-bottom:1px solid var(--bdm);position:sticky;top:0;background:var(--bg2);z-index:1}.exec-sidebar__agent,.exec-sidebar__count{font-family:var(--fm)}.exec-sidebar__fails{color:var(--fail);font-weight:700}.erow{display:flex;width:100%;align-items:center;gap:4px;padding:3px var(--s2);background:transparent;border:none;border-bottom:1px solid var(--bdm);color:var(--t2);cursor:pointer;font-size:12px;text-align:left}.erow:hover{background:var(--bgh)}.erow--sel{background:var(--bg3);border-left:2px solid var(--info)}.erow--fail{color:var(--fail)}.erow__icon{width:12px;text-align:center;font-size:12px}.erow__time{width:72px;font-size:11px;color:var(--t3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.erow__n{font-family:var(--fm);width:22px;text-align:right}.erow__dur{font-family:var(--fm);width:36px;text-align:right}.erow__bar{flex:1;height:3px;background:var(--bg);border-radius:2px;overflow:hidden}.erow__fill{display:block;height:100%;border-radius:2px}.erow__fill--ok{background:var(--ok);opacity:.4}.erow__fill--fail{background:var(--fail);opacity:.6}.agent-profile{padding:var(--s3);height:100%;display:flex;flex-direction:column}.ap-stats{display:flex;gap:var(--s5);padding:var(--s2) 0;border-bottom:1px solid var(--bdm);margin-bottom:var(--s3);flex-wrap:wrap}.ap-stat{text-align:center}.ap-stat__v{display:block;font-family:var(--fm);font-size:var(--lg);font-weight:700}.ap-stat__l{font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:.05em}.ap-tabs{display:flex;gap:0;border-bottom:1px solid var(--bdm);margin-bottom:var(--s3)}.ap-tab{background:transparent;border:none;border-bottom:2px solid transparent;padding:var(--s2) var(--s3);font-size:var(--xs);color:var(--t3);cursor:pointer}.ap-tab:hover{color:var(--t1)}.ap-tab--active{color:var(--t1);border-bottom-color:var(--info)}.ap-content{flex:1;overflow-y:auto}.pmap__controls{display:flex;align-items:center;gap:var(--s4);margin-bottom:var(--s2);font-size:var(--xs);color:var(--t2)}.pmap__slider-label{display:flex;align-items:center;gap:var(--s2)}.pmap__slider{width:120px}.pmap__info{color:var(--t3)}.pmap__svg{display:block}.var-row{padding:var(--s2) 0;border-bottom:1px solid var(--bdm)}.var-row--happy{border-left:3px solid var(--ok);padding-left:var(--s2)}.var-row__header{display:flex;align-items:center;gap:var(--s2);font-size:var(--xs);margin-bottom:var(--s1)}.var-row__rank{font-family:var(--fm);color:var(--t3);width:24px}.var-row__badge{background:#3fb95026;color:var(--ok);font-size:11px;padding:1px 6px;border-radius:3px;font-weight:600}.var-row__count{font-family:var(--fm);color:var(--t2)}.var-row__pct-bar{flex:1;height:4px;background:var(--bg3);border-radius:2px;overflow:hidden}.var-row__pct-fill{height:100%;background:var(--info);border-radius:2px;opacity:.5}.var-row__steps{display:flex;align-items:center;gap:2px;flex-wrap:wrap}.var-row__arrow{color:var(--t3);font-size:12px;margin:0 2px}.var-row__step{font-family:var(--fm);font-size:11px;padding:1px 6px;border:1px solid;border-radius:3px;white-space:nowrap}.bn-layout{display:flex;flex-direction:column;height:100%}.bn-chart-area{flex:1;min-height:200px;max-height:50%;overflow:auto;border:1px solid var(--bdm);border-radius:var(--r);margin-bottom:var(--s2);position:relative}.bn-chart-controls{position:sticky;top:0;right:0;display:flex;justify-content:flex-end;gap:2px;padding:var(--s1);z-index:1;background:#0d1117cc}.bn-ranking{flex:1;overflow-y:auto;min-height:100px}.bn-row{display:flex;align-items:center;gap:var(--s2);padding:var(--s1) 0;font-size:var(--xs)}.bn-row__name{font-family:var(--fm);width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bn-row__type{color:var(--t3);width:60px}.bn-row__p95{font-family:var(--fm);width:60px;text-align:right;color:var(--fail)}.bn-row__bar{flex:1;height:6px;background:var(--bg3);border-radius:3px;overflow:hidden}.bn-row__fill{height:100%;background:var(--fail);opacity:.6;border-radius:3px}.exec-detail{display:flex;flex-direction:column;height:100%}.ed-header{display:flex;align-items:center;gap:var(--s2);padding:var(--s2) var(--s3);border-bottom:1px solid var(--bdm);flex-shrink:0;flex-wrap:wrap}.ed-header__agent{font-family:var(--fm);font-weight:700;font-size:var(--sm)}.ed-header__meta{font-size:var(--xs);color:var(--t2)}.ed-header__ts{font-size:var(--xs);color:var(--t3);font-family:var(--fm);margin-left:auto}.ed-tag{font-size:11px;padding:1px 6px;background:var(--bg2);border:1px solid var(--bd);border-radius:3px;color:var(--t3);font-family:var(--fm)}.ed-tabs{display:flex;gap:0;border-bottom:1px solid var(--bdm);flex-shrink:0;overflow-x:auto;flex-wrap:wrap}.ed-tab{background:transparent;border:none;border-bottom:2px solid transparent;padding:var(--s1) var(--s2);font-size:var(--xs);color:var(--t3);cursor:pointer;white-space:nowrap}.ed-tab:hover{color:var(--t1)}.ed-tab--active{color:var(--t1);border-bottom-color:var(--info)}.ed-content{flex:1;overflow-y:auto;padding:var(--s3)}.flame__fail-callout{background:#f8514914;border:1px solid rgba(248,81,73,.25);border-radius:var(--r);padding:var(--s2) var(--s3);margin-bottom:var(--s3);font-size:var(--xs)}.flame__fail-title{color:var(--fail);font-weight:700;font-size:var(--sm);margin-bottom:var(--s1)}.flame__fail-item{display:flex;align-items:baseline;gap:var(--s2);padding:1px 0}.flame__fail-ts{font-family:var(--fm);color:var(--t3)}.flame__fail-err{color:var(--fail);font-family:var(--fm);font-size:11px}.flame__range{font-size:var(--xs);color:var(--t2);font-family:var(--fm);margin-bottom:var(--s2)}.flame__axis{display:flex;justify-content:space-between;padding:0 0 var(--s1) 28px;font-size:11px;color:var(--t3);font-family:var(--fm);border-bottom:1px solid var(--bdm)}.flame__row{display:flex;align-items:center;height:24px;position:relative}.flame__depth{width:28px;font-size:11px;color:var(--t3);text-align:right;padding-right:var(--s1);flex-shrink:0;font-family:var(--fm)}.flame__track{flex:1;height:18px;position:relative;background:var(--bg2);border-radius:2px;overflow:visible}.flame__bar{position:absolute;top:1px;height:16px;border-radius:2px;cursor:pointer;display:flex;align-items:center;overflow:hidden;transition:opacity .1s}.flame__bar--hov{z-index:1;box-shadow:0 0 4px #fff3}.flame__bar-label{font-size:12px;color:#fff;padding:0 3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-shadow:0 1px 2px rgba(0,0,0,.5)}.flame__side-label{position:absolute;left:calc(100% + 4px);top:1px;font-size:12px;color:var(--t1);white-space:nowrap;pointer-events:none;font-family:var(--fm)}.flame__tooltip{position:fixed;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r);padding:var(--s2);font-size:var(--xs);white-space:nowrap;z-index:9999;pointer-events:none;box-shadow:0 4px 16px #0009;min-width:220px;max-width:400px}.flame__tt-title{font-weight:700;font-size:var(--sm);margin-bottom:2px}.flame__tt-type{font-size:var(--xs);margin-bottom:2px}.flame__tt-dur{font-family:var(--fm);color:var(--t2);margin-bottom:4px}.flame__tt-meta{font-size:11px;color:var(--t3)}.flame__tt-err{font-size:var(--xs);color:var(--fail);margin-top:4px}.aflow{position:relative}.af-step{position:relative;padding:1px 0}.af-step--fail{background:#f851490a}.af-step__line{position:absolute;top:-3px;left:11px;width:1px;height:6px;background:var(--bdm)}.af-step__row{display:flex;align-items:center;gap:var(--s2);font-size:var(--xs);padding:2px var(--s2)}.af-step__icon{width:16px;text-align:center;font-size:var(--sm);flex-shrink:0}.af-step__cat{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;width:48px;flex-shrink:0}.af-step__name{font-family:var(--fm);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.af-step__dur{font-family:var(--fm);color:var(--t3);width:48px;text-align:right;flex-shrink:0}.af-step__ts{font-family:var(--fm);color:var(--t3);font-size:11px;width:64px;text-align:right;flex-shrink:0}.af-step__ops{display:flex;gap:var(--s1);align-items:center;padding:1px var(--s2) 1px 32px;flex-wrap:wrap}.af-step__op-tag{font-size:12px;padding:0 4px;border-radius:2px;background:var(--bg);border:1px solid var(--bdm);color:var(--t2);font-family:var(--fm)}.af-step__op-tag--model{border-color:#bc8cff4d;color:#bc8cff}.af-step__op-detail{font-size:12px;color:var(--t3);font-family:var(--fm)}.af-step__err{font-size:var(--xs);color:var(--fail);padding:1px var(--s2) 1px 32px;font-family:var(--fm)}.mv-row{display:flex;gap:var(--s2);flex-wrap:wrap;margin-bottom:var(--s3)}.mv-c{background:var(--bg2);border:1px solid var(--bd);border-radius:var(--r);padding:var(--s2);text-align:center;min-width:70px;flex:1}.mv-v{display:block;font-family:var(--fm);font-size:var(--lg);font-weight:700}.mv-l{font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:.05em}.c-ok{color:var(--ok)}.c-fail{color:var(--fail)}.mview__section{font-size:var(--xs);font-weight:600;color:var(--t3);text-transform:uppercase;letter-spacing:.05em;margin:var(--s3) 0 var(--s2)}.mt-row{display:flex;align-items:center;gap:var(--s2);padding:2px 0;font-size:var(--xs)}.mt-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.mt-name{font-family:var(--fm);width:70px}.mt-cnt{font-family:var(--fm);width:20px;text-align:right}.mt-fail{color:var(--fail);font-weight:700}.mt-dur{color:var(--t3);font-family:var(--fm);width:48px;text-align:right}.mt-bar{flex:1;height:5px;background:var(--bg3);border-radius:3px;overflow:hidden}.mt-fill{height:100%;border-radius:3px;opacity:.5}.dtree{font-size:var(--xs)}.dt-node{display:flex;align-items:center;gap:4px;padding:2px 0}.dt-node--fail{background:#f851490a}.dt-node__name{font-family:var(--fm);font-weight:600}.dt-node__type{font-size:11px;color:var(--t3)}.dt-node__dur{font-family:var(--fm);color:var(--t3);margin-left:auto}.dt-node__err{color:var(--fail);font-family:var(--fm);font-size:11px;margin-left:var(--s2)}.summary-content{font-size:var(--sm)}.sc-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--s2);margin-bottom:var(--s3)}.sc-label{font-size:11px;color:var(--t3);text-transform:uppercase;display:block}.sc-failures{margin:var(--s3) 0;padding:var(--s2) var(--s3);background:#f851490f;border:1px solid rgba(248,81,73,.2);border-radius:var(--r)}.sc-failures__title{color:var(--fail);font-weight:700;margin-bottom:var(--s1)}.sc-failure{display:flex;gap:var(--s2);font-size:var(--xs);padding:1px 0}.sc-failure__type{color:var(--t3)}.sc-failure__err{color:var(--fail);font-family:var(--fm)}.sc-types{margin-top:var(--s3)}.sc-types__title{font-size:var(--xs);color:var(--t3);text-transform:uppercase;margin-bottom:var(--s1)}.sc-types__list{display:flex;gap:var(--s2);flex-wrap:wrap}.sc-type-badge{font-size:11px;font-family:var(--fm);padding:1px 6px;border:1px solid var(--bd);border-radius:3px;color:var(--t2)}.alert-card{display:flex;align-items:flex-start;gap:var(--s2);padding:var(--s2) var(--s4);font-size:var(--xs);border-bottom:1px solid var(--bdm)}.alert-card--critical{background:#f851490f}.alert-card--warn{background:#d299220f}.alert-icon{flex-shrink:0}.alert-content{flex:1;min-width:0}.alert-title{font-weight:600}.alert-description{color:var(--t3)}.alert-actions{display:flex;gap:var(--s2);margin-top:3px}.alert-action{font-size:11px;font-family:var(--fm);padding:1px 6px;background:var(--bg3);border:1px solid var(--bd);border-radius:3px;color:var(--t2);cursor:pointer}.alert-action:hover{color:var(--t1)}.alert-dismiss{padding:2px;background:transparent;border:none;color:var(--t3);cursor:pointer;font-size:var(--base);flex-shrink:0}.summary-bar{display:flex;gap:var(--s5);padding:var(--s2) var(--s4);background:var(--bg2);border-top:1px solid var(--bd);font-size:var(--xs);flex-shrink:0;height:32px;align-items:center;color:var(--t2)}.tv-chat{display:flex;flex-direction:column;gap:var(--s2)}.tv-bubble{background:var(--bg2);border:1px solid var(--bd);border-radius:12px;padding:var(--s2) var(--s3);max-width:85%;font-size:var(--xs)}.tv-bubble--right{align-self:flex-end;background:#58a6ff14;border-color:#58a6ff33}.tv-bubble--user{border-color:#58a6ff40}.tv-bubble--assistant{border-color:#3fb95033}.tv-bubble--tool{border-color:#d2992233;background:#d299220a}.tv-bubble--thinking{border-color:var(--bdm);opacity:.7;border-style:dashed}.tv-bubble--system{border-color:var(--bdm);background:var(--bg3)}.tv-bubble--event{border-color:var(--bdm)}.tv-bubble--error{border-color:#f851494d;background:#f851490a}.tv-bubble__header{display:flex;align-items:center;gap:var(--s2);margin-bottom:var(--s1);flex-wrap:wrap}.tv-bubble__icon{font-size:var(--sm)}.tv-bubble__role{font-weight:600;font-size:var(--xs)}.tv-bubble__model{color:var(--t3);font-family:var(--fm);font-size:11px}.tv-bubble__tokens{color:var(--t3);font-size:11px;font-family:var(--fm)}.tv-bubble__time{color:var(--t3);margin-left:auto;font-family:var(--fm);font-size:11px}.tv-bubble__tool{margin:var(--s1) 0}.tv-bubble__tool-name{font-family:var(--fm);font-weight:600;color:var(--warn);font-size:var(--xs)}.tv-bubble__content{white-space:pre-wrap;word-break:break-word;line-height:1.5;color:var(--t1)}.tv-bubble__error{color:var(--fail);font-weight:600;margin-top:var(--s1)}.tv-code{background:var(--bg);border:1px solid var(--bdm);border-radius:6px;padding:var(--s2);font-family:var(--fm);font-size:12px;overflow-x:auto;max-height:150px;overflow-y:auto;white-space:pre;margin:var(--s1) 0;color:var(--t2)}.tv-code--error{border-color:#f8514933;color:var(--fail)}.tv-thinking-btn{background:transparent;border:none;color:var(--t3);cursor:pointer;font-size:var(--xs);padding:var(--s1) 0}.tv-bubble--left{align-self:flex-start}.tv-origin{font-size:7px;padding:1px 4px;border-radius:3px;text-transform:uppercase;letter-spacing:.04em;font-weight:700}.tv-origin--user{background:#58a6ff26;color:var(--info)}.tv-origin--agent{background:#3fb9501f;color:var(--ok)}.tv-origin--system{background:#6e768126;color:var(--t3)}.settings-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;z-index:100;display:flex;justify-content:flex-end}.settings-panel{width:420px;max-width:90vw;background:var(--bg2);border-left:1px solid var(--bd);overflow-y:auto;padding:var(--s4)}.sp-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--s4)}.sp-head h3{font-size:var(--base);font-weight:600}.sp-close{background:transparent;border:none;color:var(--t3);cursor:pointer;font-size:var(--xl)}.sp-error{padding:var(--s2);background:#f851491a;border:1px solid rgba(248,81,73,.3);border-radius:var(--r);font-size:var(--xs);color:var(--fail);margin-bottom:var(--s3)}.sp-section{font-size:var(--xs);color:var(--t3);text-transform:uppercase;letter-spacing:.06em;margin:var(--s3) 0 var(--s2);font-weight:600}.sp-dir{display:flex;align-items:center;gap:var(--s2);padding:var(--s1) var(--s2);font-size:var(--sm);border-radius:var(--r)}.sp-dir:hover{background:var(--bgh)}.sp-dir--sug{background:#d299220a}.sp-dir__path{font-family:var(--fm);font-size:var(--xs);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sp-btn{font-size:var(--xs);padding:2px 8px;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r);cursor:pointer;color:var(--t2)}.sp-btn--add{color:var(--info)}.sp-btn--add:hover{background:var(--bgh);border-color:var(--info)}.sp-btn--rm{color:var(--fail);font-size:var(--sm);padding:0 6px}.sp-btn--rm:hover{background:#f851491a}.sp-btn--rescan{width:100%;padding:var(--s2);color:var(--info);font-size:var(--sm)}.sp-btn--rescan:hover{background:var(--bgh)}.sp-btn:disabled{opacity:.5;cursor:default}.sp-manual{display:flex;gap:var(--s2);margin-bottom:var(--s2)}.sp-input{flex:1;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r);padding:var(--s1) var(--s2);color:var(--t1);font-family:var(--fm);font-size:var(--xs)}.sp-input:focus{outline:none;border-color:var(--info)}.zb{width:24px;height:24px;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r);color:var(--t1);cursor:pointer;font-size:var(--sm);display:inline-flex;align-items:center;justify-content:center}.zb:hover{background:var(--bgh);border-color:var(--t3)}.pmap__zoom{display:flex;gap:2px;margin-left:auto}.status-dot{display:inline-block;width:7px;height:7px;border-radius:50%;flex-shrink:0}.status-dot--ok{background:var(--ok)}.status-dot--critical{background:var(--fail)}.status-dot--warn{background:var(--warn)}.status-dot--inactive{background:var(--t3)}.soma-intel{padding:16px;font-size:13px;line-height:1.5}.soma-intel__header{display:flex;align-items:center;gap:8px;margin-bottom:16px}.soma-intel__title{font-size:16px;font-weight:700}.soma-intel__badge{font-size:10px;background:var(--info);color:#000;padding:2px 6px;border-radius:4px;font-weight:600}.soma-intel__ts{margin-left:auto;font-size:11px;color:var(--t3)}.soma-intel__ts--stale{color:var(--warn)}.soma-intel__agent-card{background:var(--bg2);border:1px solid var(--bd);border-radius:6px;padding:12px;margin-bottom:16px}.soma-intel__agent-name{font-weight:700;font-size:14px;margin-bottom:4px}.soma-intel__agent-stats{display:flex;gap:16px;font-size:12px;color:var(--t2)}.soma-intel__guard-block{margin-top:8px;padding:8px;background:#f851491a;border:1px solid var(--fail);border-radius:4px;color:var(--fail);font-size:12px;font-weight:600}.soma-intel__empty{color:var(--t3);padding:12px}.soma-intel__section{margin-bottom:16px}.soma-intel__section-header{display:flex;align-items:center;gap:8px;margin-bottom:8px;border-bottom:1px solid var(--bd);padding-bottom:4px;flex-wrap:wrap}.soma-intel__section-title{font-size:13px;font-weight:700;color:var(--t1);margin:0}.soma-intel__filters{display:flex;gap:4px;margin-left:auto}.soma-intel__filter{font-size:11px;padding:2px 6px;background:var(--bg2);border:1px solid var(--bd);border-radius:4px;color:var(--t1);cursor:pointer}.soma-intel__filter:focus{outline:1px solid var(--info)}.soma-intel__show-more{display:block;width:100%;padding:6px;margin-top:4px;background:none;border:1px dashed var(--bd);border-radius:4px;color:var(--t2);font-size:11px;cursor:pointer;text-align:center}.soma-intel__show-more:hover{background:var(--bg2);color:var(--t1)}.soma-intel__table{font-size:12px;font-family:var(--mono)}.soma-intel__row{display:grid;grid-template-columns:1fr 60px 50px 55px 60px;padding:4px 0;border-bottom:1px solid var(--bd)}.soma-intel__row--header{font-weight:700;color:var(--t2);border-bottom:2px solid var(--bd)}.soma-intel__row--active{background:#58a6ff14}.soma-intel__col-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.soma-intel__col-num,.soma-intel__col-status{text-align:right}.soma-intel__insight{padding:8px;background:var(--bg2);border-radius:4px;margin-bottom:6px}.soma-intel__insight-type{font-size:10px;text-transform:uppercase;color:var(--info);margin-right:6px;font-weight:600}.soma-intel__insight-conf{font-size:10px;color:var(--t3);margin-left:6px}.soma-intel__insight-claim{font-size:12px;color:var(--t2);margin-top:4px}.soma-intel__policy{padding:8px;background:var(--bg2);border-radius:4px;margin-bottom:6px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}.soma-intel__enforcement{font-size:10px;padding:2px 6px;border-radius:3px;font-weight:600}.soma-intel__enforcement--warn{background:#d2992233;color:var(--warn)}.soma-intel__enforcement--error{background:#f8514933;color:var(--fail)}.soma-intel__enforcement--abort{background:#f851494d;color:var(--fail)}.soma-intel__policy-cond{width:100%;font-size:11px;color:var(--t3);margin-top:2px}.soma-intel--teaser{text-align:center;padding:40px 20px}.soma-intel__teaser-icon{font-size:48px;margin-bottom:12px}.soma-intel__teaser-title{font-size:20px;font-weight:700;margin-bottom:4px}.soma-intel__teaser-subtitle{font-size:14px;color:var(--t2);margin-bottom:24px}.soma-intel__teaser-features{text-align:left;max-width:360px;margin:0 auto 24px;font-size:13px}.soma-intel__teaser-feature{padding:6px 0;color:var(--t1)}.soma-intel__teaser-cta{display:inline-block;padding:10px 24px;background:var(--info);color:#000;border-radius:6px;text-decoration:none;font-weight:700;font-size:14px}.soma-intel__teaser-cta:hover{opacity:.9}
1
+ :root{--bg:#0d1117;--bg2:#161b22;--bg3:#1c2129;--bgh:#21262d;--bd:#30363d;--bdm:#21262d;--t1:#e6edf3;--t2:#8b949e;--t3:#6e7681;--ok:#3fb950;--warn:#d29922;--fail:#f85149;--info:#58a6ff;--f:sans-serif;--fm:"SF Mono",Menlo,monospace;--xs:.85rem;--sm:.9rem;--base:1rem;--lg:1.15rem;--xl:1.35rem;--s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:24px;--r:5px}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--f);font-size:var(--base);color:var(--t1);background:var(--bg);line-height:1.4;-webkit-font-smoothing:antialiased}.dashboard{display:flex;flex-direction:column;height:100vh;overflow:hidden}.workspace{display:flex;flex:1;min-height:0;overflow:hidden;border-top:1px solid var(--bd)}.workspace__main{flex:1;overflow-y:auto;overflow-x:hidden}.workspace__empty{display:flex;align-items:center;justify-content:center;height:100%;color:var(--t3);font-size:var(--sm)}.health-banner{display:flex;align-items:center;gap:var(--s4);padding:0 var(--s4);height:42px;background:var(--bg2);border-bottom:1px solid var(--bd);flex-shrink:0}.health-banner__title{font-family:var(--fm);font-size:var(--base);font-weight:700;margin-right:var(--s1)}.hb-version{font-size:11px;color:var(--t3);font-family:var(--fm);margin-right:var(--s3)}.hb-live{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:700;letter-spacing:.06em;padding:1px 6px;border-radius:3px;margin-right:var(--s3)}.hb-live--on{color:var(--ok);background:#3fb9501a}.hb-live--off{color:var(--fail);background:#f851491a}.hb-live__dot{width:6px;height:6px;border-radius:50%;background:currentColor}.hb-live__dot--pulse{animation:livePulse 2s ease-in-out infinite}@keyframes livePulse{0%,to{opacity:1}50%{opacity:.3}}.health-banner__stats{display:flex;gap:var(--s4);align-items:center}.stat-cell{display:flex;flex-direction:column;align-items:center}.stat-cell__value{font-family:var(--fm);font-size:var(--sm);font-weight:700;line-height:1}.stat-cell__label{font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:.06em}.stat-cell__sparkline{display:flex;gap:1px;margin-top:2px}.spark{width:2px;height:6px;border-radius:1px}.spark--ok{background:var(--ok);opacity:.4}.spark--fail{background:var(--fail)}.dot{display:inline-block;width:7px;height:7px;border-radius:50%;flex-shrink:0}.dot--ok{background:var(--ok)}.dot--fail{background:var(--fail)}.dot--warn{background:var(--warn)}.top-section{flex-shrink:0;max-height:33vh;overflow-y:auto;background:var(--bg2);border-bottom:2px solid var(--bd)}.chip-row{display:flex;gap:var(--s1);flex-wrap:wrap;padding:var(--s1) var(--s4);border-bottom:1px solid var(--bd);background:#161b2299;align-items:center}.chip-row__label{font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:.05em;font-weight:600;margin-right:var(--s2);white-space:nowrap}.schip{display:inline-flex;align-items:center;gap:3px;font-size:11px;font-family:var(--fm);padding:2px 6px;border-radius:10px;border:1px solid var(--bd);color:var(--t2)}.schip--ok{border-color:#3fb95033}.schip--fail{border-color:#f851494d;color:var(--fail)}.schip--off{opacity:.5}.schip--infra{border-color:#58a6ff33}.schip--worker{padding:1px 6px;border-radius:var(--r)}.schip__name{font-weight:600;color:var(--t1)}.schip__detail{color:var(--t3)}.schip__state{color:var(--t3);font-style:italic}.chip{font-size:12px;font-family:var(--fm);padding:1px 8px;border-radius:10px;border:1px solid var(--bd);color:var(--t2)}.chip--ok{border-color:#3fb9504d}.chip--fail{border-color:#f851494d;color:var(--fail)}.chip--off{opacity:.5}.chip--infra{border-color:#58a6ff4d}.agroup{border-bottom:1px solid var(--bd)}.agroup__head{display:flex;width:100%;align-items:center;gap:var(--s2);padding:var(--s1) var(--s4);background:transparent;border:none;color:var(--t1);cursor:pointer;font-size:var(--xs);text-align:left}.agroup__head:hover{background:var(--bgh)}.agroup__expand{font-size:11px;color:var(--t3);width:12px}.agroup__name{font-weight:600}.agroup__stats{color:var(--t2);font-family:var(--fm)}.agroup__fail{color:var(--fail);font-weight:600}.agroup__svc{font-size:11px;color:var(--t3);font-family:var(--fm)}.agroup__svc--ok{color:var(--ok)}.agroup__count{margin-left:auto;color:var(--t3)}.agroup__body{padding:var(--s1) var(--s4);display:flex;flex-wrap:wrap;gap:var(--s3);align-items:flex-start}.asubgroup{flex:1;min-width:200px}.asubgroup__label{font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:.06em;padding:var(--s1) 0;font-weight:600}.asubgroup__cards{display:flex;gap:var(--s1);flex-wrap:wrap}.acard__merged{font-size:12px;color:var(--info);font-style:italic}.agent-row{display:flex;gap:var(--s2);flex-wrap:wrap;padding:var(--s2) var(--s4)}.acard{background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r);padding:var(--s1) var(--s2);cursor:pointer;text-align:left;min-width:120px;flex:1 1 140px;max-width:220px;transition:border-color .1s;font-size:var(--xs)}.acard:hover{border-color:var(--info)}.acard--sel{border-color:var(--info);background:#58a6ff0f}.acard--fail{border-left:3px solid var(--fail)}.acard__r1{display:flex;align-items:center;gap:3px;margin-bottom:1px}.acard__name{font-family:var(--fm);font-size:var(--xs);font-weight:600;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.acard__source{font-size:12px;padding:0 4px;border-radius:2px;background:#58a6ff26;color:var(--info);text-transform:uppercase;letter-spacing:.04em;flex-shrink:0}.acard__pct{font-family:var(--fm);font-size:var(--xs);color:var(--ok)}.acard__pct--warn{color:var(--warn)}.acard__r2{display:flex;gap:var(--s2);font-size:12px;color:var(--t3)}.acard__failn{color:var(--fail);font-weight:700}.acard__spark{display:flex;gap:1px;align-items:flex-end;height:8px;margin-top:2px;overflow:hidden}.sk{width:2px;min-height:2px;border-radius:1px;flex-shrink:0}.sk--ok{background:var(--ok);opacity:.4}.sk--fail{background:var(--fail)}.exec-sidebar{width:270px;overflow-y:auto;border-right:2px solid var(--bd);flex-shrink:0;background:var(--bg2)}.exec-sidebar__head{display:flex;justify-content:space-between;padding:var(--s2) var(--s3);font-size:var(--xs);font-weight:600;color:var(--t3);text-transform:uppercase;letter-spacing:.06em;border-bottom:1px solid var(--bdm);position:sticky;top:0;background:var(--bg2);z-index:1}.exec-sidebar__agent,.exec-sidebar__count{font-family:var(--fm)}.exec-sidebar__fails{color:var(--fail);font-weight:700}.erow{display:flex;width:100%;align-items:center;gap:4px;padding:3px var(--s2);background:transparent;border:none;border-bottom:1px solid var(--bdm);color:var(--t2);cursor:pointer;font-size:12px;text-align:left}.erow:hover{background:var(--bgh)}.erow--sel{background:var(--bg3);border-left:2px solid var(--info)}.erow--fail{color:var(--fail)}.erow__icon{width:12px;text-align:center;font-size:12px}.erow__time{width:72px;font-size:11px;color:var(--t3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.erow__n{font-family:var(--fm);width:22px;text-align:right}.erow__dur{font-family:var(--fm);width:36px;text-align:right}.erow__bar{flex:1;height:3px;background:var(--bg);border-radius:2px;overflow:hidden}.erow__fill{display:block;height:100%;border-radius:2px}.erow__fill--ok{background:var(--ok);opacity:.4}.erow__fill--fail{background:var(--fail);opacity:.6}.agent-profile{padding:var(--s3);height:100%;display:flex;flex-direction:column}.ap-stats{display:flex;gap:var(--s5);padding:var(--s2) 0;border-bottom:1px solid var(--bdm);margin-bottom:var(--s3);flex-wrap:wrap}.ap-stat{text-align:center}.ap-stat__v{display:block;font-family:var(--fm);font-size:var(--lg);font-weight:700}.ap-stat__l{font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:.05em}.ap-tabs{display:flex;gap:0;border-bottom:1px solid var(--bdm);margin-bottom:var(--s3)}.ap-tab{background:transparent;border:none;border-bottom:2px solid transparent;padding:var(--s2) var(--s3);font-size:var(--xs);color:var(--t3);cursor:pointer}.ap-tab:hover{color:var(--t1)}.ap-tab--active{color:var(--t1);border-bottom-color:var(--info)}.ap-content{flex:1;overflow-y:auto}.pmap__controls{display:flex;align-items:center;gap:var(--s4);margin-bottom:var(--s2);font-size:var(--xs);color:var(--t2)}.pmap__slider-label{display:flex;align-items:center;gap:var(--s2)}.pmap__slider{width:120px}.pmap__info{color:var(--t3)}.pmap__svg{display:block}.var-row{padding:var(--s2) 0;border-bottom:1px solid var(--bdm)}.var-row--happy{border-left:3px solid var(--ok);padding-left:var(--s2)}.var-row__header{display:flex;align-items:center;gap:var(--s2);font-size:var(--xs);margin-bottom:var(--s1)}.var-row__rank{font-family:var(--fm);color:var(--t3);width:24px}.var-row__badge{background:#3fb95026;color:var(--ok);font-size:11px;padding:1px 6px;border-radius:3px;font-weight:600}.var-row__count{font-family:var(--fm);color:var(--t2)}.var-row__pct-bar{flex:1;height:4px;background:var(--bg3);border-radius:2px;overflow:hidden}.var-row__pct-fill{height:100%;background:var(--info);border-radius:2px;opacity:.5}.var-row__steps{display:flex;align-items:center;gap:2px;flex-wrap:wrap}.var-row__arrow{color:var(--t3);font-size:12px;margin:0 2px}.var-row__step{font-family:var(--fm);font-size:11px;padding:1px 6px;border:1px solid;border-radius:3px;white-space:nowrap}.bn-layout{display:flex;flex-direction:column;height:100%}.bn-chart-area{flex:1;min-height:200px;max-height:50%;overflow:auto;border:1px solid var(--bdm);border-radius:var(--r);margin-bottom:var(--s2);position:relative}.bn-chart-controls{position:sticky;top:0;right:0;display:flex;justify-content:flex-end;gap:2px;padding:var(--s1);z-index:1;background:#0d1117cc}.bn-ranking{flex:1;overflow-y:auto;min-height:100px}.bn-row{display:flex;align-items:center;gap:var(--s2);padding:var(--s1) 0;font-size:var(--xs)}.bn-row__name{font-family:var(--fm);width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bn-row__type{color:var(--t3);width:60px}.bn-row__p95{font-family:var(--fm);width:60px;text-align:right;color:var(--fail)}.bn-row__bar{flex:1;height:6px;background:var(--bg3);border-radius:3px;overflow:hidden}.bn-row__fill{height:100%;background:var(--fail);opacity:.6;border-radius:3px}.exec-detail{display:flex;flex-direction:column;height:100%}.ed-header{display:flex;align-items:center;gap:var(--s2);padding:var(--s2) var(--s3);border-bottom:1px solid var(--bdm);flex-shrink:0;flex-wrap:wrap}.ed-header__agent{font-family:var(--fm);font-weight:700;font-size:var(--sm)}.ed-header__meta{font-size:var(--xs);color:var(--t2)}.ed-header__ts{font-size:var(--xs);color:var(--t3);font-family:var(--fm);margin-left:auto}.ed-tag{font-size:11px;padding:1px 6px;background:var(--bg2);border:1px solid var(--bd);border-radius:3px;color:var(--t3);font-family:var(--fm)}.ed-tabs{display:flex;gap:0;border-bottom:1px solid var(--bdm);flex-shrink:0;overflow-x:auto;flex-wrap:wrap}.ed-tab{background:transparent;border:none;border-bottom:2px solid transparent;padding:var(--s1) var(--s2);font-size:var(--xs);color:var(--t3);cursor:pointer;white-space:nowrap}.ed-tab:hover{color:var(--t1)}.ed-tab--active{color:var(--t1);border-bottom-color:var(--info)}.ed-content{flex:1;overflow-y:auto;padding:var(--s3)}.flame__fail-callout{background:#f8514914;border:1px solid rgba(248,81,73,.25);border-radius:var(--r);padding:var(--s2) var(--s3);margin-bottom:var(--s3);font-size:var(--xs)}.flame__fail-title{color:var(--fail);font-weight:700;font-size:var(--sm);margin-bottom:var(--s1)}.flame__fail-item{display:flex;align-items:baseline;gap:var(--s2);padding:1px 0}.flame__fail-ts{font-family:var(--fm);color:var(--t3)}.flame__fail-err{color:var(--fail);font-family:var(--fm);font-size:11px}.flame__range{font-size:var(--xs);color:var(--t2);font-family:var(--fm);margin-bottom:var(--s2)}.flame__axis{display:flex;justify-content:space-between;padding:0 0 var(--s1) 28px;font-size:11px;color:var(--t3);font-family:var(--fm);border-bottom:1px solid var(--bdm)}.flame__row{display:flex;align-items:center;height:24px;position:relative}.flame__depth{width:28px;font-size:11px;color:var(--t3);text-align:right;padding-right:var(--s1);flex-shrink:0;font-family:var(--fm)}.flame__track{flex:1;height:18px;position:relative;background:var(--bg2);border-radius:2px;overflow:visible}.flame__bar{position:absolute;top:1px;height:16px;border-radius:2px;cursor:pointer;display:flex;align-items:center;overflow:hidden;transition:opacity .1s}.flame__bar--hov{z-index:1;box-shadow:0 0 4px #fff3}.flame__bar-label{font-size:12px;color:#fff;padding:0 3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-shadow:0 1px 2px rgba(0,0,0,.5)}.flame__side-label{position:absolute;left:calc(100% + 4px);top:1px;font-size:12px;color:var(--t1);white-space:nowrap;pointer-events:none;font-family:var(--fm)}.flame__tooltip{position:fixed;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r);padding:var(--s2);font-size:var(--xs);white-space:nowrap;z-index:9999;pointer-events:none;box-shadow:0 4px 16px #0009;min-width:220px;max-width:400px}.flame__tt-title{font-weight:700;font-size:var(--sm);margin-bottom:2px}.flame__tt-type{font-size:var(--xs);margin-bottom:2px}.flame__tt-dur{font-family:var(--fm);color:var(--t2);margin-bottom:4px}.flame__tt-meta{font-size:11px;color:var(--t3)}.flame__tt-err{font-size:var(--xs);color:var(--fail);margin-top:4px}.aflow{position:relative}.af-step{position:relative;padding:1px 0}.af-step--fail{background:#f851490a}.af-step__line{position:absolute;top:-3px;left:11px;width:1px;height:6px;background:var(--bdm)}.af-step__row{display:flex;align-items:center;gap:var(--s2);font-size:var(--xs);padding:2px var(--s2)}.af-step__icon{width:16px;text-align:center;font-size:var(--sm);flex-shrink:0}.af-step__cat{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;width:48px;flex-shrink:0}.af-step__name{font-family:var(--fm);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.af-step__dur{font-family:var(--fm);color:var(--t3);width:48px;text-align:right;flex-shrink:0}.af-step__ts{font-family:var(--fm);color:var(--t3);font-size:11px;width:64px;text-align:right;flex-shrink:0}.af-step__ops{display:flex;gap:var(--s1);align-items:center;padding:1px var(--s2) 1px 32px;flex-wrap:wrap}.af-step__op-tag{font-size:12px;padding:0 4px;border-radius:2px;background:var(--bg);border:1px solid var(--bdm);color:var(--t2);font-family:var(--fm)}.af-step__op-tag--model{border-color:#bc8cff4d;color:#bc8cff}.af-step__op-detail{font-size:12px;color:var(--t3);font-family:var(--fm)}.af-step__err{font-size:var(--xs);color:var(--fail);padding:1px var(--s2) 1px 32px;font-family:var(--fm)}.mv-row{display:flex;gap:var(--s2);flex-wrap:wrap;margin-bottom:var(--s3)}.mv-c{background:var(--bg2);border:1px solid var(--bd);border-radius:var(--r);padding:var(--s2);text-align:center;min-width:70px;flex:1}.mv-v{display:block;font-family:var(--fm);font-size:var(--lg);font-weight:700}.mv-l{font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:.05em}.c-ok{color:var(--ok)}.c-fail{color:var(--fail)}.mview__section{font-size:var(--xs);font-weight:600;color:var(--t3);text-transform:uppercase;letter-spacing:.05em;margin:var(--s3) 0 var(--s2)}.mt-row{display:flex;align-items:center;gap:var(--s2);padding:2px 0;font-size:var(--xs)}.mt-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}.mt-name{font-family:var(--fm);width:70px}.mt-cnt{font-family:var(--fm);width:20px;text-align:right}.mt-fail{color:var(--fail);font-weight:700}.mt-dur{color:var(--t3);font-family:var(--fm);width:48px;text-align:right}.mt-bar{flex:1;height:5px;background:var(--bg3);border-radius:3px;overflow:hidden}.mt-fill{height:100%;border-radius:3px;opacity:.5}.dtree{font-size:var(--xs)}.dt-node{display:flex;align-items:center;gap:4px;padding:2px 0}.dt-node--fail{background:#f851490a}.dt-node__name{font-family:var(--fm);font-weight:600}.dt-node__type{font-size:11px;color:var(--t3)}.dt-node__dur{font-family:var(--fm);color:var(--t3);margin-left:auto}.dt-node__err{color:var(--fail);font-family:var(--fm);font-size:11px;margin-left:var(--s2)}.summary-content{font-size:var(--sm)}.sc-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--s2);margin-bottom:var(--s3)}.sc-label{font-size:11px;color:var(--t3);text-transform:uppercase;display:block}.sc-failures{margin:var(--s3) 0;padding:var(--s2) var(--s3);background:#f851490f;border:1px solid rgba(248,81,73,.2);border-radius:var(--r)}.sc-failures__title{color:var(--fail);font-weight:700;margin-bottom:var(--s1)}.sc-failure{display:flex;gap:var(--s2);font-size:var(--xs);padding:1px 0}.sc-failure__type{color:var(--t3)}.sc-failure__err{color:var(--fail);font-family:var(--fm)}.sc-types{margin-top:var(--s3)}.sc-types__title{font-size:var(--xs);color:var(--t3);text-transform:uppercase;margin-bottom:var(--s1)}.sc-types__list{display:flex;gap:var(--s2);flex-wrap:wrap}.sc-type-badge{font-size:11px;font-family:var(--fm);padding:1px 6px;border:1px solid var(--bd);border-radius:3px;color:var(--t2)}.alert-card{display:flex;align-items:flex-start;gap:var(--s2);padding:var(--s2) var(--s4);font-size:var(--xs);border-bottom:1px solid var(--bdm)}.alert-card--critical{background:#f851490f}.alert-card--warn{background:#d299220f}.alert-icon{flex-shrink:0}.alert-content{flex:1;min-width:0}.alert-title{font-weight:600}.alert-description{color:var(--t3)}.alert-actions{display:flex;gap:var(--s2);margin-top:3px}.alert-action{font-size:11px;font-family:var(--fm);padding:1px 6px;background:var(--bg3);border:1px solid var(--bd);border-radius:3px;color:var(--t2);cursor:pointer}.alert-action:hover{color:var(--t1)}.alert-dismiss{padding:2px;background:transparent;border:none;color:var(--t3);cursor:pointer;font-size:var(--base);flex-shrink:0}.summary-bar{display:flex;gap:var(--s5);padding:var(--s2) var(--s4);background:var(--bg2);border-top:1px solid var(--bd);font-size:var(--xs);flex-shrink:0;height:32px;align-items:center;color:var(--t2)}.tv-chat{display:flex;flex-direction:column;gap:var(--s2)}.tv-bubble{background:var(--bg2);border:1px solid var(--bd);border-radius:12px;padding:var(--s2) var(--s3);max-width:85%;font-size:var(--xs)}.tv-bubble--right{align-self:flex-end;background:#58a6ff14;border-color:#58a6ff33}.tv-bubble--user{border-color:#58a6ff40}.tv-bubble--assistant{border-color:#3fb95033}.tv-bubble--tool{border-color:#d2992233;background:#d299220a}.tv-bubble--thinking{border-color:var(--bdm);opacity:.7;border-style:dashed}.tv-bubble--system{border-color:var(--bdm);background:var(--bg3)}.tv-bubble--event{border-color:var(--bdm)}.tv-bubble--error{border-color:#f851494d;background:#f851490a}.tv-bubble__header{display:flex;align-items:center;gap:var(--s2);margin-bottom:var(--s1);flex-wrap:wrap}.tv-bubble__icon{font-size:var(--sm)}.tv-bubble__role{font-weight:600;font-size:var(--xs)}.tv-bubble__model{color:var(--t3);font-family:var(--fm);font-size:11px}.tv-bubble__tokens{color:var(--t3);font-size:11px;font-family:var(--fm)}.tv-bubble__time{color:var(--t3);margin-left:auto;font-family:var(--fm);font-size:11px}.tv-bubble__tool{margin:var(--s1) 0}.tv-bubble__tool-name{font-family:var(--fm);font-weight:600;color:var(--warn);font-size:var(--xs)}.tv-bubble__content{white-space:pre-wrap;word-break:break-word;line-height:1.5;color:var(--t1)}.tv-bubble__error{color:var(--fail);font-weight:600;margin-top:var(--s1)}.tv-code{background:var(--bg);border:1px solid var(--bdm);border-radius:6px;padding:var(--s2);font-family:var(--fm);font-size:12px;overflow-x:auto;max-height:150px;overflow-y:auto;white-space:pre;margin:var(--s1) 0;color:var(--t2)}.tv-code--error{border-color:#f8514933;color:var(--fail)}.tv-thinking-btn{background:transparent;border:none;color:var(--t3);cursor:pointer;font-size:var(--xs);padding:var(--s1) 0}.tv-bubble--left{align-self:flex-start}.tv-origin{font-size:7px;padding:1px 4px;border-radius:3px;text-transform:uppercase;letter-spacing:.04em;font-weight:700}.tv-origin--user{background:#58a6ff26;color:var(--info)}.tv-origin--agent{background:#3fb9501f;color:var(--ok)}.tv-origin--system{background:#6e768126;color:var(--t3)}.settings-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;z-index:100;display:flex;justify-content:flex-end}.settings-panel{width:420px;max-width:90vw;background:var(--bg2);border-left:1px solid var(--bd);overflow-y:auto;padding:var(--s4)}.sp-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--s4)}.sp-head h3{font-size:var(--base);font-weight:600}.sp-close{background:transparent;border:none;color:var(--t3);cursor:pointer;font-size:var(--xl)}.sp-error{padding:var(--s2);background:#f851491a;border:1px solid rgba(248,81,73,.3);border-radius:var(--r);font-size:var(--xs);color:var(--fail);margin-bottom:var(--s3)}.sp-section{font-size:var(--xs);color:var(--t3);text-transform:uppercase;letter-spacing:.06em;margin:var(--s3) 0 var(--s2);font-weight:600}.sp-dir{display:flex;align-items:center;gap:var(--s2);padding:var(--s1) var(--s2);font-size:var(--sm);border-radius:var(--r)}.sp-dir:hover{background:var(--bgh)}.sp-dir--sug{background:#d299220a}.sp-dir__path{font-family:var(--fm);font-size:var(--xs);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sp-btn{font-size:var(--xs);padding:2px 8px;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r);cursor:pointer;color:var(--t2)}.sp-btn--add{color:var(--info)}.sp-btn--add:hover{background:var(--bgh);border-color:var(--info)}.sp-btn--rm{color:var(--fail);font-size:var(--sm);padding:0 6px}.sp-btn--rm:hover{background:#f851491a}.sp-btn--rescan{width:100%;padding:var(--s2);color:var(--info);font-size:var(--sm)}.sp-btn--rescan:hover{background:var(--bgh)}.sp-btn:disabled{opacity:.5;cursor:default}.sp-manual{display:flex;gap:var(--s2);margin-bottom:var(--s2)}.sp-input{flex:1;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r);padding:var(--s1) var(--s2);color:var(--t1);font-family:var(--fm);font-size:var(--xs)}.sp-input:focus{outline:none;border-color:var(--info)}.zb{width:24px;height:24px;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r);color:var(--t1);cursor:pointer;font-size:var(--sm);display:inline-flex;align-items:center;justify-content:center}.zb:hover{background:var(--bgh);border-color:var(--t3)}.pmap__zoom{display:flex;gap:2px;margin-left:auto}.status-dot{display:inline-block;width:7px;height:7px;border-radius:50%;flex-shrink:0}.status-dot--ok{background:var(--ok)}.status-dot--critical{background:var(--fail)}.status-dot--warn{background:var(--warn)}.status-dot--inactive{background:var(--t3)}.soma-intel{padding:16px;font-size:13px;line-height:1.5}.soma-intel__header{display:flex;align-items:center;gap:8px;margin-bottom:16px}.soma-intel__title{font-size:16px;font-weight:700}.soma-intel__badge{font-size:10px;background:var(--info);color:#000;padding:2px 6px;border-radius:4px;font-weight:600}.soma-intel__ts{margin-left:auto;font-size:11px;color:var(--t3)}.soma-intel__ts--stale{color:var(--warn)}.soma-intel__agent-card{background:var(--bg2);border:1px solid var(--bd);border-radius:6px;padding:12px;margin-bottom:16px}.soma-intel__agent-name{font-weight:700;font-size:14px;margin-bottom:4px}.soma-intel__agent-stats{display:flex;gap:16px;font-size:12px;color:var(--t2)}.soma-intel__guard-block{margin-top:8px;padding:8px;background:#f851491a;border:1px solid var(--fail);border-radius:4px;color:var(--fail);font-size:12px;font-weight:600}.soma-intel__empty{color:var(--t3);padding:12px}.soma-intel__section{margin-bottom:16px}.soma-intel__section-header{display:flex;align-items:center;gap:8px;margin-bottom:8px;border-bottom:1px solid var(--bd);padding-bottom:4px;flex-wrap:wrap}.soma-intel__section-title{font-size:13px;font-weight:700;color:var(--t1);margin:0}.soma-intel__filters{display:flex;gap:4px;margin-left:auto}.soma-intel__filter{font-size:11px;padding:2px 6px;background:var(--bg2);border:1px solid var(--bd);border-radius:4px;color:var(--t1);cursor:pointer}.soma-intel__filter:focus{outline:1px solid var(--info)}.soma-intel__show-more{display:block;width:100%;padding:6px;margin-top:4px;background:none;border:1px dashed var(--bd);border-radius:4px;color:var(--t2);font-size:11px;cursor:pointer;text-align:center}.soma-intel__show-more:hover{background:var(--bg2);color:var(--t1)}.soma-intel__table{font-size:12px;font-family:var(--mono)}.soma-intel__row{display:grid;grid-template-columns:1fr 60px 50px 55px 60px;padding:4px 0;border-bottom:1px solid var(--bd)}.soma-intel__row--header{font-weight:700;color:var(--t2);border-bottom:2px solid var(--bd)}.soma-intel__row--active{background:#58a6ff14}.soma-intel__col-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.soma-intel__col-num,.soma-intel__col-status{text-align:right}.soma-intel__insight{padding:8px;background:var(--bg2);border-radius:4px;margin-bottom:6px}.soma-intel__insight-type{font-size:10px;text-transform:uppercase;color:var(--info);margin-right:6px;font-weight:600}.soma-intel__insight-conf{font-size:10px;color:var(--t3);margin-left:6px}.soma-intel__insight-claim{font-size:12px;color:var(--t2);margin-top:4px}.soma-intel__policy{padding:8px;background:var(--bg2);border-radius:4px;margin-bottom:6px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}.soma-intel__enforcement{font-size:10px;padding:2px 6px;border-radius:3px;font-weight:600}.soma-intel__enforcement--warn{background:#d2992233;color:var(--warn)}.soma-intel__enforcement--error{background:#f8514933;color:var(--fail)}.soma-intel__enforcement--abort{background:#f851494d;color:var(--fail)}.soma-intel__policy-cond{width:100%;font-size:11px;color:var(--t3);margin-top:2px}.soma-intel--teaser{text-align:center;padding:40px 20px}.soma-intel__teaser-icon{font-size:48px;margin-bottom:12px}.soma-intel__teaser-title{font-size:20px;font-weight:700;margin-bottom:4px}.soma-intel__teaser-subtitle{font-size:14px;color:var(--t2);margin-bottom:24px}.soma-intel__teaser-features{text-align:left;max-width:360px;margin:0 auto 24px;font-size:13px}.soma-intel__teaser-feature{padding:6px 0;color:var(--t1)}.soma-intel__teaser-cta{display:inline-block;padding:10px 24px;background:var(--info);color:#000;border-radius:6px;text-decoration:none;font-weight:700;font-size:14px}.soma-intel__teaser-cta:hover{opacity:.9}.page-tabs{display:flex;gap:0;background:var(--bg2);border-bottom:1px solid var(--bd);padding:0 var(--s3);flex-shrink:0}.page-tabs__tab{padding:8px 16px;font-size:13px;font-weight:600;color:var(--t2);background:transparent;border:none;border-bottom:2px solid transparent;cursor:pointer;transition:all .15s}.page-tabs__tab:hover{color:var(--t1);background:var(--bg3)}.page-tabs__tab--active{color:var(--info);border-bottom-color:var(--info)}.soma-page{flex:1;overflow-y:auto;padding:var(--s4)}.soma-page__tabs{display:flex;gap:4px;padding:0 0 var(--s3) 0;border-bottom:1px solid var(--bd);margin-bottom:var(--s3)}.soma-page__tab{padding:6px 14px;font-size:12px;font-weight:600;color:var(--t2);background:transparent;border:1px solid transparent;border-radius:var(--r);cursor:pointer;transition:all .15s}.soma-page__tab:hover{color:var(--t1);background:var(--bg3)}.soma-page__tab--active{color:var(--t1);background:var(--bg3);border-color:var(--bd)}.soma-page__tab--locked{opacity:.5;cursor:not-allowed}.soma-page__content{min-height:300px}.soma-page__loading,.soma-page__locked{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:300px;color:var(--t3);gap:var(--s3)}.soma-page__locked-icon{font-size:32px;opacity:.5}.soma-page__teaser{text-align:center;padding:48px var(--s4);max-width:600px;margin:0 auto}.soma-page__teaser-icon{font-size:48px;margin-bottom:var(--s3)}.soma-page__teaser h2{font-size:var(--xl);margin-bottom:var(--s2)}.soma-page__teaser p{color:var(--t2);margin-bottom:var(--s4)}.soma-page__teaser-features{display:grid;gap:var(--s3);text-align:left;margin-bottom:var(--s5)}.soma-page__teaser-card{padding:var(--s3);background:var(--bg2);border:1px solid var(--bd);border-radius:var(--r)}.soma-page__teaser-card strong{display:block;color:var(--t1);margin-bottom:4px;font-size:13px}.soma-page__teaser-card p{font-size:12px;color:var(--t2);margin:0}.soma-page__teaser-cta{font-size:12px;color:var(--t3)}.soma-page__teaser-cta code{background:var(--bg3);padding:2px 6px;border-radius:3px;font-family:var(--fm);font-size:11px}.soma-policies{padding:var(--s3)}.soma-policies__header{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--s3)}.soma-policies__header h3{font-size:var(--base);font-weight:700}.soma-policies__add{font-size:12px;padding:4px 12px;background:var(--info);color:#000;border:none;border-radius:var(--r);cursor:pointer;font-weight:600}.soma-policies__form{display:flex;gap:var(--s2);margin-bottom:var(--s3);flex-wrap:wrap}.soma-policies__form input,.soma-policies__form select{padding:6px 10px;background:var(--bg);color:var(--t1);border:1px solid var(--bd);border-radius:var(--r);font-size:12px;flex:1;min-width:120px}.soma-policies__submit{padding:6px 16px;background:var(--ok);color:#000;border:none;border-radius:var(--r);cursor:pointer;font-weight:600;font-size:12px}.soma-policies__list{display:flex;flex-direction:column;gap:4px}.soma-policies__row{display:flex;align-items:center;gap:var(--s2);padding:8px var(--s3);background:var(--bg2);border:1px solid var(--bd);border-radius:var(--r);font-size:12px}.soma-policies__name{font-weight:600;color:var(--t1);min-width:120px}.soma-policies__badge{font-size:10px;font-weight:700;border:1px solid;border-radius:3px;padding:1px 6px}.soma-policies__scope{color:var(--t2);flex:1}.soma-policies__cond{color:var(--t3);flex:2}.soma-policies__del{background:none;border:none;color:var(--fail);cursor:pointer;font-size:12px;padding:2px 6px}.soma-policies__empty{color:var(--t3);font-size:12px;padding:var(--s4);text-align:center}.soma-knowledge{padding:var(--s3)}.soma-knowledge__filters{display:flex;gap:var(--s2);margin-bottom:var(--s3);align-items:center;flex-wrap:wrap}.soma-knowledge__search{padding:6px 10px;background:var(--bg);color:var(--t1);border:1px solid var(--bd);border-radius:var(--r);font-size:12px;flex:1;min-width:150px}.soma-knowledge__filters select{padding:6px 8px;background:var(--bg);color:var(--t1);border:1px solid var(--bd);border-radius:var(--r);font-size:12px}.soma-knowledge__count{font-size:11px;color:var(--t3)}.soma-knowledge__body{display:flex;gap:var(--s3);min-height:400px}.soma-knowledge__list{flex:1;display:flex;flex-direction:column;gap:2px;overflow-y:auto;max-height:600px}.soma-knowledge__row{display:flex;align-items:center;gap:var(--s2);padding:6px var(--s3);background:var(--bg2);border:1px solid var(--bd);border-radius:var(--r);font-size:12px;cursor:pointer;text-align:left;width:100%;color:var(--t1)}.soma-knowledge__row:hover{background:var(--bg3)}.soma-knowledge__row--sel{border-color:var(--info);background:var(--bg3)}.soma-knowledge__type{font-size:10px;font-weight:600;color:var(--t3);min-width:60px;text-transform:uppercase}.soma-knowledge__name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.soma-knowledge__layer{font-size:10px;font-weight:600;border:1px solid;border-radius:3px;padding:1px 4px}.soma-knowledge__empty{color:var(--t3);font-size:12px;padding:var(--s4);text-align:center}.soma-knowledge__more{padding:6px;background:var(--bg3);border:1px solid var(--bd);border-radius:var(--r);color:var(--info);cursor:pointer;font-size:12px;width:100%}.soma-knowledge__detail{flex:1;background:var(--bg2);border:1px solid var(--bd);border-radius:var(--r);padding:var(--s3);overflow-y:auto;max-height:600px}.soma-knowledge__detail-header{display:flex;align-items:center;gap:var(--s2);margin-bottom:var(--s3);flex-wrap:wrap}.soma-knowledge__close{margin-left:auto;background:none;border:none;color:var(--t3);cursor:pointer;font-size:14px}.soma-knowledge__detail-body{margin-bottom:var(--s3)}.soma-knowledge__detail-body pre{font-family:var(--fm);font-size:12px;color:var(--t2);white-space:pre-wrap;word-break:break-word}.soma-knowledge__tags{display:flex;gap:4px;flex-wrap:wrap;margin-bottom:var(--s2)}.soma-knowledge__tag{font-size:10px;padding:2px 6px;background:var(--bg3);border-radius:3px;color:var(--t2)}.soma-knowledge__related{font-size:12px;color:var(--t2)}.soma-knowledge__link{background:none;border:none;color:var(--info);cursor:pointer;font-size:12px;text-decoration:underline;margin-left:4px}.soma-activity{padding:var(--s3)}.soma-activity__header{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--s3)}.soma-activity__header h3{font-size:var(--base);font-weight:700}.soma-activity__status{font-size:11px;color:var(--t3)}.soma-activity__list{display:flex;flex-direction:column;gap:2px;max-height:600px;overflow-y:auto}.soma-activity__empty{color:var(--t3);font-size:12px;padding:var(--s5);text-align:center}.soma-activity__event{display:flex;align-items:center;gap:var(--s2);padding:6px var(--s3);background:var(--bg2);border:1px solid var(--bd);border-radius:var(--r);font-size:12px}.soma-activity__icon{font-size:14px;width:20px;text-align:center}.soma-activity__time{font-family:var(--fm);font-size:11px;color:var(--t3);min-width:70px}.soma-activity__action{font-weight:600;color:var(--info);min-width:80px}.soma-activity__desc{color:var(--t2);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>AgentFlow Dashboard</title>
7
- <script type="module" crossorigin src="/assets/index-Cb5C1Pah.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-CNZqCErb.css">
7
+ <script type="module" crossorigin src="/assets/index-DCSWGDzI.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-DHcSpTgM.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
package/dist/index.cjs CHANGED
@@ -41,7 +41,7 @@ var import_node_child_process = require("child_process");
41
41
  var fs3 = __toESM(require("fs"), 1);
42
42
  var import_node_http = require("http");
43
43
  var path3 = __toESM(require("path"), 1);
44
- var import_node_url = require("url");
44
+ var import_node_url2 = require("url");
45
45
 
46
46
  // src/config.ts
47
47
  var import_node_fs = require("fs");
@@ -116,6 +116,7 @@ function getProcessPreference(config) {
116
116
 
117
117
  // src/server.ts
118
118
  var import_agentflow_core3 = require("agentflow-core");
119
+ var import_chokidar2 = __toESM(require("chokidar"), 1);
119
120
  var import_express = __toESM(require("express"), 1);
120
121
  var import_ws = require("ws");
121
122
 
@@ -890,7 +891,7 @@ var TraceWatcher = class _TraceWatcher extends import_node_events.EventEmitter {
890
891
  ...getSkipFiles(this.userConfig)
891
892
  ]);
892
893
  this.userSkipDirs = new Set(getSkipDirectories(this.userConfig));
893
- this.allWatchDirs = [this.tracesDir, ...this.dataDirs];
894
+ this.allWatchDirs = [...new Set([this.tracesDir, ...this.dataDirs].map((d) => path.resolve(d)))];
894
895
  this.ensureTracesDir();
895
896
  this.loadExistingFiles();
896
897
  this.archiveOldTraces();
@@ -2071,8 +2072,8 @@ var TraceWatcher = class _TraceWatcher extends import_node_events.EventEmitter {
2071
2072
  return (b.lastModified || b.startTime) - (a.lastModified || a.startTime);
2072
2073
  });
2073
2074
  }
2074
- getTrace(filename) {
2075
- const candidates = [];
2075
+ getTrace(filename, agentId) {
2076
+ let candidates = [];
2076
2077
  const exact = this.traces.get(filename);
2077
2078
  if (exact) candidates.push(exact);
2078
2079
  if (filename.includes("::")) {
@@ -2097,6 +2098,13 @@ var TraceWatcher = class _TraceWatcher extends import_node_events.EventEmitter {
2097
2098
  }
2098
2099
  if (candidates.length === 0) return void 0;
2099
2100
  if (candidates.length === 1) return candidates[0];
2101
+ if (agentId) {
2102
+ const agentMatches = candidates.filter((c) => c.agentId === agentId);
2103
+ if (agentMatches.length > 0) {
2104
+ candidates = agentMatches;
2105
+ }
2106
+ }
2107
+ if (candidates.length === 1) return candidates[0];
2100
2108
  let best = candidates[0];
2101
2109
  let bestNodeCount = best.nodes instanceof Map ? best.nodes.size : Object.keys(best.nodes ?? {}).length;
2102
2110
  for (let i = 1; i < candidates.length; i++) {
@@ -2154,7 +2162,10 @@ var TraceWatcher = class _TraceWatcher extends import_node_events.EventEmitter {
2154
2162
  var fs2 = __toESM(require("fs"), 1);
2155
2163
  var os = __toESM(require("os"), 1);
2156
2164
  var path2 = __toESM(require("path"), 1);
2157
- var VERSION = "0.8.0";
2165
+ var import_node_url = require("url");
2166
+ var import_meta = {};
2167
+ var __cliDirname = path2.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
2168
+ var VERSION = JSON.parse(fs2.readFileSync(path2.resolve(__cliDirname, "../package.json"), "utf-8")).version;
2158
2169
  function getLanAddress() {
2159
2170
  const interfaces = os.networkInterfaces();
2160
2171
  for (const name of Object.keys(interfaces)) {
@@ -2194,7 +2205,9 @@ function printBanner(config, traceCount, stats, configPath) {
2194
2205
  \u2192 http://localhost:${port}${isPublic && lan ? `
2195
2206
  \u2192 http://${lan}:${port} (LAN)` : ""}
2196
2207
 
2197
- Views: Agent Profile \xB7 Execution Detail \xB7 Governance
2208
+ Pages: Agents \xB7 SOMA
2209
+ Agent: Profile \xB7 Execution Detail
2210
+ SOMA: Intelligence \xB7 Review \xB7 Policies \xB7 Knowledge \xB7 Activity
2198
2211
  Tabs: Flame Chart \xB7 Agent Flow \xB7 Metrics \xB7 Dependencies
2199
2212
  State Machine \xB7 Summary \xB7 Transcript
2200
2213
 
@@ -2329,8 +2342,8 @@ Examples:
2329
2342
  }
2330
2343
 
2331
2344
  // src/server.ts
2332
- var import_meta = {};
2333
- var __filename = (0, import_node_url.fileURLToPath)(import_meta.url);
2345
+ var import_meta2 = {};
2346
+ var __filename = (0, import_node_url2.fileURLToPath)(import_meta2.url);
2334
2347
  var __dirname = path3.dirname(__filename);
2335
2348
  function serializeTrace(trace) {
2336
2349
  if (!trace) return trace;
@@ -2380,6 +2393,7 @@ var DashboardServer = class {
2380
2393
  this.setupExpress();
2381
2394
  this.setupWebSocket();
2382
2395
  this.setupTraceWatcher();
2396
+ this.setupSomaReportWatcher();
2383
2397
  let knowledgeCount = 0;
2384
2398
  for (const trace of this.watcher.getAllTraces()) {
2385
2399
  this.stats.processTrace(trace);
@@ -2435,6 +2449,10 @@ var DashboardServer = class {
2435
2449
  if (fs3.existsSync(clientDir)) {
2436
2450
  this.app.use(import_express.default.static(clientDir));
2437
2451
  }
2452
+ const pkgVersion = JSON.parse(fs3.readFileSync(path3.resolve(__dirname, "../package.json"), "utf-8")).version;
2453
+ this.app.get("/api/version", (_req, res) => {
2454
+ res.json({ version: pkgVersion });
2455
+ });
2438
2456
  this.app.get("/api/traces", (req, res) => {
2439
2457
  try {
2440
2458
  const limit = Math.min(Math.max(parseInt(req.query.limit, 10) || 50, 1), 200);
@@ -2454,7 +2472,8 @@ var DashboardServer = class {
2454
2472
  });
2455
2473
  this.app.get("/api/traces/:filename", (req, res) => {
2456
2474
  try {
2457
- const trace = this.watcher.getTrace(req.params.filename);
2475
+ const agentId = typeof req.query.agent === "string" ? req.query.agent : void 0;
2476
+ const trace = this.watcher.getTrace(req.params.filename, agentId);
2458
2477
  if (!trace) {
2459
2478
  return res.status(404).json({ error: "Trace not found" });
2460
2479
  }
@@ -2738,6 +2757,27 @@ var DashboardServer = class {
2738
2757
  res.status(500).json({ error: "Failed to load agent statistics" });
2739
2758
  }
2740
2759
  });
2760
+ this.app.get("/api/soma/tier", (_req, res) => {
2761
+ const somaVault = this.config.somaVault;
2762
+ if (!somaVault) {
2763
+ return res.json({ tier: "teaser", somaVault: false, governanceAvailable: false });
2764
+ }
2765
+ try {
2766
+ const reportPath = path3.join(somaVault, "..", "soma-report.json");
2767
+ if (!fs3.existsSync(reportPath)) {
2768
+ return res.json({ tier: "free", somaVault: true, governanceAvailable: false });
2769
+ }
2770
+ const report = JSON.parse(fs3.readFileSync(reportPath, "utf-8"));
2771
+ const hasGovernance = report.governance && typeof report.governance.pending === "number";
2772
+ return res.json({
2773
+ tier: hasGovernance ? "pro" : "free",
2774
+ somaVault: true,
2775
+ governanceAvailable: !!hasGovernance
2776
+ });
2777
+ } catch {
2778
+ return res.json({ tier: "free", somaVault: true, governanceAvailable: false });
2779
+ }
2780
+ });
2741
2781
  this.app.get("/api/soma/report", (_req, res) => {
2742
2782
  const somaVault = this.config.somaVault;
2743
2783
  if (!somaVault) {
@@ -2834,6 +2874,118 @@ var DashboardServer = class {
2834
2874
  res.status(404).json({ error: ((_a = error.stderr) == null ? void 0 : _a.trim()) || error.message });
2835
2875
  }
2836
2876
  });
2877
+ this.app.get("/api/soma/policies", (_req, res) => {
2878
+ const somaVault = this.config.somaVault;
2879
+ if (!somaVault) return res.json({ policies: [] });
2880
+ try {
2881
+ const reportPath = path3.join(somaVault, "..", "soma-report.json");
2882
+ if (!fs3.existsSync(reportPath)) return res.json({ policies: [] });
2883
+ const report = JSON.parse(fs3.readFileSync(reportPath, "utf-8"));
2884
+ res.json({ policies: report.policies ?? [] });
2885
+ } catch {
2886
+ res.json({ policies: [] });
2887
+ }
2888
+ });
2889
+ this.app.post("/api/soma/policies", import_express.default.json(), (req, res) => {
2890
+ var _a;
2891
+ const somaVault = this.config.somaVault;
2892
+ if (!somaVault) return res.status(400).json({ error: "Soma vault not configured" });
2893
+ const { name, enforcement, scope, conditions } = req.body ?? {};
2894
+ if (!name) return res.status(400).json({ error: "name required" });
2895
+ try {
2896
+ const safeName = sanitizeArg(String(name));
2897
+ const safeEnf = sanitizeArg(String(enforcement || "warn"));
2898
+ const safeScope = sanitizeReason(String(scope || "all"));
2899
+ const safeCond = sanitizeReason(String(conditions || ""));
2900
+ const result = (0, import_node_child_process.execSync)(
2901
+ `npx soma policy create "${safeName}" --enforcement ${safeEnf} --scope "${safeScope}" --conditions "${safeCond}" --vault "${somaVault}"`,
2902
+ { encoding: "utf-8", timeout: 1e4 }
2903
+ );
2904
+ res.json({ success: true, message: result.trim() });
2905
+ } catch (error) {
2906
+ res.status(400).json({ error: ((_a = error.stderr) == null ? void 0 : _a.trim()) || error.message });
2907
+ }
2908
+ });
2909
+ this.app.delete("/api/soma/policies/:name", (req, res) => {
2910
+ var _a;
2911
+ const somaVault = this.config.somaVault;
2912
+ if (!somaVault) return res.status(400).json({ error: "Soma vault not configured" });
2913
+ try {
2914
+ const safeName = sanitizeArg(String(req.params.name));
2915
+ const result = (0, import_node_child_process.execSync)(
2916
+ `npx soma policy delete "${safeName}" --vault "${somaVault}"`,
2917
+ { encoding: "utf-8", timeout: 1e4 }
2918
+ );
2919
+ res.json({ success: true, message: result.trim() });
2920
+ } catch (error) {
2921
+ res.status(400).json({ error: ((_a = error.stderr) == null ? void 0 : _a.trim()) || error.message });
2922
+ }
2923
+ });
2924
+ this.app.get("/api/soma/vault/entities", (req, res) => {
2925
+ const somaVault = this.config.somaVault;
2926
+ if (!somaVault) return res.json({ entities: [], total: 0 });
2927
+ try {
2928
+ const reportPath = path3.join(somaVault, "..", "soma-report.json");
2929
+ if (!fs3.existsSync(reportPath)) return res.json({ entities: [], total: 0 });
2930
+ const report = JSON.parse(fs3.readFileSync(reportPath, "utf-8"));
2931
+ let entities = [
2932
+ ...(report.agents ?? []).map((a) => ({ ...a, type: "agent", id: a.name })),
2933
+ ...(report.insights ?? []).map((i, idx) => {
2934
+ var _a;
2935
+ return { ...i, type: i.type || "insight", id: ((_a = i.title) == null ? void 0 : _a.replace(/\s+/g, "-").toLowerCase()) || `insight-${idx}` };
2936
+ }),
2937
+ ...(report.policies ?? []).map((p) => ({ ...p, type: "policy", id: p.name }))
2938
+ ];
2939
+ const { type, layer, q, limit: limitStr, offset: offsetStr } = req.query;
2940
+ if (type) entities = entities.filter((e) => e.type === type);
2941
+ if (layer) entities = entities.filter((e) => e.layer === layer);
2942
+ if (q) {
2943
+ const lq = q.toLowerCase();
2944
+ entities = entities.filter((e) => (e.name || e.title || "").toLowerCase().includes(lq) || (e.claim || e.body || "").toLowerCase().includes(lq));
2945
+ }
2946
+ const total = entities.length;
2947
+ const offset = parseInt(offsetStr || "0", 10);
2948
+ const limit = Math.min(parseInt(limitStr || "50", 10), 200);
2949
+ entities = entities.slice(offset, offset + limit);
2950
+ res.json({ entities, total });
2951
+ } catch (error) {
2952
+ console.error("Vault entities error:", error);
2953
+ res.json({ entities: [], total: 0 });
2954
+ }
2955
+ });
2956
+ this.app.get("/api/soma/vault/entities/:type/:id", (req, res) => {
2957
+ const somaVault = this.config.somaVault;
2958
+ if (!somaVault) return res.status(404).json({ error: "Soma vault not configured" });
2959
+ try {
2960
+ const reportPath = path3.join(somaVault, "..", "soma-report.json");
2961
+ const report = JSON.parse(fs3.readFileSync(reportPath, "utf-8"));
2962
+ const { type, id } = req.params;
2963
+ let entity = null;
2964
+ if (type === "agent") {
2965
+ entity = (report.agents ?? []).find((a) => a.name === id);
2966
+ } else if (type === "policy") {
2967
+ entity = (report.policies ?? []).find((p) => p.name === id);
2968
+ } else {
2969
+ entity = (report.insights ?? []).find(
2970
+ (i) => {
2971
+ var _a;
2972
+ return (((_a = i.title) == null ? void 0 : _a.replace(/\s+/g, "-").toLowerCase()) || "") === id || i.title === id;
2973
+ }
2974
+ );
2975
+ }
2976
+ if (!entity) return res.status(404).json({ error: "Entity not found" });
2977
+ res.json({
2978
+ ...entity,
2979
+ type,
2980
+ id,
2981
+ body: entity.claim || entity.conditions || "",
2982
+ tags: entity.tags ?? [],
2983
+ related: entity.related ?? []
2984
+ });
2985
+ } catch {
2986
+ res.status(404).json({ error: "Entity not found" });
2987
+ }
2988
+ });
2837
2989
  this.app.get("/api/process-health", (_req, res) => {
2838
2990
  var _a, _b;
2839
2991
  try {
@@ -2937,11 +3089,11 @@ var DashboardServer = class {
2937
3089
  }
2938
3090
  } catch {
2939
3091
  }
2940
- const watched = [
3092
+ const watched = [...new Set([
2941
3093
  this.config.tracesDir,
2942
3094
  ...this.config.dataDirs || [],
2943
3095
  ...extraDirs
2944
- ];
3096
+ ].map((w) => path3.resolve(w)))];
2945
3097
  const discovered = [];
2946
3098
  const svcNames = getSystemdServices(this.userConfig);
2947
3099
  if (svcNames.length > 0) {
@@ -3095,6 +3247,41 @@ var DashboardServer = class {
3095
3247
  });
3096
3248
  });
3097
3249
  }
3250
+ /** Watch soma-report.json for changes and broadcast updates via WebSocket. */
3251
+ setupSomaReportWatcher() {
3252
+ const somaVault = this.config.somaVault;
3253
+ if (!somaVault) return;
3254
+ const reportPath = path3.join(somaVault, "..", "soma-report.json");
3255
+ const reportDir = path3.dirname(reportPath);
3256
+ if (!fs3.existsSync(reportDir)) return;
3257
+ let debounceTimer = null;
3258
+ const watcher = import_chokidar2.default.watch(reportPath, {
3259
+ ignoreInitial: true,
3260
+ persistent: true,
3261
+ awaitWriteFinish: { stabilityThreshold: 500 }
3262
+ });
3263
+ watcher.on("change", () => {
3264
+ if (debounceTimer) clearTimeout(debounceTimer);
3265
+ debounceTimer = setTimeout(() => {
3266
+ var _a, _b;
3267
+ try {
3268
+ const report = JSON.parse(fs3.readFileSync(reportPath, "utf-8"));
3269
+ this.broadcast({ type: "soma-report-updated", data: report });
3270
+ if (report.generatedAt) {
3271
+ this.broadcast({
3272
+ type: "soma-activity",
3273
+ data: {
3274
+ action: "report-updated",
3275
+ description: `Report updated: ${((_a = report.totals) == null ? void 0 : _a.agents) ?? 0} agents, ${((_b = report.totals) == null ? void 0 : _b.insights) ?? 0} insights`,
3276
+ timestamp: report.generatedAt
3277
+ }
3278
+ });
3279
+ }
3280
+ } catch {
3281
+ }
3282
+ }, 500);
3283
+ });
3284
+ }
3098
3285
  /**
3099
3286
  * Filter an agent's traces to valid ExecutionGraphs and convert via loadGraph().
3100
3287
  * Returns only traces with proper nodes (Map or non-empty object), skipping session-only traces.
@@ -3366,7 +3553,7 @@ var DashboardServer = class {
3366
3553
  return this.watcher.getAllTraces();
3367
3554
  }
3368
3555
  };
3369
- if (import_meta.url === `file://${process.argv[1]}`) {
3556
+ if (import_meta2.url === `file://${process.argv[1]}`) {
3370
3557
  startDashboard().catch(console.error);
3371
3558
  }
3372
3559
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  AgentStats,
4
4
  DashboardServer,
5
5
  TraceWatcher
6
- } from "./chunk-NZFXRZYU.js";
6
+ } from "./chunk-EG254FLY.js";
7
7
  export {
8
8
  AgentStats,
9
9
  DashboardServer,