@ainyc/canonry 4.53.0 → 4.54.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/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +8 -5
- package/assets/assets/{BacklinksPage-DELb5ok3.js → BacklinksPage-BXFT4pLI.js} +1 -1
- package/assets/assets/{ProjectPage-CM_uQa2L.js → ProjectPage-DAtd9Vay.js} +1 -1
- package/assets/assets/{RunRow-aqJEr7XJ.js → RunRow-38dDceGl.js} +1 -1
- package/assets/assets/{RunsPage-Dhuj1w72.js → RunsPage-AJnFLtaE.js} +1 -1
- package/assets/assets/{SettingsPage-B2_vxr4y.js → SettingsPage-FT9ZAvFH.js} +1 -1
- package/assets/assets/{TrafficPage-BKaiZRIH.js → TrafficPage-B4A3oO8M.js} +1 -1
- package/assets/assets/TrafficSourceDetailPage-8NYU1TA6.js +1 -0
- package/assets/assets/{arrow-left-CYjzP3M3.js → arrow-left-DgI0X1Q1.js} +1 -1
- package/assets/assets/{index-BStwmAg6.js → index-DLPKqyhx.js} +49 -49
- package/assets/assets/{server-traffic-D_1gSi-b.js → server-traffic-GqiQYm6x.js} +1 -1
- package/assets/assets/{trash-2-8JiADnUJ.js → trash-2-BwPzJ8NI.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-KVE7RLBI.js → chunk-CRO6Q25G.js} +81 -2
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +8 -8
- package/assets/assets/TrafficSourceDetailPage-DXIQ4g9S.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as d,j as a,
|
|
1
|
+
import{c as d,j as a,bD as S,by as l,bE as v,aj as y,l as t,bF as m,bz as i,bG as T,bH as h,bI as p,bJ as b}from"./index-DLPKqyhx.js";import{u as s,r as C,n as c,o as u}from"./vendor-tanstack-Dq7p98wZ.js";const g=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],F=d("refresh-cw",g);function M(e){switch(e){case i.connected:return"positive";case i.paused:return"caution";case i.error:return"negative";case i.archived:return"neutral"}}function w(e){const r={};return e.kind&&e.kind!=="all"&&(r.kind=e.kind),e.sourceId&&(r.sourceId=e.sourceId),e.sinceMinutes!==void 0&&(r.since=new Date(Date.now()-e.sinceMinutes*6e4).toISOString()),e.limit!==void 0&&(r.limit=String(e.limit)),r}function o(e){e.invalidateQueries({predicate:r=>{const n=r.queryKey[0];return typeof n?._id=="string"&&n._id.startsWith("getApiV1ProjectsByNameTraffic")}})}function P(e){return s({...S({client:t,path:{name:e??""}}),enabled:!!e,staleTime:a})}function k(e){return s({...b({client:t,path:{name:e??""}}),enabled:!!e,staleTime:a})}function E(e,r){return s({...l({client:t,path:{name:e??"",id:r??""}}),enabled:!!(e&&r),staleTime:a})}function V(e,r){const n=C.useMemo(()=>w(r),[r.kind,r.sourceId,r.sinceMinutes,r.limit]);return s({...v({client:t,path:{name:e??""},query:n}),enabled:!!e,staleTime:a})}function A(e){const r=c();return u({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a Cloud Run source");return p(e,n)},onSuccess:()=>{e&&o(r)}})}function I(e){const r=c();return u({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a WordPress source");return T(e,n)},onSuccess:()=>{e&&o(r)}})}function Q(e){const r=c();return u({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a Vercel source");return h(e,n)},onSuccess:()=>{e&&o(r)}})}function R(e,r){const n=c();return u({mutationFn:f=>{if(!e||!r)throw new Error("Project and sourceId are required to sync");return m(e,r,f??void 0)},onSuccess:()=>{e&&(o(n),n.invalidateQueries({queryKey:y({client:t})}))}})}export{F as R,I as a,Q as b,A as c,P as d,E as e,V as f,R as g,M as t,k as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c}from"./index-
|
|
1
|
+
import{c}from"./index-DLPKqyhx.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,7 +12,7 @@
|
|
|
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-DLPKqyhx.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Dq7p98wZ.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-B57xfQbP.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-DWvKDyBF.js">
|
|
@@ -21260,6 +21260,9 @@ function incrementBucket(map, key, fields) {
|
|
|
21260
21260
|
else map.set(key, { fields, hits: 1 });
|
|
21261
21261
|
}
|
|
21262
21262
|
|
|
21263
|
+
// ../integration-wordpress-traffic/src/client.ts
|
|
21264
|
+
import { randomUUID } from "crypto";
|
|
21265
|
+
|
|
21263
21266
|
// ../integration-wordpress-traffic/src/normalize.ts
|
|
21264
21267
|
function trimOrNull(value) {
|
|
21265
21268
|
if (value === null || value === void 0) return null;
|
|
@@ -21290,7 +21293,7 @@ function normalizeWordpressTrafficEvent(event) {
|
|
|
21290
21293
|
queryString,
|
|
21291
21294
|
status: typeof event.status === "number" && Number.isFinite(event.status) ? event.status : null,
|
|
21292
21295
|
userAgent: trimOrNull(event.user_agent),
|
|
21293
|
-
remoteIp: trimOrNull(event.
|
|
21296
|
+
remoteIp: trimOrNull(event.remote_ip),
|
|
21294
21297
|
referer: trimOrNull(event.referer),
|
|
21295
21298
|
latencyMs: null,
|
|
21296
21299
|
requestSizeBytes: null,
|
|
@@ -21373,11 +21376,13 @@ async function listWordpressTrafficEvents(options) {
|
|
|
21373
21376
|
if (options.until !== void 0 && options.until !== "") {
|
|
21374
21377
|
url.searchParams.set("until", options.until);
|
|
21375
21378
|
}
|
|
21379
|
+
url.searchParams.set("_cb", randomUUID());
|
|
21376
21380
|
const response = await fetch(url, {
|
|
21377
21381
|
method: "GET",
|
|
21378
21382
|
headers: {
|
|
21379
21383
|
Authorization: authHeader,
|
|
21380
|
-
Accept: "application/json"
|
|
21384
|
+
Accept: "application/json",
|
|
21385
|
+
"Cache-Control": "no-cache"
|
|
21381
21386
|
},
|
|
21382
21387
|
signal: AbortSignal.timeout(timeoutMs)
|
|
21383
21388
|
});
|
|
@@ -23899,6 +23904,76 @@ var TRAFFIC_SOURCE_CHECKS = [
|
|
|
23899
23904
|
scopesCheck2
|
|
23900
23905
|
];
|
|
23901
23906
|
|
|
23907
|
+
// ../api-routes/src/doctor/checks/wordpress-publish.ts
|
|
23908
|
+
var WORDPRESS_PUBLISH_CHECKS = [
|
|
23909
|
+
{
|
|
23910
|
+
id: "wordpress.publish.connection",
|
|
23911
|
+
category: CheckCategories.auth,
|
|
23912
|
+
scope: CheckScopes.project,
|
|
23913
|
+
title: "WordPress publishing connection",
|
|
23914
|
+
run: async (ctx) => {
|
|
23915
|
+
if (!ctx.project) {
|
|
23916
|
+
return {
|
|
23917
|
+
status: CheckStatuses.skipped,
|
|
23918
|
+
code: "wordpress.publish.no-project",
|
|
23919
|
+
summary: "Project context required.",
|
|
23920
|
+
remediation: null
|
|
23921
|
+
};
|
|
23922
|
+
}
|
|
23923
|
+
const store = ctx.wordpressConnectionStore;
|
|
23924
|
+
if (!store) {
|
|
23925
|
+
return {
|
|
23926
|
+
status: CheckStatuses.skipped,
|
|
23927
|
+
code: "wordpress.publish.store-unavailable",
|
|
23928
|
+
summary: "WordPress connection store is not configured for this deployment.",
|
|
23929
|
+
remediation: null
|
|
23930
|
+
};
|
|
23931
|
+
}
|
|
23932
|
+
const connection = store.getConnection(ctx.project.name);
|
|
23933
|
+
if (!connection) {
|
|
23934
|
+
return {
|
|
23935
|
+
status: CheckStatuses.skipped,
|
|
23936
|
+
code: "wordpress.publish.not-configured",
|
|
23937
|
+
summary: `No WordPress publishing connection configured for ${ctx.project.name}.`,
|
|
23938
|
+
remediation: `If this project publishes to WordPress, run \`canonry wordpress connect ${ctx.project.name} --url <url> --user <user>\`.`
|
|
23939
|
+
};
|
|
23940
|
+
}
|
|
23941
|
+
try {
|
|
23942
|
+
const status = await verifyWordpressConnection(connection);
|
|
23943
|
+
return {
|
|
23944
|
+
status: CheckStatuses.ok,
|
|
23945
|
+
code: "wordpress.publish.connected",
|
|
23946
|
+
summary: `WordPress publishing connection verified; wp/v2 REST API reachable at ${status.url}.`,
|
|
23947
|
+
remediation: null,
|
|
23948
|
+
details: {
|
|
23949
|
+
url: status.url,
|
|
23950
|
+
wordpressVersion: status.version,
|
|
23951
|
+
pageCount: status.pageCount
|
|
23952
|
+
}
|
|
23953
|
+
};
|
|
23954
|
+
} catch (err) {
|
|
23955
|
+
if (err instanceof WordpressApiError && err.code === "AUTH_INVALID") {
|
|
23956
|
+
return {
|
|
23957
|
+
status: CheckStatuses.fail,
|
|
23958
|
+
code: "wordpress.publish.unauthorized",
|
|
23959
|
+
summary: "WordPress rejected the stored application password.",
|
|
23960
|
+
remediation: `Regenerate the Application Password in wp-admin (Users \u2192 Profile \u2192 Application Passwords), then reconnect with \`canonry wordpress connect ${ctx.project.name} --url <url> --user <user>\`.`,
|
|
23961
|
+
details: { error: err.message }
|
|
23962
|
+
};
|
|
23963
|
+
}
|
|
23964
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23965
|
+
return {
|
|
23966
|
+
status: CheckStatuses.fail,
|
|
23967
|
+
code: "wordpress.publish.verification-failed",
|
|
23968
|
+
summary: "WordPress publishing connection could not be verified.",
|
|
23969
|
+
remediation: "Confirm the site URL is correct and the WordPress REST API is reachable.",
|
|
23970
|
+
details: { error: message }
|
|
23971
|
+
};
|
|
23972
|
+
}
|
|
23973
|
+
}
|
|
23974
|
+
}
|
|
23975
|
+
];
|
|
23976
|
+
|
|
23902
23977
|
// ../api-routes/src/doctor/registry.ts
|
|
23903
23978
|
var ALL_CHECKS = [
|
|
23904
23979
|
// Runtime-state checks run first so file-system gone errors surface
|
|
@@ -23906,6 +23981,7 @@ var ALL_CHECKS = [
|
|
|
23906
23981
|
...RUNTIME_STATE_CHECKS,
|
|
23907
23982
|
...GOOGLE_AUTH_CHECKS,
|
|
23908
23983
|
...BING_AUTH_CHECKS,
|
|
23984
|
+
...WORDPRESS_PUBLISH_CHECKS,
|
|
23909
23985
|
...GA_AUTH_CHECKS,
|
|
23910
23986
|
...PROVIDERS_CHECKS,
|
|
23911
23987
|
...TRAFFIC_SOURCE_CHECKS,
|
|
@@ -23990,6 +24066,7 @@ async function doctorRoutes(app, opts) {
|
|
|
23990
24066
|
project: null,
|
|
23991
24067
|
googleConnectionStore: opts.googleConnectionStore,
|
|
23992
24068
|
bingConnectionStore: opts.bingConnectionStore,
|
|
24069
|
+
wordpressConnectionStore: opts.wordpressConnectionStore,
|
|
23993
24070
|
ga4CredentialStore: opts.ga4CredentialStore,
|
|
23994
24071
|
getGoogleAuthConfig: opts.getGoogleAuthConfig,
|
|
23995
24072
|
redirectUri,
|
|
@@ -24012,6 +24089,7 @@ async function doctorRoutes(app, opts) {
|
|
|
24012
24089
|
},
|
|
24013
24090
|
googleConnectionStore: opts.googleConnectionStore,
|
|
24014
24091
|
bingConnectionStore: opts.bingConnectionStore,
|
|
24092
|
+
wordpressConnectionStore: opts.wordpressConnectionStore,
|
|
24015
24093
|
ga4CredentialStore: opts.ga4CredentialStore,
|
|
24016
24094
|
getGoogleAuthConfig: opts.getGoogleAuthConfig,
|
|
24017
24095
|
redirectUri,
|
|
@@ -24640,6 +24718,7 @@ async function apiRoutes(app, opts) {
|
|
|
24640
24718
|
await api.register(doctorRoutes, {
|
|
24641
24719
|
googleConnectionStore: opts.googleConnectionStore,
|
|
24642
24720
|
bingConnectionStore: opts.bingConnectionStore,
|
|
24721
|
+
wordpressConnectionStore: opts.wordpressConnectionStore,
|
|
24643
24722
|
ga4CredentialStore: opts.ga4CredentialStore,
|
|
24644
24723
|
getGoogleAuthConfig: opts.getGoogleAuthConfig,
|
|
24645
24724
|
publicUrl: opts.publicUrl,
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.54.0",
|
|
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",
|
|
@@ -62,22 +62,22 @@
|
|
|
62
62
|
"tsx": "^4.19.0",
|
|
63
63
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
64
64
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
65
|
+
"@ainyc/canonry-db": "0.0.0",
|
|
65
66
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
66
|
-
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
67
67
|
"@ainyc/canonry-config": "0.0.0",
|
|
68
|
-
"@ainyc/canonry-integration-google": "0.0.0",
|
|
69
68
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
70
|
-
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
71
|
-
"@ainyc/canonry-db": "0.0.0",
|
|
72
69
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
73
|
-
"@ainyc/canonry-integration-
|
|
70
|
+
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
74
71
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
75
72
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
73
|
+
"@ainyc/canonry-integration-wordpress": "1.0.0",
|
|
74
|
+
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
76
75
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
77
76
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
77
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
78
78
|
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
79
|
-
"@ainyc/canonry-provider-
|
|
80
|
-
"@ainyc/canonry-provider-
|
|
79
|
+
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
80
|
+
"@ainyc/canonry-provider-local": "0.0.0"
|
|
81
81
|
},
|
|
82
82
|
"scripts": {
|
|
83
83
|
"build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j as e,A as pe,B as fe,r as m,L as ge}from"./vendor-tanstack-Dq7p98wZ.js";import{I as be,bA as x,T as je,B as ye,g as $,a0 as Ne,bB as ve}from"./index-BStwmAg6.js";import{d as K,e as we,C as q,a as J,c as Se}from"./ChartPrimitives-9Kx3gzQL.js";import{e as ke,f as ze,g as Ce,t as Te,R as Ae}from"./server-traffic-D_1gSi-b.js";import{R as Re,B as Ie,a as $e,X as Le,Y as Ue,T as Fe,b as O,d as B}from"./vendor-recharts-DWvKDyBF.js";import{A as Z}from"./arrow-left-CYjzP3M3.js";import"./vendor-radix-B57xfQbP.js";import"./vendor-markdown-DK7fbRNb.js";function I({value:t,label:a,delta:n,tone:r,description:u,tooltip:i,isNumeric:c=!0,progress:o,providerCoverage:d}){const y=2*Math.PI*48,h=Number.parseInt(t,10),C=typeof o=="number"&&Number.isFinite(o)?Math.min(Math.max(o,0),100)/100:c&&!Number.isNaN(h)?Math.min(h/100,1):.5,N=y*(1-C);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-${r}`,cx:"60",cy:"60",r:48,strokeWidth:6,strokeDasharray:y,strokeDashoffset:N,transform:"rotate(-90 60 60)"})]}),e.jsx("div",{className:"gauge-center",children:e.jsx("span",{className:c?"gauge-value":"gauge-value-text",children:t.split(" / ")[0]})})]}),e.jsxs("p",{className:"gauge-label",children:[a,i&&e.jsx(be,{text:i})]}),e.jsx("p",{className:"gauge-delta",children:n}),d&&e.jsx("p",{className:"gauge-provider-coverage",children:d}),e.jsx("p",{className:"gauge-description",children:u})]})}const He=[{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"}];function Me(t){return t==="all"?null:Number.parseInt(t[0],10)}function ne(t){switch(t.kind){case x.crawler:case x["ai-user-fetch"]:return t.botId;case x["ai-referral"]:return t.product}}function le(t){switch(t.kind){case x.crawler:case x["ai-user-fetch"]:return t.pathNormalized;case x["ai-referral"]:return t.landingPathNormalized}}function ie(t,a){if(a==="hour")return t;const n=new Date(t),r=n.getFullYear(),u=String(n.getMonth()+1).padStart(2,"0"),i=String(n.getDate()).padStart(2,"0");return`${r}-${u}-${i}`}function De(t,a,n){const r=a.pathQuery.trim().toLowerCase(),u=Me(a.statusClass);return t.filter(i=>!(a.selectedBucket&&ie(i.tsHour,n)!==a.selectedBucket||a.identity&&ne(i)!==a.identity||a.operator&&i.operator!==a.operator||r&&!le(i).toLowerCase().includes(r)||u!==null&&Math.floor(i.status/100)!==u))}function Ee(t,a){if(!t||typeof t!="object")return null;const n=t.activeTooltipIndex;let r;if(typeof n=="number")r=n;else if(typeof n=="string"&&n!=="")r=Number(n);else return null;return!Number.isInteger(r)||r<0||r>=a.length?null:a[r]?.bucket??null}const U=[{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}],ee=U.find(t=>t.label==="7d")??U[2],te=K[0],se=K[2],ae=K[1];function ce(t){const a=new Date(t);return`${a.getMonth()+1}/${a.getDate()} ${String(a.getHours()).padStart(2,"0")}:00`}function Oe(t){const a=new Date(`${t}T00:00:00`);return`${a.getMonth()+1}/${a.getDate()}`}function T(t){if(!t)return"never";const a=Date.now()-new Date(t).getTime(),n=Math.floor(a/6e4);if(n<1)return"just now";if(n<60)return`${n}m ago`;const r=Math.floor(n/60);return r<24?`${r}h ago`:`${Math.floor(r/24)}d ago`}function re({canGoBack:t,className:a}){const n="inline-flex items-center gap-1";if(t){const r=()=>{window.history.back()};return e.jsxs("button",{type:"button",onClick:r,className:`${n} ${a??""}`,children:[e.jsx(Z,{className:"size-3"})," Back"]})}return e.jsxs(ge,{to:"/traffic",className:`${n} ${a??""}`,children:[e.jsx(Z,{className:"size-3"})," All sources"]})}function et(){const t=pe({strict:!1}),a=t.projectName??"",n=fe(),r=t.sourceId??"",[u,i]=m.useState(ee.value),[c,o]=m.useState(()=>new Set(["crawler","ai-user-fetch","ai-referral"])),[d,w]=m.useState(null),[f,y]=m.useState(""),[h,C]=m.useState(""),[N,F]=m.useState(""),[k,H]=m.useState("all"),[W,G]=m.useState(null),[Y,X]=m.useState(null),b=m.useMemo(()=>U.find(s=>s.value===u)??ee,[u]),M=ke(a||null,r||null),j=ze(a||null,{kind:"all",sourceId:r||void 0,sinceMinutes:u,limit:b.fetchLimit}),R=Ce(a||null,r||null),l=M.data,v=j.data?.events??[],S=j.data?.totals,D=m.useMemo(()=>v.filter(s=>{switch(s.kind){case x.crawler:return c.has("crawler");case x["ai-user-fetch"]:return c.has("ai-user-fetch");case x["ai-referral"]:return c.has("ai-referral")}}),[v,c]),oe=m.useMemo(()=>{const s=new Set;for(const p of v)s.add(ne(p));return f&&s.add(f),[...s].sort((p,g)=>p.localeCompare(g))},[v,f]),ue=m.useMemo(()=>{const s=new Set;for(const p of v)s.add(p.operator);return h&&s.add(h),[...s].sort((p,g)=>p.localeCompare(g))},[v,h]),Q=m.useMemo(()=>De(D,{selectedBucket:d,identity:f,operator:h,pathQuery:N,statusClass:k},b.granularity),[D,d,f,h,N,k,b.granularity]),V=m.useMemo(()=>d?L(d,b.granularity):null,[d,b.granularity]),z=m.useMemo(()=>Be(v,b.granularity,j.data?.windowStart,j.data?.windowEnd),[v,b.granularity,j.data?.windowStart,j.data?.windowEnd]),E=s=>{o(p=>{const g=new Set(p);return g.has(s)?g.size>1&&g.delete(s):g.add(s),g})},de=s=>{const p=Ee(s,z);p&&w(g=>g===p?null:p)},xe=()=>{w(null),y(""),C(""),F(""),H("all")},he=!!(d||f||h||N.trim()||k!=="all"),me=async()=>{G(null),X(null);try{const s=await R.mutateAsync({sinceMinutes:60});X(`Pulled ${s.pulledEvents} entries · ${s.crawlerHits} crawler · ${s.aiReferralHits} AI referral · ${s.unknownHits} unknown`)}catch(s){const p=s instanceof Ne||s instanceof Error?s.message:String(s);G(p)}};return!a||!r?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."})}):M.isLoading?e.jsx("div",{className:"page-container",children:e.jsx("p",{className:"text-sm text-zinc-500",children:"Loading source…"})}):M.isError||!l?e.jsxs("div",{className:"page-container",children:[e.jsx("p",{className:"text-sm text-rose-300",children:"Could not load this source."}),e.jsx(re,{canGoBack:n,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(re,{canGoBack:n,className:"text-xs text-zinc-500 hover:text-zinc-200"}),e.jsx("h1",{className:"page-title mt-2",children:l.displayName}),e.jsxs("p",{className:"page-subtitle",children:[l.sourceType," · project ",e.jsx("span",{className:"text-zinc-300",children:a})," ·",e.jsx("span",{className:"ml-1 font-mono text-zinc-400",children:l.id})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(je,{tone:Te(l.status),children:l.status}),e.jsxs(ye,{type:"button",variant:"outline",size:"sm",disabled:R.isPending,onClick:()=>{me()},children:[e.jsx(Ae,{className:`size-3.5 ${R.isPending?"animate-spin":""}`}),R.isPending?"Syncing…":"Sync now"]})]})]}),W?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:W}):null,Y?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:Y}):null,e.jsxs("section",{className:"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(I,{label:"24h crawler hits",value:String(l.totals24h.crawlerHits),delta:l.lastSyncedAt?`last sync ${T(l.lastSyncedAt)}`:"never synced",tone:l.totals24h.crawlerHits>0?"positive":"neutral",description:"Bulk machine crawl — GPTBot, OAI-SearchBot, PerplexityBot, Googlebot, etc.",isNumeric:!0,progress:Math.min(100,Math.round(l.totals24h.crawlerHits/1e3*100))}),e.jsx(I,{label:"24h AI user fetches",value:String(l.totals24h.aiUserFetchHits),delta:l.lastSyncedAt?`last sync ${T(l.lastSyncedAt)}`:"never synced",tone:l.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(l.totals24h.aiUserFetchHits/1e3*100))}),e.jsx(I,{label:"24h AI referral sessions",value:String(l.totals24h.aiReferralHits),delta:l.lastSyncedAt?`last sync ${T(l.lastSyncedAt)}`:"never synced",tone:l.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(l.totals24h.aiReferralHits/1e3*100))}),e.jsx(I,{label:"24h sample rows",value:String(l.totals24h.sampleCount),delta:"bounded per sync",tone:"neutral",description:"Per-request samples retained for evidence (capped to keep storage bounded).",isNumeric:!0,progress:Math.min(100,Math.round(l.totals24h.sampleCount/100*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"}),l.latestRun?e.jsxs($,{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:l.latestRun.status})]}),e.jsxs("span",{className:"text-zinc-500",children:["Started: ",T(l.latestRun.startedAt)]}),l.latestRun.finishedAt?e.jsxs("span",{className:"text-zinc-500",children:["Finished: ",T(l.latestRun.finishedAt)]}):null,e.jsx("span",{className:"font-mono text-[11px] text-zinc-600",children:l.latestRun.runId})]}),l.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:l.latestRun.error}):null]}):e.jsx($,{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.crawlerHits.toLocaleString("en-US")," crawler ·"," ",S.aiUserFetchHits.toLocaleString("en-US")," AI user fetches ·"," ",S.aiReferralHits.toLocaleString("en-US")," AI referral sessions · last ",b.label]}):null]}),e.jsx("div",{className:"filter-row mb-0",role:"toolbar","aria-label":"Window",children:U.map(s=>e.jsx("button",{type:"button",className:`filter-chip ${u===s.value?"filter-chip-active":""}`,"aria-pressed":u===s.value,onClick:()=>{i(s.value),w(null)},children:s.label},s.value))})]}),e.jsxs($,{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(_,{label:"Crawler",color:te,count:S?.crawlerHits??0,active:c.has("crawler"),onToggle:()=>E("crawler")}),e.jsx(_,{label:"AI user fetches",color:se,count:S?.aiUserFetchHits??0,active:c.has("ai-user-fetch"),onToggle:()=>E("ai-user-fetch")}),e.jsx(_,{label:"AI referral sessions",color:ae,count:S?.aiReferralHits??0,active:c.has("ai-referral"),onToggle:()=>E("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…"}):z.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(Re,{children:e.jsxs(Ie,{data:z,margin:{top:4,right:4,bottom:0,left:0},onClick:de,style:{cursor:"pointer"},children:[e.jsx($e,{stroke:we,strokeDasharray:"3 3"}),e.jsx(Le,{dataKey:"label",tick:J,stroke:q,interval:"preserveStartEnd",minTickGap:b.granularity==="day"?24:32}),e.jsx(Ue,{tick:J,stroke:q,allowDecimals:!1}),e.jsx(Fe,{...Se}),c.has("crawler")?e.jsx(O,{dataKey:"crawler",name:"Crawler",fill:te,stackId:"a",children:z.map(s=>e.jsx(B,{fillOpacity:d&&d!==s.bucket?.25:1},s.bucket))}):null,c.has("ai-user-fetch")?e.jsx(O,{dataKey:"aiUserFetch",name:"AI user fetch",fill:se,stackId:"a",children:z.map(s=>e.jsx(B,{fillOpacity:d&&d!==s.bucket?.25:1},s.bucket))}):null,c.has("ai-referral")?e.jsx(O,{dataKey:"aiReferral",name:"AI referral",fill:ae,stackId:"a",children:z.map(s=>e.jsx(B,{fillOpacity:d&&d!==s.bucket?.25:1},s.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:Q.length.toLocaleString("en-US")})," of"," ",e.jsx("span",{className:"tabular-nums text-zinc-500",children:D.length.toLocaleString("en-US")})," events"]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("select",{"aria-label":"Filter by identity",value:f,onChange:s=>y(s.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"}),oe.map(s=>e.jsx("option",{value:s,children:s},s))]}),e.jsxs("select",{"aria-label":"Filter by operator",value:h,onChange:s=>C(s.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"}),ue.map(s=>e.jsx("option",{value:s,children:s},s))]}),e.jsx("select",{"aria-label":"Filter by HTTP status class",value:k,onChange:s=>H(s.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:He.map(s=>e.jsx("option",{value:s.value,children:s.label},s.value))}),e.jsx("input",{type:"search","aria-label":"Filter by path",placeholder:"path contains…",value:N,onChange:s=>F(s.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"})]})]}),he?e.jsxs("div",{className:"mb-3 flex flex-wrap items-center gap-2",children:[V?e.jsx(A,{label:`Bucket: ${V}`,onClear:()=>w(null)}):null,f?e.jsx(A,{label:`Identity: ${f}`,onClear:()=>y("")}):null,h?e.jsx(A,{label:`Operator: ${h}`,onClear:()=>C("")}):null,N.trim()?e.jsx(A,{label:`Path: ${N.trim()}`,onClear:()=>F("")}):null,k!=="all"?e.jsx(A,{label:`Status: ${k}`,onClear:()=>H("all")}):null,e.jsx("button",{type:"button",onClick:xe,className:"text-xs text-zinc-500 underline-offset-4 hover:text-zinc-200 hover:underline",children:"Clear all"})]}):null,e.jsx(We,{events:Q})]})]})}function P(t,a){return{bucket:t,label:a,crawler:0,aiUserFetch:0,aiReferral:0}}function L(t,a){return a==="day"?Oe(t):ce(t)}function Be(t,a,n,r){const u=new Map;for(const i of t){const c=ie(i.tsHour,a);let o=u.get(c);switch(o||(o=P(c,L(c,a)),u.set(c,o)),i.kind){case x.crawler:o.crawler+=i.hits;break;case x["ai-user-fetch"]:o.aiUserFetch+=i.hits;break;case x["ai-referral"]:o.aiReferral+=i.hits;break}}if(n&&r){const i=new Date(n),c=new Date(r);if(a==="day"){const o=new Date(Date.UTC(i.getUTCFullYear(),i.getUTCMonth(),i.getUTCDate())),d=new Date(Date.UTC(c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()));for(;o<=d;){const w=o.getUTCFullYear(),f=String(o.getUTCMonth()+1).padStart(2,"0"),y=String(o.getUTCDate()).padStart(2,"0"),h=`${w}-${f}-${y}`;u.has(h)||u.set(h,P(h,L(h,a))),o.setUTCDate(o.getUTCDate()+1)}}else{const o=new Date(i);for(o.setUTCMinutes(0,0,0);o<=c;){const d=o.toISOString();u.has(d)||u.set(d,P(d,L(d,a))),o.setUTCHours(o.getUTCHours()+1)}}}return[...u.values()].sort((i,c)=>i.bucket<c.bucket?-1:i.bucket>c.bucket?1:0)}function A({label:t,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:[t,e.jsx("button",{type:"button",onClick:a,"aria-label":`Clear ${t}`,className:"rounded-full p-0.5 text-zinc-400 hover:bg-zinc-700/60 hover:text-zinc-100",children:e.jsx(ve,{className:"size-3"})})]})}function _({label:t,color:a,count:n,active:r,onToggle:u}){return e.jsxs("button",{type:"button",onClick:u,"aria-pressed":r,className:`inline-flex items-center gap-2 rounded-full border px-3 py-1 text-xs font-medium transition ${r?"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 ${r?"opacity-100":"opacity-30"}`,style:{backgroundColor:a}}),e.jsx("span",{children:t}),e.jsx("span",{className:`tabular-nums ${r?"text-zinc-400":"text-zinc-600"}`,children:n.toLocaleString("en-US")})]})}function Pe(t){switch(t){case x.crawler:return"Crawler";case x["ai-user-fetch"]:return"AI hit";case x["ai-referral"]:return"AI referral"}}function _e(t){switch(t.kind){case x.crawler:case x["ai-user-fetch"]:return t.botId;case x["ai-referral"]:return t.product}}function Ke(t){switch(t.kind){case x.crawler:case x["ai-user-fetch"]:return`${t.verificationStatus} · HTTP ${t.status}`;case x["ai-referral"]:return`${t.evidenceType} · ${t.sourceDomain}`}}function We({events:t}){return t.length===0?e.jsx($,{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:"Hits"})]})}),e.jsx("tbody",{className:"divide-y divide-zinc-800/60",children:t.map((a,n)=>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:ce(a.tsHour)}),e.jsx("td",{className:"px-4 py-2 text-zinc-300",children:Pe(a.kind)}),e.jsxs("td",{className:"px-4 py-2 text-zinc-100",children:[_e(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:Ke(a)}),e.jsx("td",{className:"px-4 py-2 truncate font-mono text-xs text-zinc-300",children:le(a)}),e.jsx("td",{className:"px-4 py-2 text-right tabular-nums text-zinc-100",children:a.hits})]},`${a.kind}:${a.tsHour}:${n}`))})]})})}export{et as TrafficSourceDetailPage};
|