ccdeck 3.40.2 → 3.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -2
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/dist/web/assets/{BrowserWatchModal-CEWlounF.js → BrowserWatchModal-s7_Wr7WT.js} +1 -1
- package/dist/web/assets/RadioPanel-UcoMDWAH.js +1 -0
- package/dist/web/assets/TrafficRadar-9Qlon_77.js +1 -0
- package/dist/web/assets/{UsageHistoryModal-DLExexb7.js → UsageHistoryModal-CGh4GESl.js} +1 -1
- package/dist/web/assets/ad-B18i8NGa.svg +150 -0
- package/dist/web/assets/ae-CZRtWSox.svg +6 -0
- package/dist/web/assets/af-C77Rf6cE.svg +81 -0
- package/dist/web/assets/ag-C8MykuG2.svg +14 -0
- package/dist/web/assets/ai-Dmedkf4v.svg +29 -0
- package/dist/web/assets/al-10QRkakw.svg +5 -0
- package/dist/web/assets/am-DMt4_dd4.svg +5 -0
- package/dist/web/assets/ao-tXuRa6vm.svg +13 -0
- package/dist/web/assets/aq-CF5jO-0h.svg +5 -0
- package/dist/web/assets/ar-Be8Ju1cG.svg +32 -0
- package/dist/web/assets/as-Dekqy8Of.svg +72 -0
- package/dist/web/assets/at-DGA_6m5E.svg +4 -0
- package/dist/web/assets/au-DAHDIuPI.svg +8 -0
- package/dist/web/assets/aw-W0PWLK5p.svg +186 -0
- package/dist/web/assets/ax-DvLIy84U.svg +18 -0
- package/dist/web/assets/az-Bk-bYNxy.svg +8 -0
- package/dist/web/assets/ba-WdDiSMvP.svg +12 -0
- package/dist/web/assets/bb-DJxbaxmT.svg +6 -0
- package/dist/web/assets/bd-BF9t1-60.svg +4 -0
- package/dist/web/assets/be-CLLkK3PN.svg +7 -0
- package/dist/web/assets/bf-YclsoDuF.svg +7 -0
- package/dist/web/assets/bg-GUQenraa.svg +5 -0
- package/dist/web/assets/bh-BQqEGq6F.svg +4 -0
- package/dist/web/assets/bi-CRmKY6RQ.svg +15 -0
- package/dist/web/assets/bj-14PhO9bM.svg +14 -0
- package/dist/web/assets/bl-4CI2YcwX.svg +5 -0
- package/dist/web/assets/bm-BeYgB2z9.svg +97 -0
- package/dist/web/assets/bn-B6T3O78g.svg +36 -0
- package/dist/web/assets/bo-CcUiMqkJ.svg +673 -0
- package/dist/web/assets/bq-BYpdxEeT.svg +5 -0
- package/dist/web/assets/br-Cu5YU29T.svg +45 -0
- package/dist/web/assets/bs-7Gd_oriM.svg +13 -0
- package/dist/web/assets/bt-BTo4qm10.svg +89 -0
- package/dist/web/assets/bv-wM9JLv4R.svg +13 -0
- package/dist/web/assets/bw-n5ZaAnGL.svg +7 -0
- package/dist/web/assets/by-C621sBpd.svg +18 -0
- package/dist/web/assets/bz-BCKHR4_q.svg +145 -0
- package/dist/web/assets/ca-PYUrLVUV.svg +4 -0
- package/dist/web/assets/cc-BNT6Xjzk.svg +19 -0
- package/dist/web/assets/cd-BGclsrP6.svg +5 -0
- package/dist/web/assets/cf-DRetLmp-.svg +15 -0
- package/dist/web/assets/cg-CwIyG6SE.svg +12 -0
- package/dist/web/assets/ch-sfriZoF1.svg +9 -0
- package/dist/web/assets/ci-C8Q8IYTn.svg +7 -0
- package/dist/web/assets/ck-DfXMUOTo.svg +9 -0
- package/dist/web/assets/cl-BgYYb4qP.svg +13 -0
- package/dist/web/assets/cm-D4yjdmKT.svg +15 -0
- package/dist/web/assets/cn-DifnnI3t.svg +11 -0
- package/dist/web/assets/co-DV591zMm.svg +7 -0
- package/dist/web/assets/cp-K_ay05Q_.svg +7 -0
- package/dist/web/assets/cr-BlYVN-_Q.svg +7 -0
- package/dist/web/assets/cu-L6XVZNgo.svg +13 -0
- package/dist/web/assets/cv-CPsfcOfk.svg +13 -0
- package/dist/web/assets/cw-BbrnximR.svg +14 -0
- package/dist/web/assets/cx-DpYD6n6U.svg +15 -0
- package/dist/web/assets/cy-bZuP8hmf.svg +6 -0
- package/dist/web/assets/cz-WWBC5Aeb.svg +5 -0
- package/dist/web/assets/de-B-2o-4Z9.svg +5 -0
- package/dist/web/assets/dg-CJPJrjiZ.svg +130 -0
- package/dist/web/assets/dj-hp_BwbmO.svg +13 -0
- package/dist/web/assets/dk-DmS9BCZB.svg +5 -0
- package/dist/web/assets/dm-Cbhezfe1.svg +152 -0
- package/dist/web/assets/do-B86d445t.svg +121 -0
- package/dist/web/assets/dz-Dytc1TFu.svg +5 -0
- package/dist/web/assets/ec-CaVOFQ3t.svg +138 -0
- package/dist/web/assets/ee-DufrxGIR.svg +5 -0
- package/dist/web/assets/eg-YC70hswZ.svg +38 -0
- package/dist/web/assets/eh-0awM4TVj.svg +16 -0
- package/dist/web/assets/er-X83uml6t.svg +8 -0
- package/dist/web/assets/es-d5m8M5h8.svg +544 -0
- package/dist/web/assets/et-DwdlzOIx.svg +14 -0
- package/dist/web/assets/eu-Brdgz8ab.svg +28 -0
- package/dist/web/assets/fi-DWUIkfjL.svg +5 -0
- package/dist/web/assets/fj-DEAVMg38.svg +120 -0
- package/dist/web/assets/fk-nuUF_Ak3.svg +90 -0
- package/dist/web/assets/fm-B4Z83GL0.svg +11 -0
- package/dist/web/assets/fo-DFjwyWur.svg +12 -0
- package/dist/web/assets/fr-DVvUyOqI.svg +5 -0
- package/dist/web/assets/ga-BklUhLH_.svg +7 -0
- package/dist/web/assets/gb-DTXiLQoe.svg +7 -0
- package/dist/web/assets/gd-CO-whzUe.svg +27 -0
- package/dist/web/assets/ge-B2RiL-Ih.svg +6 -0
- package/dist/web/assets/gf-DWl5zcw0.svg +5 -0
- package/dist/web/assets/gg-jdOQS2nU.svg +9 -0
- package/dist/web/assets/gh-r3LP_X7q.svg +6 -0
- package/dist/web/assets/gi-BJKE9SzW.svg +32 -0
- package/dist/web/assets/gl-CHaBnMib.svg +4 -0
- package/dist/web/assets/gm-Bu99atwn.svg +14 -0
- package/dist/web/assets/gn-1dJNy9oQ.svg +7 -0
- package/dist/web/assets/gp-DNyt_wTA.svg +5 -0
- package/dist/web/assets/gq-Cag8QTk2.svg +23 -0
- package/dist/web/assets/gr-C5PU0p9p.svg +16 -0
- package/dist/web/assets/gs-DiiNa0F5.svg +133 -0
- package/dist/web/assets/gt-CJo5DI-7.svg +204 -0
- package/dist/web/assets/gu-Di1JYREk.svg +19 -0
- package/dist/web/assets/gw-D249VY33.svg +13 -0
- package/dist/web/assets/gy-CcVYUM2E.svg +9 -0
- package/dist/web/assets/hk-CUNIaSX0.svg +8 -0
- package/dist/web/assets/hm-Dh6t_Tj3.svg +8 -0
- package/dist/web/assets/hn-CRjyS_bm.svg +18 -0
- package/dist/web/assets/hr-fzLfaANM.svg +58 -0
- package/dist/web/assets/ht-DIMg4gti.svg +116 -0
- package/dist/web/assets/hu-7Q5wwIIi.svg +7 -0
- package/dist/web/assets/ic-CSo4d8tH.svg +7 -0
- package/dist/web/assets/id-DiSP6Fmm.svg +4 -0
- package/dist/web/assets/ie-ChAXClx3.svg +7 -0
- package/dist/web/assets/il-_56OEGLa.svg +14 -0
- package/dist/web/assets/im--VPIqfkF.svg +36 -0
- package/dist/web/assets/in-Cdwu6Bq7.svg +25 -0
- package/dist/web/assets/index-B9pQ4U7M.js +305 -0
- package/dist/web/assets/index-BhNayHbp.css +1 -0
- package/dist/web/assets/io-13HOfeJD.svg +130 -0
- package/dist/web/assets/iq-Dp8HDzo2.svg +10 -0
- package/dist/web/assets/ir-cCIgaNf6.svg +219 -0
- package/dist/web/assets/is-CZjefTNV.svg +12 -0
- package/dist/web/assets/it-Br7q0Zh6.svg +7 -0
- package/dist/web/assets/je-DyWbhIiC.svg +62 -0
- package/dist/web/assets/jm-CItSr3iX.svg +8 -0
- package/dist/web/assets/jo-BAF1FGbm.svg +16 -0
- package/dist/web/assets/jp-BIMmfxpO.svg +11 -0
- package/dist/web/assets/ke-C8foqndp.svg +23 -0
- package/dist/web/assets/kg-B0FsxZiL.svg +4 -0
- package/dist/web/assets/kh-BeWfuE30.svg +61 -0
- package/dist/web/assets/ki-p_fAQGbS.svg +36 -0
- package/dist/web/assets/km-B5tqtGG7.svg +16 -0
- package/dist/web/assets/kn-DVPxDkNY.svg +14 -0
- package/dist/web/assets/kp-CrDKzoxe.svg +15 -0
- package/dist/web/assets/kr-BCXH1Hao.svg +24 -0
- package/dist/web/assets/kw-fSBzmd30.svg +13 -0
- package/dist/web/assets/ky-Dpsu1myA.svg +103 -0
- package/dist/web/assets/kz-CwKXYZ8s.svg +36 -0
- package/dist/web/assets/la-CuJflhIW.svg +12 -0
- package/dist/web/assets/lb-BSjpYEoo.svg +15 -0
- package/dist/web/assets/lc-CNvab8Ae.svg +8 -0
- package/dist/web/assets/li-CHdhvNcr.svg +43 -0
- package/dist/web/assets/lk-DUkgV9Tq.svg +22 -0
- package/dist/web/assets/lr-B84vu3Ds.svg +14 -0
- package/dist/web/assets/ls-5Xk3Mxq5.svg +8 -0
- package/dist/web/assets/lt-DoukV-Sm.svg +7 -0
- package/dist/web/assets/lu-DOI02Msy.svg +5 -0
- package/dist/web/assets/lv-C-KfY8Yc.svg +6 -0
- package/dist/web/assets/ly-BWpTK3ux.svg +13 -0
- package/dist/web/assets/ma-BTRNTRUj.svg +4 -0
- package/dist/web/assets/mc-PK078JHl.svg +6 -0
- package/dist/web/assets/md-DRlxvNwm.svg +70 -0
- package/dist/web/assets/me-Cv4Gwqah.svg +116 -0
- package/dist/web/assets/mf-BaAGWwAq.svg +5 -0
- package/dist/web/assets/mg-C168LHXW.svg +7 -0
- package/dist/web/assets/mh-gxuIp6Wk.svg +7 -0
- package/dist/web/assets/mk-D9SIMr-a.svg +5 -0
- package/dist/web/assets/ml-DVf6ujpi.svg +7 -0
- package/dist/web/assets/mm-lwT09MQ0.svg +12 -0
- package/dist/web/assets/mn-CgXyw0O9.svg +14 -0
- package/dist/web/assets/mo-BAtCjuYA.svg +9 -0
- package/dist/web/assets/mp-CrOApEqW.svg +86 -0
- package/dist/web/assets/mq-BFnJ22KI.svg +5 -0
- package/dist/web/assets/mr-D6G1wpeZ.svg +6 -0
- package/dist/web/assets/ms-DxciGbUu.svg +29 -0
- package/dist/web/assets/mt-YqzKx9xl.svg +58 -0
- package/dist/web/assets/mu-mcq7cUFl.svg +8 -0
- package/dist/web/assets/mv-BynAllfM.svg +6 -0
- package/dist/web/assets/mw-C15nc1xZ.svg +10 -0
- package/dist/web/assets/mx-Cc8Ccfe8.svg +382 -0
- package/dist/web/assets/my-Co4JeeyE.svg +26 -0
- package/dist/web/assets/mz-Drlr_USV.svg +21 -0
- package/dist/web/assets/na-D79ffb4Z.svg +16 -0
- package/dist/web/assets/nc-5j7wEmDR.svg +13 -0
- package/dist/web/assets/ne-B1jPOYkl.svg +6 -0
- package/dist/web/assets/nf-Dl00mlk2.svg +9 -0
- package/dist/web/assets/ng-su4NM9If.svg +6 -0
- package/dist/web/assets/ni-CcFCSQxm.svg +129 -0
- package/dist/web/assets/nl-BnOa6UiA.svg +5 -0
- package/dist/web/assets/no-qf2JPO73.svg +7 -0
- package/dist/web/assets/np-CIuq5GKd.svg +13 -0
- package/dist/web/assets/nr-DERIdzkN.svg +12 -0
- package/dist/web/assets/nu-BfgWvGcd.svg +10 -0
- package/dist/web/assets/nz-5vODdBjz.svg +36 -0
- package/dist/web/assets/om-DcqxRdQL.svg +115 -0
- package/dist/web/assets/pa-BLNN9G2-.svg +14 -0
- package/dist/web/assets/pc-BJpYiA9b.svg +33 -0
- package/dist/web/assets/pe-BLqhuu1C.svg +4 -0
- package/dist/web/assets/pf-C8ahG68q.svg +19 -0
- package/dist/web/assets/pg-BAYpbp9Z.svg +9 -0
- package/dist/web/assets/ph-BEzTn62K.svg +6 -0
- package/dist/web/assets/pk-CWMEc3ad.svg +15 -0
- package/dist/web/assets/pl-o38JROoc.svg +6 -0
- package/dist/web/assets/pm-CHiP5UmZ.svg +5 -0
- package/dist/web/assets/pn-DgxdtieE.svg +53 -0
- package/dist/web/assets/pr-B4tMV0xm.svg +13 -0
- package/dist/web/assets/ps-DO8YKYeS.svg +6 -0
- package/dist/web/assets/pt-DZ2ADgIR.svg +57 -0
- package/dist/web/assets/pw-CQP52WMX.svg +11 -0
- package/dist/web/assets/py-mNzh0mZC.svg +157 -0
- package/dist/web/assets/qa-Dkmpc78M.svg +4 -0
- package/dist/web/assets/re-Bk4ipYK1.svg +5 -0
- package/dist/web/assets/ro-CoSeqKY1.svg +7 -0
- package/dist/web/assets/rs-BfwKwXtn.svg +292 -0
- package/dist/web/assets/ru-D-4tNwXt.svg +5 -0
- package/dist/web/assets/rw-D7nbSYKI.svg +13 -0
- package/dist/web/assets/sa-Dh79zbT9.svg +25 -0
- package/dist/web/assets/sb-BDTYjcbk.svg +13 -0
- package/dist/web/assets/sc-CRNsSLg9.svg +7 -0
- package/dist/web/assets/sd-ClziNjGr.svg +13 -0
- package/dist/web/assets/se-8C923vhy.svg +4 -0
- package/dist/web/assets/sg-DGYIMG0G.svg +13 -0
- package/dist/web/assets/sh-DNImvbrE.svg +7 -0
- package/dist/web/assets/si-BMKT-Tec.svg +18 -0
- package/dist/web/assets/sj-BFFEGknm.svg +7 -0
- package/dist/web/assets/sk-K9BNIYAO.svg +9 -0
- package/dist/web/assets/sl-DxLJY5vJ.svg +7 -0
- package/dist/web/assets/sm-DGBIRFB_.svg +75 -0
- package/dist/web/assets/sn-S8ipNF1U.svg +8 -0
- package/dist/web/assets/so-DlzA2Fco.svg +11 -0
- package/dist/web/assets/sr-Co7OKBh3.svg +6 -0
- package/dist/web/assets/ss-CxVEpdPD.svg +8 -0
- package/dist/web/assets/st-C1Nd1c3V.svg +16 -0
- package/dist/web/assets/sv-CJIHhYwF.svg +593 -0
- package/dist/web/assets/sx-nDhIaDNb.svg +56 -0
- package/dist/web/assets/sy-DwSud114.svg +6 -0
- package/dist/web/assets/sz-qxMwa2gs.svg +34 -0
- package/dist/web/assets/tc-dtelpZmc.svg +50 -0
- package/dist/web/assets/td-BsuVhZpT.svg +7 -0
- package/dist/web/assets/tf-Co33RhQH.svg +15 -0
- package/dist/web/assets/tg-CP1-sc35.svg +14 -0
- package/dist/web/assets/th-tzq84hgd.svg +7 -0
- package/dist/web/assets/tj-b-aWfOTb.svg +22 -0
- package/dist/web/assets/tk-CDucsEss.svg +5 -0
- package/dist/web/assets/tl-wpo93AGk.svg +13 -0
- package/dist/web/assets/tm-C_WSgUcv.svg +204 -0
- package/dist/web/assets/tn-BcKCZULf.svg +4 -0
- package/dist/web/assets/to-D8uVsoxb.svg +10 -0
- package/dist/web/assets/tr-Cd6FO9Bg.svg +8 -0
- package/dist/web/assets/tt-CTnr7aY5.svg +5 -0
- package/dist/web/assets/tv-DDqkVT-n.svg +9 -0
- package/dist/web/assets/tw-d-Mf-0VT.svg +34 -0
- package/dist/web/assets/tz-BjLtHeil.svg +13 -0
- package/dist/web/assets/ua-Bq0XgQqK.svg +6 -0
- package/dist/web/assets/ug-ByL2ejGl.svg +30 -0
- package/dist/web/assets/um-Bhke9Eic.svg +9 -0
- package/dist/web/assets/un-Bqg4Cbbh.svg +16 -0
- package/dist/web/assets/us-C73uVeEr.svg +9 -0
- package/dist/web/assets/uy-DD6peej-.svg +28 -0
- package/dist/web/assets/uz-C2f-Cubn.svg +30 -0
- package/dist/web/assets/va-B9-hqIE-.svg +190 -0
- package/dist/web/assets/vc-COpmFovN.svg +8 -0
- package/dist/web/assets/ve-BSqnIB9l.svg +26 -0
- package/dist/web/assets/vg-C7xY6pic.svg +59 -0
- package/dist/web/assets/vi-BC_zcciE.svg +28 -0
- package/dist/web/assets/vn-BEAEijd0.svg +11 -0
- package/dist/web/assets/vu-D6k0NQlg.svg +21 -0
- package/dist/web/assets/wf-DrxpOO_G.svg +5 -0
- package/dist/web/assets/ws-vzJNwdVm.svg +7 -0
- package/dist/web/assets/xk-Bj15g7cp.svg +5 -0
- package/dist/web/assets/xx-zm_JmrXl.svg +4 -0
- package/dist/web/assets/ye-BwST9gXC.svg +7 -0
- package/dist/web/assets/yt-DIfEG0ex.svg +5 -0
- package/dist/web/assets/za-Jz40JTrv.svg +17 -0
- package/dist/web/assets/zm-BmsW91ne.svg +27 -0
- package/dist/web/assets/zw-U0m7oJ5e.svg +21 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/release-notes.json +26 -0
- package/src/server/ccusage-session.mjs +17 -0
- package/src/server/codex-quota.mjs +7 -1
- package/src/server/index.mjs +4 -1
- package/src/server/quota-history.mjs +149 -0
- package/src/server/quota.mjs +7 -2
- package/src/server/request-gates.mjs +1 -0
- package/src/server/traffic-radar-config.mjs +35 -3
- package/src/server/traffic-radar-routes.mjs +13 -0
- package/src/server/traffic-radar.mjs +12 -1
- package/src/server/usage-routes.mjs +12 -0
- package/dist/web/assets/RadioPanel-B7qs4g1T.js +0 -1
- package/dist/web/assets/TrafficRadar-CGsJ5yOZ.js +0 -1
- package/dist/web/assets/index-B_uYtqRM.css +0 -1
- package/dist/web/assets/index-BepyDfFS.js +0 -306
package/README.md
CHANGED
|
@@ -166,7 +166,9 @@ Open **Telemetry Radar** from the right rail, or **More → Telemetry Radar** on
|
|
|
166
166
|
phone. Three views keep configuration, observed traffic and saved files separate:
|
|
167
167
|
|
|
168
168
|
- **Monitor** lists decoded messages and unreadable connection observations.
|
|
169
|
-
|
|
169
|
+
The empty view shows one workspace. History controls and filters appear under
|
|
170
|
+
**Filters and history** once activity arrives; the inspector appears alongside
|
|
171
|
+
the list. Filter by session, destination or message type, then select a message for its
|
|
170
172
|
readable overview or decoded **JSON**. Session attribution comes from IDs in
|
|
171
173
|
the captured payload; absent IDs remain unidentified, and an export containing
|
|
172
174
|
multiple session IDs is shown under each matching session.
|
|
@@ -174,7 +176,12 @@ phone. Three views keep configuration, observed traffic and saved files separate
|
|
|
174
176
|
their sources. Enabled flags are highlighted and recognized boolean values
|
|
175
177
|
are shown as written. These are settings-file evidence, not confirmation of a
|
|
176
178
|
running session's effective environment. Credentials and endpoint paths stay
|
|
177
|
-
hidden.
|
|
179
|
+
hidden. Each recognized telemetry/content flag has a switch that saves its
|
|
180
|
+
value to Claude's user settings for new sessions. Flags set by organization or
|
|
181
|
+
managed settings show **Managed** and require an administrator to change;
|
|
182
|
+
Radar does not rewrite cached organization policy. Controls are unavailable
|
|
183
|
+
when configuration cannot be verified. Unknown values offer explicit
|
|
184
|
+
**Enable** and **Disable** actions.
|
|
178
185
|
- **File** opens a local JSON or JSONL file, lists its records and shows the
|
|
179
186
|
original text. Files stay in the browser and are never uploaded. Search and
|
|
180
187
|
session filtering narrow the list. Inputs are bounded to 10 MB and 10,000
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -662,3 +662,32 @@ The radio map includes simplified country geometry from Natural Earth
|
|
|
662
662
|
https://github.com/nvkelso/natural-earth-vector. Natural Earth data is public
|
|
663
663
|
domain: https://www.naturalearthdata.com/about/terms-of-use/.
|
|
664
664
|
The bundled representation is in `src/web/assets/radio-world.json`.
|
|
665
|
+
|
|
666
|
+
## Radio country flags — flag-icons 7.5.0
|
|
667
|
+
|
|
668
|
+
The local SVG country flags distributed in the browser bundle come from
|
|
669
|
+
https://github.com/lipis/flag-icons (4:3 assets, unchanged).
|
|
670
|
+
|
|
671
|
+
```text
|
|
672
|
+
The MIT License (MIT)
|
|
673
|
+
|
|
674
|
+
Copyright (c) 2013 Panayiotis Lipiridis
|
|
675
|
+
|
|
676
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
677
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
678
|
+
the Software without restriction, including without limitation the rights to
|
|
679
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
680
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
681
|
+
so, subject to the following conditions:
|
|
682
|
+
|
|
683
|
+
The above copyright notice and this permission notice shall be included in all
|
|
684
|
+
copies or substantial portions of the Software.
|
|
685
|
+
|
|
686
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
687
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
688
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
689
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
690
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
691
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
692
|
+
SOFTWARE.
|
|
693
|
+
```
|
|
@@ -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-BepyDfFS.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-B9pQ4U7M.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};
|