@ainyc/canonry 4.112.1 → 4.112.3
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/assets/assets/BacklinksPage-D00sAx6q.js +1 -0
- package/assets/assets/{ChartPrimitives-DlR18JC8.js → ChartPrimitives-BjcDtBSv.js} +1 -1
- package/assets/assets/{ProjectPage-YPn3c4hw.js → ProjectPage-DVED6lF7.js} +1 -1
- package/assets/assets/{RunRow-CSbZ7ZRo.js → RunRow-Chc7eyZU.js} +1 -1
- package/assets/assets/RunsPage-DQ8ip0Tf.js +1 -0
- package/assets/assets/SettingsPage-CZokCKF4.js +1 -0
- package/assets/assets/{TrafficPage-CbHemY4N.js → TrafficPage-C0nEB9tv.js} +1 -1
- package/assets/assets/TrafficSourceDetailPage-CKsWe8kA.js +1 -0
- package/assets/assets/{arrow-left-DXeXxwzj.js → arrow-left-CeWmJYLI.js} +1 -1
- package/assets/assets/{extract-error-message-nw2axb0s.js → extract-error-message-b-rZowjX.js} +1 -1
- package/assets/assets/{index-BERU9Kvl.css → index-D01sTTr1.css} +1 -1
- package/assets/assets/{index-Cg-EISGh.js → index-DB_F_WFv.js} +52 -52
- package/assets/assets/{trash-2-DhPiFFSU.js → trash-2-6CLXNfZm.js} +1 -1
- package/assets/index.html +2 -2
- package/package.json +9 -9
- package/assets/assets/BacklinksPage-B8Vtj78r.js +0 -1
- package/assets/assets/RunsPage-CSo26DbG.js +0 -1
- package/assets/assets/SettingsPage-Dxdr95It.js +0 -1
- package/assets/assets/TrafficSourceDetailPage-BxMqtq8o.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c}from"./index-
|
|
1
|
+
import{c}from"./index-DB_F_WFv.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],n=c("circle-question-mark",e);const o=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=c("download",o);const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n as a};
|
package/assets/index.html
CHANGED
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
<link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
|
|
13
13
|
<link rel="apple-touch-icon" href="./apple-touch-icon.png" />
|
|
14
14
|
<title>Canonry</title>
|
|
15
|
-
<script type="module" crossorigin src="./assets/index-
|
|
15
|
+
<script type="module" crossorigin src="./assets/index-DB_F_WFv.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Be8JdV5M.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-CQ77EO2y.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-C9EZkgbP.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="./assets/vendor-markdown-6dwjPOKK.js">
|
|
20
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
20
|
+
<link rel="stylesheet" crossorigin href="./assets/index-D01sTTr1.css">
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
|
23
23
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "4.112.
|
|
3
|
+
"version": "4.112.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -65,27 +65,27 @@
|
|
|
65
65
|
"@types/node-cron": "^3.0.11",
|
|
66
66
|
"tsup": "^8.5.1",
|
|
67
67
|
"tsx": "^4.19.0",
|
|
68
|
-
"@ainyc/canonry-api-routes": "0.0.0",
|
|
69
68
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
69
|
+
"@ainyc/canonry-api-routes": "0.0.0",
|
|
70
70
|
"@ainyc/canonry-config": "0.0.0",
|
|
71
|
-
"@ainyc/canonry-contracts": "0.0.0",
|
|
72
71
|
"@ainyc/canonry-db": "0.0.0",
|
|
72
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
73
73
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
74
|
-
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
75
74
|
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
75
|
+
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
76
76
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
77
|
-
"@ainyc/canonry-integration-google": "0.0.0",
|
|
78
77
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
78
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
79
79
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
80
80
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
81
|
-
"@ainyc/canonry-
|
|
81
|
+
"@ainyc/canonry-intelligence": "0.0.0",
|
|
82
82
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
83
|
+
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
83
84
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
84
|
-
"@ainyc/canonry-provider-local": "0.0.0",
|
|
85
|
-
"@ainyc/canonry-intelligence": "0.0.0",
|
|
86
85
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
87
86
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
88
|
-
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
87
|
+
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
88
|
+
"@ainyc/canonry-provider-local": "0.0.0"
|
|
89
89
|
},
|
|
90
90
|
"scripts": {
|
|
91
91
|
"build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as n,j as e}from"./vendor-tanstack-Be8JdV5M.js";import{c as E,bU as O,ag as V,bV as U,bW as Y,bX as J,g as l,aJ as L,T as f,B as z,i as A,ap as K,bY as X,bZ as Z,aj as ee,b_ as se}from"./index-Cg-EISGh.js";import{C as ae,D as te,T as ne,a as ce}from"./trash-2-DhPiFFSU.js";import"./vendor-radix-CQ77EO2y.js";import"./vendor-recharts-C9EZkgbP.js";import"./vendor-markdown-6dwjPOKK.js";const ie=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]],re=E("circle-alert",ie);const le=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]],de=E("external-link",le);function h({children:a,label:m="More info",placement:t="top",className:d}){const o=n.useId(),[y,r]=n.useState(!1);return e.jsxs("span",{className:`relative inline-flex ${d??""}`,children:[e.jsx("button",{type:"button","aria-label":m,"aria-describedby":y?o:void 0,className:"inline-flex h-4 w-4 items-center justify-center rounded-full text-zinc-500 hover:text-zinc-200 focus:text-zinc-200 focus:outline-none focus-visible:ring-1 focus-visible:ring-zinc-500",onMouseEnter:()=>r(!0),onMouseLeave:()=>r(!1),onFocus:()=>r(!0),onBlur:()=>r(!1),children:e.jsx(ce,{className:"h-3.5 w-3.5","aria-hidden":!0})}),y&&e.jsx("span",{id:o,role:"tooltip",className:`absolute z-50 w-64 rounded border border-zinc-700 bg-zinc-900 px-3 py-2 text-xs font-normal leading-relaxed text-zinc-200 shadow-lg ${t==="top"?"bottom-full mb-2":"top-full mt-2"} left-1/2 -translate-x-1/2 whitespace-normal`,children:a})]})}const oe="https://commoncrawl.org/web-graphs";function w(a){return a==null?"—":a>=1e12?`${(a/1e12).toFixed(1)} TB`:a>=1e9?`${(a/1e9).toFixed(1)} GB`:a>=1e6?`${(a/1e6).toFixed(1)} MB`:a>=1e3?`${(a/1e3).toFixed(1)} KB`:`${a} B`}function b(a){if(!a)return"—";const m=Date.now()-new Date(a).getTime(),t=Math.floor(m/6e4);if(t<1)return"just now";if(t<60)return`${t}m ago`;const d=Math.floor(t/60);return d<24?`${d}h ago`:`${Math.floor(d/24)}d ago`}function v(a){switch(a){case"ready":return"positive";case"failed":return"negative";case"downloading":case"querying":case"queued":return"caution"}}function fe(){const[a,m]=n.useState(null),[t,d]=n.useState(null),[o,y]=n.useState([]),[r,M]=n.useState([]),[u,P]=n.useState(null),[D,C]=n.useState(!0),[S,B]=n.useState(!1),[p,R]=n.useState(!1),[N,g]=n.useState(""),[F,k]=n.useState(!1),[q,i]=n.useState(null),[I,x]=n.useState(null),j=n.useCallback(async()=>{C(!0),i(null);try{const[s,c,_,W,H]=await Promise.all([O(),V().catch(()=>null),U().catch(()=>[]),Y().catch(()=>[]),J().catch(()=>null)]);m(s),d(c),y(_),M(W),P(H)}catch(s){i(s instanceof Error?s.message:"Failed to load backlinks status")}finally{C(!1)}},[]);n.useEffect(()=>{j()},[j]);async function $(){B(!0),i(null),x(null);try{const s=await X();x(s.alreadyPresent?`DuckDB already installed (${s.version}).`:`Installed DuckDB ${s.version}.`),await j()}catch(s){i(s instanceof Error?s.message:"Failed to install DuckDB")}finally{B(!1)}}async function T(){const s=N.trim()||void 0;R(!0),i(null),x(null);try{const c=await Z(s);x(s?`Queued sync for ${c.release}. Download + query runs in the background.`:`Queued sync for auto-discovered release ${c.release}. Download + query runs in the background.`),g(""),k(!1),await j()}catch(c){c instanceof ee&&c.code==="MISSING_DEPENDENCY"?i("DuckDB is not installed. Install it first."):i(c instanceof Error?c.message:"Failed to trigger sync")}finally{R(!1)}}async function Q(s){i(null),x(null);try{await se(s),x(`Pruned cached release ${s}.`),await j()}catch(c){i(c instanceof Error?c.message:"Failed to prune release")}}const G=t?.status==="ready"&&r.every(s=>s.release!==t.release);return e.jsxs("div",{className:"page-container",children:[e.jsx("div",{className:"page-header",children:e.jsxs("div",{className:"page-header-left",children:[e.jsx("h1",{className:"page-title",children:"Backlinks"}),e.jsx("p",{className:"page-subtitle",children:"Find domains that link to your projects, computed from the open Common Crawl web graph. Runs entirely on your machine — nothing is sent to third parties."})]})}),e.jsx(l,{className:"surface-card p-4 mb-6 border-amber-800/60",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(L,{className:"h-5 w-5 text-amber-400 shrink-0 mt-0.5","aria-hidden":!0}),e.jsxs("div",{className:"text-sm text-zinc-300 leading-relaxed",children:[e.jsx("p",{className:"font-medium text-amber-200",children:"Heads up — a release sync is a large download."}),e.jsxs("ul",{className:"mt-1.5 space-y-1 text-zinc-400",children:[e.jsxs("li",{children:[e.jsx("span",{className:"text-zinc-200",children:"~16 GB"})," of gzipped vertex + edge files per release, stored at"," ",e.jsx("code",{className:"text-zinc-300",children:"~/.canonry/cache/commoncrawl/"}),"."]}),e.jsxs("li",{children:[e.jsx("span",{className:"text-zinc-200",children:"10–20 min on a fast connection"})," for the download, then ~5 min for the DuckDB query."]}),e.jsx("li",{children:"One sync covers every project in this workspace. Releases are immutable, so the download only happens once per release."})]})]})]})}),e.jsxs("section",{className:"page-section-divider",children:[e.jsx("div",{className:"section-head section-head-inline",children:e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"About"}),e.jsx("h2",{children:"How it works"})]})}),e.jsxs(l,{className:"surface-card p-5",children:[e.jsxs("p",{className:"text-sm text-zinc-400 leading-relaxed max-w-3xl mb-4",children:["Common Crawl publishes a quarterly snapshot of the public web’s hyperlink graph. Canonry downloads one"," ",e.jsx("span",{className:"text-zinc-200",children:"release"})," at a time and extracts backlinks for every project in this workspace in a single pass."]}),e.jsxs("ol",{className:"space-y-3 text-sm text-zinc-400 max-w-3xl",children:[e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"shrink-0 inline-flex h-6 w-6 items-center justify-center rounded-full border border-zinc-700 bg-zinc-900 text-xs font-semibold text-zinc-300 tabular-nums",children:"1"}),e.jsxs("span",{children:[e.jsx("span",{className:"text-zinc-200 font-medium",children:"Download (one-time, ~16 GB)"})," — vertex + edge files cached to"," ",e.jsx("code",{className:"text-zinc-300",children:"~/.canonry/cache/commoncrawl/"}),". Runs once per release; subsequent operations reuse the cache."]})]}),e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"shrink-0 inline-flex h-6 w-6 items-center justify-center rounded-full border border-zinc-700 bg-zinc-900 text-xs font-semibold text-zinc-300 tabular-nums",children:"2"}),e.jsxs("span",{children:[e.jsx("span",{className:"text-zinc-200 font-medium",children:"Query (~5 min)"})," — one DuckDB pass scans the cached files and extracts referring domains for every project’s canonical domain. DuckDB is only used to ",e.jsx("span",{className:"text-zinc-200",children:"read"})," these dumps; it doesn’t store any canonry state."]})]}),e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"shrink-0 inline-flex h-6 w-6 items-center justify-center rounded-full border border-zinc-700 bg-zinc-900 text-xs font-semibold text-zinc-300 tabular-nums",children:"3"}),e.jsxs("span",{children:[e.jsx("span",{className:"text-zinc-200 font-medium",children:"Persist"})," — results land in the same SQLite database the rest of canonry uses. After the first sync, per-project reads (and re-run extracts against the cached release) are instant."]})]})]})]})]}),q&&e.jsx(l,{className:"surface-card p-4 mb-4 border-rose-800/60",children:e.jsx("p",{className:"text-sm text-rose-300",children:q})}),I&&e.jsx(l,{className:"surface-card p-4 mb-4 border-emerald-800/60",children:e.jsx("p",{className:"text-sm text-emerald-300",children:I})}),e.jsxs("section",{className:"page-section-divider",children:[e.jsxs("div",{className:"section-head section-head-inline",children:[e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Dependency"}),e.jsxs("h2",{className:"flex items-center gap-2",children:["DuckDB install status",e.jsxs(h,{label:"Why DuckDB?",children:[e.jsx("span",{className:"block",children:"DuckDB is a query engine canonry uses to scan the ~16 GB Common Crawl dumps and pull out your referring domains."}),e.jsxs("span",{className:"mt-2 block text-zinc-400",children:["It does ",e.jsx("span",{className:"text-zinc-200",children:"not"})," store any canonry data — your backlink results live in SQLite alongside the rest of your projects. DuckDB is purely a tool for processing the raw CSV files."]}),e.jsxs("span",{className:"mt-2 block text-zinc-500",children:["Installed on demand (not bundled) into ",e.jsx("code",{className:"text-zinc-300",children:"~/.canonry/plugins/"})," so users who never run backlinks don’t pay the ~40 MB install cost."]})]})]})]}),a?.duckdbInstalled?e.jsx(f,{tone:"positive",children:"Installed"}):e.jsx(f,{tone:"caution",children:"Not installed"})]}),e.jsx(l,{className:"surface-card p-5",children:D?e.jsx("p",{className:"text-sm text-zinc-500",children:"Checking…"}):a?.duckdbInstalled?e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(ae,{className:"h-5 w-5 text-emerald-400 shrink-0 mt-0.5","aria-hidden":!0}),e.jsxs("div",{children:[e.jsxs("p",{className:"text-sm text-zinc-200",children:["Version ",a.duckdbVersion??"unknown"," installed at"," ",e.jsx("code",{className:"text-zinc-300",children:a.pluginDir})]}),e.jsxs("p",{className:"text-xs text-zinc-500 mt-1",children:["Required spec: ",a.duckdbSpec]})]})]}):e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(re,{className:"h-5 w-5 text-amber-400 shrink-0 mt-0.5","aria-hidden":!0}),e.jsxs("div",{className:"flex-1",children:[e.jsx("p",{className:"text-sm text-zinc-200",children:"DuckDB is not installed. It’s the query engine canonry uses to scan Common Crawl dumps — required before you can run a release sync or per-project extract."}),e.jsx("p",{className:"text-xs text-zinc-500 mt-1",children:"Installing doesn’t touch your project data. DuckDB only reads the downloaded CSV files; backlink results are written to the same SQLite database canonry already uses."}),a&&e.jsxs("p",{className:"text-xs text-zinc-500 mt-1",children:["Will be installed into ",e.jsx("code",{className:"text-zinc-300",children:a.pluginDir})," (~40 MB)."]}),e.jsx("div",{className:"mt-3",children:e.jsxs(z,{type:"button",size:"sm",disabled:S,onClick:A($),children:[e.jsx(te,{className:"h-4 w-4 mr-1.5","aria-hidden":!0}),S?"Installing…":"Install DuckDB"]})})]})]})})]}),e.jsxs("section",{className:"page-section-divider",children:[e.jsxs("div",{className:"section-head section-head-inline",children:[e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Latest sync"}),e.jsxs("h2",{className:"flex items-center gap-2",children:["Release sync",e.jsx(h,{label:"What is a release sync?",children:"A release sync downloads one Common Crawl dump (~16 GB) and extracts backlinks for every project in this workspace in one pass. This is the heavy job — subsequent per-project re-runs skip the download and just re-query the cached files."})]})]}),t&&e.jsx(f,{tone:v(t.status),children:t.status})]}),e.jsxs(l,{className:"surface-card p-5",children:[e.jsxs("p",{className:"text-xs text-zinc-500 max-w-3xl mb-4",children:["A release is one Common Crawl dump (e.g. ",e.jsx("code",{className:"text-zinc-400",children:"cc-main-2026-jan-feb-mar"}),"). Syncing it downloads the graph and populates backlinks for every project in this workspace."]}),t?e.jsxs("div",{className:"space-y-2 text-sm",children:[e.jsxs("p",{className:"text-zinc-200",children:["Release ",e.jsx("code",{className:"text-zinc-300",children:t.release})]}),t.phaseDetail&&e.jsx("p",{className:"text-zinc-500",children:t.phaseDetail}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 text-xs text-zinc-500 pt-2",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-zinc-600 uppercase tracking-wide",children:"Projects"}),e.jsx("p",{className:"text-zinc-300 mt-0.5",children:t.projectsProcessed??"—"})]}),e.jsxs("div",{children:[e.jsxs("p",{className:"text-zinc-600 uppercase tracking-wide flex items-center gap-1",children:["Rows",e.jsx(h,{label:"What are rows?",children:"Total number of (project, referring domain) pairs persisted in SQLite from this sync, across every project in the workspace."})]}),e.jsx("p",{className:"text-zinc-300 mt-0.5",children:t.domainsDiscovered??"—"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-zinc-600 uppercase tracking-wide",children:"Started"}),e.jsx("p",{className:"text-zinc-300 mt-0.5",children:b(t.downloadStartedAt??t.createdAt)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-zinc-600 uppercase tracking-wide",children:"Finished"}),e.jsx("p",{className:"text-zinc-300 mt-0.5",children:b(t.queryFinishedAt)})]})]}),t.error&&e.jsx("p",{className:"text-sm text-rose-400 pt-2",children:t.error})]}):e.jsx("p",{className:"text-sm text-zinc-500",children:"No release sync has run in this workspace yet."}),G&&e.jsx("div",{className:"mt-4 rounded border border-amber-800/60 bg-amber-950/20 p-3",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(L,{className:"h-4 w-4 text-amber-400 shrink-0 mt-0.5","aria-hidden":!0}),e.jsxs("div",{className:"text-xs text-zinc-300 leading-relaxed",children:[e.jsx("p",{className:"font-medium text-amber-200",children:"Cached files for this release are missing."}),e.jsxs("p",{className:"mt-1 text-zinc-400",children:["The sync record in the database says this release finished successfully, but the ~16 GB dump at"," ",e.jsxs("code",{className:"text-zinc-300",children:["~/.canonry/cache/commoncrawl/",t?.release,"/"]})," isn’t on disk. Your backlink data is still intact (it lives in SQLite), but per-project re-run extracts will fail until you either re-sync this release or start a new one."]})]})]})}),e.jsxs("div",{className:"mt-4 rounded border border-zinc-800 bg-zinc-900/40 p-3",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 mb-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] uppercase tracking-wide text-zinc-500",children:"Auto-detected release"}),u?e.jsxs("p",{className:"text-sm text-zinc-200 mt-0.5",children:[e.jsx("code",{className:"text-zinc-100",children:u.release}),e.jsxs("span",{className:"ml-2 text-xs text-zinc-500",children:["— vertex ",w(u.vertexBytes),", edges ",w(u.edgesBytes)]})]}):e.jsx("p",{className:"text-sm text-zinc-500 mt-0.5",children:D?"Probing Common Crawl…":"Could not auto-detect — pass an explicit release below."}),e.jsxs("a",{href:oe,target:"_blank",rel:"noopener noreferrer",className:"mt-1 inline-flex items-center gap-1 text-xs text-zinc-400 hover:text-zinc-200 focus:text-zinc-200 focus:outline-none focus-visible:ring-1 focus-visible:ring-zinc-500 rounded",children:["Browse all Common Crawl web-graph releases",e.jsx(de,{className:"h-3 w-3","aria-hidden":!0})]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsxs(z,{type:"button",size:"sm",disabled:p||!a?.duckdbInstalled||!u&&!N.trim(),onClick:A(T),children:[e.jsx(K,{className:"h-4 w-4 mr-1.5","aria-hidden":!0}),p?"Queuing…":"Run sync"]}),e.jsxs(h,{label:"What does Run sync do?",children:[e.jsxs("span",{className:"block",children:["Downloads the auto-detected (or chosen) Common Crawl release (~16 GB) to"," ",e.jsx("code",{className:"text-zinc-300",children:"~/.canonry/cache/commoncrawl/"}),", then runs a single DuckDB query that extracts referring domains for every project in this workspace."]}),e.jsxs("span",{className:"mt-2 block text-zinc-400",children:["First time for a release: ",e.jsx("span",{className:"text-zinc-200",children:"~10–20 min download + ~5 min query"}),". Re-running the same release later: ",e.jsx("span",{className:"text-zinc-200",children:"skips download, just re-queries"})," (~5 min)."]})]})]})]}),F?e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("input",{type:"text",className:"flex-1 min-w-[240px] rounded border border-zinc-700 bg-transparent px-2.5 py-1.5 text-sm text-zinc-200 placeholder-zinc-600 focus:border-zinc-500 focus:outline-none",placeholder:"cc-main-2026-jan-feb-mar",value:N,onChange:s=>g(s.target.value),disabled:p,autoFocus:!0}),e.jsx("button",{type:"button",className:"text-xs text-zinc-500 hover:text-zinc-300 focus:text-zinc-300 focus:outline-none focus-visible:ring-1 focus-visible:ring-zinc-500 rounded",onClick:()=>{g(""),k(!1)},disabled:p,children:"Cancel"})]}):e.jsx("button",{type:"button",className:"text-xs text-zinc-500 hover:text-zinc-300 focus:text-zinc-300 focus:outline-none focus-visible:ring-1 focus-visible:ring-zinc-500 rounded",onClick:()=>k(!0),disabled:p,children:"Use a different release →"})]}),!a?.duckdbInstalled&&e.jsx("p",{className:"text-xs text-zinc-600 mt-2",children:"Install DuckDB first to enable sync."})]})]}),e.jsxs("section",{className:"page-section-divider",children:[e.jsx("div",{className:"section-head section-head-inline",children:e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Cached releases"}),e.jsxs("h2",{className:"flex items-center gap-2",children:["Local disk cache",e.jsxs(h,{label:"What is this?",children:[e.jsxs("span",{className:"block",children:["Raw Common Crawl dumps stored at"," ",e.jsx("code",{className:"text-zinc-300",children:"~/.canonry/cache/commoncrawl/<release>/"}),". Each release takes ~16 GB."]}),e.jsxs("span",{className:"mt-2 block text-zinc-400",children:["These files are needed to re-run per-project extracts against a release without re-downloading. Pruning here ",e.jsx("span",{className:"text-zinc-200",children:"does not delete your backlink data"})," — that lives in SQLite."]})]})]})]})}),e.jsx("p",{className:"text-xs text-zinc-500 mb-3 max-w-3xl",children:"Each cached release is a ~16 GB pair of gzipped files. They’re needed to re-query the graph (e.g. for a newly-added project) without re-downloading. Safe to prune — backlink results persist in SQLite."}),e.jsx(l,{className:"surface-card overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-zinc-800 text-left text-xs uppercase tracking-wide text-zinc-600",children:[e.jsx("th",{className:"px-4 py-2 font-medium",children:"Release"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Sync status"}),e.jsx("th",{className:"px-4 py-2 text-right font-medium",children:"Size"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Last used"}),e.jsx("th",{className:"px-4 py-2 font-medium sr-only",children:"Actions"})]})}),e.jsxs("tbody",{children:[r.map(s=>e.jsxs("tr",{className:"border-b border-zinc-900 last:border-0",children:[e.jsx("td",{className:"px-4 py-2 text-zinc-200",children:e.jsx("code",{children:s.release})}),e.jsx("td",{className:"px-4 py-2",children:s.syncStatus?e.jsx(f,{tone:v(s.syncStatus),children:s.syncStatus}):e.jsx("span",{className:"text-zinc-600",children:"—"})}),e.jsx("td",{className:"px-4 py-2 text-right text-zinc-400 tabular-nums",children:w(s.bytes)}),e.jsx("td",{className:"px-4 py-2 text-zinc-400",children:b(s.lastUsedAt)}),e.jsx("td",{className:"px-4 py-2 text-right",children:e.jsxs("div",{className:"inline-flex items-center gap-1",children:[e.jsxs(z,{type:"button",variant:"outline",size:"sm",onClick:()=>{Q(s.release)},children:[e.jsx(ne,{className:"h-4 w-4 mr-1.5","aria-hidden":!0}),"Prune"]}),e.jsx(h,{label:"What does Prune do?",placement:"top",children:"Deletes the ~16 GB cache for this release from disk. Backlink results already in SQLite remain untouched. To re-run extracts against this release, you’d have to sync it again (another ~16 GB download)."})]})})]},s.release)),r.length===0&&e.jsx("tr",{children:e.jsx("td",{className:"px-4 py-4 text-sm text-zinc-500",colSpan:5,children:"No cached releases on this machine. If you ran a sync from a different machine (or deleted the cache), the backlink data is still in the database — but you’ll need to re-sync a release to run new extracts."})})]})]})})]}),o.length>1&&e.jsxs("section",{className:"page-section-divider",children:[e.jsx("div",{className:"section-head section-head-inline",children:e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"History"}),e.jsx("h2",{children:"Past release syncs"})]})}),e.jsx(l,{className:"surface-card overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-zinc-800 text-left text-xs uppercase tracking-wide text-zinc-600",children:[e.jsx("th",{className:"px-4 py-2 font-medium",children:"Release"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Status"}),e.jsx("th",{className:"px-4 py-2 text-right font-medium",children:"Projects"}),e.jsx("th",{className:"px-4 py-2 text-right font-medium",children:"Rows"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Finished"})]})}),e.jsx("tbody",{children:o.map(s=>e.jsxs("tr",{className:"border-b border-zinc-900 last:border-0",children:[e.jsx("td",{className:"px-4 py-2 text-zinc-200",children:e.jsx("code",{children:s.release})}),e.jsx("td",{className:"px-4 py-2",children:e.jsx(f,{tone:v(s.status),children:s.status})}),e.jsx("td",{className:"px-4 py-2 text-right text-zinc-400 tabular-nums",children:s.projectsProcessed??"—"}),e.jsx("td",{className:"px-4 py-2 text-right text-zinc-400 tabular-nums",children:s.domainsDiscovered??"—"}),e.jsx("td",{className:"px-4 py-2 text-zinc-400",children:b(s.queryFinishedAt??s.updatedAt)})]},s.id))})]})})]})]})}export{fe as BacklinksPage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j as e,r as o}from"./vendor-tanstack-Be8JdV5M.js";import{bJ as m,bK as u,B as h,t as x,g as p}from"./index-Cg-EISGh.js";import{R as j}from"./RunRow-CSbZ7ZRo.js";import"./vendor-radix-CQ77EO2y.js";import"./vendor-recharts-C9EZkgbP.js";import"./vendor-markdown-6dwjPOKK.js";function y(){const{dashboard:l,isLoading:n}=m(),t=u();if(!l||n)return e.jsxs("div",{className:"page-skeleton",children:[e.jsxs("div",{className:"page-skeleton-header",children:[e.jsx("div",{className:"skeleton-text h-6 w-20"}),e.jsx("div",{className:"skeleton-text-sm w-72"})]}),e.jsx("div",{className:"space-y-2",children:[1,2,3,4].map(s=>e.jsxs("div",{className:"rounded-xl border border-zinc-800/60 bg-zinc-900/30 p-3 flex items-center gap-3",children:[e.jsxs("div",{className:"flex-1 space-y-1.5",children:[e.jsx("div",{className:"skeleton-text w-40"}),e.jsx("div",{className:"skeleton-text-sm w-56"})]}),e.jsx("div",{className:"skeleton h-5 w-16 rounded-full"})]},s))})]});const r=l.runs,[a,c]=o.useState("all"),i=a==="all"?r:r.filter(s=>s.status===a),d=async()=>{try{await t.mutateAsync(void 0)}catch{}};return e.jsxs("div",{className:"page-container",children:[e.jsxs("div",{className:"page-header",children:[e.jsxs("div",{className:"page-header-left",children:[e.jsx("h1",{className:"page-title",children:"Runs"}),e.jsx("p",{className:"page-subtitle",children:"Status, type, project, duration, and the shortest explanation that makes the outcome trustworthy."})]}),e.jsx(h,{type:"button",variant:"outline",size:"sm",disabled:t.isPending,onClick:()=>{d()},children:t.isPending?"Queueing…":"Run all projects"})]}),e.jsxs("section",{children:[e.jsx("div",{className:"filter-row",role:"toolbar","aria-label":"Run filters",children:["all","queued","running","completed","partial","failed","cancelled"].map(s=>e.jsx("button",{className:`filter-chip ${a===s?"filter-chip-active":""}`,type:"button","aria-pressed":a===s,onClick:()=>c(s),children:s==="all"?"All runs":x(s)},s))}),e.jsx("div",{className:"run-list",children:i.length>0?i.map(s=>e.jsx(j,{run:s},s.id)):e.jsxs(p,{className:"surface-card empty-card",children:[e.jsx("h2",{children:"No runs match this filter"}),e.jsx("p",{children:"Try another status filter or queue a new run from a project command center."})]})})]})]})}export{y as RunsPage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as n,j as e}from"./vendor-tanstack-Be8JdV5M.js";import{B as f,i as A,bM as $,M as B,bN as H,bO as E,g as b,T as y,bP as q,ba as Q,bJ as V,bQ as W,bR as _,bS as F,bT as T}from"./index-Cg-EISGh.js";import"./vendor-radix-CQ77EO2y.js";import"./vendor-recharts-C9EZkgbP.js";import"./vendor-markdown-6dwjPOKK.js";function J({providerName:s,keyUrl:m,modelHint:r,onSaved:j}){const u=s.toLowerCase()==="local",[o,c]=n.useState(""),[x,d]=n.useState(""),[g,h]=n.useState(""),[p,a]=n.useState(""),[l,v]=n.useState(""),[N,S]=n.useState(""),[C,k]=n.useState(!1),[w,t]=n.useState(null),[K,M]=n.useState(!1),z=u?x.trim().length>0:o.trim().length>0;async function L(){if(z){k(!0),t(null),M(!1);try{const i=U=>{const I=parseInt(U.trim(),10);return Number.isFinite(I)&&I>0?I:void 0},P={},O=i(p);O!==void 0&&(P.maxConcurrency=O);const D=i(l);D!==void 0&&(P.maxRequestsPerMinute=D);const G=i(N);G!==void 0&&(P.maxRequestsPerDay=G),await $(s.toLowerCase(),{...o.trim()?{apiKey:o.trim()}:{},...x.trim()?{baseUrl:x.trim()}:{},...g.trim()?{model:g.trim()}:{},...Object.keys(P).length>0?{quota:P}:{}}),c(""),d(""),h(""),a(""),v(""),S(""),M(!0),B({title:"Provider updated",detail:`${s} configuration saved.`,tone:"positive",dedupeKey:`settings:provider:${s}`,dedupeMode:"replace"}),j()}catch(i){t(i instanceof Error?i.message:"Failed to update provider")}finally{k(!1)}}}const R=r??"Use default model";return e.jsxs("div",{className:"mt-3 rounded-lg border border-base bg-bg-elevated/40 p-3 space-y-2",children:[u&&e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-muted",htmlFor:`base-url-${s}`,children:"Base URL"}),e.jsx("input",{id:`base-url-${s}`,type:"text",className:"mt-0.5 w-full rounded border border-strong bg-transparent px-2 py-1.5 text-sm text-strong placeholder-mono-600 focus:border-mono-500 focus:outline-none",placeholder:"http://localhost:11434/v1",value:x,onChange:i=>d(i.target.value)}),e.jsx("p",{className:"mt-0.5 text-[10px] text-faint",children:"Any OpenAI-compatible endpoint — Ollama, LM Studio, llama.cpp, vLLM"})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("label",{className:"text-xs text-muted",htmlFor:`api-key-${s}`,children:["API Key",u?" (optional)":""]}),m&&e.jsxs("a",{href:m,target:"_blank",rel:"noopener noreferrer",className:"text-[10px] text-muted hover:text-neutral underline underline-offset-2",children:["Get API key ","↗"]})]}),e.jsx("input",{id:`api-key-${s}`,type:"password",className:"mt-0.5 w-full rounded border border-strong bg-transparent px-2 py-1.5 text-sm text-strong placeholder-mono-600 focus:border-mono-500 focus:outline-none",placeholder:u?"Optional — most local servers don't need one":`Enter ${s} API key`,value:o,onChange:i=>c(i.target.value)})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-muted",htmlFor:`model-${s}`,children:"Model (optional)"}),e.jsx("input",{id:`model-${s}`,type:"text",className:"mt-0.5 w-full rounded border border-strong bg-transparent px-2 py-1.5 text-sm text-strong placeholder-mono-600 focus:border-mono-500 focus:outline-none",placeholder:R,value:g,onChange:i=>h(i.target.value)})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-muted",children:"Quota (optional)"}),e.jsxs("div",{className:"mt-0.5 grid grid-cols-3 gap-1.5",children:[e.jsxs("div",{children:[e.jsx("input",{type:"number",min:"1",className:"w-full rounded border border-strong bg-transparent px-2 py-1.5 text-sm text-strong placeholder-mono-600 focus:border-mono-500 focus:outline-none",placeholder:"Concurrent",value:p,onChange:i=>a(i.target.value)}),e.jsx("p",{className:"mt-0.5 text-[10px] text-faint",children:"Max concurrent"})]}),e.jsxs("div",{children:[e.jsx("input",{type:"number",min:"1",className:"w-full rounded border border-strong bg-transparent px-2 py-1.5 text-sm text-strong placeholder-mono-600 focus:border-mono-500 focus:outline-none",placeholder:"/min",value:l,onChange:i=>v(i.target.value)}),e.jsx("p",{className:"mt-0.5 text-[10px] text-faint",children:"Per minute"})]}),e.jsxs("div",{children:[e.jsx("input",{type:"number",min:"1",className:"w-full rounded border border-strong bg-transparent px-2 py-1.5 text-sm text-strong placeholder-mono-600 focus:border-mono-500 focus:outline-none",placeholder:"/day",value:N,onChange:i=>S(i.target.value)}),e.jsx("p",{className:"mt-0.5 text-[10px] text-faint",children:"Per day"})]})]})]}),w&&e.jsx("p",{className:"text-xs text-negative-400",children:w}),K&&e.jsx("p",{className:"text-xs text-positive-400",children:"Provider updated."}),e.jsx(f,{type:"button",size:"sm",disabled:!z||C,onClick:A(L),children:C?"Saving...":"Save"})]})}function X({onSaved:s}){const[m,r]=n.useState(""),[j,u]=n.useState(""),[o,c]=n.useState(!1),[x,d]=n.useState(null),[g,h]=n.useState(!1),p=m.trim().length>0&&j.trim().length>0;async function a(){if(p){c(!0),d(null),h(!1);try{await H({clientId:m.trim(),clientSecret:j.trim()}),r(""),u(""),h(!0),B({title:"Google OAuth app updated",detail:"Dashboard Google credentials were saved.",tone:"positive",dedupeKey:"settings:google-oauth",dedupeMode:"replace"}),s()}catch(l){d(l instanceof Error?l.message:"Failed to update Google OAuth credentials")}finally{c(!1)}}}return e.jsxs("div",{className:"mt-3 rounded-lg border border-base bg-bg-elevated/40 p-3 space-y-2",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("label",{className:"text-xs text-muted",htmlFor:"google-client-id",children:"Client ID"}),e.jsxs("a",{href:"https://console.cloud.google.com/apis/credentials",target:"_blank",rel:"noopener noreferrer",className:"text-[10px] text-muted hover:text-neutral underline underline-offset-2",children:["Google Cloud ","↗"]})]}),e.jsx("input",{id:"google-client-id",type:"text",className:"mt-0.5 w-full rounded border border-strong bg-transparent px-2 py-1.5 text-sm text-strong placeholder-mono-600 focus:border-mono-500 focus:outline-none",placeholder:"Google OAuth client ID",value:m,onChange:l=>r(l.target.value)})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-muted",htmlFor:"google-client-secret",children:"Client secret"}),e.jsx("input",{id:"google-client-secret",type:"password",className:"mt-0.5 w-full rounded border border-strong bg-transparent px-2 py-1.5 text-sm text-strong placeholder-mono-600 focus:border-mono-500 focus:outline-none",placeholder:"Google OAuth client secret",value:j,onChange:l=>u(l.target.value)})]}),e.jsxs("p",{className:"text-[11px] text-muted",children:["These credentials are stored in ",e.jsx("code",{children:"~/.canonry/config.yaml"}),". Project-level Search Console connections are created separately per canonical domain."]}),x&&e.jsx("p",{className:"text-xs text-negative-400",children:x}),g&&e.jsx("p",{className:"text-xs text-positive-400",children:"Google OAuth credentials updated."}),e.jsx(f,{type:"button",size:"sm",disabled:!p||o,onClick:A(a),children:o?"Saving...":"Save Google OAuth app"})]})}function Y(){const[s,m]=n.useState(null),[r,j]=n.useState(null),[u,o]=n.useState(!1),[c,x]=n.useState("localhost"),[d,g]=n.useState("9222"),[h,p]=n.useState(!1);return n.useEffect(()=>{E().then(m).catch(a=>{const l=a instanceof Error?a.message:String(a);l.includes("501")||j(l)})},[]),e.jsxs(b,{className:"surface-card",children:[e.jsxs("div",{className:"section-head",children:[e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Browser provider"}),e.jsx("h2",{children:"ChatGPT (CDP)"})]}),e.jsx(y,{tone:s?.connected?"positive":"caution",children:s?.connected?"Connected":"Not connected"})]}),e.jsxs("dl",{className:"definition-list mt-3",children:[s?.endpoint&&e.jsxs("div",{children:[e.jsx("dt",{children:"Endpoint"}),e.jsx("dd",{className:"font-mono text-xs",children:s.endpoint})]}),s?.browserVersion&&e.jsxs("div",{children:[e.jsx("dt",{children:"Browser"}),e.jsx("dd",{className:"text-xs",children:s.browserVersion})]}),s?.targets&&s.targets.length>0&&e.jsxs("div",{children:[e.jsx("dt",{children:"Tabs"}),e.jsx("dd",{children:s.targets.map(a=>e.jsxs("span",{className:"mr-2",children:[a.name,": ",a.alive?"● alive":"○ idle"]},a.name))})]})]}),e.jsx("p",{className:"mt-2 text-sm text-muted",children:s?.connected?"Connected to Chrome via CDP. Launch Chrome with --remote-debugging-port to use this provider.":r||"Not configured. Set an endpoint below or run: canonry cdp connect --host localhost --port 9222"}),e.jsx("div",{className:"mt-2",children:e.jsx(f,{type:"button",variant:"outline",size:"sm",onClick:()=>o(!u),children:u?"Cancel":s?.connected?"Update endpoint":"Configure"})}),u&&e.jsxs("form",{className:"mt-3 flex flex-col gap-2",onSubmit:A(async a=>{a.preventDefault(),p(!0);try{await q(c,parseInt(d,10)||9222);const l=await E().catch(()=>null);l&&m(l),o(!1),B({title:"CDP endpoint saved",detail:`${c}:${parseInt(d,10)||9222} is now configured.`,tone:"positive",dedupeKey:"settings:cdp",dedupeMode:"replace"})}catch(l){j(l instanceof Error?l.message:String(l))}finally{p(!1)}}),children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{className:"flex-1 rounded border border-strong bg-bg-elevated px-2 py-1 text-sm text-heading placeholder-mono-500 focus:outline-none focus:ring-1 focus:ring-mono-500",placeholder:"localhost",value:c,onChange:a=>x(a.target.value),"aria-label":"CDP host"}),e.jsx("input",{className:"w-24 rounded border border-strong bg-bg-elevated px-2 py-1 text-sm text-heading placeholder-mono-500 focus:outline-none focus:ring-1 focus:ring-mono-500",placeholder:"9222",value:d,onChange:a=>g(a.target.value),"aria-label":"CDP port"})]}),e.jsx("div",{children:e.jsx(f,{type:"submit",size:"sm",disabled:h,children:h?"Saving…":"Save endpoint"})})]})]})}const Z={apiStatus:{state:"checking",detail:"Checking service health"},workerStatus:{state:"checking",detail:"Checking service health"}};function le(){const s=Q(),{dashboard:m}=V(),r=m?.settings??s?.dashboard?.settings,o=W(!s,s?.health).data??s?.health??Z,[c,x]=n.useState(null),[d,g]=n.useState(!1),[h,p]=n.useState(!1),[a,l]=n.useState(""),[v,N]=n.useState(!1),[S,C]=n.useState(null),[k,w]=n.useState(!1);return r?e.jsxs("div",{className:"page-container",children:[e.jsx("div",{className:"page-header",children:e.jsxs("div",{className:"page-header-left",children:[e.jsx("h1",{className:"page-title",children:"Settings"}),e.jsx("p",{className:"page-subtitle",children:"Provider state, Google OAuth, Bing WMT setup, and service health."})]})}),e.jsxs("section",{className:"settings-grid",children:[r.providerStatuses.map(t=>e.jsxs(b,{className:"surface-card",children:[e.jsxs("div",{className:"section-head",children:[e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Provider"}),e.jsx("h2",{children:t.displayName??t.name})]}),e.jsx(y,{tone:t.state==="ready"?"positive":"caution",children:t.state==="ready"?"Ready":"Needs config"})]}),e.jsxs("dl",{className:"definition-list mt-3",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Model"}),e.jsxs("dd",{className:"font-mono text-xs",children:[t.model??t.defaultModel??"unknown",!t.model&&t.defaultModel&&e.jsx("span",{className:"ml-1 font-sans text-zinc-500",children:"(default)"})]})]}),t.quota&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Concurrency"}),e.jsx("dd",{children:t.quota.maxConcurrency})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Rate limit"}),e.jsxs("dd",{children:[t.quota.maxRequestsPerMinute,"/min · ",t.quota.maxRequestsPerDay,"/day"]})]})]})]}),e.jsx("p",{className:"mt-2 text-sm text-zinc-500",children:t.detail}),e.jsx("div",{className:"mt-2",children:e.jsx(f,{type:"button",variant:"outline",size:"sm",onClick:()=>x(c===t.name?null:t.name),children:c===t.name?"Cancel":t.state==="ready"?t.name.toLowerCase()==="local"?"Update config":"Update key":"Configure"})}),c===t.name&&e.jsx(J,{providerName:t.name,keyUrl:t.keyUrl,modelHint:t.modelHint,onSaved:()=>{x(null)}})]},t.name)),e.jsxs(b,{className:"surface-card",children:[e.jsxs("div",{className:"section-head",children:[e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Google"}),e.jsx("h2",{children:"Search Console OAuth"})]}),e.jsx(y,{tone:r.google.state==="ready"?"positive":"caution",children:r.google.state==="ready"?"Ready":"Needs config"})]}),e.jsxs("dl",{className:"definition-list mt-3",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Auth model"}),e.jsx("dd",{children:"One app credential set, then one OAuth connection per project domain"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Storage"}),e.jsx("dd",{className:"font-mono text-xs",children:"~/.canonry/config.yaml"})]})]}),e.jsx("p",{className:"mt-2 text-sm text-zinc-500",children:r.google.detail}),e.jsx("div",{className:"mt-2",children:e.jsx(f,{type:"button",variant:"outline",size:"sm",onClick:()=>g(!d),children:d?"Cancel":r.google.state==="ready"?"Update OAuth app":"Configure Google OAuth"})}),d&&e.jsx(X,{onSaved:()=>{g(!1)}})]}),e.jsxs(b,{className:"surface-card",children:[e.jsxs("div",{className:"section-head",children:[e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Bing"}),e.jsx("h2",{children:"Webmaster Tools"})]}),e.jsx(y,{tone:r.bing.state==="ready"?"positive":"caution",children:r.bing.state==="ready"?"Ready":"Needs config"})]}),e.jsxs("dl",{className:"definition-list mt-3",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Auth model"}),e.jsx("dd",{children:"API key authentication — no OAuth needed"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Storage"}),e.jsx("dd",{className:"font-mono text-xs",children:"~/.canonry/config.yaml"})]})]}),e.jsx("p",{className:"mt-2 text-sm text-zinc-500",children:r.bing.detail}),e.jsx("div",{className:"mt-2",children:e.jsx(f,{type:"button",variant:"outline",size:"sm",onClick:()=>p(!h),children:h?"Cancel":r.bing.state==="ready"?"Update API key":"Configure Bing"})}),h&&e.jsxs("div",{className:"mt-3 rounded-lg border border-zinc-800 bg-zinc-900/40 p-3 space-y-2",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("label",{className:"text-xs text-zinc-500",htmlFor:"bing-api-key",children:"API Key"}),e.jsx("a",{href:"https://www.bing.com/webmasters/",target:"_blank",rel:"noopener noreferrer",className:"text-[10px] text-zinc-500 hover:text-zinc-300 underline underline-offset-2",children:"Bing Webmaster Tools"})]}),e.jsx("input",{id:"bing-api-key",type:"password",className:"mt-0.5 w-full rounded border border-zinc-700 bg-transparent px-2 py-1.5 text-sm text-zinc-200 placeholder-zinc-600 focus:border-zinc-500 focus:outline-none",placeholder:"Bing Webmaster Tools API key",value:a,onChange:t=>l(t.target.value)})]}),e.jsxs("p",{className:"text-[11px] text-zinc-500",children:["This key is stored in ",e.jsx("code",{children:"~/.canonry/config.yaml"}),". Project-level Bing connections are created separately per canonical domain."]}),S&&e.jsx("p",{className:"text-xs text-rose-400",children:S}),k&&e.jsx("p",{className:"text-xs text-emerald-400",children:"Bing API key updated."}),e.jsx(f,{type:"button",size:"sm",disabled:!a.trim()||v,onClick:A(async()=>{if(a.trim()){N(!0),C(null),w(!1);try{await _(a.trim()),l(""),w(!0),p(!1),B({title:"Bing API key updated",detail:"Dashboard Bing credentials were saved.",tone:"positive",dedupeKey:"settings:bing",dedupeMode:"replace"})}catch(t){C(t instanceof Error?t.message:"Failed to update Bing API key")}finally{N(!1)}}}),children:v?"Saving...":"Save Bing API key"})]})]}),e.jsx(Y,{}),e.jsxs(b,{className:"surface-card",children:[e.jsx("div",{className:"section-head",children:e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Service health"}),e.jsx("h2",{children:"API and worker"})]})}),e.jsxs("div",{className:"compact-stack",children:[e.jsxs("div",{className:"health-row",children:[e.jsxs("div",{children:[e.jsx("p",{className:"run-row-title",children:"API"}),e.jsx("p",{className:"supporting-copy",children:o.apiStatus.detail})]}),e.jsx(y,{tone:T(o.apiStatus),title:F(o.apiStatus),children:o.apiStatus.state==="ok"?"Healthy":"Attention"})]}),e.jsxs("div",{className:"health-row",children:[e.jsxs("div",{children:[e.jsx("p",{className:"run-row-title",children:"Worker"}),e.jsx("p",{className:"supporting-copy",children:o.workerStatus.detail})]}),e.jsx(y,{tone:T(o.workerStatus),title:F(o.workerStatus),children:o.workerStatus.state==="ok"?"Healthy":"Attention"})]})]})]})]}),e.jsx("section",{className:"page-section",children:e.jsxs(b,{className:"surface-card",children:[e.jsx("div",{className:"section-head",children:e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Self-host notes"}),e.jsx("h2",{children:"Operational guidance"})]})}),e.jsx("ul",{className:"detail-list",children:r.selfHostNotes.map(t=>e.jsx("li",{children:t},t))}),e.jsx("p",{className:"supporting-copy",children:r.bootstrapNote})]})})]}):null}export{le as SettingsPage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j as e,B as Le,C as Re,r as h,L as $e}from"./vendor-tanstack-Be8JdV5M.js";import{I as O,c9 as Y,ca as u,T as Ue,B as Ee,g as H,b as Fe,cb as Me,cc as He}from"./index-Cg-EISGh.js";import{g as Pe,h as Oe,i as De,t as _e,R as Be,d as Ge}from"./extract-error-message-nw2axb0s.js";import{e as ee,i as Ke,C as ie,a as le,c as We,h as Ve}from"./ChartPrimitives-DlR18JC8.js";import{R as Ye,B as Xe,a as Qe,X as qe,Y as Ze,T as Je,e as X,f as Q}from"./vendor-recharts-C9EZkgbP.js";import{A as ce}from"./arrow-left-DXeXxwzj.js";import"./vendor-radix-CQ77EO2y.js";import"./vendor-markdown-6dwjPOKK.js";function q({value:s,label:a,delta:i,tone:n,description:x,tooltip:l,isNumeric:c=!0,progress:o,providerCoverage:d}){const v=2*Math.PI*48,m=Number.parseInt(s,10),A=typeof o=="number"&&Number.isFinite(o)?Math.min(Math.max(o,0),100)/100:c&&!Number.isNaN(m)?Math.min(m/100,1):.5,y=v*(1-A);return e.jsxs("div",{className:"score-gauge",children:[e.jsxs("div",{className:"gauge-ring-wrapper",children:[e.jsxs("svg",{className:"gauge-ring",viewBox:"0 0 120 120","aria-hidden":"true",children:[e.jsx("circle",{className:"gauge-bg",cx:"60",cy:"60",r:48,strokeWidth:6}),e.jsx("circle",{className:`gauge-fill gauge-fill-${n}`,cx:"60",cy:"60",r:48,strokeWidth:6,strokeDasharray:v,strokeDashoffset:y,transform:"rotate(-90 60 60)"})]}),e.jsx("div",{className:"gauge-center",children:e.jsx("span",{className:c?"gauge-value":"gauge-value-text",children:s.split(" / ")[0]})})]}),e.jsxs("p",{className:"gauge-label",children:[a,l&&e.jsx(O,{text:l})]}),e.jsx("p",{className:"gauge-delta",children:i}),d&&e.jsx("p",{className:"gauge-provider-coverage",children:d}),e.jsx("p",{className:"gauge-description",children:x})]})}const et=[{value:"all",label:"All status"},{value:"2xx",label:"2xx success"},{value:"3xx",label:"3xx redirect"},{value:"4xx",label:"4xx client error"},{value:"5xx",label:"5xx server error"}],fe=[{value:"all",label:"All claims"},{value:Y.verified,label:"Verified"},{value:Y.claimed_unverified,label:"Claimed unverified"},{value:Y.unknown_ai_like,label:"Unknown AI-like"}];function tt(s){return s==="all"?null:Number.parseInt(s[0],10)}function pe(s){switch(s.kind){case u.crawler:case u["ai-user-fetch"]:return s.botId;case u["ai-referral"]:return s.product}}function ge(s){switch(s.kind){case u.crawler:case u["ai-user-fetch"]:return s.pathNormalized;case u["ai-referral"]:return s.landingPathNormalized}}function st(s){switch(s.kind){case u.crawler:case u["ai-user-fetch"]:return s.verificationStatus;case u["ai-referral"]:return null}}function be(s,a){if(a==="hour")return s;const i=new Date(s),n=i.getFullYear(),x=String(i.getMonth()+1).padStart(2,"0"),l=String(i.getDate()).padStart(2,"0");return`${n}-${x}-${l}`}function at(s,a,i){const n=a.pathQuery.trim().toLowerCase(),x=tt(a.statusClass);return s.filter(l=>!(a.selectedBucket&&be(l.tsHour,i)!==a.selectedBucket||a.identity&&pe(l)!==a.identity||a.operator&&l.operator!==a.operator||n&&!ge(l).toLowerCase().includes(n)||x!==null&&Math.floor(l.status/100)!==x||a.verification!=="all"&&st(l)!==a.verification))}function rt(s,a){if(!s||typeof s!="object")return null;const i=s.activeTooltipIndex;let n;if(typeof i=="number")n=i;else if(typeof i=="string"&&i!=="")n=Number(i);else return null;return!Number.isInteger(n)||n<0||n>=a.length?null:a[n]?.bucket??null}const D=[{value:60,label:"1h",granularity:"hour",fetchLimit:500},{value:360,label:"6h",granularity:"hour",fetchLimit:500},{value:1440,label:"24h",granularity:"hour",fetchLimit:500},{value:10080,label:"7d",granularity:"hour",fetchLimit:1e3},{value:720*60,label:"30d",granularity:"day",fetchLimit:2e3},{value:2160*60,label:"90d",granularity:"day",fetchLimit:5e3}],oe=D.find(s=>s.label==="24h")??D[2],R=50,ue=ee[0],de=ee[2],xe=ee[1],he=Me();function je(s){const a=new Date(s);return`${a.getMonth()+1}/${a.getDate()} ${String(a.getHours()).padStart(2,"0")}:00`}function nt(s){const a=new Date(`${s}T00:00:00`);return`${a.getMonth()+1}/${a.getDate()}`}function $(s){if(!s)return"never";const a=Date.now()-new Date(s).getTime(),i=Math.floor(a/6e4);if(i<1)return"just now";if(i<60)return`${i}m ago`;const n=Math.floor(i/60);return n<24?`${n}h ago`:`${Math.floor(n/24)}d ago`}function me({canGoBack:s,className:a}){const i="inline-flex items-center gap-1";if(s){const n=()=>{window.history.back()};return e.jsxs("button",{type:"button",onClick:n,className:`${i} ${a??""}`,children:[e.jsx(ce,{className:"size-3"})," Back"]})}return e.jsxs($e,{to:"/traffic",className:`${i} ${a??""}`,children:[e.jsx(ce,{className:"size-3"})," All sources"]})}function yt(){const s=Le({strict:!1}),a=s.projectName??"",i=Re(),n=s.sourceId??"",[x,l]=h.useState(oe.value),[c,o]=h.useState(()=>new Set(["crawler","ai-user-fetch","ai-referral"])),[d,z]=h.useState(null),[f,v]=h.useState(""),[m,A]=h.useState(""),[y,_]=h.useState(""),[C,B]=h.useState("all"),[k,G]=h.useState("all"),[ye,K]=h.useState(1),[te,se]=h.useState(null),[ae,re]=h.useState(null),b=h.useMemo(()=>D.find(t=>t.value===x)??oe,[x]),W=Pe(a||null,n||null),j=Oe(a||null,{kind:"all",sourceId:n||void 0,sinceMinutes:x,limit:b.fetchLimit}),U=De(a||null,n||null),r=W.data,N=j.data?.events??[],S=j.data?.totals,E=h.useMemo(()=>N.filter(t=>{switch(t.kind){case u.crawler:return c.has("crawler");case u["ai-user-fetch"]:return c.has("ai-user-fetch");case u["ai-referral"]:return c.has("ai-referral")}}),[N,c]),ve=h.useMemo(()=>{const t=new Set;for(const p of N)t.add(pe(p));return f&&t.add(f),[...t].sort((p,g)=>p.localeCompare(g))},[N,f]),Ne=h.useMemo(()=>{const t=new Set;for(const p of N)t.add(p.operator);return m&&t.add(m),[...t].sort((p,g)=>p.localeCompare(g))},[N,m]),w=h.useMemo(()=>at(E,{selectedBucket:d,identity:f,operator:m,pathQuery:y,statusClass:C,verification:k},b.granularity),[E,d,f,m,y,C,k,b.granularity]);h.useEffect(()=>{K(1)},[E,d,f,m,y,C,k]);const F=Math.max(1,Math.ceil(w.length/R)),M=Math.min(Math.max(1,ye),F),L=(M-1)*R,Se=h.useMemo(()=>w.slice(L,L+R),[w,L]),we=w.length>R,ze=w.length===0?0:L+1,Ce=Math.min(L+R,w.length),ne=h.useMemo(()=>d?P(d,b.granularity):null,[d,b.granularity]),T=h.useMemo(()=>it(N,b.granularity,j.data?.windowStart,j.data?.windowEnd),[N,b.granularity,j.data?.windowStart,j.data?.windowEnd]),V=t=>{o(p=>{const g=new Set(p);return g.has(t)?g.size>1&&g.delete(t):g.add(t),g})},ke=t=>{const p=rt(t,T);p&&z(g=>g===p?null:p)},Te=()=>{z(null),v(""),A(""),_(""),B("all"),G("all")},Ie=!!(d||f||m||y.trim()||C!=="all"||k!=="all"),Ae=async()=>{se(null),re(null);try{const t=await U.mutateAsync({sinceMinutes:60});re(`Pulled ${t.pulledEvents} entries · ${t.crawlerHits} crawler · ${t.aiUserFetchHits} AI user fetch · ${t.aiReferralHits} AI referral · ${t.unknownHits} unknown`)}catch(t){se(Ge(t))}};return!a||!n?e.jsx("div",{className:"page-container",children:e.jsx("p",{className:"text-sm text-zinc-500",children:"Missing project name or source id in URL."})}):W.isLoading?e.jsx("div",{className:"page-container",children:e.jsx("p",{className:"text-sm text-zinc-500",children:"Loading source…"})}):W.isError||!r?e.jsxs("div",{className:"page-container",children:[e.jsx("p",{className:"text-sm text-rose-300",children:"Could not load this source."}),e.jsx(me,{canGoBack:i,className:"mt-2 text-xs text-zinc-400 hover:text-zinc-200"})]}):e.jsxs("div",{className:"page-container space-y-8",children:[e.jsxs("div",{className:"page-header",children:[e.jsxs("div",{className:"page-header-left",children:[e.jsx(me,{canGoBack:i,className:"text-xs text-zinc-500 hover:text-zinc-200"}),e.jsx("h1",{className:"page-title mt-2",children:r.displayName}),e.jsxs("p",{className:"page-subtitle",children:[r.sourceType," · project ",e.jsx("span",{className:"text-zinc-300",children:a})," ·",e.jsx("span",{className:"ml-1 font-mono text-zinc-400",children:r.id})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ue,{tone:_e(r.status),children:r.status}),e.jsxs(Ee,{type:"button",variant:"outline",size:"sm",disabled:U.isPending,onClick:()=>{Ae()},children:[e.jsx(Be,{className:`size-3.5 ${U.isPending?"animate-spin":""}`}),U.isPending?"Syncing…":"Sync now"]})]})]}),te?e.jsx("div",{className:"rounded-md border border-rose-800/50 bg-rose-950/30 px-3 py-2 text-xs text-rose-200",children:te}):null,ae?e.jsx("div",{className:"rounded-md border border-emerald-800/50 bg-emerald-950/30 px-3 py-2 text-xs text-emerald-200",children:ae}):null,e.jsxs("section",{className:"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",children:[e.jsx(q,{label:"24h content crawls",value:String(r.totals24h.crawlerContentHits),delta:r.lastSyncedAt?`last sync ${$(r.lastSyncedAt)}`:"never synced",tone:r.totals24h.crawlerContentHits>0?"positive":"neutral",description:`Pages crawled — ${r.totals24h.crawlerInfraHits.toLocaleString("en-US")} sitemap/robots/asset fetches excluded.`,tooltip:`Content-page crawls by GPTBot, OAI-SearchBot, PerplexityBot, Googlebot, etc. Infrastructure fetches (sitemap ${r.totals24h.crawlerSegments.sitemap.toLocaleString("en-US")}, robots ${r.totals24h.crawlerSegments.robots.toLocaleString("en-US")}, assets ${r.totals24h.crawlerSegments.asset.toLocaleString("en-US")}) are tracked separately so polling doesn't inflate this number. Total crawler hits: ${r.totals24h.crawlerHits.toLocaleString("en-US")}.`,isNumeric:!0,progress:Math.min(100,Math.round(r.totals24h.crawlerContentHits/1e3*100))}),e.jsx(q,{label:"24h AI user fetches",value:String(r.totals24h.aiUserFetchHits),delta:r.lastSyncedAt?`last sync ${$(r.lastSyncedAt)}`:"never synced",tone:r.totals24h.aiUserFetchHits>0?"positive":"neutral",description:"ChatGPT-User, Perplexity-User — fetches initiated by a real user inside an AI surface (citation click, URL read).",isNumeric:!0,progress:Math.min(100,Math.round(r.totals24h.aiUserFetchHits/1e3*100))}),e.jsx(q,{label:"24h AI referral sessions",value:String(r.totals24h.aiReferralHits),delta:r.lastSyncedAt?`last sync ${$(r.lastSyncedAt)}`:"never synced",tone:r.totals24h.aiReferralHits>0?"positive":"neutral",description:"Browser click-throughs from chatgpt.com, perplexity.ai, etc. (Referer / UTM evidence).",isNumeric:!0,progress:Math.min(100,Math.round(r.totals24h.aiReferralHits/1e3*100))})]}),e.jsxs("section",{children:[e.jsx("p",{className:"mb-4 text-[10px] font-semibold uppercase tracking-wider text-zinc-500",children:"Latest sync run"}),r.latestRun?e.jsxs(H,{className:"p-4 text-sm",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-6 gap-y-1.5",children:[e.jsxs("span",{className:"text-zinc-100",children:["Status: ",e.jsx("span",{className:"font-medium",children:r.latestRun.status})]}),e.jsxs("span",{className:"text-zinc-500",children:["Started: ",$(r.latestRun.startedAt)]}),r.latestRun.finishedAt?e.jsxs("span",{className:"text-zinc-500",children:["Finished: ",$(r.latestRun.finishedAt)]}):null,e.jsx("span",{className:"font-mono text-[11px] text-zinc-600",children:r.latestRun.runId})]}),r.latestRun.error?e.jsx("p",{className:"mt-2 rounded border border-rose-900/40 bg-rose-950/30 px-3 py-2 text-xs text-rose-300",children:r.latestRun.error}):null]}):e.jsx(H,{className:"px-4 py-3 text-sm text-zinc-500",children:'No traffic-sync runs recorded yet. Hit "Sync now" above to create one.'})]}),e.jsxs("section",{children:[e.jsxs("div",{className:"mb-4 flex flex-wrap items-end justify-between gap-x-4 gap-y-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-wider text-zinc-500",children:"Events"}),e.jsx("h2",{className:"mt-1 text-base font-semibold text-zinc-50",children:b.granularity==="day"?"Daily rollups":"Hourly rollups"}),S?e.jsxs("p",{className:"mt-1.5 text-xs text-zinc-500",children:[S.crawlerContentHits.toLocaleString("en-US")," content crawls ·"," ",S.crawlerInfraHits.toLocaleString("en-US")," infra (sitemap/robots/assets) ·"," ",S.aiUserFetchHits.toLocaleString("en-US")," AI user fetches ·"," ",S.aiReferralHits.toLocaleString("en-US")," AI referral sessions · last ",b.label," · ",he]}):null]}),e.jsx("div",{className:"filter-row mb-0",role:"toolbar","aria-label":"Window",children:D.map(t=>e.jsx("button",{type:"button",className:`filter-chip ${x===t.value?"filter-chip-active":""}`,"aria-pressed":x===t.value,onClick:()=>{l(t.value),z(null)},children:t.label},t.value))})]}),e.jsxs(H,{className:"p-4",children:[e.jsxs("div",{className:"mb-3 flex flex-wrap items-center gap-2",role:"toolbar","aria-label":"Series",children:[e.jsx(J,{label:"Crawler",color:ue,count:S?.crawlerHits??0,active:c.has("crawler"),onToggle:()=>V("crawler")}),e.jsx(J,{label:"AI user fetches",color:de,count:S?.aiUserFetchHits??0,active:c.has("ai-user-fetch"),onToggle:()=>V("ai-user-fetch")}),e.jsx(J,{label:"AI referral sessions",color:xe,count:S?.aiReferralHits??0,active:c.has("ai-referral"),onToggle:()=>V("ai-referral")})]}),j.isError?e.jsxs("p",{className:"py-12 text-center text-xs text-rose-400",children:["Failed to load events: ",j.error instanceof Error?j.error.message:"Unknown error"]}):j.isLoading?e.jsx("p",{className:"py-12 text-center text-xs text-zinc-500",children:"Loading events…"}):T.length===0?e.jsx("p",{className:"py-12 text-center text-xs text-zinc-500",children:"No events in this window."}):e.jsx("div",{className:"h-72",children:e.jsx(Ye,{children:e.jsxs(Xe,{data:T,margin:{top:4,right:4,bottom:0,left:0},onClick:ke,style:{cursor:"pointer"},children:[e.jsx(Qe,{stroke:Ke,strokeDasharray:"3 3"}),e.jsx(qe,{dataKey:"label",tick:le,stroke:ie,interval:"preserveStartEnd",minTickGap:b.granularity==="day"?24:32}),e.jsx(Ze,{tick:le,stroke:ie,allowDecimals:!1}),e.jsx(Je,{...We}),c.has("crawler")?e.jsx(X,{dataKey:"crawler",name:"Crawler",fill:ue,stackId:"a",children:T.map(t=>e.jsx(Q,{fillOpacity:d&&d!==t.bucket?.25:1},t.bucket))}):null,c.has("ai-user-fetch")?e.jsx(X,{dataKey:"aiUserFetch",name:"AI user fetch",fill:de,stackId:"a",children:T.map(t=>e.jsx(Q,{fillOpacity:d&&d!==t.bucket?.25:1},t.bucket))}):null,c.has("ai-referral")?e.jsx(X,{dataKey:"aiReferral",name:"AI referral",fill:xe,stackId:"a",children:T.map(t=>e.jsx(Q,{fillOpacity:d&&d!==t.bucket?.25:1},t.bucket))}):null]})})})]})]}),e.jsxs("section",{children:[e.jsxs("div",{className:"mb-4 flex flex-wrap items-end justify-between gap-x-4 gap-y-2",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-wider text-zinc-500",children:"Event rows"}),e.jsxs("p",{className:"mt-1 text-xs text-zinc-500",children:["Showing ",e.jsx("span",{className:"tabular-nums text-zinc-300",children:w.length.toLocaleString("en-US")})," of"," ",e.jsx("span",{className:"tabular-nums text-zinc-500",children:E.length.toLocaleString("en-US")})," events · ",he]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("span",{className:"inline-flex items-center text-zinc-400",children:[e.jsxs("select",{"aria-label":"Filter by identity",value:f,onChange:t=>v(t.target.value),className:"rounded-md border border-zinc-800 bg-zinc-950 px-2.5 py-1.5 text-xs text-zinc-200 focus:outline-none focus-visible:ring-1 focus-visible:ring-zinc-600",children:[e.jsx("option",{value:"",children:"All identities"}),ve.map(t=>e.jsx("option",{value:t,children:t},t))]}),e.jsx(O,{text:"The specific bot or AI product making the request (e.g., GPTBot, ChatGPT-User, Perplexity). One operator usually runs several identities."})]}),e.jsxs("span",{className:"inline-flex items-center text-zinc-400",children:[e.jsxs("select",{"aria-label":"Filter by operator",value:m,onChange:t=>A(t.target.value),className:"rounded-md border border-zinc-800 bg-zinc-950 px-2.5 py-1.5 text-xs text-zinc-200 focus:outline-none focus-visible:ring-1 focus-visible:ring-zinc-600",children:[e.jsx("option",{value:"",children:"All operators"}),Ne.map(t=>e.jsx("option",{value:t,children:t},t))]}),e.jsx(O,{text:"The company that runs the bot or product (e.g., OpenAI, Anthropic, Perplexity). Filtering by operator includes every identity under that company."})]}),e.jsx("select",{"aria-label":"Filter by HTTP status class",value:C,onChange:t=>B(t.target.value),className:"rounded-md border border-zinc-800 bg-zinc-950 px-2.5 py-1.5 text-xs text-zinc-200 focus:outline-none focus-visible:ring-1 focus-visible:ring-zinc-600",children:et.map(t=>e.jsx("option",{value:t.value,children:t.label},t.value))}),e.jsx("select",{"aria-label":"Filter by verification claim",value:k,onChange:t=>G(t.target.value),className:"rounded-md border border-zinc-800 bg-zinc-950 px-2.5 py-1.5 text-xs text-zinc-200 focus:outline-none focus-visible:ring-1 focus-visible:ring-zinc-600",children:fe.map(t=>e.jsx("option",{value:t.value,children:t.label},t.value))}),e.jsx("input",{type:"search","aria-label":"Filter by path",placeholder:"path contains…",value:y,onChange:t=>_(t.target.value),className:"w-44 rounded-md border border-zinc-800 bg-zinc-950 px-2.5 py-1.5 text-xs text-zinc-200 placeholder:text-zinc-600 focus:outline-none focus-visible:ring-1 focus-visible:ring-zinc-600"})]})]}),Ie?e.jsxs("div",{className:"mb-3 flex flex-wrap items-center gap-2",children:[ne?e.jsx(I,{label:`Bucket: ${ne}`,onClear:()=>z(null)}):null,f?e.jsx(I,{label:`Identity: ${f}`,onClear:()=>v("")}):null,m?e.jsx(I,{label:`Operator: ${m}`,onClear:()=>A("")}):null,y.trim()?e.jsx(I,{label:`Path: ${y.trim()}`,onClear:()=>_("")}):null,C!=="all"?e.jsx(I,{label:`Status: ${C}`,onClear:()=>B("all")}):null,k!=="all"?e.jsx(I,{label:`Claim: ${lt(k)}`,onClear:()=>G("all")}):null,e.jsx("button",{type:"button",onClick:Te,className:"text-xs text-zinc-500 underline-offset-4 hover:text-zinc-200 hover:underline",children:"Clear all"})]}):null,e.jsx(dt,{events:Se}),we?e.jsxs("div",{className:"mt-3 flex flex-wrap items-center justify-between gap-x-4 gap-y-2 text-xs text-zinc-400",children:[e.jsxs("p",{className:"tabular-nums",children:["Showing ",e.jsx("span",{className:"text-zinc-300",children:ze.toLocaleString("en-US")}),"–",e.jsx("span",{className:"text-zinc-300",children:Ce.toLocaleString("en-US")})," of"," ",e.jsx("span",{className:"text-zinc-300",children:w.length.toLocaleString("en-US")})," events"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{type:"button",onClick:()=>K(t=>Math.max(1,t-1)),disabled:M<=1,"aria-label":"Previous page",className:"inline-flex items-center gap-1 rounded-md border border-zinc-800 bg-zinc-950 px-2.5 py-1.5 text-zinc-200 transition hover:border-zinc-700 hover:text-zinc-50 disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:border-zinc-800 disabled:hover:text-zinc-200",children:[e.jsx(Ve,{className:"size-3.5"}),"Prev"]}),e.jsxs("span",{className:"tabular-nums",children:["Page ",e.jsx("span",{className:"text-zinc-200",children:M})," of"," ",e.jsx("span",{className:"text-zinc-200",children:F})]}),e.jsxs("button",{type:"button",onClick:()=>K(t=>Math.min(F,t+1)),disabled:M>=F,"aria-label":"Next page",className:"inline-flex items-center gap-1 rounded-md border border-zinc-800 bg-zinc-950 px-2.5 py-1.5 text-zinc-200 transition hover:border-zinc-700 hover:text-zinc-50 disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:border-zinc-800 disabled:hover:text-zinc-200",children:["Next",e.jsx(Fe,{className:"size-3.5"})]})]})]}):null]})]})}function Z(s,a){return{bucket:s,label:a,crawler:0,aiUserFetch:0,aiReferral:0}}function P(s,a){return a==="day"?nt(s):je(s)}function it(s,a,i,n){const x=new Map;for(const l of s){const c=be(l.tsHour,a);let o=x.get(c);switch(o||(o=Z(c,P(c,a)),x.set(c,o)),l.kind){case u.crawler:o.crawler+=l.hits;break;case u["ai-user-fetch"]:o.aiUserFetch+=l.hits;break;case u["ai-referral"]:o.aiReferral+=l.hits;break}}if(i&&n){const l=new Date(i),c=new Date(n);if(a==="day"){const o=new Date(Date.UTC(l.getUTCFullYear(),l.getUTCMonth(),l.getUTCDate())),d=new Date(Date.UTC(c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()));for(;o<=d;){const z=o.getUTCFullYear(),f=String(o.getUTCMonth()+1).padStart(2,"0"),v=String(o.getUTCDate()).padStart(2,"0"),m=`${z}-${f}-${v}`;x.has(m)||x.set(m,Z(m,P(m,a))),o.setUTCDate(o.getUTCDate()+1)}}else{const o=new Date(l);for(o.setUTCMinutes(0,0,0);o<=c;){const d=o.toISOString();x.has(d)||x.set(d,Z(d,P(d,a))),o.setUTCHours(o.getUTCHours()+1)}}}return[...x.values()].sort((l,c)=>l.bucket<c.bucket?-1:l.bucket>c.bucket?1:0)}function lt(s){return fe.find(a=>a.value===s)?.label??s}function I({label:s,onClear:a}){return e.jsxs("span",{className:"inline-flex items-center gap-1.5 rounded-full border border-zinc-700 bg-zinc-800/60 px-2.5 py-1 text-[11px] text-zinc-200",children:[s,e.jsx("button",{type:"button",onClick:a,"aria-label":`Clear ${s}`,className:"rounded-full p-0.5 text-zinc-400 hover:bg-zinc-700/60 hover:text-zinc-100",children:e.jsx(He,{className:"size-3"})})]})}function J({label:s,color:a,count:i,active:n,onToggle:x}){return e.jsxs("button",{type:"button",onClick:x,"aria-pressed":n,className:`inline-flex items-center gap-2 rounded-full border px-3 py-1 text-xs font-medium transition ${n?"border-zinc-700 bg-zinc-800/60 text-zinc-100":"border-zinc-800 bg-transparent text-zinc-500 hover:text-zinc-300"}`,children:[e.jsx("span",{"aria-hidden":"true",className:`size-2 rounded-full transition-opacity ${n?"opacity-100":"opacity-30"}`,style:{backgroundColor:a}}),e.jsx("span",{children:s}),e.jsx("span",{className:`tabular-nums ${n?"text-zinc-400":"text-zinc-600"}`,children:i.toLocaleString("en-US")})]})}function ct(s){switch(s){case u.crawler:return"Crawler";case u["ai-user-fetch"]:return"AI hit";case u["ai-referral"]:return"AI referral"}}function ot(s){switch(s.kind){case u.crawler:case u["ai-user-fetch"]:return s.botId;case u["ai-referral"]:return s.product}}function ut(s){switch(s.kind){case u.crawler:case u["ai-user-fetch"]:return`${s.verificationStatus} · HTTP ${s.status}`;case u["ai-referral"]:return`${s.evidenceType} · ${s.sourceDomain}`}}function dt({events:s}){return s.length===0?e.jsx(H,{className:"p-6 text-center text-sm text-zinc-500",children:"No event rows match the current filters."}):e.jsx("div",{className:"rounded-xl border border-zinc-800/60 bg-zinc-900/30 overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-zinc-900/50 text-[10px] font-semibold uppercase tracking-wider text-zinc-500",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-2 text-left",children:"Hour"}),e.jsx("th",{className:"px-4 py-2 text-left",children:"Kind"}),e.jsx("th",{className:"px-4 py-2 text-left",children:"Identity"}),e.jsx("th",{className:"px-4 py-2 text-left",children:"Evidence / status"}),e.jsx("th",{className:"px-4 py-2 text-left",children:"Path"}),e.jsx("th",{className:"px-4 py-2 text-right",children:e.jsxs("span",{className:"inline-flex items-center",children:["Hits",e.jsx(O,{text:"Each row is one hour-bucket, not one request. Hits is the number of requests in that hour that shared the same identity, path, HTTP status, and verification claim."})]})})]})}),e.jsx("tbody",{className:"divide-y divide-zinc-800/60",children:s.map((a,i)=>e.jsxs("tr",{className:"hover:bg-zinc-900/40 transition-colors",children:[e.jsx("td",{className:"px-4 py-2 font-mono text-xs text-zinc-300",children:je(a.tsHour)}),e.jsx("td",{className:"px-4 py-2 text-zinc-300",children:ct(a.kind)}),e.jsxs("td",{className:"px-4 py-2 text-zinc-100",children:[ot(a),e.jsx("span",{className:"ml-2 text-[11px] text-zinc-500",children:a.operator})]}),e.jsx("td",{className:"px-4 py-2 text-zinc-300",children:ut(a)}),e.jsx("td",{className:"px-4 py-2 truncate font-mono text-xs text-zinc-300",children:ge(a)}),e.jsx("td",{className:"px-4 py-2 text-right tabular-nums text-zinc-100",children:a.hits})]},`${a.kind}:${a.tsHour}:${i}`))})]})})}export{yt as TrafficSourceDetailPage};
|