@canonry/canonry 4.172.4 → 4.174.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/assets/{AuditHistoryPanel-CARZK_Wi.js → AuditHistoryPanel-BRh-VMv0.js} +1 -1
- package/assets/assets/{BacklinksPage-BEA9vbC2.js → BacklinksPage-C2jbDAhv.js} +1 -1
- package/assets/assets/{HistoryPage-DKcDQw1a.js → HistoryPage-Dtr3UICp.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-BRPI_icI.js → MeasurementPropertyPage-D-z4CVyy.js} +1 -1
- package/assets/assets/{ProjectPage-B4_EEP8k.js → ProjectPage-BAiCXEdR.js} +8 -8
- package/assets/assets/{RunRow-C8C7wrzp.js → RunRow-t5iSzB9b.js} +1 -1
- package/assets/assets/{RunsPage-BeotkZcg.js → RunsPage-DR8qc686.js} +1 -1
- package/assets/assets/{SettingsPage-BukBukvW.js → SettingsPage-CCqitKyF.js} +1 -1
- package/assets/assets/{SiteHealthSection-C7RuR9AA.js → SiteHealthSection-vGzpNzMx.js} +3 -3
- package/assets/assets/TrafficPage-DpFRbcIy.js +1 -0
- package/assets/assets/{TrafficSourceDetailPage-CetULBhn.js → TrafficSourceDetailPage-CToOAg5Y.js} +1 -1
- package/assets/assets/{extract-error-message-CDRTdeQI.js → extract-error-message-p-Yg_eOO.js} +1 -1
- package/assets/assets/{index-D156-4Hr.js → index-CQ2ysGTv.js} +13 -13
- package/assets/assets/index-DQVTRT9J.css +1 -0
- package/assets/assets/{react-sigma_core.esm.min-CU8AjIPg.js → react-sigma_core.esm.min-BTa1NiIz.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-N53TZMMR.js → chunk-DSGX2IAI.js} +4 -4
- package/dist/{chunk-WFVK3XC7.js → chunk-HYKZOCBT.js} +2 -2
- package/dist/{chunk-2CXNT2AC.js → chunk-J3RVQCCQ.js} +1 -1
- package/dist/{chunk-WGN2VT7L.js → chunk-OSMUOPBR.js} +17 -1
- package/dist/{chunk-BZDNTUCZ.js → chunk-TIEHKR6K.js} +1 -1
- package/dist/cli.js +5 -5
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-2E7F6I7I.js → intelligence-service-RSZTVVX2.js} +2 -2
- package/dist/mcp.js +3 -3
- package/package.json +11 -11
- package/assets/assets/TrafficPage-D_zPUxGq.js +0 -1
- package/assets/assets/index-CFzo8iAY.css +0 -1
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
loadConfig,
|
|
10
10
|
loadConfigRaw,
|
|
11
11
|
saveConfigPatch
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-TIEHKR6K.js";
|
|
13
13
|
import {
|
|
14
14
|
CC_CACHE_DIR,
|
|
15
15
|
DUCKDB_SPEC,
|
|
@@ -145,7 +145,7 @@ import {
|
|
|
145
145
|
siteCrawlSnapshots,
|
|
146
146
|
toAlertView,
|
|
147
147
|
usageCounters
|
|
148
|
-
} from "./chunk-
|
|
148
|
+
} from "./chunk-J3RVQCCQ.js";
|
|
149
149
|
import {
|
|
150
150
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
151
151
|
AGENT_PROVIDER_IDS,
|
|
@@ -282,7 +282,7 @@ import {
|
|
|
282
282
|
validationError,
|
|
283
283
|
winnabilityClassLabel,
|
|
284
284
|
withRetry
|
|
285
|
-
} from "./chunk-
|
|
285
|
+
} from "./chunk-OSMUOPBR.js";
|
|
286
286
|
|
|
287
287
|
// src/telemetry.ts
|
|
288
288
|
import crypto from "crypto";
|
|
@@ -11839,7 +11839,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
11839
11839
|
return result;
|
|
11840
11840
|
}
|
|
11841
11841
|
async function backfillInsightsCommand(project, opts) {
|
|
11842
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
11842
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-RSZTVVX2.js");
|
|
11843
11843
|
const config = loadConfig();
|
|
11844
11844
|
const db = createClient(config.database);
|
|
11845
11845
|
migrate(db);
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
installSkills,
|
|
6
6
|
loadConfigRaw,
|
|
7
7
|
saveConfigPatch
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TIEHKR6K.js";
|
|
9
9
|
import {
|
|
10
10
|
SKILL_MANIFEST_FILENAME,
|
|
11
11
|
SkillsClients
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-OSMUOPBR.js";
|
|
13
13
|
|
|
14
14
|
// src/skills-autosync.ts
|
|
15
15
|
import fs from "fs";
|
|
@@ -628,7 +628,7 @@ import {
|
|
|
628
628
|
wordpressSchemaDeployResultDtoSchema,
|
|
629
629
|
wordpressSchemaStatusResultDtoSchema,
|
|
630
630
|
wordpressStatusDtoSchema
|
|
631
|
-
} from "./chunk-
|
|
631
|
+
} from "./chunk-OSMUOPBR.js";
|
|
632
632
|
|
|
633
633
|
// src/intelligence-service.ts
|
|
634
634
|
import { eq as eq61, desc as desc27, asc as asc11, and as and49, ne as ne8, or as or14, inArray as inArray21, gte as gte14, lte as lte12 } from "drizzle-orm";
|
|
@@ -3338,8 +3338,24 @@ function normalizeUrlPath(input) {
|
|
|
3338
3338
|
var WORD_SEGMENTER = new Intl.Segmenter("en", { granularity: "word" });
|
|
3339
3339
|
var NON_WORD = /[^\p{L}\p{N}]+/gu;
|
|
3340
3340
|
var WORD_RUNS = /[\p{L}\p{N}]+/gu;
|
|
3341
|
+
var ACCENT_BEARING_SCRIPT = /[\p{Script=Latin}\p{Script=Greek}\p{Script=Cyrillic}]/u;
|
|
3342
|
+
var NON_ASCII = new RegExp("\\P{ASCII}", "u");
|
|
3343
|
+
function foldAccents(value) {
|
|
3344
|
+
if (!NON_ASCII.test(value)) return value;
|
|
3345
|
+
let folded = "";
|
|
3346
|
+
for (const character of value) {
|
|
3347
|
+
if (character.charCodeAt(0) < 128) {
|
|
3348
|
+
folded += character;
|
|
3349
|
+
continue;
|
|
3350
|
+
}
|
|
3351
|
+
const decomposed = character.normalize("NFD");
|
|
3352
|
+
const base = decomposed[0];
|
|
3353
|
+
folded += decomposed.length > 1 && ACCENT_BEARING_SCRIPT.test(base) ? base : character;
|
|
3354
|
+
}
|
|
3355
|
+
return folded;
|
|
3356
|
+
}
|
|
3341
3357
|
function normalizeForMatch(value) {
|
|
3342
|
-
return value.normalize("NFKC").toLocaleLowerCase("en");
|
|
3358
|
+
return foldAccents(value.normalize("NFKC")).toLocaleLowerCase("en");
|
|
3343
3359
|
}
|
|
3344
3360
|
function wordsOfNormalized(normalized) {
|
|
3345
3361
|
const words = [];
|
package/dist/cli.js
CHANGED
|
@@ -26,11 +26,11 @@ import {
|
|
|
26
26
|
showFirstRunNotice,
|
|
27
27
|
trackCliCommandFinished,
|
|
28
28
|
trackEvent
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-DSGX2IAI.js";
|
|
30
30
|
import {
|
|
31
31
|
autoSyncSkills,
|
|
32
32
|
formatAutoSyncNotice
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-HYKZOCBT.js";
|
|
34
34
|
import {
|
|
35
35
|
CliError,
|
|
36
36
|
EXIT_SYSTEM_ERROR,
|
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
saveConfigPatch,
|
|
56
56
|
systemError,
|
|
57
57
|
usageError
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-TIEHKR6K.js";
|
|
59
59
|
import {
|
|
60
60
|
CLOUDFLARE_WORKER_BINDINGS,
|
|
61
61
|
CLOUDFLARE_WORKER_GENERATED_MARKER,
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
projects,
|
|
70
70
|
queries,
|
|
71
71
|
renderReportHtml
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-J3RVQCCQ.js";
|
|
73
73
|
import {
|
|
74
74
|
AdsDeliverySnapshotStatuses,
|
|
75
75
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -137,7 +137,7 @@ import {
|
|
|
137
137
|
providerQuotaPolicySchema,
|
|
138
138
|
resolveProviderInput,
|
|
139
139
|
winnabilityClassSchema
|
|
140
|
-
} from "./chunk-
|
|
140
|
+
} from "./chunk-OSMUOPBR.js";
|
|
141
141
|
|
|
142
142
|
// src/cli.ts
|
|
143
143
|
import { pathToFileURL } from "url";
|
package/dist/index.js
CHANGED
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
createGoogleMarketingCredentialStore,
|
|
4
4
|
createGoogleMarketingRuntime,
|
|
5
5
|
createServer
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DSGX2IAI.js";
|
|
7
7
|
import {
|
|
8
8
|
loadConfig
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-TIEHKR6K.js";
|
|
10
|
+
import "./chunk-J3RVQCCQ.js";
|
|
11
|
+
import "./chunk-OSMUOPBR.js";
|
|
12
12
|
export {
|
|
13
13
|
GoogleMarketingRuntimeError,
|
|
14
14
|
createGoogleMarketingCredentialStore,
|
package/dist/mcp.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
autoSyncSkills
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HYKZOCBT.js";
|
|
4
4
|
import {
|
|
5
5
|
CliError,
|
|
6
6
|
PACKAGE_VERSION,
|
|
7
7
|
canonryMcpTools,
|
|
8
8
|
createApiClient
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-TIEHKR6K.js";
|
|
10
10
|
import {
|
|
11
11
|
isReadOnlyKey
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-OSMUOPBR.js";
|
|
13
13
|
|
|
14
14
|
// src/mcp/cli.ts
|
|
15
15
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.174.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",
|
|
@@ -70,31 +70,31 @@
|
|
|
70
70
|
"@types/node-cron": "^3.0.11",
|
|
71
71
|
"tsup": "^8.5.1",
|
|
72
72
|
"tsx": "^4.19.0",
|
|
73
|
-
"@ainyc/canonry-api-client": "0.0.0",
|
|
74
73
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
75
|
-
"@ainyc/canonry-
|
|
74
|
+
"@ainyc/canonry-api-client": "0.0.0",
|
|
76
75
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
76
|
+
"@ainyc/canonry-config": "0.0.0",
|
|
77
77
|
"@ainyc/canonry-db": "0.0.0",
|
|
78
78
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
79
79
|
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
80
80
|
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
81
|
-
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
82
81
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
83
|
-
"@ainyc/canonry-integration-google": "0.0.0",
|
|
84
|
-
"@ainyc/canonry-integration-google-ads": "0.0.0",
|
|
85
82
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
83
|
+
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
84
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
86
85
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
87
|
-
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
88
86
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
87
|
+
"@ainyc/canonry-integration-google-ads": "0.0.0",
|
|
88
|
+
"@ainyc/canonry-integration-google-tag-manager": "0.0.0",
|
|
89
|
+
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
89
90
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
91
|
+
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
90
92
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
91
93
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
92
|
-
"@ainyc/canonry-provider-
|
|
94
|
+
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
93
95
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
94
96
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
95
|
-
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
96
|
-
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
97
|
-
"@ainyc/canonry-integration-google-tag-manager": "0.0.0"
|
|
97
|
+
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
98
98
|
},
|
|
99
99
|
"scripts": {
|
|
100
100
|
"build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as c,j as e,h as V,u as E,f as L,L as U}from"./vendor-tanstack-Dock0eH1.js";import{cT as O,cU as z,cV as I,cW as F,cX as A,B as N,f as B,cY as W,bT as $,k as D,i as w,d as S,cZ as H,T as G}from"./index-D156-4Hr.js";import{b as J,c as M,d as Q,a as T,f as _,t as K}from"./extract-error-message-CDRTdeQI.js";import{G as Y,w as X,x as Z,y as ee,p as q,A as te}from"./vendor-lucide-nYKv-BB7.js";import"./vendor-radix-4UOaVWza.js";import"./vendor-recharts-D8rt5lKn.js";import"./vendor-markdown-Bn7fRwrx.js";import"./vendor-yaml-GWJz5H2G.js";function re({open:t,onOpenChange:a,projectName:n}){const[r,s]=c.useState("pick");c.useEffect(()=>{t&&s("pick")},[t]);const o=()=>{a(!1),s("pick")};return e.jsx(O,{open:t,onOpenChange:i=>{i?a(!0):o()},children:e.jsx(z,{children:r==="pick"?e.jsx(ne,{onPick:s}):r==="wordpress"?e.jsx(ie,{projectName:n,onBack:()=>s("pick"),onClose:o}):r==="vercel"?e.jsx(ce,{projectName:n,onBack:()=>s("pick"),onClose:o}):e.jsx(le,{projectName:n,onBack:()=>s("pick"),onClose:o})})})}const se=[{type:"wordpress",name:"WordPress",action:"Install the traffic plugin",icon:Y},{type:"cloud-run",name:"Google Cloud Run",action:"Read request logs",icon:X},{type:"vercel",name:"Vercel",action:"Read request logs",icon:Z}];function ne({onPick:t}){return e.jsxs(e.Fragment,{children:[e.jsxs(I,{children:[e.jsx(F,{children:"Connect a traffic source"}),e.jsx(A,{children:"Choose where Canonry should read traffic logs."})]}),e.jsx("div",{className:"mt-6 flex flex-col gap-3",children:se.map(({type:a,name:n,action:r,icon:s})=>e.jsxs("button",{type:"button",onClick:()=>t(a),className:"group flex items-center gap-3 rounded-md border border-base bg-bg-elevated/30 px-3 py-3 text-left transition-colors hover:border-mono-600 hover:bg-bg-elevated/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-mono-400",children:[e.jsx("span",{className:"mt-0.5 inline-flex size-9 shrink-0 items-center justify-center rounded-md border border-base bg-bg text-neutral group-hover:text-heading",children:e.jsx(s,{className:"size-4"})}),e.jsxs("span",{className:"flex min-w-0 flex-1 items-baseline justify-between gap-3",children:[e.jsx("span",{className:"text-sm font-medium text-heading",children:n}),e.jsx("span",{className:"text-sm text-secondary",children:r})]})]},a))})]})}function oe({title:t,description:a,onBack:n}){return e.jsxs(I,{children:[e.jsxs("button",{type:"button",onClick:n,className:"mb-1 inline-flex w-fit items-center gap-1 rounded text-sm text-secondary transition-colors hover:text-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-mono-400",children:[e.jsx(ee,{className:"size-3"}),"Choose a different source"]}),e.jsx(F,{children:t}),e.jsx(A,{children:a})]})}function ae(t,a){const n=V();return async(r,s)=>{await W(t,r),s?.(),a(),n({to:"/traffic/$projectName/$sourceId",params:{projectName:t,sourceId:r}})}}function k(t,a){const[n,r]=c.useState(null),s=ae(t,a);return{error:n,runConnect:async i=>{r(null);const d=i.validate();if(d){r(d);return}let u;try{u=await i.mutate()}catch(l){r(T(l));return}try{await s(u.id,i.onConnected)}catch(l){r(`Source connected, but starting the initial backfill failed: ${T(l)}`)}}}}function P({title:t,description:a,projectName:n,onBack:r,onClose:s,onSubmit:o,isPending:i,error:d,children:u}){return e.jsxs(e.Fragment,{children:[e.jsx(oe,{title:t,description:a,onBack:r}),e.jsxs("form",{onSubmit:B(async l=>{l.preventDefault(),await o()}),className:"mt-6 flex flex-col gap-5 overflow-y-auto pr-1",children:[e.jsx(p,{label:"Project",description:"Canonry project this source attaches to.",children:e.jsx("input",{type:"text",value:n,disabled:!0,className:"w-full rounded border border-strong bg-bg-elevated/50 px-2 py-1.5 text-sm text-neutral"})}),u,d?e.jsx("p",{className:"rounded-md border border-negative-800/50 bg-negative-950/30 px-3 py-2 text-xs text-negative-200",children:d}):null,e.jsxs("div",{className:"mt-2 flex items-center justify-end gap-2 border-t border-default pt-4",children:[e.jsx(N,{type:"button",variant:"ghost",size:"sm",onClick:s,children:"Close"}),e.jsx(N,{type:"submit",disabled:i,size:"sm",children:i?"Connecting…":"Connect"})]})]})]})}function ie({projectName:t,onBack:a,onClose:n}){const[r,s]=c.useState(""),[o,i]=c.useState(""),[d,u]=c.useState(""),[l,j]=c.useState(""),f=J(t||null),{error:g,runConnect:b}=k(t,n),y=()=>b({validate:()=>r.trim()?o.trim()?d.trim()?null:"Application Password is required.":"Username is required.":"WordPress site URL is required.",mutate:()=>f.mutateAsync({baseUrl:r.trim(),username:o.trim(),applicationPassword:d.trim(),displayName:l.trim()||void 0}),onConnected:()=>u("")});return e.jsxs(P,{title:"Connect a WordPress site",description:e.jsxs(e.Fragment,{children:["Pulls request events from the Canonry Traffic Logger plugin. The Application Password is stored in ",e.jsx("code",{children:"~/.canonry/config.yaml"})," on the server and never echoed back to the dashboard."]}),projectName:t,onBack:a,onClose:n,onSubmit:y,isPending:f.isPending,error:g,children:[e.jsx(p,{label:"WordPress site URL",description:"Base URL of the site running the Canonry Traffic Logger plugin.",required:!0,children:e.jsx("input",{type:"url",value:r,onChange:x=>s(x.target.value),required:!0,autoComplete:"url",placeholder:"https://example.com",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"})}),e.jsx(p,{label:"Username",description:"WordPress user that owns the Application Password.",required:!0,children:e.jsx("input",{type:"text",value:o,onChange:x=>i(x.target.value),required:!0,autoComplete:"username",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"})}),e.jsx(p,{label:"Application Password",description:"Create one in wp-admin under Users -> Profile -> Application Passwords.",required:!0,children:e.jsx("input",{type:"password",value:d,onChange:x=>u(x.target.value),required:!0,autoComplete:"new-password",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"})}),e.jsx(p,{label:"Display name (optional)",description:"Friendly label shown in the dashboard. Defaults to the WordPress host.",children:e.jsx("input",{type:"text",value:l,onChange:x=>j(x.target.value),autoComplete:"off",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"})})]})}function le({projectName:t,onBack:a,onClose:n}){const[r,s]=c.useState(""),[o,i]=c.useState(""),[d,u]=c.useState(""),[l,j]=c.useState(""),[f,g]=c.useState(""),b=Q(t||null),{error:y,runConnect:x}=k(t,n),C=()=>x({validate:()=>r.trim()?f.trim()?null:"Service-account JSON content is required.":"GCP project ID is required.",mutate:()=>b.mutateAsync({gcpProjectId:r.trim(),serviceName:o.trim()||void 0,location:d.trim()||void 0,displayName:l.trim()||void 0,keyJson:f.trim()}),onConnected:()=>g("")}),h=async m=>{if(!m)return;const R=await m.text();g(R)};return e.jsxs(P,{title:"Connect a Cloud Run service",description:e.jsxs(e.Fragment,{children:["v1 supports service-account JSON only. The private key is stored in"," ",e.jsx("code",{children:"~/.canonry/config.yaml"})," on the server and never echoed back to the dashboard."]}),projectName:t,onBack:a,onClose:n,onSubmit:C,isPending:b.isPending,error:y,children:[e.jsx(p,{label:"GCP project ID",description:"The Google Cloud project hosting the Cloud Run service (e.g. my-prod-foo).",required:!0,children:e.jsx("input",{type:"text",value:r,onChange:m=>s(m.target.value),required:!0,autoComplete:"off",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"})}),e.jsx(p,{label:"Service name (optional)",description:"Restrict log pulls to a specific Cloud Run service. Omit to pull all services in the project.",children:e.jsx("input",{type:"text",value:o,onChange:m=>i(m.target.value),autoComplete:"off",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"})}),e.jsx(p,{label:"Location (optional)",description:"Region of the Cloud Run service (e.g. us-central1). Helpful when multiple regions emit logs.",children:e.jsx("input",{type:"text",value:d,onChange:m=>u(m.target.value),autoComplete:"off",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"})}),e.jsx(p,{label:"Display name (optional)",description:"Friendly label shown in the dashboard. Defaults to the project + service combo.",children:e.jsx("input",{type:"text",value:l,onChange:m=>j(m.target.value),autoComplete:"off",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"})}),e.jsxs(p,{label:"Service-account JSON",description:"Paste the contents of the SA key (JSON). The SA needs roles/logging.viewer (or any role granting logging.logEntries.list).",required:!0,children:[e.jsx("textarea",{value:f,onChange:m=>g(m.target.value),rows:6,spellCheck:!1,autoComplete:"off",className:"w-full rounded border border-strong bg-transparent px-2 py-1.5 font-mono text-sm text-strong placeholder-mono-600 focus:border-mono-500 focus:outline-none",placeholder:'{"type":"service_account","project_id":"…","private_key":"…"}',required:!0}),e.jsxs("label",{className:"mt-2 inline-flex cursor-pointer items-center gap-2 text-sm text-secondary hover:text-strong",children:[e.jsx("input",{type:"file",accept:"application/json,.json",className:"hidden",onChange:m=>{h(m.target.files?.[0]??null)}}),e.jsx("span",{className:"rounded-md border border-base px-2 py-1",children:"Or upload a key file"})]})]})]})}function ce({projectName:t,onBack:a,onClose:n}){const[r,s]=c.useState(""),[o,i]=c.useState(""),[d,u]=c.useState(""),[l,j]=c.useState("production"),[f,g]=c.useState(""),b=M(t||null),{error:y,runConnect:x}=k(t,n),C=()=>x({validate:()=>r.trim()?o.trim()?d.trim()?null:"Vercel personal access token is required.":"Vercel team / account ID is required.":"Vercel project ID is required.",mutate:()=>b.mutateAsync({projectId:r.trim(),teamId:o.trim(),token:d.trim(),environment:l,displayName:f.trim()||void 0}),onConnected:()=>u("")});return e.jsxs(P,{title:"Connect a Vercel project",description:e.jsxs(e.Fragment,{children:["Pulls request logs straight from Vercel, no in-app instrumentation needed. The personal access token is stored in ",e.jsx("code",{children:"~/.canonry/config.yaml"})," on the server and never echoed back to the dashboard."]}),projectName:t,onBack:a,onClose:n,onSubmit:C,isPending:b.isPending,error:y,children:[e.jsx(p,{label:"Vercel project ID",description:"The prj_… id from the Vercel dashboard or .vercel/project.json.",required:!0,children:e.jsx("input",{type:"text",value:r,onChange:h=>s(h.target.value),required:!0,autoComplete:"off",placeholder:"prj_…",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"})}),e.jsx(p,{label:"Vercel team / account ID",description:"The Vercel team or personal account that owns the project. Find it as orgId in your .vercel/project.json.",required:!0,children:e.jsx("input",{type:"text",value:o,onChange:h=>i(h.target.value),required:!0,autoComplete:"off",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"})}),e.jsx(p,{label:"Personal access token",description:"Create a Vercel personal access token under Account Settings → Tokens. Tokens can expire, so use a long-lived one.",required:!0,children:e.jsx("input",{type:"password",value:d,onChange:h=>u(h.target.value),required:!0,autoComplete:"new-password",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"})}),e.jsx(p,{label:"Environment",description:"Which deployment environment's request logs to pull.",children:e.jsxs("select",{value:l,onChange:h=>j(h.target.value),className:"w-full rounded border border-strong bg-transparent px-2 py-1.5 text-sm text-strong focus:border-mono-500 focus:outline-none",children:[e.jsx("option",{value:"production",children:"production"}),e.jsx("option",{value:"preview",children:"preview"})]})}),e.jsx(p,{label:"Display name (optional)",description:"Friendly label shown in the dashboard. Defaults to the Vercel project ID.",children:e.jsx("input",{type:"text",value:f,onChange:h=>g(h.target.value),autoComplete:"off",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"})})]})}function p({label:t,description:a,required:n,children:r}){return e.jsxs("label",{className:"flex flex-col gap-1",children:[e.jsxs("span",{className:"text-sm font-medium text-strong",children:[t,n?e.jsx("span",{className:"ml-1 text-negative-400",children:"*"}):null]}),r,e.jsx("span",{className:"text-[13px] leading-5 text-secondary",children:a})]})}function de(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 v(t){return t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${(t/1e3).toFixed(1)}K`:t.toLocaleString()}function ye(){const[t,a]=c.useState(""),[n,r]=c.useState(!1),o=E($({client:D})).data??[],i=c.useMemo(()=>t||(o[0]?.name??""),[t,o]),d=_(i||null),u=d.data?.sources??[];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:"Traffic sources"}),e.jsx("p",{className:"page-subtitle",children:"AI crawler hits and referral sessions from your server logs."})]}),!w()&&e.jsx("div",{className:"flex flex-wrap items-center justify-end gap-2",children:e.jsxs(N,{type:"button",variant:"outline",size:"sm",onClick:()=>r(!0),disabled:!i,children:[e.jsx(q,{className:"size-3.5"}),"Connect a source"]})})]}),e.jsxs("section",{children:[o.length>1&&e.jsxs("label",{className:"mb-4 flex w-fit items-center gap-2 text-sm font-medium text-secondary",htmlFor:"traffic-project",children:["Project",e.jsx("select",{id:"traffic-project",className:"h-8 min-w-44 rounded-md border border-base bg-bg px-2 text-sm text-heading outline-none transition focus:border-mono-500 focus:ring-1 focus:ring-mono-500",value:i,onChange:l=>a(l.target.value),children:o.map(l=>e.jsx("option",{value:l.name,children:l.displayName??l.name},l.id))})]}),i?d.isLoading?e.jsx(S,{className:"p-6 text-center text-sm text-muted",children:"Loading sources…"}):u.length===0?e.jsxs(S,{className:"p-8 text-center",children:[e.jsxs("p",{className:"text-sm text-neutral",children:["No traffic sources connected for ",i,"."]}),!w()&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"mt-1 text-sm text-secondary",children:"Connect a source to start collecting traffic."}),e.jsx("div",{className:"mt-4 flex flex-wrap items-center justify-center gap-2",children:e.jsxs(N,{type:"button",variant:"outline",size:"sm",onClick:()=>r(!0),children:[e.jsx(q,{className:"size-3.5"}),"Connect a source"]})})]})]}):e.jsx(ue,{projectName:i,sources:u}):e.jsx(S,{className:"p-6 text-center text-sm text-muted",children:"No projects yet."})]}),!w()&&e.jsx(re,{open:n,onOpenChange:r,projectName:i})]})}function ue({projectName:t,sources:a}){const n=L({queries:a.map(s=>({...H({client:D,path:{name:t,id:s.id}}),staleTime:3e4}))}),r=a.map((s,o)=>({source:s,detail:n[o]?.data,isLoading:n[o]?.isLoading??!1}));return e.jsx("div",{className:"rounded-xl border border-default bg-surface overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-bg-elevated/50 text-[10px] font-semibold uppercase tracking-wider text-muted",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-2 text-left",children:"Source"}),e.jsx("th",{className:"px-4 py-2 text-left",children:"Status"}),e.jsx("th",{className:"px-4 py-2 text-left",children:"Last sync"}),e.jsx("th",{className:"px-4 py-2 text-right",children:"Content crawls"}),e.jsx("th",{className:"px-4 py-2 text-right",children:"Infra crawls"}),e.jsx("th",{className:"px-4 py-2 text-right",children:"AI fetches"}),e.jsx("th",{className:"px-4 py-2 text-right",children:"AI referrals"}),e.jsx("th",{className:"px-4 py-2 text-right"})]})}),e.jsx("tbody",{className:"divide-y divide-mono-800/60",children:r.map(({source:s,detail:o,isLoading:i})=>e.jsxs("tr",{className:"hover:bg-bg-elevated/40 transition-colors",children:[e.jsx("td",{className:"px-4 py-3",children:e.jsx("div",{className:"font-medium text-heading",children:s.displayName})}),e.jsxs("td",{className:"px-4 py-3",children:[e.jsx(G,{tone:K(s.status),children:s.status}),s.lastError?e.jsx("p",{className:"mt-1 max-w-[18rem] truncate text-sm text-negative-400",title:s.lastError,children:s.lastError}):null]}),e.jsx("td",{className:"px-4 py-3 text-neutral",children:de(s.lastSyncedAt)}),e.jsx("td",{className:"px-4 py-3 text-right tabular-nums text-heading",title:o?`${o.totals24h.crawlerHits.toLocaleString("en-US")} total crawler hits`:void 0,children:i?"—":v(o?.totals24h.crawlerContentHits??0)}),e.jsx("td",{className:"px-4 py-3 text-right tabular-nums text-muted",children:i?"—":v(o?.totals24h.crawlerInfraHits??0)}),e.jsx("td",{className:"px-4 py-3 text-right tabular-nums text-heading",children:i?"—":v(o?.totals24h.aiUserFetchHits??0)}),e.jsx("td",{className:"px-4 py-3 text-right tabular-nums text-heading",children:i?"—":v(o?.totals24h.aiReferralHits??0)}),e.jsx("td",{className:"px-4 py-3 text-right",children:e.jsxs(U,{to:"/traffic/$projectName/$sourceId",params:{projectName:t,sourceId:s.id},className:"inline-flex items-center gap-1 text-sm text-secondary hover:text-heading",children:["View",e.jsx(te,{className:"size-3.5"})]})})]},s.id))})]})})}export{ye as TrafficPage};
|