ccdeck 3.39.3 → 3.39.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/web/assets/{BrowserWatchModal-Bdhu_T4K.js → BrowserWatchModal-DvLtvWy6.js} +1 -1
- package/dist/web/assets/{TrafficRadar-DC8wkrSd.js → TrafficRadar-MfnZJeq1.js} +1 -1
- package/dist/web/assets/{UsageHistoryModal-D1HsLOz_.js → UsageHistoryModal-X4UF2sFE.js} +1 -1
- package/dist/web/assets/{index-ChuHd6Ho.js → index-CxIdVCPz.js} +52 -52
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
- package/release-notes.json +2 -1
- package/src/server/lan-beacon.mjs +5 -1
- package/src/server/lan-engine.mjs +6 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e,r,l as Q,m as _,n as Y,v as z,o as V,q as X,t as Z,w as ee,s as se,u as te,d as ne,x as ae,y as ie,h as re}from"./index-ChuHd6Ho.js";function oe({snap:s}){return e.jsxs("section",{className:"bw-feed",children:[e.jsxs("h4",{className:"bw-sec-head bw-head-row",children:["Live activity",e.jsxs("span",{className:"bw-feed-count",children:[s.log.length," ",s.log.length===1?"event":"events"]})]}),e.jsx("p",{className:"bw-since bw-feed-note",children:"Pages you opened yourself — counted to run the rule, never written down. Addresses appear under Findings, and only for pages a program opened."}),e.jsx("div",{className:"bw-log","aria-live":"polite","aria-relevant":"additions",children:s.log.length===0?e.jsx("p",{className:"bw-note",children:"The deck writes a line here each time it looks at a profile."}):s.log.map(a=>e.jsxs("div",{className:`bw-log-line ${a.level}${a.parts?"":" sys"}`,children:[e.jsx("span",{className:"bw-log-time",children:new Date(a.atMs).toLocaleTimeString("en-GB",{hour12:!1})}),a.parts?e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"bw-log-browser",children:a.parts.browser}),e.jsx("span",{className:"bw-log-profile",title:a.parts.profile,children:a.parts.profile}),e.jsxs("span",{className:"bw-log-value",children:[a.parts.value,a.parts.flagged>0&&e.jsxs("span",{className:"bw-log-flag",children:[" · ",a.parts.flagged," flagged"]})]})]}):e.jsx("span",{className:"bw-log-sys",children:a.text})]},`${a.atMs}-${a.level}-${a.text}`))})]})}const E=s=>`${s.host}-${s.startMs}`;function le(s){const a=h=>new Date(h).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",hour12:!1});return s.count===1||s.endMs-s.startMs<6e4?a(s.startMs):`${a(s.startMs)} → ${a(s.endMs)}`}function ce(s){return new Date(s).toLocaleDateString(void 0,{weekday:"short",day:"numeric",month:"short"})}function U(s){const a=Math.round((s.endMs-s.startMs)/6e4);return a<1?"":`${a} min`}function de({snap:s,dismiss:a,refreshRef:h}){const[c,d]=r.useState(null),u=r.useRef(new Map),t=r.useRef(null);r.useEffect(()=>{var i,w;const o=t.current;!o||s.episodes.some(b=>E(b)===o.id)||(t.current=null,Q(((i=document.activeElement)==null?void 0:i.tagName)??null)&&((w=(o.next?u.current.get(o.next):void 0)??h.current)==null||w.focus()))},[s]);const n=o=>{t.current={id:E(o),next:_(s.episodes.map(E),E(o))},a(o)},l=r.useMemo(()=>{const o=[];for(const i of s.episodes){const w=ce(i.startMs),b=o[o.length-1];b&&b.label===w?b.episodes.push(i):o.push({label:w,episodes:[i]})}return o},[s]);return e.jsxs("section",{className:"bw-findings",children:[e.jsxs("h4",{className:"bw-sec-head bw-head-row",children:["Findings",s.episodes.length>0&&e.jsxs("span",{className:"bw-feed-count",children:[s.episodes.length," ",s.episodes.length===1?"episode":"episodes"]})]}),e.jsx("div",{className:"bw-eps",children:l.length===0?e.jsxs("div",{className:"bw-empty",children:[e.jsx("p",{className:"bw-empty-head",children:"Nothing found yet"}),e.jsxs("p",{className:"bw-empty-note",children:["An episode lands here when a program opens pages in a browser nobody has touched for"," ",s.settings.quietMinutes," ",s.settings.quietMinutes===1?"minute":"minutes",". On most machines that is rare, so an empty list is the ordinary result rather than a sign something is wrong."]}),!s.settings.enabled&&e.jsx("p",{className:"bw-empty-note",children:"Watching is off, so this shows only what this deck has seen since it started. Anything an earlier run recorded comes back when you switch it on."})]}):l.map(o=>e.jsxs("div",{className:"bw-day",children:[e.jsx("h4",{className:"bw-sec-head",children:o.label}),o.episodes.map(i=>{const w=E(i),b=c===w;return e.jsxs("div",{className:`bw-ep${b?" open":""}`,children:[e.jsxs("div",{className:"bw-ep-row",children:[e.jsxs("button",{className:"bw-ep-head",ref:p=>{p?u.current.set(w,p):u.current.delete(w)},onClick:()=>d(b?null:w),"aria-expanded":b,children:[e.jsx("span",{className:"bw-chev","aria-hidden":!0,children:b?"▾":"▸"}),e.jsx("span",{className:"bw-ep-host",children:i.host}),e.jsxs("span",{className:"bw-ep-meta",children:[le(i),U(i)&&e.jsxs(e.Fragment,{children:[" · ",U(i)]}),i.provisional&&e.jsxs(e.Fragment,{children:[" · ",e.jsx("span",{title:"Its quiet window has not closed yet. If somebody used the browser in the minutes after it, it is withdrawn; until then it is not written down and no reaction runs.",children:"provisional"})]})]}),e.jsxs("span",{className:"bw-ep-count",children:[i.count," ",i.count===1?"page":"pages"]})]}),e.jsx("button",{className:"glyph-btn bw-ep-x",onClick:()=>n(i),"aria-label":`Dismiss ${i.host}`,title:"Dismiss — it leaves this list for good, and stays in the log file",children:"×"})]}),b&&e.jsx("ul",{className:"bw-urls",children:i.urls.map((p,y)=>e.jsxs("li",{children:[e.jsx("span",{className:"bw-url-time",children:new Date(p.timeMs).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",hour12:!1})}),e.jsx("span",{className:"bw-url",children:p.url})]},`${p.url}-${p.timeMs}-${y}`))})]},w)})]},o.label))})]})}function he(s){const a=/^#?([0-9a-f]{6})$/i.exec((s??"").trim());if(!a)return!1;const h=parseInt(a[1],16),c=[h>>16&255,h>>8&255,h&255].map(d=>{const u=d/255;return u<=.03928?u/12.92:Math.pow((u+.055)/1.055,2.4)});return .2126*c[0]+.7152*c[1]+.0722*c[2]>.5}const G=1e4,ue=12e3;function we({browsers:s,findings:a,watching:h,palette:c}){const d=r.useRef(null),u=r.useRef(null);return u.current={browsers:s,findings:a,watching:h},r.useEffect(()=>{var b;const t=d.current;if(!t)return;const n=t.getContext("2d");if(!n)return;const l=((b=window.matchMedia)==null?void 0:b.call(window,"(prefers-reduced-motion: reduce)").matches)??!1;let o=0,i=!1;const w=()=>{var q;if(i)return;const p=u.current;if(!p)return;const{browsers:y,findings:j,watching:P}=p,S=c["--accent"]||"#7dd3fc",g=c["--line"]||"#1f2229",v=c["--text-dim"]||"#6e727c",$=he(c["--bg"]),N=$?42:26,k=$?.85:.65,A=Date.now(),R=Math.min(window.devicePixelRatio||1,2),C=t.clientWidth,W=t.clientHeight;(t.width!==C*R||t.height!==W*R)&&(t.width=C*R,t.height=W*R),n.setTransform(R,0,0,R,0,0),n.clearRect(0,0,C,W);const m=C/2,x=W/2,M=Math.min(C,W)/2-6;n.strokeStyle=g,n.lineWidth=1,n.globalAlpha=$?1:.9;for(const f of[.4,.7,1])n.beginPath(),n.arc(m,x,M*f,0,Math.PI*2),n.stroke();n.beginPath(),n.moveTo(m-M,x),n.lineTo(m+M,x),n.moveTo(m,x-M),n.lineTo(m,x+M),n.stroke(),n.globalAlpha=1;const I=(P&&!l?A%G/G:0)*Math.PI*2-Math.PI/2;if(P){const f=(q=n.createConicGradient)==null?void 0:q.call(n,I-.85,m,x);f&&(f.addColorStop(0,"transparent"),f.addColorStop(.85/(Math.PI*2),`color-mix(in srgb, ${S} ${N}%, transparent)`),f.addColorStop(1,"transparent"),n.fillStyle=f,n.beginPath(),n.moveTo(m,x),n.arc(m,x,M,I-.85,I),n.closePath(),n.fill()),n.strokeStyle=S,n.globalAlpha=k,n.beginPath(),n.moveTo(m,x),n.lineTo(m+Math.cos(I)*M,x+Math.sin(I)*M),n.stroke(),n.globalAlpha=1}y.forEach((f,T)=>{const B=T/Math.max(y.length,1)*Math.PI*2-Math.PI/2,D=f.lastReadMs===null?1:Math.min(1,(A-f.lastReadMs)/12e4),O=M*(.42+D*.5),F=m+Math.cos(B)*O,L=x+Math.sin(B)*O,J=Math.abs((I-B+Math.PI*3)%(Math.PI*2)-Math.PI),K=P?Math.max(0,1-J/.55):0;n.beginPath(),n.arc(F,L,3+K*1.6,0,Math.PI*2),n.fillStyle=f.running?S:v,n.globalAlpha=f.running?.55+K*.45:.35,n.fill(),n.globalAlpha=1});for(const f of j){const T=(A-f.atMs)/ue;if(T<0||T>1)continue;const D=Math.max(0,y.findIndex(L=>L.key===f.browser))/Math.max(y.length,1)*Math.PI*2-Math.PI/2,O=m+Math.cos(D)*M*.6,F=x+Math.sin(D)*M*.6;n.beginPath(),n.arc(O,F,4+T*22,0,Math.PI*2),n.strokeStyle=S,n.globalAlpha=(1-T)*.8,n.lineWidth=1.5,n.stroke(),n.globalAlpha=1}o=requestAnimationFrame(w)};return w(),()=>{i=!0,cancelAnimationFrame(o)}},[c]),e.jsx("canvas",{ref:d,className:"bw-radar",role:"img","aria-label":h?`Watching ${s.length} browser${s.length===1?"":"s"}`:"Not watching"})}function me({snap:s,watching:a,palette:h}){const[c,d]=r.useState(!1),[u,t]=r.useState(()=>Date.now());r.useEffect(()=>{const l=setInterval(()=>t(Date.now()),1e3);return()=>clearInterval(l)},[]);const n=Y(s.coverage.lastHumanMs,s.coverage.quietMs,u);return e.jsxs("section",{className:"bw-sec",children:[e.jsxs("h4",{className:"bw-sec-head",children:["Activity overview",e.jsx("button",{className:"bw-help",onClick:()=>d(l=>!l),"aria-expanded":c,"aria-label":"What the sweep and the dots mean",children:"?"})]}),e.jsxs("div",{className:"bw-glance",children:[e.jsx(we,{browsers:a.map(l=>{var o;return{key:l.key,name:l.name,running:l.running,lastReadMs:((o=s.profiles.find(i=>i.browser===l.key))==null?void 0:o.lastWrittenMs)??null}}),findings:s.episodes.slice(0,6).map(l=>({browser:l.browser??null,atMs:l.endMs})),watching:s.settings.enabled,palette:h}),e.jsx("ul",{className:"bw-counts",children:z(a,s.profiles).map(l=>e.jsxs("li",{children:[e.jsx("span",{className:"bw-count-n",children:l.visits.toLocaleString("en-US")}),e.jsx("span",{className:"bw-count-of",children:l.name})]},l.key))})]}),e.jsx("p",{className:"bw-since",children:"Pages a program opened, since this deck started"}),s.coverage.checkedMs>0&&e.jsxs("p",{className:"bw-since",children:["Last checked ",V(s.coverage.checkedMs,u),s.coverage.checks>0&&e.jsxs(e.Fragment,{children:[" · ",s.coverage.checks.toLocaleString("en-US")," ",s.coverage.checks===1?"check":"checks"]})]}),n!==null&&e.jsxs("p",{className:"bw-gate",children:["You are browsing — a program page would count in ",X(n)]}),c&&e.jsxs("dl",{className:"bw-key",children:[e.jsx("dt",{children:"Sweep"}),e.jsx("dd",{children:"one poll of every watched profile"}),e.jsx("dt",{children:"Dot"}),e.jsx("dd",{children:"a browser, further out the longer since it last wrote history"}),e.jsx("dt",{children:"Ring"}),e.jsx("dd",{children:"a finding, leaving the browser it came from"})]})]})}function be({watching:s,rest:a}){const[h,c]=r.useState(!1),[d,u]=r.useState(!1);return e.jsxs("section",{className:"bw-sec",children:[e.jsxs("h4",{className:"bw-sec-head",children:["Watched profiles",e.jsx("button",{className:"bw-help",onClick:()=>c(t=>!t),"aria-expanded":h,"aria-label":"What running, idle and connected to Anthropic mean",children:"?"})]}),h&&e.jsxs("dl",{className:"bw-key",children:[e.jsx("dt",{children:"Running"}),e.jsx("dd",{children:"the browser has a process on this machine right now"}),e.jsx("dt",{children:"Connected"}),e.jsx("dd",{children:"an open connection to an address Anthropic's relay uses — which it shares with claude.ai, so an open tab looks the same as an agent channel"})]}),e.jsx("ul",{className:"bw-profiles",children:s.map(t=>e.jsxs("li",{children:[e.jsx("span",{className:`bw-prof-dot${t.running?" on":""}`,"aria-hidden":!0}),e.jsx("span",{className:"bw-prof-name",children:t.name}),e.jsx("span",{className:"bw-prof-state",children:t.running?"running":"idle"}),t.running&&t.relay.state==="live"&&e.jsx("span",{className:"bw-relay",children:"connected to Anthropic"})]},t.key))}),a.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"bw-why bw-rest-head",onClick:()=>u(t=>!t),"aria-expanded":d,children:[e.jsx("span",{className:"bw-chev","aria-hidden":!0,children:d?"▾":"▸"})," ",a.length," not watched"]}),d&&e.jsxs("p",{className:"bw-rest",children:[a.map(t=>t.name).join(", ")," — not installed, or installed and never opened, so there is no history to read."]})]})]})}function pe({snap:s,quiet:a,setQuiet:h,save:c,access:d,setAccess:u}){return e.jsxs("div",{className:"bw-settings",children:[e.jsxs("label",{title:"A program opening a page counts as a finding only if nobody had touched the browser for this long. Shorter catches more and reports more of your own work; longer is quieter.",children:[e.jsx("span",{children:"Nobody browsing for"}),e.jsxs("select",{value:a??s.settings.quietMinutes,onChange:t=>{h(Number(t.target.value)),c({quietMinutes:Number(t.target.value)})},children:[e.jsx("option",{value:1,children:"1 min"}),e.jsx("option",{value:5,children:"5 min"}),e.jsx("option",{value:15,children:"15 min"}),e.jsx("option",{value:30,children:"30 min"}),e.jsx("option",{value:60,children:"60 min"})]})]}),e.jsxs("label",{children:[e.jsx("span",{children:"When it finds one"}),e.jsx("select",{value:s.settings.reaction,onChange:t=>void c({reaction:t.target.value}),disabled:!s.settings.enabled,title:s.settings.enabled?"What to do besides writing it down.":"Turn watching on to arm a reaction.",children:(s.reactions??["notify"]).map(t=>e.jsx("option",{value:t,children:t==="notify"?"notify me":t==="close-tab"?"close the tab":"quit the browser"},t))})]}),e.jsxs("div",{className:"bw-settings-note",children:[e.jsxs("p",{children:["Chrome marks a navigation that came from an extension or a command rather than from a click. These are the ones that happened while nobody had touched the browser for the time above. ",e.jsx("strong",{children:"Usually that is your own agent doing what you asked."})]}),e.jsxs("button",{className:"bw-why",onClick:()=>u(t=>!t),"aria-expanded":d,children:[e.jsx("span",{className:"bw-chev","aria-hidden":!0,children:d?"▾":"▸"})," What Browser Watch can access"]}),d&&e.jsxs("dl",{className:"bw-access",children:[e.jsx("dt",{children:"Reads"}),e.jsxs("dd",{children:["A copy of each browser's own history database — the live file is locked while the browser holds it. Only rows newer than the moment this deck started:"," ",new Date(s.coverage.startedMs).toLocaleString(),"."]}),e.jsx("dt",{children:"Keeps"}),e.jsxs("dd",{children:["Only while the switch is on, and only the episodes it flagged — never your ordinary browsing. In ",e.jsx("code",{className:"bw-path",children:s.coverage.logPath}),typeof s.coverage.logBytes=="number"?` (${Z(s.coverage.logBytes)})`:"",", with every address written in full so you can check it yourself."]}),e.jsx("dt",{children:"Sends"}),e.jsx("dd",{children:"Nothing. No part of this reads or writes over the network; the deck serves on 127.0.0.1 and this panel talks only to it."}),e.jsx("dt",{children:"Never reads"}),e.jsx("dd",{children:"Anything from before this deck started, cookies, saved passwords, page contents, or any browser profile with no history file."})]})]})]})}function H(s,a){return a?{kind:"saving",word:"Saving"}:s.settings.enabled?{kind:"on",word:"Watching"}:{kind:"off",word:"Paused"}}function ge({snap:s,saving:a,save:h,why:c,setWhy:d}){return e.jsxs("footer",{className:"bw-status",children:[e.jsx("span",{className:`bw-mode-dot${s.settings.enabled?" on":""}`,"aria-hidden":!0}),e.jsx("span",{className:"bw-mode-word",children:H(s,a).word},H(s,a).kind),e.jsx("span",{className:"bw-status-text",children:s.coverage.archived===0?s.settings.enabled?"No episodes recorded yet":"No episodes on disk":`${s.coverage.archived} ${s.coverage.archived===1?"episode":"episodes"} on disk`}),e.jsx("button",{className:`glyph-btn bw-gear${c?" on":""}`,onClick:()=>d(u=>!u),"aria-expanded":c,"aria-label":"Settings",title:"Settings",children:e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 14 14",fill:"none",stroke:"currentColor",strokeWidth:"1.3","aria-hidden":!0,children:[e.jsx("circle",{cx:"7",cy:"7",r:"2.1"}),e.jsx("path",{d:"M7 1.2v1.6M7 11.2v1.6M1.2 7h1.6M11.2 7h1.6M2.9 2.9l1.1 1.1M10 10l1.1 1.1M11.1 2.9L10 4M4 10l-1.1 1.1"})]})}),e.jsxs("label",{className:"bw-switch",htmlFor:"bw-enabled",children:[e.jsx("span",{className:"bw-switch-label",id:"bw-enabled-label",children:"Watch browser activity"}),e.jsx("button",{id:"bw-enabled",type:"button",role:"switch","aria-checked":s.settings.enabled,"aria-labelledby":"bw-enabled-label",className:"switch",onClick:()=>void h({enabled:!s.settings.enabled}),title:s.settings.enabled?"On — every episode it finds is written down, so the list outlives the browsing history being cleared":"Off — showing only what this deck has seen since it started. Anything an earlier run archived is hidden until you switch back on, and nothing new is kept",children:e.jsx("span",{className:"switch-knob"})})]})]})}function fe({relay:s}){const[a,h]=r.useState(!1),[c,d]=r.useState(!1),u=s.killswitch.blocked?"unblock":"block",t=s.command[u],n=r.useCallback(async()=>{await ee(t.command)&&(d(!0),window.setTimeout(()=>d(!1),1600))},[t.command]),l=s.profiles.filter(i=>{var w;return(w=i.report)==null?void 0:w.present}),o=s.profiles.filter(i=>i.report===null);return e.jsxs("section",{className:"bw-sec",children:[e.jsx("h4",{className:"bw-sec-head",children:"Remote control"}),e.jsx("p",{className:`bw-rc-verdict ${s.verdict}`,role:"status",children:s.verdict==="exposed"?"Claude in Chrome is live here, so any Claude Code session signed in to your Anthropic account can drive this browser — from any machine, with no prompt on this one.":s.verdict==="protected"?`The relay is black-holed in ${s.hostsPath}, so no new connection to it can be made from this machine.`:"Claude in Chrome is not installed and enabled in any profile here, so there is nothing for the relay to drive."}),s.killswitch.foreign.length>0&&e.jsxs("p",{className:"bw-rc-foreign",children:["Another entry for this host is already in ",s.hostsPath,", and ccdeck will not touch it:",s.killswitch.foreign.map(i=>e.jsx("code",{className:"bw-path",children:i},i))]}),e.jsxs("button",{className:"bw-why",onClick:()=>h(i=>!i),"aria-expanded":a,children:[e.jsx("span",{className:"bw-chev","aria-hidden":!0,children:a?"▾":"▸"})," ",s.verdict==="protected"?"How to undo the block":"What it can reach, and how to stop it"]}),a&&e.jsxs("div",{className:"bw-rc-body",children:[l.length>0&&e.jsx("dl",{className:"bw-key",children:l.map(i=>e.jsxs(r.Fragment,{children:[e.jsxs("dt",{children:[i.name,i.profile==="Default"?"":` · ${i.profile}`]}),e.jsxs("dd",{children:[i.report.enabled?"enabled":"installed but switched off",i.report.allUrls?", can act on every site":", limited to the sites it was granted",i.report.sensitiveApis.length>0&&e.jsxs(e.Fragment,{children:[" — ",i.report.sensitiveApis.join(", ")]})]})]},`${i.browser}/${i.profile}`))}),o.length>0&&e.jsxs("p",{className:"bw-rc-note",children:[o.map(i=>i.name).join(", ")," — its settings file could not be read, so nothing is claimed about it either way."]}),!s.hostsRead&&e.jsxs("p",{className:"bw-rc-note",children:[s.hostsPath," could not be read, so whether the relay is already blocked is unknown."]}),l.some(i=>i.report.allUrls)&&e.jsxs("p",{className:"bw-rc-note",children:["Narrowing the sites in ",e.jsx("code",{className:"bw-path",children:"chrome://extensions"})," does not change this: the grant is held at the browser level and the per-site list is enforced inside the extension, by the extension."]}),e.jsxs("div",{className:"bw-rc-cmd",children:[e.jsx("code",{children:t.command}),e.jsx("button",{className:"btn bw-rc-copy",onClick:n,children:c?"Copied":"Copy"})]}),e.jsx("p",{className:"bw-rc-note",children:t.note})]})]})}function xe(s){const[a,h]=r.useState(null),[c,d]=r.useState(null),[u,t]=r.useState(null),[n,l]=r.useState(!1),o=r.useRef(!1),[i,w]=r.useState(null),[b,p]=r.useState(!1),y=r.useRef(!1),j=r.useCallback(async g=>{var v,$;if(!(g&&!se(o.current))){g&&(o.current=!0,l(!0));try{const N=await fetch(`/api/browser-watch${g?"?refresh=1":""}`);if(!N.ok)throw new Error(`the deck answered ${N.status}`);const k=await N.json();h(k),y.current||w(((v=k==null?void 0:k.settings)==null?void 0:v.quietMinutes)??15),s((($=k==null?void 0:k.settings)==null?void 0:$.enabled)===!0),d(null)}catch(N){d(N instanceof Error?N.message:String(N))}finally{g&&(o.current=!1,l(!1))}}},[s]);r.useEffect(()=>{j(!1)},[j]),r.useEffect(()=>{const g=setInterval(()=>{j(!1)},1e4);return()=>clearInterval(g)},[j]);const P=r.useCallback(async g=>{try{await fetch("/api/browser-watch/dismiss",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({host:g.host,startMs:g.startMs})})}finally{await j(!1)}},[j]),S=r.useCallback(async g=>{y.current=!0,p(!0);try{const v=await fetch("/api/browser-watch",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(g)});if(!v.ok)throw new Error(`the deck answered ${v.status}`);await j(!1),t(null)}catch(v){t(v instanceof Error?v.message:String(v))}finally{y.current=!1,p(!1)}},[j]);return{snap:a,error:c,writeError:u,setWriteError:t,busy:n,quiet:i,setQuiet:w,saving:b,load:j,dismiss:P,save:S}}function ye({onClose:s,onSeen:a,onWatching:h,palette:c}){const d=te(s),u=ne(s),{snap:t,error:n,writeError:l,setWriteError:o,busy:i,quiet:w,setQuiet:b,saving:p,load:y,dismiss:j,save:P}=xe(h),[S,g]=r.useState(!1),[v,$]=r.useState(!1),N=r.useRef(null),k=r.useRef(a);k.current=a,r.useEffect(()=>()=>k.current(Date.now()),[]);const A=ae(t==null?void 0:t.browsers),R=((t==null?void 0:t.browsers)??[]).filter(m=>!(m.installed&&m.profiles>0)),C=t?ie(t):null,W=A.reduce((m,x)=>m+x.profiles,0);return e.jsx("div",{className:"modal-backdrop",...u,role:"presentation",children:e.jsxs("div",{ref:d,className:"modal bw-modal",onClick:m=>m.stopPropagation(),role:"dialog","aria-modal":"true","aria-labelledby":"bw-title",children:[e.jsxs("header",{className:"modal-head",children:[e.jsxs("div",{className:"modal-title",children:[e.jsx("span",{className:"modal-tool-name",id:"bw-title",children:"Browser watch"}),e.jsx("span",{className:"modal-tool-id",children:t?`${W} ${W===1?"profile":"profiles"} · local only`:"local only"})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{ref:N,className:"glyph-btn",onClick:()=>void y(!0),...re(i),"aria-label":"Re-read every profile now",title:"Re-read every profile now",children:i?"…":"↻"}),e.jsx("button",{className:"glyph-btn",onClick:s,"aria-label":"Close (Esc)",title:"Close (Esc)",children:"×"})]})]}),e.jsxs("div",{className:"modal-body bw-body",children:[!t&&!n&&e.jsxs("div",{className:"bw-loading",children:[e.jsx("span",{className:"bw-loading-bar","aria-hidden":!0}),e.jsx("p",{children:"Reading each browser's history. The first look copies the file, which takes a moment."})]}),n&&e.jsx("div",{className:"bw-state",children:e.jsxs("div",{className:"bw-row err",children:[e.jsx("span",{className:"bw-dot","aria-hidden":!0}),e.jsx("span",{className:"bw-row-label",children:"Could not read"}),e.jsx("span",{className:"bw-row-detail",children:n})]})}),t&&C&&e.jsx("p",{className:`bw-trouble ${C.kind}`,role:"status",children:C.text}),t&&e.jsxs("div",{className:"bw-work",children:[e.jsxs("aside",{className:"bw-side",children:[e.jsx(me,{snap:t,watching:A,palette:c}),e.jsx(be,{watching:A,rest:R}),t.relay&&e.jsx(fe,{relay:t.relay})]}),e.jsxs("div",{className:"bw-main",children:[e.jsx(de,{snap:t,dismiss:j,refreshRef:N}),e.jsx(oe,{snap:t})]})]}),t&&S&&e.jsx(pe,{snap:t,quiet:w,setQuiet:b,save:P,access:v,setAccess:$}),l&&e.jsx("div",{className:"bw-state bw-write-err",role:"alert",children:e.jsxs("div",{className:"bw-row err",children:[e.jsx("span",{className:"bw-dot","aria-hidden":!0}),e.jsx("span",{className:"bw-row-label",children:"Could not save that setting"}),e.jsxs("span",{className:"bw-row-detail",children:[l," — the switches below show what is stored, not what you pressed."]}),e.jsx("button",{className:"glyph-btn bw-write-err-x",onClick:()=>o(null),"aria-label":"Dismiss",title:"Dismiss",children:"×"})]})}),t&&e.jsx(ge,{snap:t,saving:p,save:P,why:S,setWhy:g})]})]})})}export{ye as default};
|
|
1
|
+
import{j as e,r,l as Q,m as _,n as Y,v as z,o as V,q as X,t as Z,w as ee,s as se,u as te,d as ne,x as ae,y as ie,h as re}from"./index-CxIdVCPz.js";function oe({snap:s}){return e.jsxs("section",{className:"bw-feed",children:[e.jsxs("h4",{className:"bw-sec-head bw-head-row",children:["Live activity",e.jsxs("span",{className:"bw-feed-count",children:[s.log.length," ",s.log.length===1?"event":"events"]})]}),e.jsx("p",{className:"bw-since bw-feed-note",children:"Pages you opened yourself — counted to run the rule, never written down. Addresses appear under Findings, and only for pages a program opened."}),e.jsx("div",{className:"bw-log","aria-live":"polite","aria-relevant":"additions",children:s.log.length===0?e.jsx("p",{className:"bw-note",children:"The deck writes a line here each time it looks at a profile."}):s.log.map(a=>e.jsxs("div",{className:`bw-log-line ${a.level}${a.parts?"":" sys"}`,children:[e.jsx("span",{className:"bw-log-time",children:new Date(a.atMs).toLocaleTimeString("en-GB",{hour12:!1})}),a.parts?e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"bw-log-browser",children:a.parts.browser}),e.jsx("span",{className:"bw-log-profile",title:a.parts.profile,children:a.parts.profile}),e.jsxs("span",{className:"bw-log-value",children:[a.parts.value,a.parts.flagged>0&&e.jsxs("span",{className:"bw-log-flag",children:[" · ",a.parts.flagged," flagged"]})]})]}):e.jsx("span",{className:"bw-log-sys",children:a.text})]},`${a.atMs}-${a.level}-${a.text}`))})]})}const E=s=>`${s.host}-${s.startMs}`;function le(s){const a=h=>new Date(h).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",hour12:!1});return s.count===1||s.endMs-s.startMs<6e4?a(s.startMs):`${a(s.startMs)} → ${a(s.endMs)}`}function ce(s){return new Date(s).toLocaleDateString(void 0,{weekday:"short",day:"numeric",month:"short"})}function U(s){const a=Math.round((s.endMs-s.startMs)/6e4);return a<1?"":`${a} min`}function de({snap:s,dismiss:a,refreshRef:h}){const[c,d]=r.useState(null),u=r.useRef(new Map),t=r.useRef(null);r.useEffect(()=>{var i,w;const o=t.current;!o||s.episodes.some(b=>E(b)===o.id)||(t.current=null,Q(((i=document.activeElement)==null?void 0:i.tagName)??null)&&((w=(o.next?u.current.get(o.next):void 0)??h.current)==null||w.focus()))},[s]);const n=o=>{t.current={id:E(o),next:_(s.episodes.map(E),E(o))},a(o)},l=r.useMemo(()=>{const o=[];for(const i of s.episodes){const w=ce(i.startMs),b=o[o.length-1];b&&b.label===w?b.episodes.push(i):o.push({label:w,episodes:[i]})}return o},[s]);return e.jsxs("section",{className:"bw-findings",children:[e.jsxs("h4",{className:"bw-sec-head bw-head-row",children:["Findings",s.episodes.length>0&&e.jsxs("span",{className:"bw-feed-count",children:[s.episodes.length," ",s.episodes.length===1?"episode":"episodes"]})]}),e.jsx("div",{className:"bw-eps",children:l.length===0?e.jsxs("div",{className:"bw-empty",children:[e.jsx("p",{className:"bw-empty-head",children:"Nothing found yet"}),e.jsxs("p",{className:"bw-empty-note",children:["An episode lands here when a program opens pages in a browser nobody has touched for"," ",s.settings.quietMinutes," ",s.settings.quietMinutes===1?"minute":"minutes",". On most machines that is rare, so an empty list is the ordinary result rather than a sign something is wrong."]}),!s.settings.enabled&&e.jsx("p",{className:"bw-empty-note",children:"Watching is off, so this shows only what this deck has seen since it started. Anything an earlier run recorded comes back when you switch it on."})]}):l.map(o=>e.jsxs("div",{className:"bw-day",children:[e.jsx("h4",{className:"bw-sec-head",children:o.label}),o.episodes.map(i=>{const w=E(i),b=c===w;return e.jsxs("div",{className:`bw-ep${b?" open":""}`,children:[e.jsxs("div",{className:"bw-ep-row",children:[e.jsxs("button",{className:"bw-ep-head",ref:p=>{p?u.current.set(w,p):u.current.delete(w)},onClick:()=>d(b?null:w),"aria-expanded":b,children:[e.jsx("span",{className:"bw-chev","aria-hidden":!0,children:b?"▾":"▸"}),e.jsx("span",{className:"bw-ep-host",children:i.host}),e.jsxs("span",{className:"bw-ep-meta",children:[le(i),U(i)&&e.jsxs(e.Fragment,{children:[" · ",U(i)]}),i.provisional&&e.jsxs(e.Fragment,{children:[" · ",e.jsx("span",{title:"Its quiet window has not closed yet. If somebody used the browser in the minutes after it, it is withdrawn; until then it is not written down and no reaction runs.",children:"provisional"})]})]}),e.jsxs("span",{className:"bw-ep-count",children:[i.count," ",i.count===1?"page":"pages"]})]}),e.jsx("button",{className:"glyph-btn bw-ep-x",onClick:()=>n(i),"aria-label":`Dismiss ${i.host}`,title:"Dismiss — it leaves this list for good, and stays in the log file",children:"×"})]}),b&&e.jsx("ul",{className:"bw-urls",children:i.urls.map((p,y)=>e.jsxs("li",{children:[e.jsx("span",{className:"bw-url-time",children:new Date(p.timeMs).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",hour12:!1})}),e.jsx("span",{className:"bw-url",children:p.url})]},`${p.url}-${p.timeMs}-${y}`))})]},w)})]},o.label))})]})}function he(s){const a=/^#?([0-9a-f]{6})$/i.exec((s??"").trim());if(!a)return!1;const h=parseInt(a[1],16),c=[h>>16&255,h>>8&255,h&255].map(d=>{const u=d/255;return u<=.03928?u/12.92:Math.pow((u+.055)/1.055,2.4)});return .2126*c[0]+.7152*c[1]+.0722*c[2]>.5}const G=1e4,ue=12e3;function we({browsers:s,findings:a,watching:h,palette:c}){const d=r.useRef(null),u=r.useRef(null);return u.current={browsers:s,findings:a,watching:h},r.useEffect(()=>{var b;const t=d.current;if(!t)return;const n=t.getContext("2d");if(!n)return;const l=((b=window.matchMedia)==null?void 0:b.call(window,"(prefers-reduced-motion: reduce)").matches)??!1;let o=0,i=!1;const w=()=>{var q;if(i)return;const p=u.current;if(!p)return;const{browsers:y,findings:j,watching:P}=p,S=c["--accent"]||"#7dd3fc",g=c["--line"]||"#1f2229",v=c["--text-dim"]||"#6e727c",$=he(c["--bg"]),N=$?42:26,k=$?.85:.65,A=Date.now(),R=Math.min(window.devicePixelRatio||1,2),C=t.clientWidth,W=t.clientHeight;(t.width!==C*R||t.height!==W*R)&&(t.width=C*R,t.height=W*R),n.setTransform(R,0,0,R,0,0),n.clearRect(0,0,C,W);const m=C/2,x=W/2,M=Math.min(C,W)/2-6;n.strokeStyle=g,n.lineWidth=1,n.globalAlpha=$?1:.9;for(const f of[.4,.7,1])n.beginPath(),n.arc(m,x,M*f,0,Math.PI*2),n.stroke();n.beginPath(),n.moveTo(m-M,x),n.lineTo(m+M,x),n.moveTo(m,x-M),n.lineTo(m,x+M),n.stroke(),n.globalAlpha=1;const I=(P&&!l?A%G/G:0)*Math.PI*2-Math.PI/2;if(P){const f=(q=n.createConicGradient)==null?void 0:q.call(n,I-.85,m,x);f&&(f.addColorStop(0,"transparent"),f.addColorStop(.85/(Math.PI*2),`color-mix(in srgb, ${S} ${N}%, transparent)`),f.addColorStop(1,"transparent"),n.fillStyle=f,n.beginPath(),n.moveTo(m,x),n.arc(m,x,M,I-.85,I),n.closePath(),n.fill()),n.strokeStyle=S,n.globalAlpha=k,n.beginPath(),n.moveTo(m,x),n.lineTo(m+Math.cos(I)*M,x+Math.sin(I)*M),n.stroke(),n.globalAlpha=1}y.forEach((f,T)=>{const B=T/Math.max(y.length,1)*Math.PI*2-Math.PI/2,D=f.lastReadMs===null?1:Math.min(1,(A-f.lastReadMs)/12e4),O=M*(.42+D*.5),F=m+Math.cos(B)*O,L=x+Math.sin(B)*O,J=Math.abs((I-B+Math.PI*3)%(Math.PI*2)-Math.PI),K=P?Math.max(0,1-J/.55):0;n.beginPath(),n.arc(F,L,3+K*1.6,0,Math.PI*2),n.fillStyle=f.running?S:v,n.globalAlpha=f.running?.55+K*.45:.35,n.fill(),n.globalAlpha=1});for(const f of j){const T=(A-f.atMs)/ue;if(T<0||T>1)continue;const D=Math.max(0,y.findIndex(L=>L.key===f.browser))/Math.max(y.length,1)*Math.PI*2-Math.PI/2,O=m+Math.cos(D)*M*.6,F=x+Math.sin(D)*M*.6;n.beginPath(),n.arc(O,F,4+T*22,0,Math.PI*2),n.strokeStyle=S,n.globalAlpha=(1-T)*.8,n.lineWidth=1.5,n.stroke(),n.globalAlpha=1}o=requestAnimationFrame(w)};return w(),()=>{i=!0,cancelAnimationFrame(o)}},[c]),e.jsx("canvas",{ref:d,className:"bw-radar",role:"img","aria-label":h?`Watching ${s.length} browser${s.length===1?"":"s"}`:"Not watching"})}function me({snap:s,watching:a,palette:h}){const[c,d]=r.useState(!1),[u,t]=r.useState(()=>Date.now());r.useEffect(()=>{const l=setInterval(()=>t(Date.now()),1e3);return()=>clearInterval(l)},[]);const n=Y(s.coverage.lastHumanMs,s.coverage.quietMs,u);return e.jsxs("section",{className:"bw-sec",children:[e.jsxs("h4",{className:"bw-sec-head",children:["Activity overview",e.jsx("button",{className:"bw-help",onClick:()=>d(l=>!l),"aria-expanded":c,"aria-label":"What the sweep and the dots mean",children:"?"})]}),e.jsxs("div",{className:"bw-glance",children:[e.jsx(we,{browsers:a.map(l=>{var o;return{key:l.key,name:l.name,running:l.running,lastReadMs:((o=s.profiles.find(i=>i.browser===l.key))==null?void 0:o.lastWrittenMs)??null}}),findings:s.episodes.slice(0,6).map(l=>({browser:l.browser??null,atMs:l.endMs})),watching:s.settings.enabled,palette:h}),e.jsx("ul",{className:"bw-counts",children:z(a,s.profiles).map(l=>e.jsxs("li",{children:[e.jsx("span",{className:"bw-count-n",children:l.visits.toLocaleString("en-US")}),e.jsx("span",{className:"bw-count-of",children:l.name})]},l.key))})]}),e.jsx("p",{className:"bw-since",children:"Pages a program opened, since this deck started"}),s.coverage.checkedMs>0&&e.jsxs("p",{className:"bw-since",children:["Last checked ",V(s.coverage.checkedMs,u),s.coverage.checks>0&&e.jsxs(e.Fragment,{children:[" · ",s.coverage.checks.toLocaleString("en-US")," ",s.coverage.checks===1?"check":"checks"]})]}),n!==null&&e.jsxs("p",{className:"bw-gate",children:["You are browsing — a program page would count in ",X(n)]}),c&&e.jsxs("dl",{className:"bw-key",children:[e.jsx("dt",{children:"Sweep"}),e.jsx("dd",{children:"one poll of every watched profile"}),e.jsx("dt",{children:"Dot"}),e.jsx("dd",{children:"a browser, further out the longer since it last wrote history"}),e.jsx("dt",{children:"Ring"}),e.jsx("dd",{children:"a finding, leaving the browser it came from"})]})]})}function be({watching:s,rest:a}){const[h,c]=r.useState(!1),[d,u]=r.useState(!1);return e.jsxs("section",{className:"bw-sec",children:[e.jsxs("h4",{className:"bw-sec-head",children:["Watched profiles",e.jsx("button",{className:"bw-help",onClick:()=>c(t=>!t),"aria-expanded":h,"aria-label":"What running, idle and connected to Anthropic mean",children:"?"})]}),h&&e.jsxs("dl",{className:"bw-key",children:[e.jsx("dt",{children:"Running"}),e.jsx("dd",{children:"the browser has a process on this machine right now"}),e.jsx("dt",{children:"Connected"}),e.jsx("dd",{children:"an open connection to an address Anthropic's relay uses — which it shares with claude.ai, so an open tab looks the same as an agent channel"})]}),e.jsx("ul",{className:"bw-profiles",children:s.map(t=>e.jsxs("li",{children:[e.jsx("span",{className:`bw-prof-dot${t.running?" on":""}`,"aria-hidden":!0}),e.jsx("span",{className:"bw-prof-name",children:t.name}),e.jsx("span",{className:"bw-prof-state",children:t.running?"running":"idle"}),t.running&&t.relay.state==="live"&&e.jsx("span",{className:"bw-relay",children:"connected to Anthropic"})]},t.key))}),a.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"bw-why bw-rest-head",onClick:()=>u(t=>!t),"aria-expanded":d,children:[e.jsx("span",{className:"bw-chev","aria-hidden":!0,children:d?"▾":"▸"})," ",a.length," not watched"]}),d&&e.jsxs("p",{className:"bw-rest",children:[a.map(t=>t.name).join(", ")," — not installed, or installed and never opened, so there is no history to read."]})]})]})}function pe({snap:s,quiet:a,setQuiet:h,save:c,access:d,setAccess:u}){return e.jsxs("div",{className:"bw-settings",children:[e.jsxs("label",{title:"A program opening a page counts as a finding only if nobody had touched the browser for this long. Shorter catches more and reports more of your own work; longer is quieter.",children:[e.jsx("span",{children:"Nobody browsing for"}),e.jsxs("select",{value:a??s.settings.quietMinutes,onChange:t=>{h(Number(t.target.value)),c({quietMinutes:Number(t.target.value)})},children:[e.jsx("option",{value:1,children:"1 min"}),e.jsx("option",{value:5,children:"5 min"}),e.jsx("option",{value:15,children:"15 min"}),e.jsx("option",{value:30,children:"30 min"}),e.jsx("option",{value:60,children:"60 min"})]})]}),e.jsxs("label",{children:[e.jsx("span",{children:"When it finds one"}),e.jsx("select",{value:s.settings.reaction,onChange:t=>void c({reaction:t.target.value}),disabled:!s.settings.enabled,title:s.settings.enabled?"What to do besides writing it down.":"Turn watching on to arm a reaction.",children:(s.reactions??["notify"]).map(t=>e.jsx("option",{value:t,children:t==="notify"?"notify me":t==="close-tab"?"close the tab":"quit the browser"},t))})]}),e.jsxs("div",{className:"bw-settings-note",children:[e.jsxs("p",{children:["Chrome marks a navigation that came from an extension or a command rather than from a click. These are the ones that happened while nobody had touched the browser for the time above. ",e.jsx("strong",{children:"Usually that is your own agent doing what you asked."})]}),e.jsxs("button",{className:"bw-why",onClick:()=>u(t=>!t),"aria-expanded":d,children:[e.jsx("span",{className:"bw-chev","aria-hidden":!0,children:d?"▾":"▸"})," What Browser Watch can access"]}),d&&e.jsxs("dl",{className:"bw-access",children:[e.jsx("dt",{children:"Reads"}),e.jsxs("dd",{children:["A copy of each browser's own history database — the live file is locked while the browser holds it. Only rows newer than the moment this deck started:"," ",new Date(s.coverage.startedMs).toLocaleString(),"."]}),e.jsx("dt",{children:"Keeps"}),e.jsxs("dd",{children:["Only while the switch is on, and only the episodes it flagged — never your ordinary browsing. In ",e.jsx("code",{className:"bw-path",children:s.coverage.logPath}),typeof s.coverage.logBytes=="number"?` (${Z(s.coverage.logBytes)})`:"",", with every address written in full so you can check it yourself."]}),e.jsx("dt",{children:"Sends"}),e.jsx("dd",{children:"Nothing. No part of this reads or writes over the network; the deck serves on 127.0.0.1 and this panel talks only to it."}),e.jsx("dt",{children:"Never reads"}),e.jsx("dd",{children:"Anything from before this deck started, cookies, saved passwords, page contents, or any browser profile with no history file."})]})]})]})}function H(s,a){return a?{kind:"saving",word:"Saving"}:s.settings.enabled?{kind:"on",word:"Watching"}:{kind:"off",word:"Paused"}}function ge({snap:s,saving:a,save:h,why:c,setWhy:d}){return e.jsxs("footer",{className:"bw-status",children:[e.jsx("span",{className:`bw-mode-dot${s.settings.enabled?" on":""}`,"aria-hidden":!0}),e.jsx("span",{className:"bw-mode-word",children:H(s,a).word},H(s,a).kind),e.jsx("span",{className:"bw-status-text",children:s.coverage.archived===0?s.settings.enabled?"No episodes recorded yet":"No episodes on disk":`${s.coverage.archived} ${s.coverage.archived===1?"episode":"episodes"} on disk`}),e.jsx("button",{className:`glyph-btn bw-gear${c?" on":""}`,onClick:()=>d(u=>!u),"aria-expanded":c,"aria-label":"Settings",title:"Settings",children:e.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 14 14",fill:"none",stroke:"currentColor",strokeWidth:"1.3","aria-hidden":!0,children:[e.jsx("circle",{cx:"7",cy:"7",r:"2.1"}),e.jsx("path",{d:"M7 1.2v1.6M7 11.2v1.6M1.2 7h1.6M11.2 7h1.6M2.9 2.9l1.1 1.1M10 10l1.1 1.1M11.1 2.9L10 4M4 10l-1.1 1.1"})]})}),e.jsxs("label",{className:"bw-switch",htmlFor:"bw-enabled",children:[e.jsx("span",{className:"bw-switch-label",id:"bw-enabled-label",children:"Watch browser activity"}),e.jsx("button",{id:"bw-enabled",type:"button",role:"switch","aria-checked":s.settings.enabled,"aria-labelledby":"bw-enabled-label",className:"switch",onClick:()=>void h({enabled:!s.settings.enabled}),title:s.settings.enabled?"On — every episode it finds is written down, so the list outlives the browsing history being cleared":"Off — showing only what this deck has seen since it started. Anything an earlier run archived is hidden until you switch back on, and nothing new is kept",children:e.jsx("span",{className:"switch-knob"})})]})]})}function fe({relay:s}){const[a,h]=r.useState(!1),[c,d]=r.useState(!1),u=s.killswitch.blocked?"unblock":"block",t=s.command[u],n=r.useCallback(async()=>{await ee(t.command)&&(d(!0),window.setTimeout(()=>d(!1),1600))},[t.command]),l=s.profiles.filter(i=>{var w;return(w=i.report)==null?void 0:w.present}),o=s.profiles.filter(i=>i.report===null);return e.jsxs("section",{className:"bw-sec",children:[e.jsx("h4",{className:"bw-sec-head",children:"Remote control"}),e.jsx("p",{className:`bw-rc-verdict ${s.verdict}`,role:"status",children:s.verdict==="exposed"?"Claude in Chrome is live here, so any Claude Code session signed in to your Anthropic account can drive this browser — from any machine, with no prompt on this one.":s.verdict==="protected"?`The relay is black-holed in ${s.hostsPath}, so no new connection to it can be made from this machine.`:"Claude in Chrome is not installed and enabled in any profile here, so there is nothing for the relay to drive."}),s.killswitch.foreign.length>0&&e.jsxs("p",{className:"bw-rc-foreign",children:["Another entry for this host is already in ",s.hostsPath,", and ccdeck will not touch it:",s.killswitch.foreign.map(i=>e.jsx("code",{className:"bw-path",children:i},i))]}),e.jsxs("button",{className:"bw-why",onClick:()=>h(i=>!i),"aria-expanded":a,children:[e.jsx("span",{className:"bw-chev","aria-hidden":!0,children:a?"▾":"▸"})," ",s.verdict==="protected"?"How to undo the block":"What it can reach, and how to stop it"]}),a&&e.jsxs("div",{className:"bw-rc-body",children:[l.length>0&&e.jsx("dl",{className:"bw-key",children:l.map(i=>e.jsxs(r.Fragment,{children:[e.jsxs("dt",{children:[i.name,i.profile==="Default"?"":` · ${i.profile}`]}),e.jsxs("dd",{children:[i.report.enabled?"enabled":"installed but switched off",i.report.allUrls?", can act on every site":", limited to the sites it was granted",i.report.sensitiveApis.length>0&&e.jsxs(e.Fragment,{children:[" — ",i.report.sensitiveApis.join(", ")]})]})]},`${i.browser}/${i.profile}`))}),o.length>0&&e.jsxs("p",{className:"bw-rc-note",children:[o.map(i=>i.name).join(", ")," — its settings file could not be read, so nothing is claimed about it either way."]}),!s.hostsRead&&e.jsxs("p",{className:"bw-rc-note",children:[s.hostsPath," could not be read, so whether the relay is already blocked is unknown."]}),l.some(i=>i.report.allUrls)&&e.jsxs("p",{className:"bw-rc-note",children:["Narrowing the sites in ",e.jsx("code",{className:"bw-path",children:"chrome://extensions"})," does not change this: the grant is held at the browser level and the per-site list is enforced inside the extension, by the extension."]}),e.jsxs("div",{className:"bw-rc-cmd",children:[e.jsx("code",{children:t.command}),e.jsx("button",{className:"btn bw-rc-copy",onClick:n,children:c?"Copied":"Copy"})]}),e.jsx("p",{className:"bw-rc-note",children:t.note})]})]})}function xe(s){const[a,h]=r.useState(null),[c,d]=r.useState(null),[u,t]=r.useState(null),[n,l]=r.useState(!1),o=r.useRef(!1),[i,w]=r.useState(null),[b,p]=r.useState(!1),y=r.useRef(!1),j=r.useCallback(async g=>{var v,$;if(!(g&&!se(o.current))){g&&(o.current=!0,l(!0));try{const N=await fetch(`/api/browser-watch${g?"?refresh=1":""}`);if(!N.ok)throw new Error(`the deck answered ${N.status}`);const k=await N.json();h(k),y.current||w(((v=k==null?void 0:k.settings)==null?void 0:v.quietMinutes)??15),s((($=k==null?void 0:k.settings)==null?void 0:$.enabled)===!0),d(null)}catch(N){d(N instanceof Error?N.message:String(N))}finally{g&&(o.current=!1,l(!1))}}},[s]);r.useEffect(()=>{j(!1)},[j]),r.useEffect(()=>{const g=setInterval(()=>{j(!1)},1e4);return()=>clearInterval(g)},[j]);const P=r.useCallback(async g=>{try{await fetch("/api/browser-watch/dismiss",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({host:g.host,startMs:g.startMs})})}finally{await j(!1)}},[j]),S=r.useCallback(async g=>{y.current=!0,p(!0);try{const v=await fetch("/api/browser-watch",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(g)});if(!v.ok)throw new Error(`the deck answered ${v.status}`);await j(!1),t(null)}catch(v){t(v instanceof Error?v.message:String(v))}finally{y.current=!1,p(!1)}},[j]);return{snap:a,error:c,writeError:u,setWriteError:t,busy:n,quiet:i,setQuiet:w,saving:b,load:j,dismiss:P,save:S}}function ye({onClose:s,onSeen:a,onWatching:h,palette:c}){const d=te(s),u=ne(s),{snap:t,error:n,writeError:l,setWriteError:o,busy:i,quiet:w,setQuiet:b,saving:p,load:y,dismiss:j,save:P}=xe(h),[S,g]=r.useState(!1),[v,$]=r.useState(!1),N=r.useRef(null),k=r.useRef(a);k.current=a,r.useEffect(()=>()=>k.current(Date.now()),[]);const A=ae(t==null?void 0:t.browsers),R=((t==null?void 0:t.browsers)??[]).filter(m=>!(m.installed&&m.profiles>0)),C=t?ie(t):null,W=A.reduce((m,x)=>m+x.profiles,0);return e.jsx("div",{className:"modal-backdrop",...u,role:"presentation",children:e.jsxs("div",{ref:d,className:"modal bw-modal",onClick:m=>m.stopPropagation(),role:"dialog","aria-modal":"true","aria-labelledby":"bw-title",children:[e.jsxs("header",{className:"modal-head",children:[e.jsxs("div",{className:"modal-title",children:[e.jsx("span",{className:"modal-tool-name",id:"bw-title",children:"Browser watch"}),e.jsx("span",{className:"modal-tool-id",children:t?`${W} ${W===1?"profile":"profiles"} · local only`:"local only"})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{ref:N,className:"glyph-btn",onClick:()=>void y(!0),...re(i),"aria-label":"Re-read every profile now",title:"Re-read every profile now",children:i?"…":"↻"}),e.jsx("button",{className:"glyph-btn",onClick:s,"aria-label":"Close (Esc)",title:"Close (Esc)",children:"×"})]})]}),e.jsxs("div",{className:"modal-body bw-body",children:[!t&&!n&&e.jsxs("div",{className:"bw-loading",children:[e.jsx("span",{className:"bw-loading-bar","aria-hidden":!0}),e.jsx("p",{children:"Reading each browser's history. The first look copies the file, which takes a moment."})]}),n&&e.jsx("div",{className:"bw-state",children:e.jsxs("div",{className:"bw-row err",children:[e.jsx("span",{className:"bw-dot","aria-hidden":!0}),e.jsx("span",{className:"bw-row-label",children:"Could not read"}),e.jsx("span",{className:"bw-row-detail",children:n})]})}),t&&C&&e.jsx("p",{className:`bw-trouble ${C.kind}`,role:"status",children:C.text}),t&&e.jsxs("div",{className:"bw-work",children:[e.jsxs("aside",{className:"bw-side",children:[e.jsx(me,{snap:t,watching:A,palette:c}),e.jsx(be,{watching:A,rest:R}),t.relay&&e.jsx(fe,{relay:t.relay})]}),e.jsxs("div",{className:"bw-main",children:[e.jsx(de,{snap:t,dismiss:j,refreshRef:N}),e.jsx(oe,{snap:t})]})]}),t&&S&&e.jsx(pe,{snap:t,quiet:w,setQuiet:b,save:P,access:v,setAccess:$}),l&&e.jsx("div",{className:"bw-state bw-write-err",role:"alert",children:e.jsxs("div",{className:"bw-row err",children:[e.jsx("span",{className:"bw-dot","aria-hidden":!0}),e.jsx("span",{className:"bw-row-label",children:"Could not save that setting"}),e.jsxs("span",{className:"bw-row-detail",children:[l," — the switches below show what is stored, not what you pressed."]}),e.jsx("button",{className:"glyph-btn bw-write-err-x",onClick:()=>o(null),"aria-label":"Dismiss",title:"Dismiss",children:"×"})]})}),t&&e.jsx(ge,{snap:t,saving:p,save:P,why:S,setWhy:g})]})]})})}export{ye as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e,r as a,z as ss,A as ns,B as ts,u as is,d as rs,C as os}from"./index-ChuHd6Ho.js";const as={radar:e.jsxs(e.Fragment,{children:[e.jsx("path",{d:"M20 12a8 8 0 1 1-8-8v8l5-5"}),e.jsx("path",{d:"M12 8a4 4 0 1 0 4 4"}),e.jsx("circle",{cx:"12",cy:"12",r:"1"})]}),connection:e.jsxs(e.Fragment,{children:[e.jsx("path",{d:"M8 8h8v8H8zM12 3v5M12 16v5M3 12h5M16 12h5"}),e.jsx("circle",{cx:"12",cy:"3",r:"1"}),e.jsx("circle",{cx:"21",cy:"12",r:"1"})]}),logs:e.jsxs(e.Fragment,{children:[e.jsx("rect",{x:"5",y:"3",width:"14",height:"18",rx:"2"}),e.jsx("path",{d:"M9 8h6M9 12h6M9 16h3"})]}),metrics:e.jsx(e.Fragment,{children:e.jsx("path",{d:"M4 20h16M7 16v-5M12 16V4M17 16V8"})}),traces:e.jsxs(e.Fragment,{children:[e.jsx("path",{d:"M7 5h10M7 12h10M7 19h10M12 5v14"}),e.jsx("circle",{cx:"7",cy:"5",r:"2"}),e.jsx("circle",{cx:"17",cy:"12",r:"2"}),e.jsx("circle",{cx:"7",cy:"19",r:"2"})]}),info:e.jsxs(e.Fragment,{children:[e.jsx("circle",{cx:"12",cy:"12",r:"9"}),e.jsx("path",{d:"M12 11v5M12 7h.01"})]})};function G({kind:s,...t}){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",...t,children:as[s]})}function de({className:s="",children:t,...r}){return e.jsxs("span",{className:"tr-select-wrap",children:[e.jsx("select",{...r,className:`tr-select${s?` ${s}`:""}`,children:t}),e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:e.jsx("path",{d:"m6 9 6 6 6-6"})})]})}function Ve(s){return[...new Set(s.filter(t=>t.key.endsWith("ENDPOINT")).map(t=>t.value).filter(t=>/^https?:\/\//.test(t)))]}function He(s){return(s==null?void 0:s.status)!=="observing"?[]:[...new Set(s.connections.filter(t=>t.active===!0).map(t=>t.destination))]}function Be(s){try{const t=new URL(s);return/^\d+\.\d+\.\d+\.\d+$/.test(t.hostname)?`${t.hostname}:${t.port||(t.protocol==="https:"?"443":"80")}`:null}catch{return null}}function ls(s){const t=s.filter(r=>r.key==="CLAUDE_CODE_ENABLE_TELEMETRY").map(r=>r.value);return t.length?new Set(t).size>1?"Conflicting settings":t[0]==="Enabled"?"Enabled in settings":t[0]==="Disabled"?"Disabled in settings":"Unknown":"Unknown"}function cs(s){const t=s.replace(/^\uFEFF/,"").trim();if(!t)return[];let r;try{JSON.parse(t),r=[t]}catch{r=s.replace(/^\uFEFF/,"").split(/\r?\n/)}if(r.length>1e4)throw new Error("This file has more than 10,000 lines. Choose a smaller export.");return r.flatMap((o,c)=>{var g;if(!o.trim())return[];try{const x=JSON.parse(o),d=x&&typeof x=="object"?x:{},h=new Set,i=[x];for(;i.length;){const v=i.pop();if(!v||typeof v!="object")continue;if(Array.isArray(v)){for(const l of v)i.push(l);continue}const p=v;for(const l of["session.id","session_id","sessionId"])typeof p[l]=="string"&&h.add(p[l]);if(["session.id","session_id"].includes(String(p.key))){const l=p.value;typeof(l==null?void 0:l.stringValue)=="string"&&h.add(l.stringValue)}for(const l of Object.values(p))i.push(l)}return[{line:c+1,raw:o,sessionIds:[...h],label:String(d.eventName??((g=d.event)==null?void 0:g.name)??d.type??d.model??"JSON record").slice(0,160),sessionId:typeof(d.session_id??d.sessionId??d["session.id"])=="string"?d.session_id??d.sessionId??d["session.id"]:null,timestamp:typeof d.timestamp=="string"?d.timestamp:null,valid:!0}]}catch{return[{line:c+1,raw:o,label:"Invalid JSON",sessionId:null,timestamp:null,sessionIds:[],valid:!1}]}})}function ds(){const[s,t]=a.useState(null),[r,o]=a.useState(!1);return a.useEffect(()=>{let c=!0,g,x=null;const d=()=>document.visibilityState!=="hidden",h=()=>{clearTimeout(g),x==null||x.abort(),x=null},i=async()=>{if(!c||!d()||x)return;const p=new AbortController;x=p;try{const l=await fetch("/api/system/traffic-radar",{signal:p.signal});if(!l.ok)throw new Error("radar_unavailable");const y=await l.json();if(!y.ok)throw new Error("radar_unavailable");c&&!p.signal.aborted&&(t(y),o(!1))}catch{c&&!p.signal.aborted&&o(!0)}finally{x===p&&(x=null),c&&!p.signal.aborted&&d()&&(g=setTimeout(i,5e3))}},v=()=>{h(),document.visibilityState!=="hidden"&&i()};return i(),document.addEventListener("visibilitychange",v),()=>{c=!1,h(),document.removeEventListener("visibilitychange",v)}},[]),{snapshot:s,failed:r}}function hs(){const[s,t]=a.useState(null),[r,o]=a.useState(!1),[c,g]=a.useState(!1),[x,d]=a.useState(""),[h,i]=a.useState(""),[v,p]=a.useState([]),[l,y]=a.useState(null),[w,R]=a.useState(null),C=a.useRef(null),D=a.useRef(null),S=a.useRef(0);a.useEffect(()=>{let j=!0,m,b=null;const _=()=>document.visibilityState!=="hidden",T=()=>{clearTimeout(m),b==null||b.abort(),b=null},O=async()=>{if(!j||!_()||b)return;if(C.current){m=setTimeout(O,1e3);return}const B=S.current,P=new AbortController;b=P;try{const z=await fetch("/api/system/traffic-radar/capture",{signal:P.signal});if(!z.ok)throw new Error;const A=await z.json();j&&!P.signal.aborted&&B===S.current&&(t(A),o(!1))}catch{j&&!P.signal.aborted&&B===S.current&&o(!0)}finally{b===P&&(b=null),j&&!P.signal.aborted&&_()&&(m=setTimeout(O,1e3))}},J=()=>{T(),document.visibilityState!=="hidden"&&O()};return O(),document.addEventListener("visibilitychange",J),()=>{var B;j=!1,T(),(B=D.current)==null||B.abort(),document.removeEventListener("visibilitychange",J)}},[]);const u=async(j,m)=>{if(!ss(C.current))return;S.current++,C.current=j,R(j),g(!0),d("");const b=new AbortController;D.current=b;const _=setTimeout(()=>b.abort(),2e4);try{const T=await fetch(`/api/system/traffic-radar/capture/${j}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({destination:m}),signal:b.signal}),O=await T.json();if(!T.ok)throw new Error(O.error||"Capture action failed. Please retry.");j==="prepare"&&(i(O.command),p(O.commands??[{destination:String(m),command:O.command}]),y(O.sessionId)),j==="stop"&&(i(""),p([]));const J=await fetch("/api/system/traffic-radar/capture",{signal:b.signal});J.ok&&(t(await J.json()),o(!1))}catch(T){d(T instanceof Error?T.message:"Capture action failed. Please retry.")}finally{clearTimeout(_),D.current=null,C.current=null,R(null),g(!1)}};return{capture:s,failed:r,busy:c,pendingAction:w,error:x,commands:(s==null?void 0:s.sessionId)===l?v:[],command:(s==null?void 0:s.sessionId)===l?h:"",action:u}}const be=50,ms=2e5;function Ue({name:s}){return e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"tr-json-key",children:typeof s=="string"?JSON.stringify(s):s}),": "]})}function We({value:s,name:t,root:r=!1}){if(s!==null&&typeof s=="object")return e.jsx(us,{value:s,name:t,root:r});const o=s===null?"null":typeof s;return e.jsxs("div",{children:[t!==void 0&&e.jsx(Ue,{name:t}),e.jsx("span",{className:`tr-json-${o}`,children:JSON.stringify(s)})]})}function us({value:s,name:t,root:r}){const[o,c]=a.useState(r),[g,x]=a.useState(be),d=Array.isArray(s),h=a.useMemo(()=>Array.isArray(s)?null:Object.keys(s),[s]),i=d?s.length:h.length,v=Math.min(g,i);return e.jsxs("details",{open:o,onToggle:p=>{p.target===p.currentTarget&&c(p.currentTarget.open)},children:[e.jsxs("summary",{children:[t!==void 0&&e.jsx(Ue,{name:t}),e.jsxs("span",{children:[d?"[":"{",i===0?d?"]":"}":"…"]}),i>0&&e.jsxs("span",{className:"tr-count",children:[i," ",d?i===1?"item":"items":i===1?"key":"keys"]})]}),o&&i>0&&e.jsxs("div",{children:[Array.from({length:v},(p,l)=>{const y=h?h[l]:l,w=Array.isArray(s)?s[l]:s[y];return e.jsx(We,{name:y,value:w},y)}),v<i&&e.jsxs("button",{type:"button",className:"btn",onClick:()=>x(p=>p+be),children:["Show ",Math.min(be,i-v)," more (",i-v," remaining)"]}),e.jsx("div",{children:d?"]":"}"})]})]})}function xs({value:s}){const t=a.useMemo(()=>{const r=JSON.stringify(s,null,2);if(r.length>ms)return r;const o=[],c=/"(?:\\.|[^"\\])*"(\s*:)?|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|\b(?:true|false|null)\b/g;let g=0;for(const x of r.matchAll(c)){const d=x.index;d>g&&o.push(r.slice(g,d));const h=x[0],i=x[1]||"",v=i?"key":h[0]==='"'?"string":h==="null"?"null":h==="true"||h==="false"?"boolean":"number";o.push(e.jsx("span",{className:`tr-json-${v}`,children:i?h.slice(0,-i.length):h},d)),i&&o.push(i),g=d+h.length}return g<r.length&&o.push(r.slice(g)),o},[s]);return e.jsx("pre",{className:"tr-value",children:t})}function js({value:s,initialMode:t="tree"}){const[r,o]=a.useState(t);return e.jsxs("div",{children:[e.jsxs("div",{className:"tr-detail-tabs",role:"group","aria-label":"JSON view",children:[e.jsx("button",{type:"button",className:"btn","aria-pressed":r==="tree",onClick:()=>o("tree"),children:"Tree"}),e.jsx("button",{type:"button",className:"btn","aria-pressed":r==="raw",onClick:()=>o("raw"),children:"Raw JSON"})]}),r==="raw"?e.jsx(xs,{value:s}):e.jsx("div",{className:"tr-value tr-json-tree",children:e.jsx(We,{value:s,root:!0})})]})}function ps(s,t=!1){var v,p,l,y;const r=!!s&&(s.enabled??["awaiting","receiving","capturing"].includes(s.state)),o=((v=s==null?void 0:s.sources)==null?void 0:v.filter(w=>w.active).length)??0,c=!!((p=s==null?void 0:s.sources)!=null&&p.some(w=>/permission/i.test(w.error??""))),g=(s==null?void 0:s.events.length)??0,x=((l=s==null?void 0:s.observations)==null?void 0:l.length)??0,d=!!(s!=null&&s.bytes)||x>0||g>0;let h="Monitoring stopped",i="neutral";return t?(h="Monitor connection lost",i="error"):s?s.state==="error"?(h="Capture error",i="error"):r&&o>0&&o<(((y=s.sources)==null?void 0:y.length)??0)?(h="Listening to some destinations",i="attention"):r&&c?(h="Capture permission needed",i="attention"):r&&s.state==="interrupted"?(h="Reconnecting capture…",i="attention"):r&&(o||!s.managed&&["receiving","capturing"].includes(s.state))?(h="Listening for telemetry",i="ok"):r&&(h=s.managed?"Starting monitoring…":"Activation needed"):h="Reading monitor…",{enabled:r,active:o,permission:c,decoded:g,observed:x,traffic:d,title:h,tone:i}}const I=s=>s&&typeof s=="object"&&!Array.isArray(s)?s:{},q=s=>Array.isArray(s)?s:[],ce=s=>new Date(s).toLocaleTimeString(),fs=s=>({unconfirmed:"Transfer observed · receipt unconfirmed",accepted:"Collector accepted",partial:"Collector reported partial success",rejected:"Collector rejected",unknown:"Response incomplete",reset:"Stream reset"})[s.outcome],ye={encrypted:"Encrypted traffic observed; contents cannot be read.",joined_midstream:"Capture joined an existing connection. Waiting for a new HTTP/2 connection to decode it reliably.",capture_gap:"Incomplete packets or a gap were observed. Affected contents are not shown as decoded.",decode_failed:"Some payloads could not be decoded. They are not shown as verified events.",payload_limit:"A payload exceeded the inspection limit and was omitted.",stream_limit:"A stream exceeded the inspection limit.",connection_limit:"The connection inspection limit was reached.",unsupported_compression:"A compression format other than gzip was observed.",unsupported_link:"This network capture format is not supported.",unsupported_network:"Some packets used a network protocol this decoder does not support.",fragmented:"Fragmented IP packets cannot be decoded in this version.",unknown_export:"A request could not be identified as an OTLP export.",connection_closed:"An HTTP/2 connection closed.",idle_connection:"An idle connection was removed from the decoder."};function he(s){const t=I(s);for(const r of["stringValue","intValue","doubleValue","boolValue","bytesValue"])if(t[r]!==void 0)return t[r];return t.arrayValue?q(I(t.arrayValue).values).map(he):t.kvlistValue?Object.fromEntries(q(I(t.kvlistValue).values).map(r=>{const o=I(r);return[String(o.key),he(o.value)]})):null}function gs(s){return/prompt/i.test(s)?"Prompt-related field included in this export.":/response|completion/i.test(s)?"Response-related field included in this export.":/tool/i.test(s)?"Tool-related field included in this export.":/session/i.test(s)?"Session identifier or session metadata.":/user|email|account/i.test(s)?"User or account metadata.":/token|cost|duration|latency/i.test(s)?"Usage or timing measurement.":"Attribute included in this export."}function ee({value:s}){return e.jsx("pre",{className:"tr-value",children:typeof s=="string"?s:JSON.stringify(s,null,2)})}function Ne({value:s}){return e.jsx("dl",{className:"tr-attributes",children:q(s).map((t,r)=>{const o=I(t);return e.jsxs("div",{children:[e.jsxs("dt",{children:[e.jsx("code",{children:String(o.key??"Unnamed attribute")}),e.jsx("span",{children:gs(String(o.key))})]}),e.jsx("dd",{children:e.jsx(ee,{value:he(o.value)})})]},r)})})}function vs({record:s}){const t=["gauge","sum","histogram","exponentialHistogram","summary"].find(r=>s[r]);return t?e.jsxs("div",{children:[s.description&&e.jsx("p",{className:"tr-note",children:String(s.description)}),q(I(s[t]).dataPoints).map((r,o)=>{const c=I(r);return e.jsxs("section",{children:[e.jsxs("dl",{className:"tr-facts",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Measurement"}),e.jsx("dd",{children:t})]}),c.asInt!==void 0||c.asDouble!==void 0?e.jsxs("div",{children:[e.jsx("dt",{children:"Value"}),e.jsx("dd",{children:e.jsxs("code",{children:[String(c.asInt??c.asDouble)," ",String(s.unit??"")]})})]}):null,c.count!==void 0&&e.jsxs("div",{children:[e.jsx("dt",{children:"Count"}),e.jsx("dd",{children:e.jsx("code",{children:String(c.count)})})]}),c.sum!==void 0&&e.jsxs("div",{children:[e.jsx("dt",{children:"Sum"}),e.jsx("dd",{children:e.jsxs("code",{children:[String(c.sum)," ",String(s.unit??"")]})})]})]}),e.jsx(Ne,{value:c.attributes}),e.jsxs("details",{className:"tr-details",children:[e.jsx("summary",{children:"All measurement fields"}),e.jsx(ee,{value:c})]})]},o)})]}):null}function bs({record:s}){let t=null;try{t=`${Number(BigInt(String(s.endTimeUnixNano))-BigInt(String(s.startTimeUnixNano)))/1e6} ms`}catch{t=null}return e.jsxs("dl",{className:"tr-facts",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Duration"}),e.jsx("dd",{children:t??"Not included"})]}),s.kind&&e.jsxs("div",{children:[e.jsx("dt",{children:"Span kind"}),e.jsx("dd",{children:String(s.kind)})]}),s.status&&e.jsxs("div",{children:[e.jsx("dt",{children:"Span status"}),e.jsx("dd",{children:e.jsx(ee,{value:s.status})})]})]})}function ys({payload:s,signal:t}){const r=t==="traces"?"Spans":t==="logs"?"Logs":"Metrics",o=t==="traces"?"spans":t==="logs"?"logRecords":"metrics";return e.jsx("div",{className:"tr-decoded",children:q(s["resource"+r]).map((c,g)=>{const x=I(c);return e.jsxs("section",{children:[e.jsxs("details",{className:"tr-details",children:[e.jsx("summary",{children:"Resource metadata"}),e.jsx(Ne,{value:I(x.resource).attributes})]}),q(x["scope"+r]).map((d,h)=>{const i=I(d);return e.jsxs("div",{children:[i.scope&&e.jsxs("p",{className:"tr-note",children:["Instrumentation: ",String(I(i.scope).name??"Unnamed")," ",String(I(i.scope).version??"")]}),q(i[o]).map((v,p)=>{const l=I(v);return e.jsxs("article",{className:"tr-record",children:[e.jsx("h4",{children:String(l.eventName??l.name??`${t==="logs"?"Log record":"Record"} ${p+1}`)}),l.body&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"tr-note",children:"Event body"}),e.jsx(ee,{value:he(l.body)})]}),t==="metrics"&&e.jsx(vs,{record:l}),t==="traces"&&e.jsx(bs,{record:l}),l.attributes&&e.jsx(Ne,{value:l.attributes}),e.jsxs("details",{className:"tr-details",children:[e.jsx("summary",{children:"All record fields"}),e.jsx(ee,{value:l})]})]},p)})]},h)})]},g)})})}function Ns({capture:s,radar:t,failed:r,busy:o,pendingAction:c=null,error:g,command:x,commands:d=[],action:h,sessionFilter:i="all",sessions:v=[]}){var Ee,Ae,Oe,Le,Me,Ie,Re,_e,De,Pe,$e,Fe;const p=Ve(((Ee=t==null?void 0:t.config)==null?void 0:Ee.variables)??[]),l=[...new Set(p.map(Be).filter(n=>!!n))],y=He(t).filter(n=>!l.includes(n)&&Be(`http://${n}`)),[w,R]=a.useState("all"),[C,D]=a.useState(""),[S,u]=a.useState(null),[j,m]=a.useState(null),[b,_]=a.useState("all"),[T,O]=a.useState("all"),[J,B]=a.useState(100),[P,z]=a.useState(null),[A,me]=a.useState(null),[$,se]=a.useState(null),[Y,re]=a.useState(!1),we=a.useRef(0),[ue,Se]=a.useState("summary"),[L,xe]=a.useState(null),[Ce,Ge]=a.useState(0),ne=a.useRef(null),K=(s==null?void 0:s.events)??[],qe=new Map(K.map(n=>[n.id,n])),je=A?A.map(n=>qe.get(n.id)).filter(n=>!!n):K,V=je.filter(n=>{var f,k;return(T==="all"||n.signal===T)&&(b==="all"||b===n.destination)&&(i==="all"||(i==="unidentified"?!((f=n.sessionIds)!=null&&f.length):(k=n.sessionIds)==null?void 0:k.includes(i)))}),H=((s==null?void 0:s.observations)??[]).filter(n=>(P===null||P.includes(n.id))&&T==="all"&&(i==="all"||i==="unidentified")&&(b==="all"||b===n.destination)),M=H.find(n=>n.id===S),N=S!==null?void 0:j===null?V[0]:V.find(n=>n.id===j),te=[...V.map(n=>({kind:"export",event:n})),...H.map(n=>({kind:"observation",event:n}))].sort((n,f)=>f.event.at-n.event.at||f.event.id-n.event.id),ze=new Set(A==null?void 0:A.map(n=>n.id)),Ye=new Set(P),pe=A===null?0:K.filter(n=>!ze.has(n.id)).length+((s==null?void 0:s.observations)??[]).filter(n=>!Ye.has(n.id)).length,ie=N==null?void 0:N.id;a.useEffect(()=>{m(null),u(null),B(100)},[i,T,b]),a.useEffect(()=>{j!==null||S!==null||(V.length?m(V[0].id):H.length&&u(H[0].id))},[(Ae=V[0])==null?void 0:Ae.id,(Oe=H[0])==null?void 0:Oe.id,j,S]),a.useEffect(()=>{if(xe(null),se(null),ie===void 0)return;const n=new AbortController;let f=!0;const k=setTimeout(()=>n.abort(),5e3);return fetch(`/api/system/traffic-radar/capture/event?id=${ie}`,{signal:n.signal}).then(async E=>{if(!E.ok)throw new Error("This message has expired. Select a newer message.");const W=await E.json();f&&!n.signal.aborted&&xe({id:ie,payload:W.payload})}).catch(E=>{f&&xe({id:ie,error:n.signal.aborted?"Loading timed out. Try again.":E instanceof Error?E.message:"Could not read this message."})}).finally(()=>clearTimeout(k)),()=>{f=!1,clearTimeout(k),n.abort()}},[ie,S,Ce]),a.useEffect(()=>{if(!$||$==="failed")return;const n=setTimeout(()=>se(null),2e3);return()=>clearTimeout(n)},[$]),a.useEffect(()=>{if(!Y)return;const n=setTimeout(()=>re(!1),5e3);return()=>clearTimeout(n)},[Y]);const oe=(s==null?void 0:s.shell)??((t==null?void 0:t.platform)==="win32"?"PowerShell":"Terminal"),fe=oe==="PowerShell",U=ps(s,r),F=U.enabled,Z=!!(s!=null&&s.managed),Ke=Z&&U.permission,ae=U.active,Q=((Le=s==null?void 0:s.sources)==null?void 0:Le.length)??1,Ze=U.title,X=n=>{const f=ts(c??(o?"capture":null),n);return{disabled:f.disabled,"aria-busy":f.busy}},Qe=n=>{var f,k,E;u(null),m(n.id),typeof window<"u"&&((f=window.matchMedia)!=null&&f.call(window,"(max-width: 640px)").matches)&&((k=ne.current)==null||k.focus({preventScroll:!0}),(E=ne.current)==null||E.scrollIntoView({block:"start",behavior:"auto"}))},Xe=()=>{const n=Date.now(),f=ns({armedFor:Y?"history":null,target:"history",armedAt:we.current,now:n,gapMs:350});if(f==="arm"){we.current=n,re(!0);return}f!=="ignore"&&(re(!1),m(null),u(null),me(null),z(null),h("clear"))},ke=()=>{var f;se(null),me(null),z(null),m(null),u(null);const n=w==="custom"?[C.trim()]:w==="all"?l:[w];h("prepare",n.length?n:((f=s==null?void 0:s.sources)==null?void 0:f.map(k=>k.destination))??(s!=null&&s.destination?[s.destination]:[]))},ge=d.length?d:x?[{destination:(s==null?void 0:s.destination)??"Collector",command:x}]:[],le=async(n,f)=>{try{await navigator.clipboard.writeText(n),se(f)}catch{se("failed")}},Te=(n=[])=>n.length?n.map(f=>{var k;return`${((k=v.find(E=>E.id===f))==null?void 0:k.label)??"Session"} · ${f.slice(0,8)}`}).join(", "):"Unidentified session",es=new Set([...((Me=s==null?void 0:s.sources)==null?void 0:Me.map(n=>n.destination))??[],...l]),ve=(t==null?void 0:t.status)==="observing"?t.connections.filter(n=>n.active&&es.has(n.destination)):[];return e.jsxs("div",{className:"tr-telemetry",children:[e.jsxs("div",{className:"tr-capture-bar",children:[e.jsxs("div",{children:[e.jsxs("h3",{role:"status","aria-live":"polite",children:[e.jsx("span",{className:`tr-live-dot tr-dot-${U.tone}`}),Ze]}),e.jsx("p",{className:"tr-note",children:r?"Showing the last successful read. Reconnecting automatically.":F?ae?`${ae} of ${Q} destination${Q===1?"":"s"} listening · ${U.traffic?"Traffic observed":"No traffic observed yet"}`:"Monitoring is enabled; the listener is not ready yet.":"Start Radar to inspect new collector traffic. Claude settings stay unchanged."}),F&&e.jsxs("div",{className:"tr-active-destinations",role:"group","aria-label":"Monitored destinations",children:[e.jsxs("span",{children:["Destination",Q>1?"s":""]}),(Ie=s==null?void 0:s.sources)!=null&&Ie.length?s.sources.map(n=>e.jsxs("span",{className:"tr-destination-entry",children:[e.jsx("code",{children:n.destination}),(Q>1||!n.active)&&e.jsx("span",{className:n.active?"tr-source-ready":"tr-source-pending",children:n.active?"Listening":"Not listening"}),!n.active&&n.error&&e.jsx("span",{className:"tr-source-error",children:n.error})]},n.destination)):(s==null?void 0:s.destination)&&e.jsx("code",{children:s.destination})]})]}),e.jsxs("div",{className:"tr-capture-actions",children:[F?e.jsx("button",{className:"btn",...X("stop"),onClick:()=>void h("stop"),children:"Stop monitoring"}):e.jsx("button",{className:"btn primary",...X("prepare"),disabled:X("prepare").disabled||!s||r||(t==null?void 0:t.status)==="unsupported"||w==="all"&&!l.length||w==="custom"&&!C.trim(),onClick:ke,children:c==="prepare"?"Starting…":"Start monitoring"}),e.jsx("button",{className:Y?"btn danger armed":"btn",...X("clear"),disabled:X("clear").disabled||!(s!=null&&s.events.length)&&!((Re=s==null?void 0:s.observations)!=null&&Re.length),title:Y?"Remove decoded messages and observations. Monitoring continues.":"Clear retained messages and connection observations",onBlur:()=>re(!1),onClick:Xe,children:Y?"Confirm clear history":"Clear history"})]})]}),!F&&e.jsxs("div",{className:"tr-destination",children:[e.jsxs("label",{children:["Destination",e.jsxs(de,{"aria-label":"Capture destination",value:w,onChange:n=>R(n.target.value),children:[e.jsxs("option",{value:"all",children:["All configured IPv4 destinations (",l.length,")"]}),l.map(n=>e.jsx("option",{value:n,children:n},n)),y.length>0&&e.jsx("optgroup",{label:"Observed Claude connections · telemetry unverified",children:y.map(n=>e.jsxs("option",{value:n,children:[n," · observed"]},n))}),e.jsx("option",{value:"custom",children:"Another IPv4 address…"})]})]}),w==="custom"&&e.jsx("input",{className:"tr-input","aria-label":"Collector IPv4 and port",value:C,onChange:n=>D(n.target.value),placeholder:"192.168.1.10:4317"}),!l.length&&w==="all"&&e.jsx("span",{className:"tr-note",children:y.length?"Choose an observed connection or enter your collector address.":"Enter your collector address to monitor traffic. Missing settings do not mean telemetry is off."})]}),(t==null?void 0:t.status)==="unsupported"&&e.jsx("p",{className:"tr-capture-error",role:"status",children:"Live capture is available on macOS, Linux and Windows. You can still inspect a local file."}),g&&e.jsxs("p",{className:"tr-capture-error",role:"alert",children:[g,fe&&g.includes("Npcap")&&e.jsxs(e.Fragment,{children:[" ",e.jsx("a",{href:"https://www.wireshark.org/download.html",target:"_blank",rel:"noreferrer",children:"Get Wireshark"})]})]}),!Z&&F&&!ge.length&&(s==null?void 0:s.state)==="awaiting"&&e.jsxs("div",{className:"tr-activation",children:[e.jsx("p",{children:"Activation is pending. Generate the Terminal instructions again to continue."}),e.jsx("button",{className:"btn",...X("prepare"),onClick:ke,children:"Show activation instructions"}),e.jsx("p",{className:"tr-note",children:"The previous token will be invalidated."})]}),!Z&&ge.length>0&&F&&e.jsxs("details",{className:"tr-activation",open:!ae,children:[e.jsxs("summary",{children:["Activate in ",oe,Q>1?` · ${ae}/${Q} listening`:""]}),e.jsx("p",{children:fe?"Run each command in a separate PowerShell tab. Wireshark with Npcap is required; use an administrator tab if Npcap restricts capture.":"Run each command in a separate Terminal tab. Only tcpdump asks for administrator permission."}),ge.map(n=>e.jsxs("div",{className:"tr-command-entry",children:[e.jsxs("div",{children:[e.jsx("code",{children:n.destination}),e.jsx("button",{className:"btn",onClick:()=>void le(n.command,n.destination),children:$===n.destination?"Copied":"Copy command"})]}),e.jsx("pre",{className:"tr-command",children:n.command})]},n.destination)),e.jsxs("p",{className:"tr-note",children:["Press Ctrl+C in each ",oe," tab to stop capture. Monitoring continues until you stop it. Commands contain a local token; do not share them."]})]}),Ke&&e.jsxs("div",{className:"tr-activation",role:"status",children:[e.jsx("strong",{children:"Allow packet capture once"}),e.jsxs("p",{className:"tr-note",children:[fe?"Npcap is restricting access. Allow this user to capture traffic in Npcap setup.":(s==null?void 0:s.platform)==="darwin"?"Install Wireshark’s ChmodBPF permission helper to allow capture without a Terminal command.":"Grant tcpdump packet capture permissions for this user."," ccdeck retries automatically when access is available."]}),e.jsx("a",{href:"https://wiki.wireshark.org/CaptureSetup/CapturePrivileges",target:"_blank",rel:"noreferrer",children:"Capture permission setup"})]}),$==="failed"&&e.jsx("p",{className:"tr-capture-error",role:"alert",children:"Clipboard unavailable. Select the text and copy it manually."}),e.jsxs("div",{className:"tr-workspace",children:[e.jsxs("section",{className:"tr-feed","aria-label":"Collector activity",children:[e.jsxs("div",{className:"tr-feed-head",children:[e.jsxs("h3",{children:["Activity ",e.jsx("span",{className:"tr-count",children:te.length})]}),e.jsx("button",{className:"btn","aria-pressed":A!==null,title:A?"Show new entries received while the list was paused":"Freeze the list while monitoring continues",disabled:!je.length&&!H.length&&A===null,onClick:()=>{me(A?null:[...je]),z(A?null:((s==null?void 0:s.observations)??[]).map(n=>n.id))},children:A?"Resume list":"Pause list"})]}),e.jsxs("p",{className:"tr-history",children:["Last 24 hours · ",V.length," decoded ",V.length===1?"message":"messages"," · ",H.length," ",H.length===1?"observation":"observations"]}),e.jsxs("div",{className:"tr-filter",children:[e.jsxs("label",{children:["Type",e.jsxs(de,{"aria-label":"Message type",value:T,onChange:n=>{m(null),O(n.target.value)},children:[e.jsx("option",{value:"all",children:"All types"}),e.jsx("option",{value:"logs",children:"Events"}),e.jsx("option",{value:"metrics",children:"Metrics"}),e.jsx("option",{value:"traces",children:"Traces"})]})]}),e.jsxs("label",{children:["To",e.jsxs(de,{"aria-label":"Message destination",value:b,onChange:n=>{m(null),_(n.target.value)},children:[e.jsx("option",{value:"all",children:"All destinations"}),[...new Set([...l,...((_e=s==null?void 0:s.sources)==null?void 0:_e.map(n=>n.destination))??[],...K.map(n=>n.destination),...((s==null?void 0:s.observations)??[]).map(n=>n.destination)])].map(n=>e.jsx("option",{value:n,children:n},n))]})]})]}),A&&e.jsxs("p",{className:"tr-list-notice",role:"status",children:["List paused · Monitoring continues",pe>0?` · ${pe} new ${pe===1?"entry":"entries"}`:""]}),(De=s==null?void 0:s.retention)!=null&&De.evictedExports?e.jsxs("p",{className:"tr-note",children:[s.retention.evictedExports.toLocaleString()," older messages removed by history limits."]}):null,te.length?e.jsx("ul",{className:"tr-connections",onKeyDown:n=>{var Je;if(!["ArrowDown","ArrowUp","Home","End"].includes(n.key))return;const f=Array.from(n.currentTarget.querySelectorAll(".tr-message")),k=f.indexOf(document.activeElement);if(k<0)return;n.preventDefault();const E=n.key==="Home"?0:n.key==="End"?f.length-1:Math.max(0,Math.min(f.length-1,k+(n.key==="ArrowDown"?1:-1))),W=te[E];W&&(m(W.kind==="export"?W.event.id:null),u(W.kind==="observation"?W.event.id:null)),(Je=f[E])==null||Je.focus()},children:te.slice(0,J).map(n=>n.kind==="export"?e.jsx("li",{children:e.jsxs("button",{className:"tr-message","aria-pressed":(N==null?void 0:N.id)===n.event.id,onClick:()=>Qe(n.event),children:[e.jsx(G,{kind:n.event.signal,className:"tr-row-icon"}),e.jsxs("span",{className:"tr-event-top",children:[e.jsx("strong",{className:"tr-event-name",children:n.event.name}),e.jsx("time",{dateTime:new Date(n.event.at).toISOString(),children:ce(n.event.at)})]}),e.jsxs("span",{className:"tr-event-context",children:[e.jsx("span",{className:"tr-signal",children:n.event.signal==="logs"?"Decoded event":n.event.signal==="metrics"?"Decoded metric":"Decoded trace"}),e.jsx("span",{children:Te(n.event.sessionIds)})]}),e.jsx("code",{className:"tr-event-destination",children:n.event.destination}),e.jsxs("span",{className:"tr-event-bottom",children:[e.jsx("span",{className:`tr-receipt ${n.event.outcome==="accepted"?"tr-tone-ok":n.event.outcome==="rejected"?"tr-tone-error":n.event.outcome==="partial"?"tr-tone-enabled":""}`,children:n.event.outcome==="accepted"?"Accepted":n.event.outcome==="unconfirmed"?"Receipt unconfirmed":n.event.outcome==="partial"?"Partially accepted":n.event.outcome==="rejected"?"Rejected":"Receipt unknown"}),e.jsxs("span",{children:[n.event.count," ",n.event.count===1?"record":"records"]})]})]})},`event-${n.event.id}`):e.jsx("li",{children:e.jsxs("button",{className:"tr-message","aria-pressed":S===n.event.id,onClick:()=>{var f,k,E;m(null),u(n.event.id),(f=window.matchMedia)!=null&&f.call(window,"(max-width: 640px)").matches&&((k=ne.current)==null||k.focus({preventScroll:!0}),(E=ne.current)==null||E.scrollIntoView({block:"start",behavior:"auto"}))},children:[e.jsx(G,{kind:"connection",className:"tr-row-icon"}),e.jsxs("span",{className:"tr-event-top",children:[e.jsx("strong",{className:"tr-event-name",children:"Connection observed"}),e.jsx("time",{dateTime:new Date(n.event.at).toISOString(),children:ce(n.event.at)})]}),e.jsx("code",{className:"tr-event-destination",children:n.event.destination}),e.jsx("span",{children:n.event.reason==="encrypted"?"Encrypted contents":"Contents not decoded"})]})},`observation-${n.event.id}`))}):e.jsxs("div",{className:"tr-empty-capture",children:[e.jsx("h4",{children:K.length||(Pe=s==null?void 0:s.observations)!=null&&Pe.length?"No matching activity":F?"Waiting for traffic":"Message capture is off"}),e.jsx("p",{className:"tr-note",children:K.length||($e=s==null?void 0:s.observations)!=null&&$e.length?"Try another session, type or destination.":F?"Activity appears when traffic reaches a monitored destination. Decoded messages will be identified separately.":"No messages have been captured by Radar. Claude may still be sending telemetry. Choose a destination and start monitoring to inspect new traffic."})]}),te.length>J&&e.jsx("button",{className:"btn",onClick:()=>B(n=>n+100),children:"Show older messages"}),ve.length>0&&e.jsxs("details",{className:"tr-details",children:[e.jsxs("summary",{children:["Connections to these collectors (",ve.length,")"]}),e.jsx("ul",{className:"tr-live-connections",children:ve.map(n=>e.jsxs("li",{children:[e.jsx("code",{children:n.destination}),e.jsxs("span",{children:["Claude · PID ",n.pid," · ",n.workspace??"Workspace unknown"]})]},`${n.pid}:${n.destination}`))}),e.jsx("p",{className:"tr-note",children:"A connection alone does not prove a telemetry message was sent. These connections are not filtered by session."})]})]}),e.jsx("section",{className:"tr-inspector","aria-label":"Activity inspector",ref:ne,tabIndex:-1,children:M?e.jsxs("div",{children:[e.jsx("div",{className:"tr-inspector-head",children:e.jsxs("h3",{children:[e.jsx(G,{kind:"connection"}),"Connection details"]})}),e.jsxs("dl",{className:"tr-facts",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Destination"}),e.jsxs("dd",{className:"tr-fact-copy",children:[e.jsx("code",{children:M.destination}),e.jsx("button",{className:"tr-inline-copy","aria-label":"Copy destination",onClick:()=>void le(M.destination,"destination"),title:$==="destination"?"Copied destination":"Copy destination",children:e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:$==="destination"?e.jsx("path",{d:"m5 12 4 4L19 6"}):e.jsxs(e.Fragment,{children:[e.jsx("rect",{x:"8",y:"8",width:"12",height:"12",rx:"2"}),e.jsx("path",{d:"M16 8V4H4v12h4"})]})})})]})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Observed"}),e.jsx("dd",{children:e.jsx("time",{dateTime:new Date(M.at).toISOString(),children:new Date(M.at).toLocaleString()})})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Source"}),e.jsx("dd",{children:e.jsx("code",{children:M.source||"Not identified"})})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Contents"}),e.jsx("dd",{children:M.reason==="encrypted"?"Encrypted":"Not decoded"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Session"}),e.jsx("dd",{children:"Not identified"})]})]}),e.jsxs("div",{className:"tr-inspection-limit",children:[e.jsx(G,{kind:"info"}),e.jsxs("div",{children:[e.jsx("h4",{children:M.reason==="encrypted"?"Encrypted connection":"Message contents unavailable"}),e.jsx("p",{children:M.reason==="joined_midstream"?"Radar joined an existing connection. Keep listening: new connections may allow decoding.":M.reason==="encrypted"?"Radar cannot decrypt HTTPS. Inspect the collector’s own records for the contents.":ye[M.reason]??"This connection could not be decoded."}),e.jsxs("details",{className:"tr-details",children:[e.jsx("summary",{children:"Technical details"}),e.jsx("p",{className:"tr-note",children:ye[M.reason]??"The decoder could not read this connection."}),e.jsxs("p",{className:"tr-note",children:["There is no decoded JSON or confirmed session ID for this observation. ",M.reason==="joined_midstream"&&"Already captured traffic cannot be reconstructed."]})]})]})]})]}):N?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"tr-inspector-head",children:[e.jsxs("h3",{children:[e.jsx(G,{kind:N.signal}),N.name]}),e.jsxs("p",{className:"tr-note",children:["Decoded ",N.signal==="logs"?"event":N.signal==="metrics"?"metrics":"trace"," · ",Te(N.sessionIds)," · ",ce(N.at)]})]}),e.jsxs("div",{className:"tr-detail-tabs",role:"group","aria-label":"Message format",children:[e.jsx("button",{className:"btn","aria-pressed":ue==="summary",onClick:()=>Se("summary"),children:"Overview"}),e.jsx("button",{className:"btn","aria-pressed":ue==="json",onClick:()=>Se("json"),children:"JSON"}),e.jsx("button",{className:"btn tr-copy-json",disabled:!(L!=null&&L.payload)||L.id!==N.id,onClick:()=>void le(JSON.stringify(L==null?void 0:L.payload,null,2),"json"),children:$==="json"?"Copied":"Copy JSON"})]}),(L==null?void 0:L.id)===N.id?L.payload?ue==="json"?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"tr-note",children:"Decoded OTLP fields. Unknown protobuf fields and transport headers are excluded."}),e.jsx(js,{value:L.payload})]}):e.jsxs(e.Fragment,{children:[e.jsxs("dl",{className:"tr-facts",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Destination"}),e.jsxs("dd",{className:"tr-fact-copy",children:[e.jsx("code",{children:N.destination}),e.jsx("button",{className:"tr-inline-copy","aria-label":"Copy destination",onClick:()=>void le(N.destination,"destination"),title:$==="destination"?"Copied destination":"Copy destination",children:e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:$==="destination"?e.jsx("path",{d:"m5 12 4 4L19 6"}):e.jsxs(e.Fragment,{children:[e.jsx("rect",{x:"8",y:"8",width:"12",height:"12",rx:"2"}),e.jsx("path",{d:"M16 8V4H4v12h4"})]})})})]})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Time"}),e.jsx("dd",{children:ce(N.at)})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Receipt"}),e.jsx("dd",{children:fs(N)})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Size"}),e.jsxs("dd",{children:[N.bytes.toLocaleString()," bytes · ",N.count," ",N.count===1?"record":"records"]})]}),((Fe=N.response)==null?void 0:Fe.message)&&e.jsxs("div",{children:[e.jsx("dt",{children:"Response"}),e.jsx("dd",{children:e.jsx(ee,{value:N.response.message})})]})]}),e.jsx(ys,{payload:L.payload,signal:N.signal})]}):e.jsxs("div",{role:"alert",children:[e.jsx("p",{children:L.error}),e.jsx("button",{className:"btn",onClick:()=>Ge(Ce+1),children:"Retry"})]}):e.jsx("p",{className:"tr-note",role:"status",children:"Loading message contents…"})]}):e.jsxs("div",{className:"tr-inspector-empty",children:[e.jsx("svg",{width:"40",height:"40",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.25","aria-hidden":"true",children:e.jsx("path",{d:"M8 4H5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h3M16 4h3a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3M10 8l-3 4 3 4M14 8l3 4-3 4"})}),e.jsx("h3",{children:j!==null||S!==null?"Activity no longer available":"Inspect collector activity"}),e.jsx("p",{className:"tr-note",children:j!==null||S!==null?"The selected entry is no longer retained or does not match your filter. Select another entry.":U.traffic&&!U.decoded?"Traffic has been observed, but no messages have been decoded. Select a connection observation to see what is known.":"Select an entry to inspect its metadata and any decoded contents."})]})})]}),e.jsxs("footer",{className:"tr-monitor-footer",children:[e.jsxs("span",{children:[r?"Connection interrupted":F?Z?"Continuous local monitoring":"Local capture":"Not monitoring"," · History in local memory"]}),e.jsxs("details",{children:[e.jsx("summary",{children:"Monitoring limits"}),e.jsxs("div",{children:[e.jsx("p",{children:"Plaintext IPv4 OTLP/gRPC only. HTTPS contents cannot be decoded. Traffic to the chosen addresses can come from any process, not only Claude."}),e.jsx("p",{children:"History covers the last 24 hours, up to 2,000 exports and a 32 MiB payload budget. When a limit is reached, the oldest messages are removed."}),e.jsxs("p",{children:["History stays in local memory. Restarting ccdeck or clearing messages removes it. Closing this modal does not stop capture or clear history; stopping monitoring preserves history. No capture file is written. Use Stop monitoring",!Z&&e.jsxs(e.Fragment,{children:[" and Ctrl+C in ",oe]})," to stop capture."]}),s!=null&&s.bytes?e.jsxs("p",{children:["Captured transport bytes: ",s.bytes.toLocaleString(),". This is not a decoded-message count."]}):null,Z&&e.jsx("p",{children:"Enabled monitoring resumes after a ccdeck restart; the in-memory history does not."}),Object.entries((s==null?void 0:s.issues)??{}).map(([n,f])=>e.jsxs("p",{children:[ye[n]??"An inspection limitation was observed."," (",f,")"]},n))]})]})]})]})}function ws({sessionFilter:s="all",onSessions:t}){const[r,o]=a.useState([]),[c,g]=a.useState(""),[x,d]=a.useState(""),[h,i]=a.useState(!1),[v,p]=a.useState(null),[l,y]=a.useState(""),[w,R]=a.useState(!1),C=a.useRef(0),D=async m=>{if(!m)return;const b=++C.current;d(""),i(!0),R(!1);try{if(m.size>10*1024*1024)throw new Error("Choose a file smaller than 10 MB.");const _=await m.text(),T=cs(_);if(b!==C.current)return;t==null||t([...new Set(T.flatMap(O=>O.sessionIds))]),o(T),g(m.name),p(null),y(""),T.length||d("This file is empty. Choose a JSON or JSONL telemetry file.")}catch(_){b===C.current&&d(_ instanceof Error?_.message:"Could not read this file.")}finally{b===C.current&&i(!1)}},S=r.filter(m=>(s==="all"||(s==="unidentified"?!m.sessionIds.length:m.sessionIds.includes(s)))&&(!l||m.raw.toLowerCase().includes(l.toLowerCase()))),u=S.slice(0,200),j=v===null?u[0]:S.find(m=>m.line===v);return e.jsxs("div",{className:"tr-file",children:[e.jsxs("div",{className:"tr-file-toolbar",children:[e.jsxs("div",{children:[e.jsx("h3",{children:"Inspect a telemetry file"}),e.jsx("p",{className:"tr-note",children:"Open a local JSON or JSONL file. It stays in your browser and is not uploaded."})]}),e.jsxs("label",{className:"btn tr-file-picker",children:[h?"Reading…":c?"Choose another file":"Open file",e.jsx("input",{type:"file",accept:".json,.jsonl,.ndjson,application/json","aria-label":"Open telemetry file",onChange:m=>{var b;D((b=m.target.files)==null?void 0:b[0]),m.target.value=""}})]})]}),x&&e.jsx("p",{className:"tr-capture-error",role:"alert",children:x}),e.jsxs("div",{className:"tr-workspace",children:[e.jsxs("section",{className:"tr-feed","aria-label":"File records",children:[e.jsxs("h3",{children:[c||"File records"," ",e.jsx("span",{className:"tr-count",children:S.length})]}),r.length>0&&e.jsx("input",{type:"search",className:"tr-input tr-search","aria-label":"Search file contents",placeholder:"Search contents…",value:l,onChange:m=>{y(m.target.value),p(null)}}),u.length?e.jsx("ul",{className:"tr-connections",children:u.map(m=>e.jsx("li",{children:e.jsxs("button",{className:"tr-message","aria-pressed":(j==null?void 0:j.line)===m.line,onClick:()=>{p(m.line),R(!1)},children:[e.jsxs("span",{className:"tr-event-top",children:[e.jsxs("span",{children:["Line ",m.line]}),e.jsx("span",{className:m.valid?"":"tr-tone-enabled",children:m.valid?"JSON":"Invalid JSON"})]}),e.jsx("strong",{children:m.label}),m.timestamp&&e.jsx("span",{children:m.timestamp}),e.jsx("span",{children:m.sessionIds.join(", ")||"Unidentified session"})]})},m.line))}):e.jsxs("div",{className:"tr-empty-capture",children:[e.jsx("h4",{children:r.length?"No matching records":"Your saved records, in one place"}),e.jsx("p",{className:"tr-note",children:r.length?"Try another session or search.":"Choose a file to browse its rows and inspect the original JSON. A saved file is separate from live network capture."})]}),S.length>u.length&&e.jsx("p",{className:"tr-note",children:"Showing the first 200 matching rows. Search to narrow the list."})]}),e.jsx("section",{className:"tr-inspector","aria-label":"File record contents",children:j?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"tr-feed-head",children:[e.jsxs("h3",{children:["Line ",j.line]}),e.jsx("button",{className:"btn",onClick:()=>{navigator.clipboard.writeText(j.raw).then(()=>R(!0),()=>d("Clipboard unavailable. Select the JSON and copy it manually."))},children:w?"Copied":"Copy JSON"})]}),e.jsx("p",{className:"tr-note",children:"Original file contents. This does not prove the record was sent or received."}),e.jsx("pre",{className:"tr-value",children:j.raw})]}):e.jsxs("div",{className:"tr-inspector-empty",children:[e.jsx("h3",{children:"Inspect a record"}),e.jsx("p",{className:"tr-note",children:"Select a row to read its original contents."})]})})]})]})}function Ts({onClose:s,sessions:t=[]}){const r=is(s),o=rs(s),{snapshot:c,failed:g}=ds(),x=hs();return e.jsx("div",{className:"modal-backdrop",...o,role:"presentation",children:e.jsxs("div",{className:"modal tr-modal",ref:r,role:"dialog","aria-modal":"true","aria-labelledby":"tr-title","aria-describedby":"tr-purpose",onClick:d=>d.stopPropagation(),children:[e.jsxs("header",{className:"modal-head",children:[e.jsxs("div",{className:"tr-identity",children:[e.jsx(G,{kind:"radar"}),e.jsxs("div",{children:[e.jsxs("div",{className:"modal-title",children:[e.jsx("span",{className:"modal-tool-name",id:"tr-title",children:"Telemetry Radar"}),e.jsx("span",{className:"tr-beta",title:"Beta feature — still being tested and improved.",children:"Beta"})]}),e.jsx("p",{id:"tr-purpose",children:"Inspect Claude Code’s collector traffic."})]})]}),e.jsx("button",{className:"glyph-btn",onClick:s,"aria-label":"Close (Esc)",title:"Close (Esc)",children:"×"})]}),e.jsx(Ss,{snapshot:c,failed:g,captureState:x,sessions:t})]})})}function Ss({snapshot:s,failed:t=!1,captureState:r,sessions:o=[]}){var D,S;const[c,g]=a.useState("monitor"),[x,d]=a.useState([]),[h,i]=a.useState("all"),v=["monitor","configuration","file"],p=u=>{var b;const j=os(u,v.indexOf(c),v.length);if(j.kind!=="select")return;u.preventDefault();const m=v[j.index];g(m),(b=document.getElementById(`tr-tab-${m}`))==null||b.focus()},l=((D=s==null?void 0:s.config)==null?void 0:D.variables)??[],y=Ve(l),w=ls(l),R=t?[]:He(s),C=new Map(o.map(u=>[u.id,u.label]));for(const u of((S=r==null?void 0:r.capture)==null?void 0:S.events)??[])for(const j of u.sessionIds??[])C.has(j)||C.set(j,j.slice(0,8));for(const u of x)C.has(u)||C.set(u,u.slice(0,8));return e.jsxs("div",{className:"tr-body",children:[e.jsxs("div",{className:"tr-navigation",children:[e.jsx("div",{className:"tr-tabs",role:"tablist","aria-label":"Radar views",onKeyDown:p,children:[["monitor","Monitor"],["configuration","Configuration"],["file","File"]].map(([u,j])=>e.jsx("button",{id:`tr-tab-${u}`,className:"tr-tab",role:"tab","aria-selected":c===u,"aria-controls":`tr-panel-${u}`,tabIndex:c===u?0:-1,onClick:()=>g(u),children:j},u))}),e.jsxs("label",{className:"tr-session-filter",children:["Session",e.jsxs(de,{value:h,onChange:u=>i(u.target.value),"aria-label":"Session",children:[e.jsx("option",{value:"all",children:"All sessions"}),[...C].map(([u,j])=>e.jsxs("option",{value:u,children:[j," · ",u.slice(0,8)]},u)),e.jsx("option",{value:"unidentified",children:"Unidentified session"})]})]}),e.jsxs("details",{className:"tr-help",children:[e.jsxs("summary",{children:[e.jsx(G,{kind:"info"}),e.jsx("span",{className:"tr-help-label",children:"About Radar"})]}),e.jsxs("div",{children:[e.jsx("h3",{children:"What does Radar show?"}),e.jsx("p",{children:"See what Claude Code sends to your telemetry collectors. Destinations can be configured by you or your organization."}),e.jsx("p",{children:"Radar inspects configured OpenTelemetry exports, including prompts or responses when enabled and captured. It does not show everything Claude knows about you, ordinary AI requests, or Anthropic’s separate service telemetry."}),e.jsx("p",{children:"An address does not identify who owns a collector or who can access its data. Encrypted connections can be observed, but their contents cannot be decoded here."}),e.jsx("a",{href:"https://code.claude.com/docs/en/monitoring-usage",target:"_blank",rel:"noreferrer",children:"Claude Code telemetry documentation"})]})]})]}),e.jsx("div",{className:"tr-page",id:"tr-panel-monitor",role:"tabpanel","aria-labelledby":"tr-tab-monitor",hidden:c!=="monitor",children:r?e.jsx(Ns,{...r,radar:t&&s?{...s,status:"unavailable"}:s,sessionFilter:h,sessions:o}):e.jsx("p",{className:"tr-empty",children:"Reading monitor status…"})}),e.jsxs("div",{className:"tr-page",id:"tr-panel-configuration",role:"tabpanel","aria-labelledby":"tr-tab-configuration",hidden:c!=="configuration",children:[e.jsxs("div",{className:"tr-summary",children:[e.jsxs("div",{className:"tr-summary-state",children:[e.jsx("span",{className:`tr-state ${t||!s?"tr-tone-unknown":w==="Enabled in settings"?"tr-tone-enabled":"tr-tone-unknown"}`,children:t?"Configuration unavailable":s?w==="Unknown"?"Configuration unknown":w:"Reading settings…"}),e.jsx("span",{className:"tr-note",children:y.length?`${y.length} configured destination${y.length===1?"":"s"}`:"No destination found in the settings files read. Telemetry may still be running."})]}),y.length>0&&e.jsx("div",{className:"tr-endpoints",children:y.map(u=>e.jsx("code",{children:u},u))}),!y.length&&R.length>0&&e.jsxs("div",{className:"tr-observed-summary",children:[e.jsx("span",{className:"tr-state",children:"Claude connections observed"}),e.jsx("div",{className:"tr-endpoints",children:R.map(u=>e.jsx("code",{children:u},u))}),e.jsx("p",{className:"tr-note",children:"These are active connections, not confirmed telemetry messages. Choose an observed address below to inspect its traffic."})]})]}),s?e.jsx(Cs,{snapshot:s,stale:t,sessionLabel:h==="all"?void 0:C.get(h)??h}):e.jsx("p",{className:"tr-empty",children:t?"Could not read settings. Sampling will retry.":"Reading local settings…"})]}),e.jsx("div",{className:"tr-page",id:"tr-panel-file",role:"tabpanel","aria-labelledby":"tr-tab-file",hidden:c!=="file",children:e.jsx(ws,{onSessions:d,sessionFilter:h})})]})}function Cs({snapshot:s,sessionLabel:t,stale:r=!1}){var d,h;const o=((d=s.config)==null?void 0:d.variables)??[],c=o.filter(i=>i.key.endsWith("ENDPOINT")),g=o.filter(i=>i.key.startsWith("OTEL_LOG_")||i.key.includes("ENABLE")||i.key.includes("TELEMETRY_BETA")),x={CLAUDE_CODE_ENABLE_TELEMETRY:"Telemetry",OTEL_LOG_USER_PROMPTS:"Your prompts",OTEL_LOG_ASSISTANT_RESPONSES:"Claude responses",OTEL_LOG_TOOL_DETAILS:"Tool details",OTEL_LOG_TOOL_CONTENT:"Tool contents",OTEL_LOG_RAW_API_BODIES:"Full API bodies",OTEL_LOG_MANAGED_SETTINGS:"Managed settings",CLAUDE_CODE_ENHANCED_TELEMETRY_BETA:"Enhanced telemetry",ENABLE_ENHANCED_TELEMETRY_BETA:"Enhanced telemetry"};return e.jsxs("section",{className:"tr-config","aria-label":"Telemetry configuration",children:[e.jsx("h3",{children:"What Claude is configured to send"}),r&&e.jsx("p",{className:"tr-warning",role:"status",children:"Last successfully read settings. Current configuration could not be verified."}),e.jsx("p",{className:"tr-note",children:"Read from local Claude settings. The effective environment of a running session is not verified."}),t&&e.jsxs("p",{className:"tr-note",children:["Selected session: ",t,". These shared settings are evidence; this session’s runtime values are unverified."]}),e.jsx("h4",{children:"Destinations"}),c.length?e.jsx("ul",{className:"tr-destinations",children:c.map(i=>e.jsxs("li",{children:[e.jsx("code",{children:i.value}),e.jsxs("span",{children:[i.source," · ",i.key]})]},`${i.source}:${i.key}`))}):e.jsx("p",{className:"tr-note",children:"No destination found in the sources read. This does not mean telemetry is off."}),!c.length&&s.connections.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("h4",{children:"Observed Claude connections"}),e.jsx("ul",{className:"tr-live-connections",children:s.connections.map(i=>e.jsxs("li",{children:[e.jsx("code",{children:i.destination}),e.jsxs("span",{children:[r||i.active===null?"Visibility unavailable":i.active?"Active connection":"Previously observed"," · PID ",i.pid," · ",i.workspace??"Workspace unknown"]})]},`${i.pid}:${i.destination}`))}),e.jsx("p",{className:"tr-note",children:"A running process can keep previously loaded settings after a settings file disappears. Connections alone do not identify telemetry or prove a message was sent."})]}),e.jsx("h4",{children:"Telemetry and content"}),g.length?e.jsx("dl",{className:"tr-variables",children:g.map(i=>e.jsxs("div",{children:[e.jsxs("dt",{children:[e.jsx("strong",{children:x[i.key]??i.key}),e.jsx("code",{children:i.key}),e.jsx("span",{children:i.source})]}),e.jsxs("dd",{children:[e.jsx("span",{className:`tr-state ${i.value.startsWith("Enabled")?"tr-tone-enabled":"tr-tone-unknown"}`,children:i.value}),i.rawValue!==void 0&&e.jsx("code",{className:"tr-raw-flag",children:i.rawValue})]})]},`${i.source}:${i.key}`))}):e.jsx("p",{className:"tr-note",children:"No telemetry flags found in the settings read."}),e.jsxs("details",{className:"tr-details",children:[e.jsx("summary",{children:"All variables and sources"}),e.jsx("dl",{className:"tr-variables",children:o.map(i=>e.jsxs("div",{children:[e.jsxs("dt",{children:[e.jsx("code",{children:i.key}),e.jsx("span",{children:i.source})]}),e.jsx("dd",{children:i.value})]},`${i.source}:${i.key}`))}),e.jsx("ul",{className:"tr-sources",children:(h=s.config)==null?void 0:h.sources.map(i=>e.jsxs("li",{children:[e.jsx("span",{children:i.name}),e.jsx("span",{children:i.status==="read"?"Read":i.status==="absent"?"Not found":"Unavailable"})]},i.name))}),e.jsx("p",{className:"tr-note",children:"Endpoint credentials and headers are hidden. Settings can differ from an already running process."})]})]})}export{Cs as Configuration,Ss as TrafficRadarView,Ts as default};
|
|
1
|
+
import{j as e,r as a,z as ss,A as ns,B as ts,u as is,d as rs,C as os}from"./index-CxIdVCPz.js";const as={radar:e.jsxs(e.Fragment,{children:[e.jsx("path",{d:"M20 12a8 8 0 1 1-8-8v8l5-5"}),e.jsx("path",{d:"M12 8a4 4 0 1 0 4 4"}),e.jsx("circle",{cx:"12",cy:"12",r:"1"})]}),connection:e.jsxs(e.Fragment,{children:[e.jsx("path",{d:"M8 8h8v8H8zM12 3v5M12 16v5M3 12h5M16 12h5"}),e.jsx("circle",{cx:"12",cy:"3",r:"1"}),e.jsx("circle",{cx:"21",cy:"12",r:"1"})]}),logs:e.jsxs(e.Fragment,{children:[e.jsx("rect",{x:"5",y:"3",width:"14",height:"18",rx:"2"}),e.jsx("path",{d:"M9 8h6M9 12h6M9 16h3"})]}),metrics:e.jsx(e.Fragment,{children:e.jsx("path",{d:"M4 20h16M7 16v-5M12 16V4M17 16V8"})}),traces:e.jsxs(e.Fragment,{children:[e.jsx("path",{d:"M7 5h10M7 12h10M7 19h10M12 5v14"}),e.jsx("circle",{cx:"7",cy:"5",r:"2"}),e.jsx("circle",{cx:"17",cy:"12",r:"2"}),e.jsx("circle",{cx:"7",cy:"19",r:"2"})]}),info:e.jsxs(e.Fragment,{children:[e.jsx("circle",{cx:"12",cy:"12",r:"9"}),e.jsx("path",{d:"M12 11v5M12 7h.01"})]})};function G({kind:s,...t}){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",...t,children:as[s]})}function de({className:s="",children:t,...r}){return e.jsxs("span",{className:"tr-select-wrap",children:[e.jsx("select",{...r,className:`tr-select${s?` ${s}`:""}`,children:t}),e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:e.jsx("path",{d:"m6 9 6 6 6-6"})})]})}function Ve(s){return[...new Set(s.filter(t=>t.key.endsWith("ENDPOINT")).map(t=>t.value).filter(t=>/^https?:\/\//.test(t)))]}function He(s){return(s==null?void 0:s.status)!=="observing"?[]:[...new Set(s.connections.filter(t=>t.active===!0).map(t=>t.destination))]}function Be(s){try{const t=new URL(s);return/^\d+\.\d+\.\d+\.\d+$/.test(t.hostname)?`${t.hostname}:${t.port||(t.protocol==="https:"?"443":"80")}`:null}catch{return null}}function ls(s){const t=s.filter(r=>r.key==="CLAUDE_CODE_ENABLE_TELEMETRY").map(r=>r.value);return t.length?new Set(t).size>1?"Conflicting settings":t[0]==="Enabled"?"Enabled in settings":t[0]==="Disabled"?"Disabled in settings":"Unknown":"Unknown"}function cs(s){const t=s.replace(/^\uFEFF/,"").trim();if(!t)return[];let r;try{JSON.parse(t),r=[t]}catch{r=s.replace(/^\uFEFF/,"").split(/\r?\n/)}if(r.length>1e4)throw new Error("This file has more than 10,000 lines. Choose a smaller export.");return r.flatMap((o,c)=>{var g;if(!o.trim())return[];try{const x=JSON.parse(o),d=x&&typeof x=="object"?x:{},h=new Set,i=[x];for(;i.length;){const v=i.pop();if(!v||typeof v!="object")continue;if(Array.isArray(v)){for(const l of v)i.push(l);continue}const p=v;for(const l of["session.id","session_id","sessionId"])typeof p[l]=="string"&&h.add(p[l]);if(["session.id","session_id"].includes(String(p.key))){const l=p.value;typeof(l==null?void 0:l.stringValue)=="string"&&h.add(l.stringValue)}for(const l of Object.values(p))i.push(l)}return[{line:c+1,raw:o,sessionIds:[...h],label:String(d.eventName??((g=d.event)==null?void 0:g.name)??d.type??d.model??"JSON record").slice(0,160),sessionId:typeof(d.session_id??d.sessionId??d["session.id"])=="string"?d.session_id??d.sessionId??d["session.id"]:null,timestamp:typeof d.timestamp=="string"?d.timestamp:null,valid:!0}]}catch{return[{line:c+1,raw:o,label:"Invalid JSON",sessionId:null,timestamp:null,sessionIds:[],valid:!1}]}})}function ds(){const[s,t]=a.useState(null),[r,o]=a.useState(!1);return a.useEffect(()=>{let c=!0,g,x=null;const d=()=>document.visibilityState!=="hidden",h=()=>{clearTimeout(g),x==null||x.abort(),x=null},i=async()=>{if(!c||!d()||x)return;const p=new AbortController;x=p;try{const l=await fetch("/api/system/traffic-radar",{signal:p.signal});if(!l.ok)throw new Error("radar_unavailable");const y=await l.json();if(!y.ok)throw new Error("radar_unavailable");c&&!p.signal.aborted&&(t(y),o(!1))}catch{c&&!p.signal.aborted&&o(!0)}finally{x===p&&(x=null),c&&!p.signal.aborted&&d()&&(g=setTimeout(i,5e3))}},v=()=>{h(),document.visibilityState!=="hidden"&&i()};return i(),document.addEventListener("visibilitychange",v),()=>{c=!1,h(),document.removeEventListener("visibilitychange",v)}},[]),{snapshot:s,failed:r}}function hs(){const[s,t]=a.useState(null),[r,o]=a.useState(!1),[c,g]=a.useState(!1),[x,d]=a.useState(""),[h,i]=a.useState(""),[v,p]=a.useState([]),[l,y]=a.useState(null),[w,R]=a.useState(null),C=a.useRef(null),D=a.useRef(null),S=a.useRef(0);a.useEffect(()=>{let j=!0,m,b=null;const _=()=>document.visibilityState!=="hidden",T=()=>{clearTimeout(m),b==null||b.abort(),b=null},O=async()=>{if(!j||!_()||b)return;if(C.current){m=setTimeout(O,1e3);return}const B=S.current,P=new AbortController;b=P;try{const z=await fetch("/api/system/traffic-radar/capture",{signal:P.signal});if(!z.ok)throw new Error;const A=await z.json();j&&!P.signal.aborted&&B===S.current&&(t(A),o(!1))}catch{j&&!P.signal.aborted&&B===S.current&&o(!0)}finally{b===P&&(b=null),j&&!P.signal.aborted&&_()&&(m=setTimeout(O,1e3))}},J=()=>{T(),document.visibilityState!=="hidden"&&O()};return O(),document.addEventListener("visibilitychange",J),()=>{var B;j=!1,T(),(B=D.current)==null||B.abort(),document.removeEventListener("visibilitychange",J)}},[]);const u=async(j,m)=>{if(!ss(C.current))return;S.current++,C.current=j,R(j),g(!0),d("");const b=new AbortController;D.current=b;const _=setTimeout(()=>b.abort(),2e4);try{const T=await fetch(`/api/system/traffic-radar/capture/${j}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({destination:m}),signal:b.signal}),O=await T.json();if(!T.ok)throw new Error(O.error||"Capture action failed. Please retry.");j==="prepare"&&(i(O.command),p(O.commands??[{destination:String(m),command:O.command}]),y(O.sessionId)),j==="stop"&&(i(""),p([]));const J=await fetch("/api/system/traffic-radar/capture",{signal:b.signal});J.ok&&(t(await J.json()),o(!1))}catch(T){d(T instanceof Error?T.message:"Capture action failed. Please retry.")}finally{clearTimeout(_),D.current=null,C.current=null,R(null),g(!1)}};return{capture:s,failed:r,busy:c,pendingAction:w,error:x,commands:(s==null?void 0:s.sessionId)===l?v:[],command:(s==null?void 0:s.sessionId)===l?h:"",action:u}}const be=50,ms=2e5;function Ue({name:s}){return e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"tr-json-key",children:typeof s=="string"?JSON.stringify(s):s}),": "]})}function We({value:s,name:t,root:r=!1}){if(s!==null&&typeof s=="object")return e.jsx(us,{value:s,name:t,root:r});const o=s===null?"null":typeof s;return e.jsxs("div",{children:[t!==void 0&&e.jsx(Ue,{name:t}),e.jsx("span",{className:`tr-json-${o}`,children:JSON.stringify(s)})]})}function us({value:s,name:t,root:r}){const[o,c]=a.useState(r),[g,x]=a.useState(be),d=Array.isArray(s),h=a.useMemo(()=>Array.isArray(s)?null:Object.keys(s),[s]),i=d?s.length:h.length,v=Math.min(g,i);return e.jsxs("details",{open:o,onToggle:p=>{p.target===p.currentTarget&&c(p.currentTarget.open)},children:[e.jsxs("summary",{children:[t!==void 0&&e.jsx(Ue,{name:t}),e.jsxs("span",{children:[d?"[":"{",i===0?d?"]":"}":"…"]}),i>0&&e.jsxs("span",{className:"tr-count",children:[i," ",d?i===1?"item":"items":i===1?"key":"keys"]})]}),o&&i>0&&e.jsxs("div",{children:[Array.from({length:v},(p,l)=>{const y=h?h[l]:l,w=Array.isArray(s)?s[l]:s[y];return e.jsx(We,{name:y,value:w},y)}),v<i&&e.jsxs("button",{type:"button",className:"btn",onClick:()=>x(p=>p+be),children:["Show ",Math.min(be,i-v)," more (",i-v," remaining)"]}),e.jsx("div",{children:d?"]":"}"})]})]})}function xs({value:s}){const t=a.useMemo(()=>{const r=JSON.stringify(s,null,2);if(r.length>ms)return r;const o=[],c=/"(?:\\.|[^"\\])*"(\s*:)?|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|\b(?:true|false|null)\b/g;let g=0;for(const x of r.matchAll(c)){const d=x.index;d>g&&o.push(r.slice(g,d));const h=x[0],i=x[1]||"",v=i?"key":h[0]==='"'?"string":h==="null"?"null":h==="true"||h==="false"?"boolean":"number";o.push(e.jsx("span",{className:`tr-json-${v}`,children:i?h.slice(0,-i.length):h},d)),i&&o.push(i),g=d+h.length}return g<r.length&&o.push(r.slice(g)),o},[s]);return e.jsx("pre",{className:"tr-value",children:t})}function js({value:s,initialMode:t="tree"}){const[r,o]=a.useState(t);return e.jsxs("div",{children:[e.jsxs("div",{className:"tr-detail-tabs",role:"group","aria-label":"JSON view",children:[e.jsx("button",{type:"button",className:"btn","aria-pressed":r==="tree",onClick:()=>o("tree"),children:"Tree"}),e.jsx("button",{type:"button",className:"btn","aria-pressed":r==="raw",onClick:()=>o("raw"),children:"Raw JSON"})]}),r==="raw"?e.jsx(xs,{value:s}):e.jsx("div",{className:"tr-value tr-json-tree",children:e.jsx(We,{value:s,root:!0})})]})}function ps(s,t=!1){var v,p,l,y;const r=!!s&&(s.enabled??["awaiting","receiving","capturing"].includes(s.state)),o=((v=s==null?void 0:s.sources)==null?void 0:v.filter(w=>w.active).length)??0,c=!!((p=s==null?void 0:s.sources)!=null&&p.some(w=>/permission/i.test(w.error??""))),g=(s==null?void 0:s.events.length)??0,x=((l=s==null?void 0:s.observations)==null?void 0:l.length)??0,d=!!(s!=null&&s.bytes)||x>0||g>0;let h="Monitoring stopped",i="neutral";return t?(h="Monitor connection lost",i="error"):s?s.state==="error"?(h="Capture error",i="error"):r&&o>0&&o<(((y=s.sources)==null?void 0:y.length)??0)?(h="Listening to some destinations",i="attention"):r&&c?(h="Capture permission needed",i="attention"):r&&s.state==="interrupted"?(h="Reconnecting capture…",i="attention"):r&&(o||!s.managed&&["receiving","capturing"].includes(s.state))?(h="Listening for telemetry",i="ok"):r&&(h=s.managed?"Starting monitoring…":"Activation needed"):h="Reading monitor…",{enabled:r,active:o,permission:c,decoded:g,observed:x,traffic:d,title:h,tone:i}}const I=s=>s&&typeof s=="object"&&!Array.isArray(s)?s:{},q=s=>Array.isArray(s)?s:[],ce=s=>new Date(s).toLocaleTimeString(),fs=s=>({unconfirmed:"Transfer observed · receipt unconfirmed",accepted:"Collector accepted",partial:"Collector reported partial success",rejected:"Collector rejected",unknown:"Response incomplete",reset:"Stream reset"})[s.outcome],ye={encrypted:"Encrypted traffic observed; contents cannot be read.",joined_midstream:"Capture joined an existing connection. Waiting for a new HTTP/2 connection to decode it reliably.",capture_gap:"Incomplete packets or a gap were observed. Affected contents are not shown as decoded.",decode_failed:"Some payloads could not be decoded. They are not shown as verified events.",payload_limit:"A payload exceeded the inspection limit and was omitted.",stream_limit:"A stream exceeded the inspection limit.",connection_limit:"The connection inspection limit was reached.",unsupported_compression:"A compression format other than gzip was observed.",unsupported_link:"This network capture format is not supported.",unsupported_network:"Some packets used a network protocol this decoder does not support.",fragmented:"Fragmented IP packets cannot be decoded in this version.",unknown_export:"A request could not be identified as an OTLP export.",connection_closed:"An HTTP/2 connection closed.",idle_connection:"An idle connection was removed from the decoder."};function he(s){const t=I(s);for(const r of["stringValue","intValue","doubleValue","boolValue","bytesValue"])if(t[r]!==void 0)return t[r];return t.arrayValue?q(I(t.arrayValue).values).map(he):t.kvlistValue?Object.fromEntries(q(I(t.kvlistValue).values).map(r=>{const o=I(r);return[String(o.key),he(o.value)]})):null}function gs(s){return/prompt/i.test(s)?"Prompt-related field included in this export.":/response|completion/i.test(s)?"Response-related field included in this export.":/tool/i.test(s)?"Tool-related field included in this export.":/session/i.test(s)?"Session identifier or session metadata.":/user|email|account/i.test(s)?"User or account metadata.":/token|cost|duration|latency/i.test(s)?"Usage or timing measurement.":"Attribute included in this export."}function ee({value:s}){return e.jsx("pre",{className:"tr-value",children:typeof s=="string"?s:JSON.stringify(s,null,2)})}function Ne({value:s}){return e.jsx("dl",{className:"tr-attributes",children:q(s).map((t,r)=>{const o=I(t);return e.jsxs("div",{children:[e.jsxs("dt",{children:[e.jsx("code",{children:String(o.key??"Unnamed attribute")}),e.jsx("span",{children:gs(String(o.key))})]}),e.jsx("dd",{children:e.jsx(ee,{value:he(o.value)})})]},r)})})}function vs({record:s}){const t=["gauge","sum","histogram","exponentialHistogram","summary"].find(r=>s[r]);return t?e.jsxs("div",{children:[s.description&&e.jsx("p",{className:"tr-note",children:String(s.description)}),q(I(s[t]).dataPoints).map((r,o)=>{const c=I(r);return e.jsxs("section",{children:[e.jsxs("dl",{className:"tr-facts",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Measurement"}),e.jsx("dd",{children:t})]}),c.asInt!==void 0||c.asDouble!==void 0?e.jsxs("div",{children:[e.jsx("dt",{children:"Value"}),e.jsx("dd",{children:e.jsxs("code",{children:[String(c.asInt??c.asDouble)," ",String(s.unit??"")]})})]}):null,c.count!==void 0&&e.jsxs("div",{children:[e.jsx("dt",{children:"Count"}),e.jsx("dd",{children:e.jsx("code",{children:String(c.count)})})]}),c.sum!==void 0&&e.jsxs("div",{children:[e.jsx("dt",{children:"Sum"}),e.jsx("dd",{children:e.jsxs("code",{children:[String(c.sum)," ",String(s.unit??"")]})})]})]}),e.jsx(Ne,{value:c.attributes}),e.jsxs("details",{className:"tr-details",children:[e.jsx("summary",{children:"All measurement fields"}),e.jsx(ee,{value:c})]})]},o)})]}):null}function bs({record:s}){let t=null;try{t=`${Number(BigInt(String(s.endTimeUnixNano))-BigInt(String(s.startTimeUnixNano)))/1e6} ms`}catch{t=null}return e.jsxs("dl",{className:"tr-facts",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Duration"}),e.jsx("dd",{children:t??"Not included"})]}),s.kind&&e.jsxs("div",{children:[e.jsx("dt",{children:"Span kind"}),e.jsx("dd",{children:String(s.kind)})]}),s.status&&e.jsxs("div",{children:[e.jsx("dt",{children:"Span status"}),e.jsx("dd",{children:e.jsx(ee,{value:s.status})})]})]})}function ys({payload:s,signal:t}){const r=t==="traces"?"Spans":t==="logs"?"Logs":"Metrics",o=t==="traces"?"spans":t==="logs"?"logRecords":"metrics";return e.jsx("div",{className:"tr-decoded",children:q(s["resource"+r]).map((c,g)=>{const x=I(c);return e.jsxs("section",{children:[e.jsxs("details",{className:"tr-details",children:[e.jsx("summary",{children:"Resource metadata"}),e.jsx(Ne,{value:I(x.resource).attributes})]}),q(x["scope"+r]).map((d,h)=>{const i=I(d);return e.jsxs("div",{children:[i.scope&&e.jsxs("p",{className:"tr-note",children:["Instrumentation: ",String(I(i.scope).name??"Unnamed")," ",String(I(i.scope).version??"")]}),q(i[o]).map((v,p)=>{const l=I(v);return e.jsxs("article",{className:"tr-record",children:[e.jsx("h4",{children:String(l.eventName??l.name??`${t==="logs"?"Log record":"Record"} ${p+1}`)}),l.body&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"tr-note",children:"Event body"}),e.jsx(ee,{value:he(l.body)})]}),t==="metrics"&&e.jsx(vs,{record:l}),t==="traces"&&e.jsx(bs,{record:l}),l.attributes&&e.jsx(Ne,{value:l.attributes}),e.jsxs("details",{className:"tr-details",children:[e.jsx("summary",{children:"All record fields"}),e.jsx(ee,{value:l})]})]},p)})]},h)})]},g)})})}function Ns({capture:s,radar:t,failed:r,busy:o,pendingAction:c=null,error:g,command:x,commands:d=[],action:h,sessionFilter:i="all",sessions:v=[]}){var Ee,Ae,Oe,Le,Me,Ie,Re,_e,De,Pe,$e,Fe;const p=Ve(((Ee=t==null?void 0:t.config)==null?void 0:Ee.variables)??[]),l=[...new Set(p.map(Be).filter(n=>!!n))],y=He(t).filter(n=>!l.includes(n)&&Be(`http://${n}`)),[w,R]=a.useState("all"),[C,D]=a.useState(""),[S,u]=a.useState(null),[j,m]=a.useState(null),[b,_]=a.useState("all"),[T,O]=a.useState("all"),[J,B]=a.useState(100),[P,z]=a.useState(null),[A,me]=a.useState(null),[$,se]=a.useState(null),[Y,re]=a.useState(!1),we=a.useRef(0),[ue,Se]=a.useState("summary"),[L,xe]=a.useState(null),[Ce,Ge]=a.useState(0),ne=a.useRef(null),K=(s==null?void 0:s.events)??[],qe=new Map(K.map(n=>[n.id,n])),je=A?A.map(n=>qe.get(n.id)).filter(n=>!!n):K,V=je.filter(n=>{var f,k;return(T==="all"||n.signal===T)&&(b==="all"||b===n.destination)&&(i==="all"||(i==="unidentified"?!((f=n.sessionIds)!=null&&f.length):(k=n.sessionIds)==null?void 0:k.includes(i)))}),H=((s==null?void 0:s.observations)??[]).filter(n=>(P===null||P.includes(n.id))&&T==="all"&&(i==="all"||i==="unidentified")&&(b==="all"||b===n.destination)),M=H.find(n=>n.id===S),N=S!==null?void 0:j===null?V[0]:V.find(n=>n.id===j),te=[...V.map(n=>({kind:"export",event:n})),...H.map(n=>({kind:"observation",event:n}))].sort((n,f)=>f.event.at-n.event.at||f.event.id-n.event.id),ze=new Set(A==null?void 0:A.map(n=>n.id)),Ye=new Set(P),pe=A===null?0:K.filter(n=>!ze.has(n.id)).length+((s==null?void 0:s.observations)??[]).filter(n=>!Ye.has(n.id)).length,ie=N==null?void 0:N.id;a.useEffect(()=>{m(null),u(null),B(100)},[i,T,b]),a.useEffect(()=>{j!==null||S!==null||(V.length?m(V[0].id):H.length&&u(H[0].id))},[(Ae=V[0])==null?void 0:Ae.id,(Oe=H[0])==null?void 0:Oe.id,j,S]),a.useEffect(()=>{if(xe(null),se(null),ie===void 0)return;const n=new AbortController;let f=!0;const k=setTimeout(()=>n.abort(),5e3);return fetch(`/api/system/traffic-radar/capture/event?id=${ie}`,{signal:n.signal}).then(async E=>{if(!E.ok)throw new Error("This message has expired. Select a newer message.");const W=await E.json();f&&!n.signal.aborted&&xe({id:ie,payload:W.payload})}).catch(E=>{f&&xe({id:ie,error:n.signal.aborted?"Loading timed out. Try again.":E instanceof Error?E.message:"Could not read this message."})}).finally(()=>clearTimeout(k)),()=>{f=!1,clearTimeout(k),n.abort()}},[ie,S,Ce]),a.useEffect(()=>{if(!$||$==="failed")return;const n=setTimeout(()=>se(null),2e3);return()=>clearTimeout(n)},[$]),a.useEffect(()=>{if(!Y)return;const n=setTimeout(()=>re(!1),5e3);return()=>clearTimeout(n)},[Y]);const oe=(s==null?void 0:s.shell)??((t==null?void 0:t.platform)==="win32"?"PowerShell":"Terminal"),fe=oe==="PowerShell",U=ps(s,r),F=U.enabled,Z=!!(s!=null&&s.managed),Ke=Z&&U.permission,ae=U.active,Q=((Le=s==null?void 0:s.sources)==null?void 0:Le.length)??1,Ze=U.title,X=n=>{const f=ts(c??(o?"capture":null),n);return{disabled:f.disabled,"aria-busy":f.busy}},Qe=n=>{var f,k,E;u(null),m(n.id),typeof window<"u"&&((f=window.matchMedia)!=null&&f.call(window,"(max-width: 640px)").matches)&&((k=ne.current)==null||k.focus({preventScroll:!0}),(E=ne.current)==null||E.scrollIntoView({block:"start",behavior:"auto"}))},Xe=()=>{const n=Date.now(),f=ns({armedFor:Y?"history":null,target:"history",armedAt:we.current,now:n,gapMs:350});if(f==="arm"){we.current=n,re(!0);return}f!=="ignore"&&(re(!1),m(null),u(null),me(null),z(null),h("clear"))},ke=()=>{var f;se(null),me(null),z(null),m(null),u(null);const n=w==="custom"?[C.trim()]:w==="all"?l:[w];h("prepare",n.length?n:((f=s==null?void 0:s.sources)==null?void 0:f.map(k=>k.destination))??(s!=null&&s.destination?[s.destination]:[]))},ge=d.length?d:x?[{destination:(s==null?void 0:s.destination)??"Collector",command:x}]:[],le=async(n,f)=>{try{await navigator.clipboard.writeText(n),se(f)}catch{se("failed")}},Te=(n=[])=>n.length?n.map(f=>{var k;return`${((k=v.find(E=>E.id===f))==null?void 0:k.label)??"Session"} · ${f.slice(0,8)}`}).join(", "):"Unidentified session",es=new Set([...((Me=s==null?void 0:s.sources)==null?void 0:Me.map(n=>n.destination))??[],...l]),ve=(t==null?void 0:t.status)==="observing"?t.connections.filter(n=>n.active&&es.has(n.destination)):[];return e.jsxs("div",{className:"tr-telemetry",children:[e.jsxs("div",{className:"tr-capture-bar",children:[e.jsxs("div",{children:[e.jsxs("h3",{role:"status","aria-live":"polite",children:[e.jsx("span",{className:`tr-live-dot tr-dot-${U.tone}`}),Ze]}),e.jsx("p",{className:"tr-note",children:r?"Showing the last successful read. Reconnecting automatically.":F?ae?`${ae} of ${Q} destination${Q===1?"":"s"} listening · ${U.traffic?"Traffic observed":"No traffic observed yet"}`:"Monitoring is enabled; the listener is not ready yet.":"Start Radar to inspect new collector traffic. Claude settings stay unchanged."}),F&&e.jsxs("div",{className:"tr-active-destinations",role:"group","aria-label":"Monitored destinations",children:[e.jsxs("span",{children:["Destination",Q>1?"s":""]}),(Ie=s==null?void 0:s.sources)!=null&&Ie.length?s.sources.map(n=>e.jsxs("span",{className:"tr-destination-entry",children:[e.jsx("code",{children:n.destination}),(Q>1||!n.active)&&e.jsx("span",{className:n.active?"tr-source-ready":"tr-source-pending",children:n.active?"Listening":"Not listening"}),!n.active&&n.error&&e.jsx("span",{className:"tr-source-error",children:n.error})]},n.destination)):(s==null?void 0:s.destination)&&e.jsx("code",{children:s.destination})]})]}),e.jsxs("div",{className:"tr-capture-actions",children:[F?e.jsx("button",{className:"btn",...X("stop"),onClick:()=>void h("stop"),children:"Stop monitoring"}):e.jsx("button",{className:"btn primary",...X("prepare"),disabled:X("prepare").disabled||!s||r||(t==null?void 0:t.status)==="unsupported"||w==="all"&&!l.length||w==="custom"&&!C.trim(),onClick:ke,children:c==="prepare"?"Starting…":"Start monitoring"}),e.jsx("button",{className:Y?"btn danger armed":"btn",...X("clear"),disabled:X("clear").disabled||!(s!=null&&s.events.length)&&!((Re=s==null?void 0:s.observations)!=null&&Re.length),title:Y?"Remove decoded messages and observations. Monitoring continues.":"Clear retained messages and connection observations",onBlur:()=>re(!1),onClick:Xe,children:Y?"Confirm clear history":"Clear history"})]})]}),!F&&e.jsxs("div",{className:"tr-destination",children:[e.jsxs("label",{children:["Destination",e.jsxs(de,{"aria-label":"Capture destination",value:w,onChange:n=>R(n.target.value),children:[e.jsxs("option",{value:"all",children:["All configured IPv4 destinations (",l.length,")"]}),l.map(n=>e.jsx("option",{value:n,children:n},n)),y.length>0&&e.jsx("optgroup",{label:"Observed Claude connections · telemetry unverified",children:y.map(n=>e.jsxs("option",{value:n,children:[n," · observed"]},n))}),e.jsx("option",{value:"custom",children:"Another IPv4 address…"})]})]}),w==="custom"&&e.jsx("input",{className:"tr-input","aria-label":"Collector IPv4 and port",value:C,onChange:n=>D(n.target.value),placeholder:"192.168.1.10:4317"}),!l.length&&w==="all"&&e.jsx("span",{className:"tr-note",children:y.length?"Choose an observed connection or enter your collector address.":"Enter your collector address to monitor traffic. Missing settings do not mean telemetry is off."})]}),(t==null?void 0:t.status)==="unsupported"&&e.jsx("p",{className:"tr-capture-error",role:"status",children:"Live capture is available on macOS, Linux and Windows. You can still inspect a local file."}),g&&e.jsxs("p",{className:"tr-capture-error",role:"alert",children:[g,fe&&g.includes("Npcap")&&e.jsxs(e.Fragment,{children:[" ",e.jsx("a",{href:"https://www.wireshark.org/download.html",target:"_blank",rel:"noreferrer",children:"Get Wireshark"})]})]}),!Z&&F&&!ge.length&&(s==null?void 0:s.state)==="awaiting"&&e.jsxs("div",{className:"tr-activation",children:[e.jsx("p",{children:"Activation is pending. Generate the Terminal instructions again to continue."}),e.jsx("button",{className:"btn",...X("prepare"),onClick:ke,children:"Show activation instructions"}),e.jsx("p",{className:"tr-note",children:"The previous token will be invalidated."})]}),!Z&&ge.length>0&&F&&e.jsxs("details",{className:"tr-activation",open:!ae,children:[e.jsxs("summary",{children:["Activate in ",oe,Q>1?` · ${ae}/${Q} listening`:""]}),e.jsx("p",{children:fe?"Run each command in a separate PowerShell tab. Wireshark with Npcap is required; use an administrator tab if Npcap restricts capture.":"Run each command in a separate Terminal tab. Only tcpdump asks for administrator permission."}),ge.map(n=>e.jsxs("div",{className:"tr-command-entry",children:[e.jsxs("div",{children:[e.jsx("code",{children:n.destination}),e.jsx("button",{className:"btn",onClick:()=>void le(n.command,n.destination),children:$===n.destination?"Copied":"Copy command"})]}),e.jsx("pre",{className:"tr-command",children:n.command})]},n.destination)),e.jsxs("p",{className:"tr-note",children:["Press Ctrl+C in each ",oe," tab to stop capture. Monitoring continues until you stop it. Commands contain a local token; do not share them."]})]}),Ke&&e.jsxs("div",{className:"tr-activation",role:"status",children:[e.jsx("strong",{children:"Allow packet capture once"}),e.jsxs("p",{className:"tr-note",children:[fe?"Npcap is restricting access. Allow this user to capture traffic in Npcap setup.":(s==null?void 0:s.platform)==="darwin"?"Install Wireshark’s ChmodBPF permission helper to allow capture without a Terminal command.":"Grant tcpdump packet capture permissions for this user."," ccdeck retries automatically when access is available."]}),e.jsx("a",{href:"https://wiki.wireshark.org/CaptureSetup/CapturePrivileges",target:"_blank",rel:"noreferrer",children:"Capture permission setup"})]}),$==="failed"&&e.jsx("p",{className:"tr-capture-error",role:"alert",children:"Clipboard unavailable. Select the text and copy it manually."}),e.jsxs("div",{className:"tr-workspace",children:[e.jsxs("section",{className:"tr-feed","aria-label":"Collector activity",children:[e.jsxs("div",{className:"tr-feed-head",children:[e.jsxs("h3",{children:["Activity ",e.jsx("span",{className:"tr-count",children:te.length})]}),e.jsx("button",{className:"btn","aria-pressed":A!==null,title:A?"Show new entries received while the list was paused":"Freeze the list while monitoring continues",disabled:!je.length&&!H.length&&A===null,onClick:()=>{me(A?null:[...je]),z(A?null:((s==null?void 0:s.observations)??[]).map(n=>n.id))},children:A?"Resume list":"Pause list"})]}),e.jsxs("p",{className:"tr-history",children:["Last 24 hours · ",V.length," decoded ",V.length===1?"message":"messages"," · ",H.length," ",H.length===1?"observation":"observations"]}),e.jsxs("div",{className:"tr-filter",children:[e.jsxs("label",{children:["Type",e.jsxs(de,{"aria-label":"Message type",value:T,onChange:n=>{m(null),O(n.target.value)},children:[e.jsx("option",{value:"all",children:"All types"}),e.jsx("option",{value:"logs",children:"Events"}),e.jsx("option",{value:"metrics",children:"Metrics"}),e.jsx("option",{value:"traces",children:"Traces"})]})]}),e.jsxs("label",{children:["To",e.jsxs(de,{"aria-label":"Message destination",value:b,onChange:n=>{m(null),_(n.target.value)},children:[e.jsx("option",{value:"all",children:"All destinations"}),[...new Set([...l,...((_e=s==null?void 0:s.sources)==null?void 0:_e.map(n=>n.destination))??[],...K.map(n=>n.destination),...((s==null?void 0:s.observations)??[]).map(n=>n.destination)])].map(n=>e.jsx("option",{value:n,children:n},n))]})]})]}),A&&e.jsxs("p",{className:"tr-list-notice",role:"status",children:["List paused · Monitoring continues",pe>0?` · ${pe} new ${pe===1?"entry":"entries"}`:""]}),(De=s==null?void 0:s.retention)!=null&&De.evictedExports?e.jsxs("p",{className:"tr-note",children:[s.retention.evictedExports.toLocaleString()," older messages removed by history limits."]}):null,te.length?e.jsx("ul",{className:"tr-connections",onKeyDown:n=>{var Je;if(!["ArrowDown","ArrowUp","Home","End"].includes(n.key))return;const f=Array.from(n.currentTarget.querySelectorAll(".tr-message")),k=f.indexOf(document.activeElement);if(k<0)return;n.preventDefault();const E=n.key==="Home"?0:n.key==="End"?f.length-1:Math.max(0,Math.min(f.length-1,k+(n.key==="ArrowDown"?1:-1))),W=te[E];W&&(m(W.kind==="export"?W.event.id:null),u(W.kind==="observation"?W.event.id:null)),(Je=f[E])==null||Je.focus()},children:te.slice(0,J).map(n=>n.kind==="export"?e.jsx("li",{children:e.jsxs("button",{className:"tr-message","aria-pressed":(N==null?void 0:N.id)===n.event.id,onClick:()=>Qe(n.event),children:[e.jsx(G,{kind:n.event.signal,className:"tr-row-icon"}),e.jsxs("span",{className:"tr-event-top",children:[e.jsx("strong",{className:"tr-event-name",children:n.event.name}),e.jsx("time",{dateTime:new Date(n.event.at).toISOString(),children:ce(n.event.at)})]}),e.jsxs("span",{className:"tr-event-context",children:[e.jsx("span",{className:"tr-signal",children:n.event.signal==="logs"?"Decoded event":n.event.signal==="metrics"?"Decoded metric":"Decoded trace"}),e.jsx("span",{children:Te(n.event.sessionIds)})]}),e.jsx("code",{className:"tr-event-destination",children:n.event.destination}),e.jsxs("span",{className:"tr-event-bottom",children:[e.jsx("span",{className:`tr-receipt ${n.event.outcome==="accepted"?"tr-tone-ok":n.event.outcome==="rejected"?"tr-tone-error":n.event.outcome==="partial"?"tr-tone-enabled":""}`,children:n.event.outcome==="accepted"?"Accepted":n.event.outcome==="unconfirmed"?"Receipt unconfirmed":n.event.outcome==="partial"?"Partially accepted":n.event.outcome==="rejected"?"Rejected":"Receipt unknown"}),e.jsxs("span",{children:[n.event.count," ",n.event.count===1?"record":"records"]})]})]})},`event-${n.event.id}`):e.jsx("li",{children:e.jsxs("button",{className:"tr-message","aria-pressed":S===n.event.id,onClick:()=>{var f,k,E;m(null),u(n.event.id),(f=window.matchMedia)!=null&&f.call(window,"(max-width: 640px)").matches&&((k=ne.current)==null||k.focus({preventScroll:!0}),(E=ne.current)==null||E.scrollIntoView({block:"start",behavior:"auto"}))},children:[e.jsx(G,{kind:"connection",className:"tr-row-icon"}),e.jsxs("span",{className:"tr-event-top",children:[e.jsx("strong",{className:"tr-event-name",children:"Connection observed"}),e.jsx("time",{dateTime:new Date(n.event.at).toISOString(),children:ce(n.event.at)})]}),e.jsx("code",{className:"tr-event-destination",children:n.event.destination}),e.jsx("span",{children:n.event.reason==="encrypted"?"Encrypted contents":"Contents not decoded"})]})},`observation-${n.event.id}`))}):e.jsxs("div",{className:"tr-empty-capture",children:[e.jsx("h4",{children:K.length||(Pe=s==null?void 0:s.observations)!=null&&Pe.length?"No matching activity":F?"Waiting for traffic":"Message capture is off"}),e.jsx("p",{className:"tr-note",children:K.length||($e=s==null?void 0:s.observations)!=null&&$e.length?"Try another session, type or destination.":F?"Activity appears when traffic reaches a monitored destination. Decoded messages will be identified separately.":"No messages have been captured by Radar. Claude may still be sending telemetry. Choose a destination and start monitoring to inspect new traffic."})]}),te.length>J&&e.jsx("button",{className:"btn",onClick:()=>B(n=>n+100),children:"Show older messages"}),ve.length>0&&e.jsxs("details",{className:"tr-details",children:[e.jsxs("summary",{children:["Connections to these collectors (",ve.length,")"]}),e.jsx("ul",{className:"tr-live-connections",children:ve.map(n=>e.jsxs("li",{children:[e.jsx("code",{children:n.destination}),e.jsxs("span",{children:["Claude · PID ",n.pid," · ",n.workspace??"Workspace unknown"]})]},`${n.pid}:${n.destination}`))}),e.jsx("p",{className:"tr-note",children:"A connection alone does not prove a telemetry message was sent. These connections are not filtered by session."})]})]}),e.jsx("section",{className:"tr-inspector","aria-label":"Activity inspector",ref:ne,tabIndex:-1,children:M?e.jsxs("div",{children:[e.jsx("div",{className:"tr-inspector-head",children:e.jsxs("h3",{children:[e.jsx(G,{kind:"connection"}),"Connection details"]})}),e.jsxs("dl",{className:"tr-facts",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Destination"}),e.jsxs("dd",{className:"tr-fact-copy",children:[e.jsx("code",{children:M.destination}),e.jsx("button",{className:"tr-inline-copy","aria-label":"Copy destination",onClick:()=>void le(M.destination,"destination"),title:$==="destination"?"Copied destination":"Copy destination",children:e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:$==="destination"?e.jsx("path",{d:"m5 12 4 4L19 6"}):e.jsxs(e.Fragment,{children:[e.jsx("rect",{x:"8",y:"8",width:"12",height:"12",rx:"2"}),e.jsx("path",{d:"M16 8V4H4v12h4"})]})})})]})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Observed"}),e.jsx("dd",{children:e.jsx("time",{dateTime:new Date(M.at).toISOString(),children:new Date(M.at).toLocaleString()})})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Source"}),e.jsx("dd",{children:e.jsx("code",{children:M.source||"Not identified"})})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Contents"}),e.jsx("dd",{children:M.reason==="encrypted"?"Encrypted":"Not decoded"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Session"}),e.jsx("dd",{children:"Not identified"})]})]}),e.jsxs("div",{className:"tr-inspection-limit",children:[e.jsx(G,{kind:"info"}),e.jsxs("div",{children:[e.jsx("h4",{children:M.reason==="encrypted"?"Encrypted connection":"Message contents unavailable"}),e.jsx("p",{children:M.reason==="joined_midstream"?"Radar joined an existing connection. Keep listening: new connections may allow decoding.":M.reason==="encrypted"?"Radar cannot decrypt HTTPS. Inspect the collector’s own records for the contents.":ye[M.reason]??"This connection could not be decoded."}),e.jsxs("details",{className:"tr-details",children:[e.jsx("summary",{children:"Technical details"}),e.jsx("p",{className:"tr-note",children:ye[M.reason]??"The decoder could not read this connection."}),e.jsxs("p",{className:"tr-note",children:["There is no decoded JSON or confirmed session ID for this observation. ",M.reason==="joined_midstream"&&"Already captured traffic cannot be reconstructed."]})]})]})]})]}):N?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"tr-inspector-head",children:[e.jsxs("h3",{children:[e.jsx(G,{kind:N.signal}),N.name]}),e.jsxs("p",{className:"tr-note",children:["Decoded ",N.signal==="logs"?"event":N.signal==="metrics"?"metrics":"trace"," · ",Te(N.sessionIds)," · ",ce(N.at)]})]}),e.jsxs("div",{className:"tr-detail-tabs",role:"group","aria-label":"Message format",children:[e.jsx("button",{className:"btn","aria-pressed":ue==="summary",onClick:()=>Se("summary"),children:"Overview"}),e.jsx("button",{className:"btn","aria-pressed":ue==="json",onClick:()=>Se("json"),children:"JSON"}),e.jsx("button",{className:"btn tr-copy-json",disabled:!(L!=null&&L.payload)||L.id!==N.id,onClick:()=>void le(JSON.stringify(L==null?void 0:L.payload,null,2),"json"),children:$==="json"?"Copied":"Copy JSON"})]}),(L==null?void 0:L.id)===N.id?L.payload?ue==="json"?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"tr-note",children:"Decoded OTLP fields. Unknown protobuf fields and transport headers are excluded."}),e.jsx(js,{value:L.payload})]}):e.jsxs(e.Fragment,{children:[e.jsxs("dl",{className:"tr-facts",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Destination"}),e.jsxs("dd",{className:"tr-fact-copy",children:[e.jsx("code",{children:N.destination}),e.jsx("button",{className:"tr-inline-copy","aria-label":"Copy destination",onClick:()=>void le(N.destination,"destination"),title:$==="destination"?"Copied destination":"Copy destination",children:e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:$==="destination"?e.jsx("path",{d:"m5 12 4 4L19 6"}):e.jsxs(e.Fragment,{children:[e.jsx("rect",{x:"8",y:"8",width:"12",height:"12",rx:"2"}),e.jsx("path",{d:"M16 8V4H4v12h4"})]})})})]})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Time"}),e.jsx("dd",{children:ce(N.at)})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Receipt"}),e.jsx("dd",{children:fs(N)})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Size"}),e.jsxs("dd",{children:[N.bytes.toLocaleString()," bytes · ",N.count," ",N.count===1?"record":"records"]})]}),((Fe=N.response)==null?void 0:Fe.message)&&e.jsxs("div",{children:[e.jsx("dt",{children:"Response"}),e.jsx("dd",{children:e.jsx(ee,{value:N.response.message})})]})]}),e.jsx(ys,{payload:L.payload,signal:N.signal})]}):e.jsxs("div",{role:"alert",children:[e.jsx("p",{children:L.error}),e.jsx("button",{className:"btn",onClick:()=>Ge(Ce+1),children:"Retry"})]}):e.jsx("p",{className:"tr-note",role:"status",children:"Loading message contents…"})]}):e.jsxs("div",{className:"tr-inspector-empty",children:[e.jsx("svg",{width:"40",height:"40",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.25","aria-hidden":"true",children:e.jsx("path",{d:"M8 4H5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h3M16 4h3a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3M10 8l-3 4 3 4M14 8l3 4-3 4"})}),e.jsx("h3",{children:j!==null||S!==null?"Activity no longer available":"Inspect collector activity"}),e.jsx("p",{className:"tr-note",children:j!==null||S!==null?"The selected entry is no longer retained or does not match your filter. Select another entry.":U.traffic&&!U.decoded?"Traffic has been observed, but no messages have been decoded. Select a connection observation to see what is known.":"Select an entry to inspect its metadata and any decoded contents."})]})})]}),e.jsxs("footer",{className:"tr-monitor-footer",children:[e.jsxs("span",{children:[r?"Connection interrupted":F?Z?"Continuous local monitoring":"Local capture":"Not monitoring"," · History in local memory"]}),e.jsxs("details",{children:[e.jsx("summary",{children:"Monitoring limits"}),e.jsxs("div",{children:[e.jsx("p",{children:"Plaintext IPv4 OTLP/gRPC only. HTTPS contents cannot be decoded. Traffic to the chosen addresses can come from any process, not only Claude."}),e.jsx("p",{children:"History covers the last 24 hours, up to 2,000 exports and a 32 MiB payload budget. When a limit is reached, the oldest messages are removed."}),e.jsxs("p",{children:["History stays in local memory. Restarting ccdeck or clearing messages removes it. Closing this modal does not stop capture or clear history; stopping monitoring preserves history. No capture file is written. Use Stop monitoring",!Z&&e.jsxs(e.Fragment,{children:[" and Ctrl+C in ",oe]})," to stop capture."]}),s!=null&&s.bytes?e.jsxs("p",{children:["Captured transport bytes: ",s.bytes.toLocaleString(),". This is not a decoded-message count."]}):null,Z&&e.jsx("p",{children:"Enabled monitoring resumes after a ccdeck restart; the in-memory history does not."}),Object.entries((s==null?void 0:s.issues)??{}).map(([n,f])=>e.jsxs("p",{children:[ye[n]??"An inspection limitation was observed."," (",f,")"]},n))]})]})]})]})}function ws({sessionFilter:s="all",onSessions:t}){const[r,o]=a.useState([]),[c,g]=a.useState(""),[x,d]=a.useState(""),[h,i]=a.useState(!1),[v,p]=a.useState(null),[l,y]=a.useState(""),[w,R]=a.useState(!1),C=a.useRef(0),D=async m=>{if(!m)return;const b=++C.current;d(""),i(!0),R(!1);try{if(m.size>10*1024*1024)throw new Error("Choose a file smaller than 10 MB.");const _=await m.text(),T=cs(_);if(b!==C.current)return;t==null||t([...new Set(T.flatMap(O=>O.sessionIds))]),o(T),g(m.name),p(null),y(""),T.length||d("This file is empty. Choose a JSON or JSONL telemetry file.")}catch(_){b===C.current&&d(_ instanceof Error?_.message:"Could not read this file.")}finally{b===C.current&&i(!1)}},S=r.filter(m=>(s==="all"||(s==="unidentified"?!m.sessionIds.length:m.sessionIds.includes(s)))&&(!l||m.raw.toLowerCase().includes(l.toLowerCase()))),u=S.slice(0,200),j=v===null?u[0]:S.find(m=>m.line===v);return e.jsxs("div",{className:"tr-file",children:[e.jsxs("div",{className:"tr-file-toolbar",children:[e.jsxs("div",{children:[e.jsx("h3",{children:"Inspect a telemetry file"}),e.jsx("p",{className:"tr-note",children:"Open a local JSON or JSONL file. It stays in your browser and is not uploaded."})]}),e.jsxs("label",{className:"btn tr-file-picker",children:[h?"Reading…":c?"Choose another file":"Open file",e.jsx("input",{type:"file",accept:".json,.jsonl,.ndjson,application/json","aria-label":"Open telemetry file",onChange:m=>{var b;D((b=m.target.files)==null?void 0:b[0]),m.target.value=""}})]})]}),x&&e.jsx("p",{className:"tr-capture-error",role:"alert",children:x}),e.jsxs("div",{className:"tr-workspace",children:[e.jsxs("section",{className:"tr-feed","aria-label":"File records",children:[e.jsxs("h3",{children:[c||"File records"," ",e.jsx("span",{className:"tr-count",children:S.length})]}),r.length>0&&e.jsx("input",{type:"search",className:"tr-input tr-search","aria-label":"Search file contents",placeholder:"Search contents…",value:l,onChange:m=>{y(m.target.value),p(null)}}),u.length?e.jsx("ul",{className:"tr-connections",children:u.map(m=>e.jsx("li",{children:e.jsxs("button",{className:"tr-message","aria-pressed":(j==null?void 0:j.line)===m.line,onClick:()=>{p(m.line),R(!1)},children:[e.jsxs("span",{className:"tr-event-top",children:[e.jsxs("span",{children:["Line ",m.line]}),e.jsx("span",{className:m.valid?"":"tr-tone-enabled",children:m.valid?"JSON":"Invalid JSON"})]}),e.jsx("strong",{children:m.label}),m.timestamp&&e.jsx("span",{children:m.timestamp}),e.jsx("span",{children:m.sessionIds.join(", ")||"Unidentified session"})]})},m.line))}):e.jsxs("div",{className:"tr-empty-capture",children:[e.jsx("h4",{children:r.length?"No matching records":"Your saved records, in one place"}),e.jsx("p",{className:"tr-note",children:r.length?"Try another session or search.":"Choose a file to browse its rows and inspect the original JSON. A saved file is separate from live network capture."})]}),S.length>u.length&&e.jsx("p",{className:"tr-note",children:"Showing the first 200 matching rows. Search to narrow the list."})]}),e.jsx("section",{className:"tr-inspector","aria-label":"File record contents",children:j?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"tr-feed-head",children:[e.jsxs("h3",{children:["Line ",j.line]}),e.jsx("button",{className:"btn",onClick:()=>{navigator.clipboard.writeText(j.raw).then(()=>R(!0),()=>d("Clipboard unavailable. Select the JSON and copy it manually."))},children:w?"Copied":"Copy JSON"})]}),e.jsx("p",{className:"tr-note",children:"Original file contents. This does not prove the record was sent or received."}),e.jsx("pre",{className:"tr-value",children:j.raw})]}):e.jsxs("div",{className:"tr-inspector-empty",children:[e.jsx("h3",{children:"Inspect a record"}),e.jsx("p",{className:"tr-note",children:"Select a row to read its original contents."})]})})]})]})}function Ts({onClose:s,sessions:t=[]}){const r=is(s),o=rs(s),{snapshot:c,failed:g}=ds(),x=hs();return e.jsx("div",{className:"modal-backdrop",...o,role:"presentation",children:e.jsxs("div",{className:"modal tr-modal",ref:r,role:"dialog","aria-modal":"true","aria-labelledby":"tr-title","aria-describedby":"tr-purpose",onClick:d=>d.stopPropagation(),children:[e.jsxs("header",{className:"modal-head",children:[e.jsxs("div",{className:"tr-identity",children:[e.jsx(G,{kind:"radar"}),e.jsxs("div",{children:[e.jsxs("div",{className:"modal-title",children:[e.jsx("span",{className:"modal-tool-name",id:"tr-title",children:"Telemetry Radar"}),e.jsx("span",{className:"tr-beta",title:"Beta feature — still being tested and improved.",children:"Beta"})]}),e.jsx("p",{id:"tr-purpose",children:"Inspect Claude Code’s collector traffic."})]})]}),e.jsx("button",{className:"glyph-btn",onClick:s,"aria-label":"Close (Esc)",title:"Close (Esc)",children:"×"})]}),e.jsx(Ss,{snapshot:c,failed:g,captureState:x,sessions:t})]})})}function Ss({snapshot:s,failed:t=!1,captureState:r,sessions:o=[]}){var D,S;const[c,g]=a.useState("monitor"),[x,d]=a.useState([]),[h,i]=a.useState("all"),v=["monitor","configuration","file"],p=u=>{var b;const j=os(u,v.indexOf(c),v.length);if(j.kind!=="select")return;u.preventDefault();const m=v[j.index];g(m),(b=document.getElementById(`tr-tab-${m}`))==null||b.focus()},l=((D=s==null?void 0:s.config)==null?void 0:D.variables)??[],y=Ve(l),w=ls(l),R=t?[]:He(s),C=new Map(o.map(u=>[u.id,u.label]));for(const u of((S=r==null?void 0:r.capture)==null?void 0:S.events)??[])for(const j of u.sessionIds??[])C.has(j)||C.set(j,j.slice(0,8));for(const u of x)C.has(u)||C.set(u,u.slice(0,8));return e.jsxs("div",{className:"tr-body",children:[e.jsxs("div",{className:"tr-navigation",children:[e.jsx("div",{className:"tr-tabs",role:"tablist","aria-label":"Radar views",onKeyDown:p,children:[["monitor","Monitor"],["configuration","Configuration"],["file","File"]].map(([u,j])=>e.jsx("button",{id:`tr-tab-${u}`,className:"tr-tab",role:"tab","aria-selected":c===u,"aria-controls":`tr-panel-${u}`,tabIndex:c===u?0:-1,onClick:()=>g(u),children:j},u))}),e.jsxs("label",{className:"tr-session-filter",children:["Session",e.jsxs(de,{value:h,onChange:u=>i(u.target.value),"aria-label":"Session",children:[e.jsx("option",{value:"all",children:"All sessions"}),[...C].map(([u,j])=>e.jsxs("option",{value:u,children:[j," · ",u.slice(0,8)]},u)),e.jsx("option",{value:"unidentified",children:"Unidentified session"})]})]}),e.jsxs("details",{className:"tr-help",children:[e.jsxs("summary",{children:[e.jsx(G,{kind:"info"}),e.jsx("span",{className:"tr-help-label",children:"About Radar"})]}),e.jsxs("div",{children:[e.jsx("h3",{children:"What does Radar show?"}),e.jsx("p",{children:"See what Claude Code sends to your telemetry collectors. Destinations can be configured by you or your organization."}),e.jsx("p",{children:"Radar inspects configured OpenTelemetry exports, including prompts or responses when enabled and captured. It does not show everything Claude knows about you, ordinary AI requests, or Anthropic’s separate service telemetry."}),e.jsx("p",{children:"An address does not identify who owns a collector or who can access its data. Encrypted connections can be observed, but their contents cannot be decoded here."}),e.jsx("a",{href:"https://code.claude.com/docs/en/monitoring-usage",target:"_blank",rel:"noreferrer",children:"Claude Code telemetry documentation"})]})]})]}),e.jsx("div",{className:"tr-page",id:"tr-panel-monitor",role:"tabpanel","aria-labelledby":"tr-tab-monitor",hidden:c!=="monitor",children:r?e.jsx(Ns,{...r,radar:t&&s?{...s,status:"unavailable"}:s,sessionFilter:h,sessions:o}):e.jsx("p",{className:"tr-empty",children:"Reading monitor status…"})}),e.jsxs("div",{className:"tr-page",id:"tr-panel-configuration",role:"tabpanel","aria-labelledby":"tr-tab-configuration",hidden:c!=="configuration",children:[e.jsxs("div",{className:"tr-summary",children:[e.jsxs("div",{className:"tr-summary-state",children:[e.jsx("span",{className:`tr-state ${t||!s?"tr-tone-unknown":w==="Enabled in settings"?"tr-tone-enabled":"tr-tone-unknown"}`,children:t?"Configuration unavailable":s?w==="Unknown"?"Configuration unknown":w:"Reading settings…"}),e.jsx("span",{className:"tr-note",children:y.length?`${y.length} configured destination${y.length===1?"":"s"}`:"No destination found in the settings files read. Telemetry may still be running."})]}),y.length>0&&e.jsx("div",{className:"tr-endpoints",children:y.map(u=>e.jsx("code",{children:u},u))}),!y.length&&R.length>0&&e.jsxs("div",{className:"tr-observed-summary",children:[e.jsx("span",{className:"tr-state",children:"Claude connections observed"}),e.jsx("div",{className:"tr-endpoints",children:R.map(u=>e.jsx("code",{children:u},u))}),e.jsx("p",{className:"tr-note",children:"These are active connections, not confirmed telemetry messages. Choose an observed address below to inspect its traffic."})]})]}),s?e.jsx(Cs,{snapshot:s,stale:t,sessionLabel:h==="all"?void 0:C.get(h)??h}):e.jsx("p",{className:"tr-empty",children:t?"Could not read settings. Sampling will retry.":"Reading local settings…"})]}),e.jsx("div",{className:"tr-page",id:"tr-panel-file",role:"tabpanel","aria-labelledby":"tr-tab-file",hidden:c!=="file",children:e.jsx(ws,{onSessions:d,sessionFilter:h})})]})}function Cs({snapshot:s,sessionLabel:t,stale:r=!1}){var d,h;const o=((d=s.config)==null?void 0:d.variables)??[],c=o.filter(i=>i.key.endsWith("ENDPOINT")),g=o.filter(i=>i.key.startsWith("OTEL_LOG_")||i.key.includes("ENABLE")||i.key.includes("TELEMETRY_BETA")),x={CLAUDE_CODE_ENABLE_TELEMETRY:"Telemetry",OTEL_LOG_USER_PROMPTS:"Your prompts",OTEL_LOG_ASSISTANT_RESPONSES:"Claude responses",OTEL_LOG_TOOL_DETAILS:"Tool details",OTEL_LOG_TOOL_CONTENT:"Tool contents",OTEL_LOG_RAW_API_BODIES:"Full API bodies",OTEL_LOG_MANAGED_SETTINGS:"Managed settings",CLAUDE_CODE_ENHANCED_TELEMETRY_BETA:"Enhanced telemetry",ENABLE_ENHANCED_TELEMETRY_BETA:"Enhanced telemetry"};return e.jsxs("section",{className:"tr-config","aria-label":"Telemetry configuration",children:[e.jsx("h3",{children:"What Claude is configured to send"}),r&&e.jsx("p",{className:"tr-warning",role:"status",children:"Last successfully read settings. Current configuration could not be verified."}),e.jsx("p",{className:"tr-note",children:"Read from local Claude settings. The effective environment of a running session is not verified."}),t&&e.jsxs("p",{className:"tr-note",children:["Selected session: ",t,". These shared settings are evidence; this session’s runtime values are unverified."]}),e.jsx("h4",{children:"Destinations"}),c.length?e.jsx("ul",{className:"tr-destinations",children:c.map(i=>e.jsxs("li",{children:[e.jsx("code",{children:i.value}),e.jsxs("span",{children:[i.source," · ",i.key]})]},`${i.source}:${i.key}`))}):e.jsx("p",{className:"tr-note",children:"No destination found in the sources read. This does not mean telemetry is off."}),!c.length&&s.connections.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("h4",{children:"Observed Claude connections"}),e.jsx("ul",{className:"tr-live-connections",children:s.connections.map(i=>e.jsxs("li",{children:[e.jsx("code",{children:i.destination}),e.jsxs("span",{children:[r||i.active===null?"Visibility unavailable":i.active?"Active connection":"Previously observed"," · PID ",i.pid," · ",i.workspace??"Workspace unknown"]})]},`${i.pid}:${i.destination}`))}),e.jsx("p",{className:"tr-note",children:"A running process can keep previously loaded settings after a settings file disappears. Connections alone do not identify telemetry or prove a message was sent."})]}),e.jsx("h4",{children:"Telemetry and content"}),g.length?e.jsx("dl",{className:"tr-variables",children:g.map(i=>e.jsxs("div",{children:[e.jsxs("dt",{children:[e.jsx("strong",{children:x[i.key]??i.key}),e.jsx("code",{children:i.key}),e.jsx("span",{children:i.source})]}),e.jsxs("dd",{children:[e.jsx("span",{className:`tr-state ${i.value.startsWith("Enabled")?"tr-tone-enabled":"tr-tone-unknown"}`,children:i.value}),i.rawValue!==void 0&&e.jsx("code",{className:"tr-raw-flag",children:i.rawValue})]})]},`${i.source}:${i.key}`))}):e.jsx("p",{className:"tr-note",children:"No telemetry flags found in the settings read."}),e.jsxs("details",{className:"tr-details",children:[e.jsx("summary",{children:"All variables and sources"}),e.jsx("dl",{className:"tr-variables",children:o.map(i=>e.jsxs("div",{children:[e.jsxs("dt",{children:[e.jsx("code",{children:i.key}),e.jsx("span",{children:i.source})]}),e.jsx("dd",{children:i.value})]},`${i.source}:${i.key}`))}),e.jsx("ul",{className:"tr-sources",children:(h=s.config)==null?void 0:h.sources.map(i=>e.jsxs("li",{children:[e.jsx("span",{children:i.name}),e.jsx("span",{children:i.status==="read"?"Read":i.status==="absent"?"Not found":"Unavailable"})]},i.name))}),e.jsx("p",{className:"tr-note",children:"Endpoint credentials and headers are hidden. Settings can differ from an already running process."})]})]})}export{Cs as Configuration,Ss as TrafficRadarView,Ts as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as O,f as p,r as i,s as Z,p as _,j as a,b as g,c as I,u as ee,d as se,e as ae,g as te,h as E,i as ne,k as oe}from"./index-
|
|
1
|
+
import{a as O,f as p,r as i,s as Z,p as _,j as a,b as g,c as I,u as ee,d as se,e as ae,g as te,h as E,i as ne,k as oe}from"./index-CxIdVCPz.js";function le(s){return!s.answer||s.answer.range!==s.want?{phase:"busy",stale:!1}:s.answer.ok?{phase:s.answer.days>0?"chart":"empty",stale:s.loading}:{phase:"error",stale:s.loading}}function q(s){const e=new Map;for(const n of s)for(const o of n.agents??[]){if(!o||typeof o.agent!="string"||o.agent==="")continue;const r=e.get(o.agent)??{id:o.agent,cost:0,tokens:0};r.cost+=Number.isFinite(o.totalCost)?o.totalCost:0,r.tokens+=Number.isFinite(o.totalTokens)?o.totalTokens:0,e.set(o.agent,r)}return[...e.values()].sort((n,o)=>o.cost-n.cost||n.id.localeCompare(o.id))}function re(s){const e=q([{agents:s}]);return e.length<2?null:e.map(n=>`${O(n.id)} ${p(n.cost)}`).join(" · ")}function F(s){switch(s.toLowerCase()){case"claude":return"var(--model-opus)";case"codex":return"var(--model-codex)";case"gemini":return"var(--model-gemini)";case"copilot":return"var(--model-haiku)";default:return"var(--model-other)"}}function ce(s,e){if(!(e>0)||!(s>0))return"0%";const n=s/e*100;return n<.1?"<0.1%":`${n.toFixed(1)}%`}const u=s=>typeof s=="number"&&Number.isFinite(s)?s:0,$=s=>typeof s=="string"?s:"",U=s=>Array.isArray(s)?s.filter(e=>typeof e=="string"):[];function ie(s){const e=s??{};return{modelName:$(e.modelName),cost:u(e.cost),inputTokens:u(e.inputTokens),outputTokens:u(e.outputTokens),cacheCreationTokens:u(e.cacheCreationTokens),cacheReadTokens:u(e.cacheReadTokens)}}function ue(s){const e=s??{},n=Array.isArray(e.agents)?e.agents.map(o=>{const r=o??{};return{agent:$(r.agent),totalCost:u(r.totalCost),totalTokens:u(r.totalTokens)}}):void 0;return{period:$(e.period),totalCost:u(e.totalCost),totalTokens:u(e.totalTokens),inputTokens:u(e.inputTokens),outputTokens:u(e.outputTokens),cacheCreationTokens:u(e.cacheCreationTokens),cacheReadTokens:u(e.cacheReadTokens),modelsUsed:U(e.modelsUsed),modelBreakdowns:Array.isArray(e.modelBreakdowns)?e.modelBreakdowns.map(ie):[],...n?{agents:n}:{},...e.metadata&&typeof e.metadata=="object"?{metadata:{agents:U(e.metadata.agents)}}:{}}}function de(s){const e=s??{};return{...e,ok:e.ok===!0,days:Array.isArray(e.days)?e.days.map(ue):void 0}}function C(s){const e=s.toLowerCase();return e.includes("opus")?"var(--model-opus)":e.includes("sonnet")?"var(--model-sonnet)":e.includes("haiku")?"var(--model-haiku)":e.includes("gpt-5")||e.includes("gpt5")?"var(--model-gpt5)":e.includes("gpt")?"var(--model-gpt)":e.includes("gemini")?"var(--model-gemini)":e.includes("codex")?"var(--model-codex)":e.includes("fable")||e.includes("mythos")?"var(--model-fable)":"var(--model-other)"}function he(s){let e=0,n=0,o=0,r=0;const m=new Map;for(const l of s){e+=l.totalCost,n+=l.totalTokens,o+=l.inputTokens+l.outputTokens,r+=l.cacheReadTokens;for(const d of l.modelBreakdowns)m.set(d.modelName,(m.get(d.modelName)??0)+d.cost)}return{totalCost:e,totalTok:n,inOut:o,cacheRead:r,modelCosts:m}}function me(s){return Array.from(s.entries()).sort((e,n)=>n[1]-e[1])}function G(s){return s.slice().sort((e,n)=>n.cost-e.cost)}function v(s,e){return e>0?s/e*100:0}function pe(s){var n,o;return re(s.agents)??((o=(n=s.metadata)==null?void 0:n.agents)!=null&&o.length?s.metadata.agents.join(" · "):null)}function ge(){let s=0;return{begin(){const e=++s;return()=>e===s},cancel(){s++}}}function fe(s){const[e,n]=i.useState(null),[o,r]=i.useState(!1),m=i.useState(ge)[0],l=i.useRef(!1),d=(f=!1)=>{if(f&&!Z(l.current))return;const x=m.begin();l.current=f;const j=s;r(!0);const h=`/api/ccusage?since=${_(j)}${f?"&refresh=1":""}`;fetch(h).then(c=>c.json()).then(c=>{x()&&n({range:j,resp:de(c)})}).catch(()=>{x()&&n({range:j,resp:{ok:!1,reason:"unreachable"}})}).finally(()=>{x()&&(l.current=!1,r(!1))})};return i.useEffect(()=>(d(!1),()=>m.cancel()),[s]),{landed:e,loading:o,reload:()=>d(!0)}}function xe({selectedDay:s}){const e=pe(s);return a.jsxs("div",{className:"uh-detail",children:[a.jsxs("div",{className:"uh-detail-head",children:[a.jsx("span",{className:"uh-detail-date",children:s.period}),a.jsx("span",{className:"uh-detail-cost",children:p(s.totalCost)}),e&&a.jsx("span",{className:"uh-detail-agents",title:e,children:e})]}),a.jsxs("div",{className:"uh-detail-mini",children:[a.jsx(b,{label:"input",val:g(s.inputTokens)}),a.jsx(b,{label:"output",val:g(s.outputTokens)}),a.jsx(b,{label:"cache write",val:g(s.cacheCreationTokens)}),a.jsx(b,{label:"cache read",val:g(s.cacheReadTokens)})]}),a.jsx("div",{className:"uh-detail-models",children:G(s.modelBreakdowns).map(n=>{const o=v(n.cost,s.totalCost);return a.jsxs("div",{className:"uh-model-row",title:n.modelName,children:[a.jsxs("span",{className:"uh-model-name",children:[a.jsx("span",{className:"uh-legend-dot",style:{background:C(n.modelName)}}),a.jsx("span",{className:"uh-model-label",children:I(n.modelName)})]}),a.jsx("span",{className:"uh-model-bar",children:a.jsx("span",{className:"uh-model-bar-fill",style:{width:`${o}%`,background:C(n.modelName)}})}),a.jsx("span",{className:"uh-model-cost",children:p(n.cost)})]},n.modelName)})})]})}function b({label:s,val:e}){return a.jsxs("div",{className:"uh-ministat",children:[a.jsx("span",{className:"uh-ministat-val",children:e}),a.jsx("span",{className:"uh-ministat-label",children:s})]})}const je=[7,14,30,90];function Ne({onClose:s,providers:e}){var P;const[n,o]=i.useState(30),[r,m]=i.useState(null),{landed:l,loading:d,reload:f}=fe(n),x=i.useRef(null),j=ee(s,{focusRef:x}),S=se(s),h=le({loading:d,want:n,answer:l&&{range:l.range,ok:l.resp.ok===!0,days:((P=l.resp.days)==null?void 0:P.length)??0}}),c=h.phase==="chart"?l.resp.days??[]:[],M=i.useRef(null),H=ae(h.phase!=="error",M),V=i.useMemo(()=>c.reduce((t,k)=>Math.max(t,k.totalCost),0),[c]),A=i.useRef(null);i.useLayoutEffect(()=>{const t=A.current;t&&(t.scrollLeft=t.scrollWidth)},[c]);const{totalCost:T,totalTok:W,inOut:z,cacheRead:D,modelCosts:L}=i.useMemo(()=>he(c),[c]),J=i.useMemo(()=>me(L),[L]),N=i.useMemo(()=>q(c),[c]),K=N.length>1,B=r?c.find(t=>t.period===r)??null:null;return a.jsx("div",{className:"modal-backdrop",...S,role:"presentation",children:a.jsxs("div",{ref:j,className:"modal uh-modal",onClick:t=>t.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":"Usage history",children:[a.jsxs("header",{className:"uh-head",children:[a.jsxs("div",{className:"uh-titlewrap",children:[a.jsx("div",{className:"uh-title",children:"Usage history"}),a.jsx("div",{className:"uh-sub",children:h.stale?"running ccusage…":te(e,N.map(t=>t.id))})]}),a.jsx("div",{className:"uh-range",role:"group","aria-label":"Range",children:je.map(t=>a.jsxs("button",{type:"button","aria-pressed":n===t,className:"uh-range-btn",onClick:()=>{o(t),m(null)},children:[t,"d"]},t))}),a.jsx("button",{ref:M,className:"glyph-btn uh-reload",onClick:f,...E(d),title:"Re-run ccusage","aria-label":"Reload",children:d?"…":"↻"}),a.jsx("button",{ref:x,className:"glyph-btn uh-close",onClick:s,"aria-label":"Close",children:"×"})]}),h.phase==="busy"?a.jsxs("div",{className:"uh-status uh-status-wait","aria-busy":"true",children:[a.jsx("span",{className:"uh-wait-word",children:l?"running ccusage…":"running ccusage… (first run downloads the package)"}),a.jsx("span",{className:"uh-wait-axis","aria-hidden":!0})]}):h.phase==="error"?a.jsxs("div",{className:"uh-status uh-err",title:oe(l.resp)||void 0,children:[ne(l.resp,"ccusage did not report usage"),a.jsx("div",{children:a.jsx("button",{className:"btn uh-retry",onClick:()=>{H(),f()},...E(d),children:d?"trying…":"Try again"})})]}):h.phase==="empty"?a.jsx("div",{className:`uh-status${h.stale?" uh-stale":""}`,"aria-busy":h.stale||void 0,children:"no usage in this range"}):a.jsxs("div",{className:h.stale?"uh-stale":void 0,"aria-busy":h.stale||void 0,children:[a.jsxs("div",{className:"uh-totals",children:[a.jsx(y,{label:"total cost",val:p(T),accent:!0}),a.jsx(y,{label:"tokens",val:g(W)}),a.jsx(y,{label:"input+output",val:g(z)}),a.jsx(y,{label:"cache reads",val:g(D)})]}),K&&a.jsxs("div",{className:"uh-agents",role:"group","aria-label":"Cost by CLI",children:[a.jsx("div",{className:"uh-agent-bar","aria-hidden":"true",children:N.map(t=>a.jsx("span",{className:"uh-agent-seg",style:{width:`${v(t.cost,T)}%`,background:F(t.id)}},t.id))}),a.jsx("div",{className:"uh-agent-keys",children:N.map(t=>a.jsxs("span",{className:"uh-agent-key",title:`${t.id} · ${g(t.tokens)} tokens`,children:[a.jsx("span",{className:"uh-legend-dot",style:{background:F(t.id)}}),O(t.id),a.jsx("span",{className:"uh-agent-cost",children:p(t.cost)}),a.jsx("span",{className:"uh-agent-share",children:ce(t.cost,T)})]},t.id))})]}),a.jsx("div",{ref:A,className:"uh-chart",role:"group","aria-label":"Daily cost by model",children:c.map((t,k)=>{const Q=v(t.totalCost,V),w=t.period===r,X=`${t.period}, ${p(t.totalCost)}`;return a.jsxs("button",{className:`uh-bar-col${w?" sel":""}`,onClick:()=>m(w?null:t.period),"aria-pressed":w,"aria-label":X,title:`${t.period} · ${p(t.totalCost)}`,style:{flexBasis:`${100/c.length}%`,"--uh-i":k,"--uh-step":`${Math.min(10,200/Math.max(c.length,1))}ms`},children:[a.jsx("div",{className:"uh-bar",style:{height:`${Math.max(Q,t.totalCost>0?2:0)}%`},children:G(t.modelBreakdowns).map(R=>{const Y=v(R.cost,t.totalCost);return a.jsx("div",{className:"uh-bar-seg",style:{height:`${Y}%`,background:C(R.modelName)}},R.modelName)})}),a.jsx("span",{className:"uh-bar-label",children:t.period.slice(5)})]},t.period)})}),a.jsx("div",{className:"uh-legend",children:J.map(([t,k])=>a.jsxs("span",{className:"uh-legend-item",title:t,children:[a.jsx("span",{className:"uh-legend-dot",style:{background:C(t)}}),I(t)," ",a.jsx("span",{className:"uh-legend-cost",children:p(k)})]},t))}),B&&a.jsx(xe,{selectedDay:B})]})]})})}function y({label:s,val:e,accent:n}){return a.jsxs("div",{className:"uh-stat",children:[a.jsx("span",{className:`uh-stat-val${n?" accent":""}`,children:e}),a.jsx("span",{className:"uh-stat-label",children:s})]})}export{Ne as default};
|