@swestash/agent-lens 0.9.3 → 0.9.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.
- package/dist/agent-lens.js +271 -239
- package/dist/agent-lens.js.map +1 -1
- package/package.json +1 -1
- package/web/404.html +25 -0
- package/web/assets/Dashboard-BkRLAY2N.js +69 -0
- package/web/assets/{FileView-CJ6k5gBT.js → FileView-BbPK6hx9.js} +1 -1
- package/web/assets/{FilesView-ZB8kU8Hl.js → FilesView-D0gm4_XO.js} +1 -1
- package/web/assets/SecurityView-92YGEb3-.js +1 -0
- package/web/assets/{SessionView-BsrumXE9.js → SessionView-Dy0ELjaS.js} +8 -8
- package/web/assets/{SkillView-DhhjbXCQ.js → SkillView-Te5jcVBw.js} +1 -1
- package/web/assets/{SkillsView-CXjGf2j5.js → SkillsView-FtrADGqR.js} +1 -1
- package/web/assets/{WorkflowView-DVgrrFly.js → WorkflowView-D45UzOuV.js} +1 -1
- package/web/assets/{index-DumYdTnf.js → index-Bgxu3c84.js} +1 -1
- package/web/assets/{index-Dt08Kre7.css → index-DBaa9asK.css} +1 -1
- package/web/assets/{index-F_4kZQVd.js → index-DYY0_SmQ.js} +2 -2
- package/web/assets/jsonish-Dd3X-MG6.js +1 -0
- package/web/assets/{severity-ChuAKM2D.js → severity-CoO1IKlD.js} +1 -1
- package/web/index.html +2 -2
- package/web/assets/Dashboard-BeHGt7nW.js +0 -69
- package/web/assets/SecurityView-DOUnL_jp.js +0 -1
- package/web/assets/jsonish-B1rzsNYu.js +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as se,d as P,r as c,z as te,w as ie,j as e,D as m,F as ae,G as x,E as le,L as ne,S as M,P as re,v as ce,o as oe}from"./index-F_4kZQVd.js";import{S as de,a as ue}from"./severity-ChuAKM2D.js";const L=50,he={total:0,findings:[]};function ye(){const{get:t,set:a,clear:n}=se(),l=P("/sources",[]),R=P("/projects",[]),[F,f]=c.useState(null),[p,K]=c.useState(!1),[_,D]=c.useState(1),[d,w]=c.useState(new Set),[N,B]=c.useState(0),{sort:r,toggle:C}=te("severity","desc"),y=t("severity"),b=t("category"),v=t("rule"),E=t("session"),T=t("source"),A=t("project"),$=t("from"),z=t("to"),u=t("status","open"),k=c.useMemo(()=>{const s=new URLSearchParams;for(const[o,h]of Object.entries({severity:y,category:b,rule:v,session:E,source:T,project:A,from:$,to:z,status:u}))h&&s.set(o,h);return s},[y,b,v,E,T,A,$,z,u]),i=P("/security/summary",null,[N]),I=P(m?null:"/security/mutes",[],[N]);c.useEffect(()=>D(1),[k.toString(),r.key,r.dir]),c.useEffect(()=>w(new Set),[k.toString(),r.key,r.dir,_,N]);const S=new URLSearchParams(k);S.set("sort",r.key),S.set("dir",r.dir),S.set("limit",String(L)),S.set("offset",String((_-1)*L));const{data:H,loading:G,error:V}=ie("/security/findings?"+S.toString(),{deps:[N]}),q=F??V;c.useEffect(()=>f(null),[k,r.key,r.dir,_,N]);const{total:g,findings:O}=H??he,j=c.useCallback(async s=>{K(!0),f(null);try{await s(),B(o=>o+1)}catch(o){f(String(o))}finally{K(!1)}},[]),Y=c.useMemo(()=>new Map(((i==null?void 0:i.by_severity)??[]).map(s=>[s.severity,s.n])),[i]),Q=c.useMemo(()=>((i==null?void 0:i.by_rule)??[]).filter(s=>!b||s.category===b),[i,b]),J=Math.max(1,Math.ceil(g/L)),X=[...k.keys()].some(s=>s!=="status")||u!=="open",W=O.map(s=>s.id),Z=W.length>0&&W.every(s=>d.has(s)),ee=s=>w(o=>{const h=new Set(o);return h.has(s)?h.delete(s):h.add(s),h});return e.jsxs("div",{children:[e.jsxs("div",{className:"detail-head",children:[e.jsx("h1",{children:"Security findings"}),e.jsxs("p",{className:"muted",style:{margin:"4px 0 0",maxWidth:760},children:["Risky operations the agent performed, flagged after the fact by deterministic rules over each tool call. Counts show ",e.jsx("strong",{children:"open"})," findings — mark benign ones safe or mute a noisy rule so a real one stands out. agent-lens is retrospective; it surfaces what ",e.jsx("em",{children:"happened"}),", it doesn't block."]})]}),m&&e.jsxs("div",{className:"demo-note",role:"note",children:["📦 This is a static demo over synthetic sessions. Browse the findings and reference below —"," ",e.jsx("strong",{children:"triage"})," (mark safe, mute rules) and live filtering run in the local app on your own data."]}),e.jsxs("div",{className:"kpi-row sev-kpis",role:"group","aria-label":"Open findings by severity",children:[e.jsxs("button",{type:"button",className:"kpi kpi-btn"+(y?"":" is-active"),onClick:()=>a({severity:""}),children:[e.jsx("div",{className:"kpi-label",children:"Open findings"}),e.jsx("div",{className:"kpi-value",children:(i==null?void 0:i.total)??"—"}),e.jsxs("div",{className:"kpi-sub",children:[(i==null?void 0:i.sessions_flagged)??0," sessions flagged"]})]}),de.map(s=>e.jsxs("button",{type:"button",className:"kpi kpi-btn sev-kpi sev-"+s+(y===s?" is-active":""),onClick:()=>a({severity:y===s?"":s}),"aria-pressed":y===s,children:[e.jsx("div",{className:"kpi-label",children:s}),e.jsx("div",{className:"kpi-value",children:Y.get(s)??0})]},s))]}),i&&(i.dismissed>0||i.muted>0)&&e.jsxs("div",{className:"triage-counts muted small",children:[e.jsxs("button",{type:"button",className:"linkish",onClick:()=>a({status:"dismissed",severity:""}),children:[i.dismissed," dismissed"]})," · ",e.jsxs("button",{type:"button",className:"linkish",onClick:()=>a({status:"muted",severity:""}),children:[i.muted," muted by rule"]})]}),e.jsxs("div",{className:"filters",children:[e.jsxs("select",{"aria-label":"Filter by status",value:u,onChange:s=>a({status:s.target.value}),children:[e.jsx("option",{value:"open",children:"open"}),e.jsx("option",{value:"dismissed",children:"dismissed"}),e.jsx("option",{value:"muted",children:"muted"}),e.jsx("option",{value:"all",children:"all"})]}),e.jsxs("select",{"aria-label":"Filter by category",value:b,onChange:s=>{const o=s.target.value,h=!v||Q.some(U=>U.rule_id===v&&(!o||U.category===o));a({category:o,rule:h?v:""})},children:[e.jsx("option",{value:"",children:"all categories"}),((i==null?void 0:i.categories)??[]).map(s=>e.jsx("option",{value:s.key,children:s.title},s.key))]}),e.jsxs("select",{"aria-label":"Filter by rule",value:v,onChange:s=>a({rule:s.target.value}),children:[e.jsx("option",{value:"",children:"all rules"}),Q.map(s=>e.jsxs("option",{value:s.rule_id,children:[s.rule_id," (",s.n,")"]},s.rule_id))]}),e.jsxs("select",{"aria-label":"Filter by source",value:T,onChange:s=>a({source:s.target.value}),children:[e.jsx("option",{value:"",children:"all sources"}),l.map(s=>e.jsx("option",{value:s.id,children:s.label},s.id))]}),e.jsx(ae,{ariaLabel:"Filter by project",searchPlaceholder:"Find project…",value:A,onChange:s=>a({project:s}),options:[{value:"",label:"all projects"},...R.map(s=>({value:s.id,label:s.path.replace(/^.*\//,"")}))]}),e.jsxs("label",{className:"ctl",children:["from ",e.jsx("input",{type:"date",value:$,onChange:s=>a({from:s.target.value})})]}),e.jsxs("label",{className:"ctl",children:["to ",e.jsx("input",{type:"date",value:z,onChange:s=>a({to:s.target.value})})]}),E&&e.jsxs("span",{className:"tag",style:{alignSelf:"center"},children:["session ",E.slice(0,8),"… ",e.jsx("button",{type:"button",className:"linkish",onClick:()=>a({session:""}),children:"✕"})]}),X&&e.jsx("button",{type:"button",className:"ghost",onClick:n,children:"clear filters"})]}),!m&&(d.size>0||u==="open"&&g>0)&&e.jsxs("div",{className:"triage-bar",role:"group","aria-label":"Triage actions",children:[d.size>0&&u!=="dismissed"&&e.jsxs("button",{type:"button",disabled:p,onClick:()=>j(()=>x("/security/dismiss",{ids:[...d]})),children:["✓ Mark ",d.size," safe"]}),d.size>0&&u==="dismissed"&&e.jsxs("button",{type:"button",disabled:p,onClick:()=>j(()=>x("/security/reopen",{ids:[...d]})),children:["↩ Reopen ",d.size]}),d.size>0&&e.jsx("button",{type:"button",className:"ghost",onClick:()=>w(new Set),children:"clear selection"}),u==="open"&&g>0&&e.jsxs("button",{type:"button",className:"ghost",disabled:p,onClick:()=>{confirm(`Dismiss all ${g} open findings matching the current filter as safe?`)&&j(()=>x("/security/dismiss-matching",{filter:Object.fromEntries(k)}))},title:"Mark every open finding matching the current filter as safe",children:["Dismiss all ",g," matching"]})]}),e.jsx(le,{error:q}),G?e.jsx(ne,{}):O.length===0?e.jsx("div",{className:"muted pad",role:"status",children:i&&i.total===0&&u==="open"?"No open security findings — nothing risky is awaiting review.":"No findings match these filters."}):e.jsxs("table",{className:"sessions findings-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[!m&&e.jsx("th",{className:"check-col",children:e.jsx("input",{type:"checkbox","aria-label":"Select all on this page",checked:Z,onChange:s=>w(s.target.checked?new Set(W):new Set)})}),e.jsx(M,{label:"Severity",sortKey:"severity",active:r.key,dir:r.dir,onSort:C}),e.jsx("th",{children:"Finding"}),e.jsx(M,{label:"Category",sortKey:"category",active:r.key,dir:r.dir,onSort:C}),e.jsx("th",{children:"Evidence"}),e.jsx(M,{label:"When",sortKey:"time",active:r.key,dir:r.dir,onSort:C}),e.jsx(M,{label:"Session",sortKey:"session",active:r.key,dir:r.dir,onSort:C}),!m&&e.jsx("th",{children:"Actions"})]})}),e.jsx("tbody",{children:O.map(s=>e.jsx(me,{f:s,selected:d.has(s.id),onToggle:()=>ee(s.id),busy:p,onDismiss:()=>j(()=>x("/security/dismiss",{ids:[s.id]})),onReopen:()=>j(()=>x("/security/reopen",{ids:[s.id]})),onMute:()=>j(()=>x("/security/mute",{rule_id:s.rule_id,scope:"global"}))},s.id))})]}),!G&&g>L&&e.jsx(re,{page:_,pages:J,total:g,unit:"findings",onPage:D}),!m&&I.length>0&&e.jsx(pe,{mutes:I,busy:p,onUnmute:s=>j(()=>x("/security/unmute",{rule_id:s.rule_id,scope:s.scope,scope_id:s.scope_id}))}),i&&i.categories.length>0&&e.jsx(ge,{summary:i})]})}function me({f:t,selected:a,onToggle:n,busy:l,onDismiss:R,onReopen:F,onMute:f}){const p=`/session/${t.session_id}${t.event_uuid?`#ev-${t.event_uuid}`:""}`;return e.jsxs("tr",{className:t.dismissed?"is-dismissed":"",children:[!m&&e.jsx("td",{className:"check-col",children:e.jsx("input",{type:"checkbox","aria-label":"Select finding",checked:a,onChange:n})}),e.jsxs("td",{children:[e.jsx(ue,{severity:t.severity}),t.dismissed?e.jsx("span",{className:"tag",style:{marginLeft:4},title:t.dismiss_note??"",children:"safe"}):null]}),e.jsxs("td",{children:[e.jsx("div",{className:"finding-title",children:t.title??t.rule_id}),e.jsxs("div",{className:"muted small",children:[e.jsx("code",{children:t.rule_id}),t.framework_ref&&e.jsx("span",{className:"tag framework",style:{marginLeft:6},children:t.framework_ref})]})]}),e.jsx("td",{className:"small",children:t.category}),e.jsxs("td",{className:"finding-evidence-cell",children:[t.tool_name&&e.jsx("span",{className:"tag tool-tag",title:"Tool the finding fired on",children:t.tool_name}),e.jsx("code",{title:t.evidence??"",children:t.evidence})]}),e.jsx("td",{className:"small muted",title:t.started_at??"",children:ce(t.started_at??null)}),e.jsxs("td",{className:"small",children:[e.jsx(oe,{to:p,className:"title",children:t.session_title||t.session_id.slice(0,12)}),t.is_sidechain?e.jsx("span",{className:"tag subagent",style:{marginLeft:6},children:"subagent"}):null,t.project_path&&e.jsx("div",{className:"muted path",children:t.project_path.replace(/^.*\//,"")})]}),!m&&e.jsxs("td",{className:"finding-actions small",children:[t.dismissed?e.jsx("button",{type:"button",className:"linkish",disabled:l,onClick:F,children:"reopen"}):e.jsx("button",{type:"button",className:"linkish",disabled:l,onClick:R,children:"safe"}),e.jsx("button",{type:"button",className:"linkish",disabled:l,onClick:f,title:`Mute rule ${t.rule_id} everywhere`,children:"mute rule"})]})]})}function pe({mutes:t,busy:a,onUnmute:n}){return e.jsxs("details",{className:"card muted-rules",children:[e.jsx("summary",{children:e.jsxs("span",{className:"sec-ref-title",children:["Muted rules (",t.length,")"]})}),e.jsx("ul",{className:"muted-rules-list",children:t.map(l=>e.jsxs("li",{children:[e.jsx("code",{children:l.rule_id}),e.jsxs("span",{className:"tag",style:{marginLeft:6},children:[l.scope,l.scope_id?`: ${l.scope_id}`:""]}),l.note&&e.jsx("span",{className:"muted small",style:{marginLeft:6},children:l.note}),e.jsx("button",{type:"button",className:"linkish",style:{marginLeft:8},disabled:a,onClick:()=>n(l),children:"unmute"})]},`${l.rule_id}:${l.scope}:${l.scope_id}`))})]})}function ge({summary:t}){const a=new Map(t.by_category.map(n=>[n.category,n.n]));return e.jsxs("section",{className:"sec-reference",children:[e.jsx("h2",{children:"Risk categories"}),e.jsx("p",{className:"muted small",style:{marginTop:0},children:"What each category means and why it matters, anchored to OWASP Top 10 for Agentic Apps and MITRE ATLAS."}),e.jsx("div",{className:"sec-ref-grid",children:t.categories.map(n=>e.jsxs("details",{className:"card sec-ref",children:[e.jsxs("summary",{children:[e.jsx("span",{className:"sec-ref-title",children:n.title}),e.jsxs("a",{className:"tag framework",href:n.framework_url,target:"_blank",rel:"noreferrer",onClick:l=>l.stopPropagation(),children:[n.framework_ref," ↗"]}),e.jsxs("span",{className:"muted small",children:[a.get(n.key)??0," open"]})]}),e.jsxs("dl",{className:"sec-ref-body",children:[e.jsx("dt",{children:"What"}),e.jsx("dd",{children:n.what}),e.jsx("dt",{children:"Why it matters"}),e.jsx("dd",{children:n.why}),e.jsx("dt",{children:"What to do"}),e.jsx("dd",{children:n.remediation})]})]},n.key))})]})}export{ye as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as u,j as l,o as d,h as f,i as m,k as h,r as y}from"./index-F_4kZQVd.js";function x({a:e}){const t=e.agent_description||e.title||e.id.slice(0,12),n=(e.models??"").split(",").filter(Boolean).map(u).join(", ");return l.jsxs("li",{children:[l.jsx(d,{to:`/session/${e.id}`,children:t}),e.agent_type&&l.jsx("span",{className:"tag subagent meta-type",children:e.agent_type}),e.spawn_depth!=null&&e.spawn_depth>1&&l.jsxs("span",{className:"tag meta-depth",title:`nested ${e.spawn_depth} levels deep`,children:["↳",e.spawn_depth]}),l.jsxs("span",{className:"muted",children:[" ","· ",n||"—"," · ",f(e.tokens)," tok · ",m(e.cost),e.duration_ms!=null?` · ${h(e.duration_ms)}`:""]})]})}function j({text:e,label:t,title:n="Copy to clipboard",className:a=""}){const[o,i]=y.useState(!1),c=async()=>{try{await navigator.clipboard.writeText(e)}catch{const s=document.createElement("textarea");s.value=e,s.style.position="fixed",s.style.opacity="0",document.body.appendChild(s),s.select();try{document.execCommand("copy")}catch{}s.remove()}i(!0),window.setTimeout(()=>i(!1),1200)};return l.jsxs("button",{type:"button",className:"ghost small copy-btn "+a,onClick:c,"aria-label":n,title:n,children:[o?"✓ Copied":"⧉",t?" "+t:""]})}function k(e){return e.replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/?9;|'/g,"'").replace(/&/g,"&")}function w(e){const t=e.match(/\s*\(\s*truncated[^)]*\)\s*$/i);return!t||t.index==null?{body:e,note:null}:{body:e.slice(0,t.index).trimEnd(),note:t[0].trim()}}function C(e){try{return{value:JSON.parse(e),repaired:!1}}catch{}const t=[];let n=!1,a=!1,o=-1,i=[];for(let s=0;s<e.length;s++){const r=e[s];if(n){a?a=!1:r==="\\"?a=!0:r==='"'&&(n=!1);continue}r==='"'?n=!0:r==="{"||r==="["?t.push(r==="{"?"}":"]"):r==="}"||r==="]"?(t.pop(),o=s+1,i=[...t]):r===","&&(o=s,i=[...t])}if(o<0)return{value:void 0,repaired:!1};const c=e.slice(0,o)+i.reverse().join("");try{return{value:JSON.parse(c),repaired:!0}}catch{return{value:void 0,repaired:!1}}}function p(e){if(typeof e=="string"){const t=e.trim();if(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]"))try{return p(JSON.parse(t))}catch{return e}return e}if(Array.isArray(e))return e.map(p);if(e&&typeof e=="object"){const t={};for(const[n,a]of Object.entries(e))t[n]=p(a);return t}return e}function N(e,t=2e4){try{return JSON.stringify(JSON.parse(e),null,2).slice(0,t)}catch{return e.slice(0,t)}}export{x as A,j as C,p as a,k as d,C as l,N as p,w as s};
|