@canonry/canonry 7.99.0 → 7.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -16
- package/assets/agent-workspace/AGENTS.md +13 -6
- package/assets/agent-workspace/skills/aero/SKILL.md +45 -26
- package/assets/agent-workspace/skills/aero/references/agent-operations.md +47 -12
- package/assets/agent-workspace/skills/aero/references/memory-patterns.md +1 -1
- package/assets/agent-workspace/skills/aero/references/orchestration.md +9 -9
- package/assets/agent-workspace/skills/aero/references/reporting.md +8 -4
- package/assets/agent-workspace/skills/aero/references/seo-analysis.md +2 -2
- package/assets/agent-workspace/skills/aero/references/site-health.md +23 -22
- package/assets/agent-workspace/skills/aero/soul.md +2 -2
- package/assets/agent-workspace/skills/canonry/SKILL.md +37 -7
- package/assets/agent-workspace/skills/canonry/references/aeo-analysis.md +14 -11
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +122 -53
- package/assets/assets/AccessControls-DzO5Y8v9.js +2 -0
- package/assets/assets/AgentSetupPage-DWWovaCw.js +36 -0
- package/assets/assets/AuditHistoryPanel-BG-n1i8c.js +1 -0
- package/assets/assets/BacklinksPage-D6wdOMXt.js +1 -0
- package/assets/assets/ChartPrimitives-CtKdkn64.js +3 -0
- package/assets/assets/Hint-3TTi0MgX.js +1 -0
- package/assets/assets/{HistoryPage-DNE76LNh.js → HistoryPage-B_ReWHbL.js} +1 -1
- package/assets/assets/InfoTooltip-D29JcNMW.js +1 -0
- package/assets/assets/MeasurementPropertyPage-zdyLL-kl.js +4 -0
- package/assets/assets/ProjectPage-KZNKXR4w.js +15 -0
- package/assets/assets/RunsPage-DxN0xXQh.js +1 -0
- package/assets/assets/ServerTrafficSection-CvISj5pf.js +40 -0
- package/assets/assets/SettingsPage-CpRpBlMV.js +1 -0
- package/assets/assets/ToneBadge-DcwPruHr.js +60 -0
- package/assets/assets/TrafficPage-zk6zMZyz.js +1 -0
- package/assets/assets/TrafficSourceDetailPage-DJtsI06Z.js +1 -0
- package/assets/assets/{account-context-j3asaevn.js → account-context-CoJVqEXZ.js} +1 -1
- package/assets/assets/{agent-trust-copy--U_DFYQE.js → agent-trust-copy-BIXDMtBm.js} +1 -1
- package/assets/assets/{card-CQAQ-c3g.js → card-Dwmc7Srx.js} +1 -1
- package/assets/assets/index-fh1T5JQY.css +1 -0
- package/assets/assets/index-mqc2mWUR.js +42 -0
- package/assets/assets/query-client-Tg1fZu4i.js +1 -0
- package/assets/assets/react-query-BqcEEfEO.js +1 -0
- package/assets/assets/{react-sigma_core.esm.min-BAq_-iP1.js → react-sigma_core.esm.min-D1q0DR_j.js} +3 -3
- package/assets/assets/{server-traffic-jKXLZyeC.js → server-traffic-Djnh_9f0.js} +1 -1
- package/assets/assets/service-BQjBdN4O.js +1 -0
- package/assets/assets/use-tooltip-position-BOzm-6Wy.js +1 -0
- package/assets/assets/vendor-lucide-iE5MEh2-.js +1 -0
- package/assets/assets/{vendor-markdown-BDQ1GKGP.js → vendor-markdown-BBGbNklj.js} +1 -1
- package/assets/assets/{vendor-radix-BGYlvS2l.js → vendor-radix-DKCt5Z_h.js} +1 -1
- package/assets/assets/{vendor-recharts-DhEHcK3G.js → vendor-recharts-D3MLFU3q.js} +1 -1
- package/assets/assets/{vendor-tanstack-BNuZ37rE.js → vendor-tanstack-B90HW50P.js} +2 -2
- package/assets/index.html +16 -15
- package/dist/{ads-EYDUTG4U.js → ads-FVPZ6R6Z.js} +3 -3
- package/dist/{agent-KTK2IDB3.js → agent-2LPU2E5I.js} +7 -7
- package/dist/{agent-ask-KPZOH6RY.js → agent-ask-5ODREK6D.js} +3 -3
- package/dist/{agent-conversations-BCWA4JJL.js → agent-conversations-SNLOOJEM.js} +3 -3
- package/dist/{agent-journeys-UBVLQ7JV.js → agent-journeys-XDXVL6PK.js} +3 -3
- package/dist/{agent-memory-24SYEGEX.js → agent-memory-NKAI2S3U.js} +3 -3
- package/dist/{agent-providers-E7EWFE5P.js → agent-providers-R5L7A72X.js} +3 -3
- package/dist/{agent-transcript-QGJ45NW5.js → agent-transcript-C5WAGYVC.js} +3 -3
- package/dist/{analytics-GHVG5CCT.js → analytics-EJVOLIQL.js} +33 -13
- package/dist/{apply-7YLB2DPH.js → apply-I6JOM247.js} +3 -3
- package/dist/{backfill-WNQ6O5WP.js → backfill-UVUR36IB.js} +10 -10
- package/dist/{backlinks-ZBZR4D27.js → backlinks-3VMVACWN.js} +3 -3
- package/dist/{bing-4VBSKPSX.js → bing-R5RL3PW2.js} +3 -3
- package/dist/{bootstrap-7ESCLP2G.js → bootstrap-GMMSDTNO.js} +12 -12
- package/dist/{cdp-WBL6FZTL.js → cdp-FJKUXHEY.js} +7 -7
- package/dist/{chunk-L53ZSQN5.js → chunk-2DV7F6XA.js} +91 -2
- package/dist/{chunk-MTW37GXF.js → chunk-2FWYWGIR.js} +2 -2
- package/dist/{chunk-DMPSA7ZS.js → chunk-56VVRWJM.js} +14 -5
- package/dist/{chunk-YACKJGY4.js → chunk-7BEGCVVB.js} +1 -1
- package/dist/{chunk-YMHN4UIT.js → chunk-7BH53MOB.js} +27 -2
- package/dist/{chunk-XPIMVXAI.js → chunk-7J2RIIYU.js} +1366 -1033
- package/dist/{chunk-UY6SKAKW.js → chunk-7SNMIXEQ.js} +2 -2
- package/dist/{chunk-C55P75G4.js → chunk-AMGM55CP.js} +2 -2
- package/dist/{chunk-ZN2TEBBX.js → chunk-AYKTVQF7.js} +13 -5
- package/dist/{chunk-74V5EPZH.js → chunk-BKDRT4VS.js} +7 -7
- package/dist/{chunk-O6RXNSNW.js → chunk-COHSL6KW.js} +1 -1
- package/dist/{chunk-3WDQ5GPO.js → chunk-DGDLLRS4.js} +1 -1
- package/dist/{chunk-VADVPARO.js → chunk-DHIB7EIA.js} +4 -4
- package/dist/{chunk-3MFYM2IS.js → chunk-EE3QTCLS.js} +18 -6
- package/dist/{chunk-DLOWRO5R.js → chunk-F46TBLXK.js} +204 -94
- package/dist/{chunk-P764TJKQ.js → chunk-FBO25TA3.js} +1 -1
- package/dist/{chunk-SY3CWJR4.js → chunk-FZ3MUTU3.js} +2 -2
- package/dist/{chunk-WA6APXI6.js → chunk-G6QN4VFS.js} +16 -10
- package/dist/{chunk-YBWATBX4.js → chunk-HBHLYWKE.js} +9 -6
- package/dist/{chunk-5ZOM5BJS.js → chunk-HL2LGRTI.js} +8 -6
- package/dist/chunk-J6536OL6.js +31 -0
- package/dist/{chunk-3MKJ4LP6.js → chunk-KVRX7YIH.js} +20 -10
- package/dist/{chunk-3VPBRGPN.js → chunk-LJO2BKWU.js} +1 -1
- package/dist/{chunk-YEUULP44.js → chunk-LNVFERI4.js} +1 -1
- package/dist/{chunk-WXAF7AMC.js → chunk-NQYJHKML.js} +39 -7
- package/dist/{chunk-UPHHKO3L.js → chunk-O5UFAXUI.js} +646 -588
- package/dist/{chunk-XQP3XHLJ.js → chunk-O6APBEJE.js} +2 -2
- package/dist/{chunk-47X24IJG.js → chunk-O7S7OHLE.js} +9393 -8394
- package/dist/{chunk-2RW5D55K.js → chunk-QS5DWJDI.js} +2 -2
- package/dist/{chunk-TVBOK4P2.js → chunk-RBG2QXQM.js} +4 -4
- package/dist/{chunk-LM7HTNUO.js → chunk-SWZXHHAG.js} +16 -8
- package/dist/{chunk-AY7SDX6G.js → chunk-T7UDY7W3.js} +26 -11
- package/dist/{chunk-AJD252SX.js → chunk-UGO2FO6V.js} +119 -55
- package/dist/{chunk-PT5HNVCM.js → chunk-VHULVUDL.js} +1 -1
- package/dist/{chunk-ZGBLNKFN.js → chunk-YGAQQSCL.js} +56303 -54933
- package/dist/{chunk-RRXLJPBN.js → chunk-YIIRS7V7.js} +98 -65
- package/dist/{chunk-VOVT2H25.js → chunk-YU2WX7RD.js} +3 -3
- package/dist/{citations-N5MGNKJN.js → citations-LOEQRDUB.js} +21 -10
- package/dist/{cli-catalog-FFU7PHW7.js → cli-catalog-5RXNUFBS.js} +3 -3
- package/dist/{cli-commands-AMIDEUO2.js → cli-commands-HE2BQY3Y.js} +7 -7
- package/dist/cli.js +22 -17
- package/dist/{competitor-GRA2GMZR.js → competitor-PIX2BHJW.js} +3 -3
- package/dist/{content-YVAPTIV4.js → content-PJGW4WZF.js} +3 -3
- package/dist/{dashboard-33ACBR5A.js → dashboard-7OKBD4MG.js} +6 -6
- package/dist/{demo-AGXWBMR6.js → demo-SCOFAWFM.js} +1 -1
- package/dist/{demo-server-W4YAC7GT.js → demo-server-SJPI6RSL.js} +38 -36
- package/dist/{discover-BH33TO4Z.js → discover-I3WL2QUN.js} +10 -8
- package/dist/{discover-eval-3CEA6DEE.js → discover-eval-YRECOIP5.js} +3 -3
- package/dist/{doctor-ZAYTD5PC.js → doctor-F4J6LILX.js} +3 -3
- package/dist/{evidence-247GL7UK.js → evidence-MYQTCY4V.js} +25 -10
- package/dist/{export-cmd-HLKWFI5Q.js → export-cmd-3SUFOJM6.js} +3 -3
- package/dist/{ga-BMING57Z.js → ga-VA6FYK4L.js} +3 -3
- package/dist/{gbp-MIB5CXSD.js → gbp-DI6ZVFHL.js} +3 -3
- package/dist/{google-5JP6RYAW.js → google-UVKWJCD2.js} +4 -4
- package/dist/{google-marketing-25OBMPS6.js → google-marketing-S63HN733.js} +1 -1
- package/dist/{health-cmd-D5XSEL7H.js → health-cmd-DOZXGI46.js} +16 -9
- package/dist/{history-6MDRFPQ3.js → history-UTJTUDYK.js} +3 -3
- package/dist/index.d.ts +211 -19
- package/dist/index.js +26 -26
- package/dist/{init-RDR75N2Y.js → init-IVJSS33J.js} +19 -19
- package/dist/{insights-QZVMBGVM.js → insights-UHCVCZ76.js} +3 -3
- package/dist/intelligence-service-3EENJ5DS.js +16 -0
- package/dist/{journeys-TABTZDFZ.js → journeys-XIT7WDM2.js} +3 -3
- package/dist/{keys-SL5YF7NQ.js → keys-MQKW4JUI.js} +3 -3
- package/dist/{keyword-OCDEXRSW.js → keyword-EASMKYZ3.js} +3 -3
- package/dist/{logs-CSC7O364.js → logs-ZHZ6XM55.js} +3 -3
- package/dist/{mcp-P725OHAJ.js → mcp-ECVT2YGU.js} +4 -4
- package/dist/mcp.js +10 -10
- package/dist/{measurement-plan-Z42GBJBO.js → measurement-plan-7FQKUOMR.js} +5 -5
- package/dist/{notify-E5JBES4I.js → notify-TC7ARC6W.js} +3 -3
- package/dist/{organic-evidence-CUA3T64O.js → organic-evidence-M34MWJXE.js} +7 -4
- package/dist/overview-P6BRMXJN.js +314 -0
- package/dist/{project-2ULM64TV.js → project-WZ2YXFPJ.js} +4 -4
- package/dist/project-setup-WV6SPGIV.js +176 -0
- package/dist/{query-Y47IEFKJ.js → query-WAFJKDHG.js} +3 -3
- package/dist/{research-DPFQZ3TE.js → research-B5ZPQX7R.js} +3 -3
- package/dist/{results-export-KBHOBQAH.js → results-export-NIZV6R3K.js} +3 -3
- package/dist/{run-4CYHVIIU.js → run-ICLPZ7QT.js} +7 -4
- package/dist/{schedule-GY4P3RON.js → schedule-4C44LQ7R.js} +22 -3
- package/dist/{search-AGVNZMJQ.js → search-UJM7KII3.js} +11 -4
- package/dist/{serve-5LFKIXNL.js → serve-A6UIO6WP.js} +30 -29
- package/dist/{session-YAYEDM3P.js → session-RTE22GQT.js} +14 -14
- package/dist/settings-BOF5Z7ML.js +211 -0
- package/dist/{sitemaps-APTY7U6H.js → sitemaps-BM7S76H2.js} +4 -4
- package/dist/{skills-4BUONEIZ.js → skills-X5SR4HRO.js} +2 -2
- package/dist/{snapshot-BXCWSF5P.js → snapshot-KLKE37VY.js} +4 -4
- package/dist/{src-R7XZUX3D.js → src-EKLG5A6O.js} +4 -2
- package/dist/{status-SB6HPBYJ.js → status-OYG57DWU.js} +6 -5
- package/dist/{technical-aeo-G7UEMWZD.js → technical-aeo-KWVWOOTI.js} +23 -23
- package/dist/{telemetry-H4S4Y7YV.js → telemetry-KGE6FF3Y.js} +4 -4
- package/dist/{tools-46XX6I4R.js → tools-4R33AZQ3.js} +11 -11
- package/dist/{traffic-I6WRJN3W.js → traffic-SVMOKCSS.js} +7 -11
- package/dist/{trends-AQK3GLWF.js → trends-RGAKGX3L.js} +4 -4
- package/dist/{users-SNTVY6OB.js → users-47WKA2TO.js} +3 -3
- package/dist/{visibility-stats-44QAD2XS.js → visibility-stats-DTGQJPNV.js} +9 -5
- package/dist/{wordpress-N7LTOW46.js → wordpress-2CNUX4UE.js} +3 -3
- package/package.json +1 -1
- package/assets/assets/AgentSetupPage-yOqSVJ-e.js +0 -18
- package/assets/assets/AuditHistoryPanel-CiTzFgbw.js +0 -1
- package/assets/assets/BacklinksPage-DmRdQsFQ.js +0 -1
- package/assets/assets/ChartPrimitives-CvK6CQrj.js +0 -1
- package/assets/assets/Hint-c4a4W87X.js +0 -1
- package/assets/assets/InfoTooltip-Drnst4ML.js +0 -1
- package/assets/assets/MeasurementPropertyPage-Cx64Fnmz.js +0 -4
- package/assets/assets/ProjectPage-DNfgC82V.js +0 -11
- package/assets/assets/RunsPage-BmPKBKKr.js +0 -1
- package/assets/assets/SettingsPage-Dl0TNeVK.js +0 -1
- package/assets/assets/SiteHealthSection-DxQPaR--.js +0 -2
- package/assets/assets/ToneBadge-BhjTBHi-.js +0 -60
- package/assets/assets/TrafficPage-CJp0pS01.js +0 -40
- package/assets/assets/TrafficSourceDetailPage-DKE8tSw5.js +0 -1
- package/assets/assets/format-helpers-BPugHeIX.js +0 -3
- package/assets/assets/index-BAxHW-1G.css +0 -1
- package/assets/assets/index-xlDLvgRC.js +0 -60
- package/assets/assets/query-client-CwZpfiiD.js +0 -1
- package/assets/assets/react-query-CBpNFR4t.js +0 -1
- package/assets/assets/service-DFumlmXt.js +0 -1
- package/assets/assets/vendor-lucide-DuOM7wVi.js +0 -1
- package/dist/intelligence-service-KQE7RO5I.js +0 -16
- package/dist/overview-UKQ52I72.js +0 -213
- package/dist/settings-HUKMWRHY.js +0 -119
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{ft as t}from"./vendor-lucide-iE5MEh2-.js";import{a as n,i as r,o as i,r as a,s as o,t as s}from"./vendor-radix-DKCt5Z_h.js";import{r as c}from"./vendor-markdown-BBGbNklj.js";import{d as l,f as u,x as d}from"./vendor-tanstack-B90HW50P.js";import{Et as f,Tt as p,Xi as m,Zi as h,gt as g,r as _}from"./ToneBadge-DcwPruHr.js";import{n as v}from"./AccessControls-DzO5Y8v9.js";import{I as y}from"./ChartPrimitives-CtKdkn64.js";import{a as b}from"./query-client-Tg1fZu4i.js";import{gn as x,pn as S}from"./react-query-BqcEEfEO.js";import{t as C}from"./InfoTooltip-D29JcNMW.js";import{t as w}from"./card-Dwmc7Srx.js";import{A as T,Ot as E,bt as D,ct as O,r as k,st as A,tt as j}from"./index-mqc2mWUR.js";var M=e(t(),1),N=c(),P={"30d":{label:`Last 30 days`,days:30},"90d":{label:`Last 90 days`,days:90},"365d":{label:`Last year`,days:365}};function F(e){return new Date(Date.now()-P[e].days*24*60*60*1e3).toISOString()}function I({open:e,projectCount:t,pending:c,onOpenChange:l,onConfirm:u,onClosed:d}){let f=t===1;return(0,N.jsx)(s,{open:e,onOpenChange:l,children:(0,N.jsxs)(i,{children:[(0,N.jsx)(n,{className:`fixed inset-0 z-50 bg-overlay-scrim/70 backdrop-blur-sm`}),(0,N.jsxs)(a,{className:`material-modal fixed left-1/2 top-1/2 z-50 max-h-[85dvh] w-[calc(100%-2rem)] max-w-xl -translate-x-1/2 -translate-y-1/2 overflow-y-auto p-5`,onCloseAutoFocus:e=>{e.preventDefault(),d()},children:[(0,N.jsxs)(`div`,{className:`space-y-2`,children:[(0,N.jsx)(o,{className:`text-heading-20 text-heading`,children:`Review AI Visibility checks`}),(0,N.jsx)(r,{className:`text-copy-14 text-secondary`,children:f?`Checks 1 project. It runs its saved queries on its selected engines. Provider charges apply.`:`Checks all ${t} projects. Each runs its saved queries on its selected engines. Provider charges apply.`})]}),(0,N.jsx)(`p`,{className:`mt-4 text-copy-13 text-secondary`,children:`Runs once. Schedules stay unchanged. Projects already running or not set up are skipped.`}),(0,N.jsxs)(`div`,{className:`mt-6 flex flex-wrap gap-3`,children:[(0,N.jsx)(_,{type:`button`,variant:`outline`,onClick:()=>l(!1),children:`Cancel`}),(0,N.jsx)(v,{type:`button`,disabled:c,onClick:u,children:c?`Queueing…`:`Run ${t} ${f?`project`:`projects`}`})]})]})]})})}function L(){let e=A()?.dashboard,t=u({strict:!1}),n=l(),r=Object.values(h).includes(t.runStatus)?t.runStatus:`all`,i=Object.values(m).includes(t.runKind)?t.runKind:`all`,a=t.runProject??`all`,o=Object.hasOwn(P,t.runWindow??``)?t.runWindow:`30d`,s=t.runQuery??``,c=(0,M.useMemo)(()=>F(o),[o]),L=d({...S({client:g}),initialData:e?.projects.map(({project:e})=>e),initialDataUpdatedAt:0}),R=d({...x({client:g,query:{limit:1e3,since:c}}),initialData:e?.runs,initialDataUpdatedAt:0,staleTime:b,refetchInterval:e=>e.state.data?.some(e=>e.status===h.queued||e.status===h.running)?3e3:b}),z=k(),[B,V]=(0,M.useState)(!1),H=(0,M.useRef)(null),U=(0,M.useMemo)(()=>new Map((L.data??[]).map(e=>[e.id,e.displayName||e.name])),[L.data]),W=(0,M.useMemo)(()=>(R.data??[]).map(e=>`projectName`in e?e:O(e,U.get(e.projectId)??`Unknown project`)),[U,R.data]),G=s.trim().toLowerCase(),K=W.filter(e=>r!==`all`&&e.status!==r||i!==`all`&&e.kind!==i||a!==`all`&&e.projectId!==a?!1:!G||[e.summary,e.projectName,e.kindLabel,e.statusDetail].some(e=>e.toLowerCase().includes(G))),q=r!==`all`||i!==`all`||a!==`all`||s.trim()!==``||o!==`30d`,J=e=>{n({to:`/runs`,search:t=>({...t,...e}),replace:!0})};if(L.isLoading||R.isLoading)return(0,N.jsxs)(`div`,{className:`page-skeleton`,children:[(0,N.jsxs)(`div`,{className:`page-skeleton-header`,children:[(0,N.jsx)(`div`,{className:`skeleton-text h-6 w-20`}),(0,N.jsx)(`div`,{className:`skeleton-text-sm w-72`})]}),(0,N.jsx)(`div`,{className:`space-y-2`,children:[1,2,3,4].map(e=>(0,N.jsxs)(`div`,{className:`material-base p-3 flex items-center gap-3`,children:[(0,N.jsxs)(`div`,{className:`flex-1 space-y-1.5`,children:[(0,N.jsx)(`div`,{className:`skeleton-text w-40`}),(0,N.jsx)(`div`,{className:`skeleton-text-sm w-56`})]}),(0,N.jsx)(`div`,{className:`skeleton h-5 w-16 rounded-full`})]},e))})]});let Y=L.data?.length??0,X=async()=>{try{await z.mutateAsync(void 0),V(!1)}catch{}};return(0,N.jsxs)(`div`,{className:`page-container`,children:[(0,N.jsxs)(`div`,{className:`page-header`,children:[(0,N.jsxs)(`div`,{className:`page-header-left`,children:[(0,N.jsx)(`h1`,{className:`page-title`,children:`Runs`}),(0,N.jsx)(`p`,{className:`page-subtitle`,children:`Recent jobs across all projects.`})]}),!f()&&(p()?(0,N.jsx)(`p`,{className:`text-copy-14 text-secondary`,children:`AI Visibility checks are run by your Canonry team`}):Y>0?(0,N.jsx)(v,{type:`button`,variant:`outline`,size:`sm`,"aria-haspopup":`dialog`,onClick:e=>{H.current=e.currentTarget,V(!0)},children:`Run all projects`}):null)]}),!f()&&!p()?(0,N.jsx)(I,{open:B,projectCount:Y,pending:z.isPending,onOpenChange:V,onConfirm:()=>void X(),onClosed:()=>H.current?.focus()}):null,(0,N.jsxs)(`section`,{children:[(0,N.jsxs)(`div`,{className:`run-filters`,role:`group`,"aria-label":`Run filters`,children:[(0,N.jsx)(`input`,{type:`search`,"aria-label":`Search runs`,value:s,onChange:e=>J({runQuery:e.target.value||void 0}),placeholder:`Search runs or projects`,className:`run-filter-control`}),(0,N.jsxs)(`select`,{"aria-label":`Filter runs by status`,value:r,onChange:e=>J({runStatus:e.target.value===`all`?void 0:e.target.value}),className:`run-filter-control`,children:[(0,N.jsx)(`option`,{value:`all`,children:`All statuses`}),Object.values(h).map(e=>(0,N.jsx)(`option`,{value:e,children:y(e)},e))]}),(0,N.jsxs)(`select`,{"aria-label":`Filter runs by project`,value:a,onChange:e=>J({runProject:e.target.value===`all`?void 0:e.target.value}),className:`run-filter-control`,children:[(0,N.jsx)(`option`,{value:`all`,children:`All projects`}),(L.data??[]).map(e=>(0,N.jsx)(`option`,{value:e.id,children:e.displayName||e.name},e.id))]}),(0,N.jsxs)(`select`,{"aria-label":`Filter runs by type`,value:i,onChange:e=>J({runKind:e.target.value===`all`?void 0:e.target.value}),className:`run-filter-control`,children:[(0,N.jsx)(`option`,{value:`all`,children:`All run types`}),Object.values(m).map(e=>(0,N.jsx)(`option`,{value:e,children:j(e)},e))]}),(0,N.jsx)(`select`,{"aria-label":`Filter runs by date range`,value:o,onChange:e=>J({runWindow:e.target.value===`30d`?void 0:e.target.value}),className:`run-filter-control`,children:Object.entries(P).map(([e,t])=>(0,N.jsx)(`option`,{value:e,children:t.label},e))}),q?(0,N.jsx)(_,{type:`button`,variant:`ghost`,onClick:()=>J({runStatus:void 0,runKind:void 0,runProject:void 0,runWindow:void 0,runQuery:void 0}),children:`Clear filters`}):null]}),R.isError?(0,N.jsxs)(w,{className:`surface-card empty-card`,children:[(0,N.jsx)(`h2`,{children:`Run history unavailable`}),(0,N.jsx)(`p`,{children:E(R.error)}),(0,N.jsx)(_,{variant:`outline`,onClick:()=>void R.refetch(),children:`Try again`})]}):null,!R.isError&&K.length>0?(0,N.jsx)(`div`,{className:`data-table-wrapper`,children:(0,N.jsxs)(`table`,{className:`data-table runs-table`,children:[(0,N.jsx)(`caption`,{className:`sr-only`,children:`Recent runs across projects`}),(0,N.jsx)(`thead`,{children:(0,N.jsxs)(`tr`,{children:[(0,N.jsx)(`th`,{scope:`col`,children:`Run`}),(0,N.jsx)(`th`,{scope:`col`,children:`Project`}),(0,N.jsx)(`th`,{scope:`col`,children:`Status`}),(0,N.jsx)(`th`,{scope:`col`,children:`Started`}),(0,N.jsx)(`th`,{scope:`col`,children:`Duration`}),(0,N.jsx)(`th`,{scope:`col`,children:`Trigger`})]})}),(0,N.jsx)(`tbody`,{children:K.map(e=>(0,N.jsxs)(`tr`,{children:[(0,N.jsx)(`td`,{children:(0,N.jsx)(T,{run:e,projectName:L.data?.find(t=>t.id===e.projectId)?.name,className:`text-link text-label-14-strong text-left`,label:`View ${e.summary} for ${e.projectName}`,children:e.kindLabel})}),(0,N.jsxs)(`td`,{children:[(0,N.jsx)(`span`,{className:`text-primary`,children:e.projectName}),e.location?(0,N.jsx)(`span`,{className:`block text-copy-13 text-secondary`,children:e.location}):null]}),(0,N.jsx)(`td`,{children:(0,N.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,N.jsx)(D,{status:e.status}),(0,N.jsx)(C,{text:e.statusDetail})]})}),(0,N.jsx)(`td`,{className:`whitespace-nowrap tabular-nums`,children:e.startedAt}),(0,N.jsx)(`td`,{className:`whitespace-nowrap tabular-nums`,children:e.duration}),(0,N.jsx)(`td`,{className:`whitespace-nowrap`,children:e.triggerLabel})]},e.id))})]})}):R.isError?null:(0,N.jsxs)(w,{className:`surface-card empty-card`,children:[(0,N.jsx)(`h2`,{children:q?`No runs match these filters`:`No recent runs`}),(0,N.jsx)(`p`,{children:q?`Change or clear the filters to see more runs.`:`Start a check from a project, or choose a wider date range.`})]})]})]})}export{L as RunsPage};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{C as t,H as n,W as r,f as i,ft as a,it as o,lt as s,o as c,q as l,tt as u,ut as d,z as f}from"./vendor-lucide-iE5MEh2-.js";import{r as p}from"./vendor-markdown-BBGbNklj.js";import{S as m,d as h,u as g}from"./vendor-tanstack-B90HW50P.js";import{Et as _,gt as v,r as y,t as ee,yn as b}from"./ToneBadge-DcwPruHr.js";import{t as te}from"./async-handler-Bj3TnIRw.js";import{d as ne}from"./query-client-Tg1fZu4i.js";import{cn as re}from"./react-query-BqcEEfEO.js";import{t as x}from"./InfoTooltip-D29JcNMW.js";import{t as S}from"./card-Dwmc7Srx.js";import{Bt as C,Ot as w,_t as T,gt as ie,ht as E,k as ae,vt as D,yt as O}from"./index-mqc2mWUR.js";import{i as k,n as A,r as oe,s as se,t as ce}from"./server-traffic-Djnh_9f0.js";var j=e(a(),1),M=p();function le({open:e,onOpenChange:t,onClosed:n,projectName:r}){let[i,a]=(0,j.useState)(`pick`);(0,j.useEffect)(()=>{e&&a(`pick`)},[e]);let o=()=>{t(!1),a(`pick`)};return(0,M.jsx)(E,{open:e,onOpenChange:e=>{e?t(!0):o()},children:(0,M.jsx)(ie,{onCloseAutoFocus:e=>{n&&(e.preventDefault(),n())},children:i===`pick`?(0,M.jsx)(de,{onPick:a}):i===`cloudflare`?(0,M.jsx)(he,{projectName:r,onBack:()=>a(`pick`),onClose:o}):i===`wordpress`?(0,M.jsx)(L,{projectName:r,onBack:()=>a(`pick`),onClose:o}):i===`vercel`?(0,M.jsx)(z,{projectName:r,onBack:()=>a(`pick`),onClose:o}):(0,M.jsx)(R,{projectName:r,onBack:()=>a(`pick`),onClose:o})})})}var ue=[{type:`cloudflare`,name:`Cloudflare`,needs:`A zone you manage. Set up from the terminal.`,icon:i},{type:`wordpress`,name:`WordPress`,needs:`wp-admin access to install a plugin`,icon:f},{type:`vercel`,name:`Vercel`,needs:`A Vercel access token`,icon:c},{type:`cloud-run`,name:`Google Cloud Run`,needs:`A service account that can read logs`,icon:l}];function de({onPick:e}){return(0,M.jsxs)(M.Fragment,{children:[(0,M.jsxs)(D,{children:[(0,M.jsx)(O,{children:`Connect a traffic source`}),(0,M.jsx)(T,{children:`Pick where your site runs. Canonry reads AI crawler visits and AI referrals from there.`})]}),(0,M.jsx)(`div`,{className:`mt-6 flex flex-col gap-3`,children:ue.map(({type:t,name:n,needs:r,icon:i})=>(0,M.jsxs)(`button`,{type:`button`,onClick:()=>e(t),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:[(0,M.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:(0,M.jsx)(i,{className:`size-4`})}),(0,M.jsxs)(`span`,{className:`flex min-w-0 flex-1 flex-col`,children:[(0,M.jsx)(`span`,{className:`text-label-14-strong text-heading`,children:n}),(0,M.jsx)(`span`,{className:`text-label-13 text-secondary`,children:r})]})]},t))}),(0,M.jsx)(`p`,{className:`mt-6 text-copy-13 text-secondary`,children:`Your agent can set up any of these for you. Pick a source to copy instructions for it.`})]})}function N({title:e,description:t,onBack:n}){return(0,M.jsxs)(D,{children:[(0,M.jsxs)(`button`,{type:`button`,onClick:n,className:`mb-1 inline-flex w-fit items-center gap-1 rounded text-button-14 text-secondary transition-colors hover:text-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-mono-400`,children:[(0,M.jsx)(d,{className:`size-3`}),`Choose a different source`]}),(0,M.jsx)(O,{children:e}),(0,M.jsx)(T,{children:t})]})}function P(e,t){let n=h();return async(r,i)=>{i.startInitialBackfill&&await b(e,r),i.afterConnected?.(),t(),n({to:`/traffic/$projectName/$sourceId`,params:{projectName:e,sourceId:r}})}}function F(e,t){let[n,r]=(0,j.useState)(null),i=P(e,t);return{error:n,runConnect:async e=>{r(null);let t=e.validate();if(t){r(t);return}let n;try{n=await e.mutate()}catch(e){r(w(e));return}try{await i(n.id,{startInitialBackfill:e.startInitialBackfill??!0,afterConnected:e.onConnected})}catch(e){r(`Source connected, but starting the initial backfill failed: ${w(e)}`)}}}}function I({title:e,description:t,projectName:n,onBack:r,onClose:i,onSubmit:a,isPending:o,error:s,guide:c,children:l}){return(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(N,{title:e,description:t,onBack:r}),(0,M.jsxs)(`div`,{className:`-mr-1 mt-6 min-h-0 flex-1 overflow-y-auto pr-1`,children:[(0,M.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[(0,M.jsx)(X,{request:c.agentRequest,docsUrl:c.docsUrl}),(0,M.jsx)(Z,{steps:c.steps})]}),(0,M.jsxs)(`form`,{onSubmit:te(async e=>{e.preventDefault(),await a()}),className:`mt-6 flex flex-col gap-5 border-t border-default pt-5`,children:[(0,M.jsxs)(`p`,{className:`text-copy-14-strong text-heading`,children:[`Then connect it to `,(0,M.jsx)(`span`,{className:`text-label-13-mono`,children:n})]}),l,s?(0,M.jsx)(`p`,{className:`rounded-md border border-negative-800/50 bg-negative-950/30 px-3 py-2 text-copy-13 text-negative-200`,children:s}):null,(0,M.jsxs)(`div`,{className:`mt-2 flex items-center justify-end gap-2 border-t border-default pt-4`,children:[(0,M.jsx)(y,{type:`button`,variant:`ghost`,size:`sm`,onClick:i,children:`Close`}),(0,M.jsx)(y,{type:`submit`,disabled:o,size:`sm`,children:o?`Connecting…`:`Connect`})]})]})]})]})}function L({projectName:e,onBack:t,onClose:n}){let[r,i]=(0,j.useState)(``),[a,o]=(0,j.useState)(``),[s,c]=(0,j.useState)(``),[l,u]=(0,j.useState)(``),d=k(e||null),{error:f,runConnect:p}=F(e,n);return(0,M.jsxs)(I,{title:`Connect a WordPress site`,description:(0,M.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[`Reads AI crawler visits from the Canonry Traffic Logger plugin.`,(0,M.jsx)(x,{text:`${K(`Application Password`)} Pages served from a full-page cache never reach the plugin, so exclude AI crawlers from your cache. The docs list the user agents.`})]}),guide:Y(e,r),projectName:e,onBack:t,onClose:n,onSubmit:()=>p({validate:()=>r.trim()?a.trim()?s.trim()?null:`Application Password is required.`:`Username is required.`:`WordPress site URL is required.`,mutate:()=>d.mutateAsync({baseUrl:r.trim(),username:a.trim(),applicationPassword:s.trim(),displayName:l.trim()||void 0}),onConnected:()=>c(``)}),isPending:d.isPending,error:f,children:[(0,M.jsx)(B,{label:`WordPress site URL`,description:`Base URL of the site running the Canonry Traffic Logger plugin.`,required:!0,children:(0,M.jsx)(`input`,{type:`url`,value:r,onChange:e=>i(e.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-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})}),(0,M.jsx)(B,{label:`Username`,description:`WordPress user that owns the Application Password.`,required:!0,children:(0,M.jsx)(`input`,{type:`text`,value:a,onChange:e=>o(e.target.value),required:!0,autoComplete:`username`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})}),(0,M.jsx)(B,{label:`Application Password`,description:`Create one in wp-admin under Users -> Profile -> Application Passwords.`,required:!0,children:(0,M.jsx)(`input`,{type:`password`,value:s,onChange:e=>c(e.target.value),required:!0,autoComplete:`new-password`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})}),(0,M.jsx)(Q,{children:(0,M.jsx)(B,{label:`Display name (optional)`,description:`Friendly label shown in the dashboard. Defaults to the WordPress host.`,children:(0,M.jsx)(`input`,{type:`text`,value:l,onChange:e=>u(e.target.value),autoComplete:`off`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})})})]})}function R({projectName:e,onBack:t,onClose:n}){let[r,i]=(0,j.useState)(``),[a,o]=(0,j.useState)(``),[s,c]=(0,j.useState)(``),[l,u]=(0,j.useState)(``),[d,f]=(0,j.useState)(``),p=A(e||null),{error:m,runConnect:h}=F(e,n),g=()=>h({validate:()=>r.trim()?d.trim()?null:`Service-account JSON content is required.`:`GCP project ID is required.`,mutate:()=>p.mutateAsync({gcpProjectId:r.trim(),serviceName:a.trim()||void 0,location:s.trim()||void 0,displayName:l.trim()||void 0,keyJson:d.trim()}),onConnected:()=>f(``)}),_=async e=>{if(!e)return;let t=await e.text();f(t)};return(0,M.jsxs)(I,{title:`Connect a Cloud Run service`,description:(0,M.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[`Reads AI crawler visits from your Cloud Run request logs.`,(0,M.jsx)(x,{text:K(`service-account private key`)})]}),guide:pe(e,r),projectName:e,onBack:t,onClose:n,onSubmit:g,isPending:p.isPending,error:m,children:[(0,M.jsx)(B,{label:`GCP project ID`,description:`The Google Cloud project hosting the Cloud Run service (e.g. my-prod-foo).`,required:!0,children:(0,M.jsx)(`input`,{type:`text`,value:r,onChange:e=>i(e.target.value),required:!0,autoComplete:`off`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})}),(0,M.jsxs)(B,{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:[(0,M.jsx)(`textarea`,{value:d,onChange:e=>f(e.target.value),rows:6,spellCheck:!1,autoComplete:`off`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-copy-14-mono text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`,placeholder:`{"type":"service_account","project_id":"…","private_key":"…"}`,required:!0}),(0,M.jsxs)(`label`,{className:`mt-2 inline-flex cursor-pointer items-center gap-2 text-label-14 text-secondary hover:text-strong`,children:[(0,M.jsx)(`input`,{type:`file`,accept:`application/json,.json`,className:`hidden`,onChange:e=>void _(e.target.files?.[0]??null)}),(0,M.jsx)(`span`,{className:`rounded-md border border-base px-2 py-1`,children:`Or upload a key file`})]})]}),(0,M.jsxs)(Q,{children:[(0,M.jsx)(B,{label:`Service name (optional)`,description:`Restrict log pulls to a specific Cloud Run service. Omit to pull all services in the project.`,children:(0,M.jsx)(`input`,{type:`text`,value:a,onChange:e=>o(e.target.value),autoComplete:`off`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})}),(0,M.jsx)(B,{label:`Location (optional)`,description:`Region of the Cloud Run service (e.g. us-central1). Helpful when multiple regions emit logs.`,children:(0,M.jsx)(`input`,{type:`text`,value:s,onChange:e=>c(e.target.value),autoComplete:`off`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})}),(0,M.jsx)(B,{label:`Display name (optional)`,description:`Friendly label shown in the dashboard. Defaults to the project + service combo.`,children:(0,M.jsx)(`input`,{type:`text`,value:l,onChange:e=>u(e.target.value),autoComplete:`off`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})})]})]})}function z({projectName:e,onBack:t,onClose:n}){let[r,i]=(0,j.useState)(``),[a,o]=(0,j.useState)(``),[s,c]=(0,j.useState)(``),[l,u]=(0,j.useState)(`production`),[d,f]=(0,j.useState)(``),p=oe(e||null),{error:m,runConnect:h}=F(e,n);return(0,M.jsxs)(I,{title:`Connect a Vercel project`,description:(0,M.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[`Reads AI crawler visits from Vercel request logs. Nothing to install on your site.`,(0,M.jsx)(x,{text:K(`access token`)})]}),guide:fe(e),projectName:e,onBack:t,onClose:n,onSubmit:()=>h({validate:()=>r.trim()?a.trim()?s.trim()?null:`Vercel personal access token is required.`:`Vercel team / account ID is required.`:`Vercel project ID is required.`,mutate:()=>p.mutateAsync({projectId:r.trim(),teamId:a.trim(),token:s.trim(),environment:l,displayName:d.trim()||void 0}),startInitialBackfill:!1,onConnected:()=>c(``)}),isPending:p.isPending,error:m,children:[(0,M.jsx)(B,{label:`Vercel project ID`,description:`The prj_… id from the Vercel dashboard or .vercel/project.json.`,required:!0,children:(0,M.jsx)(`input`,{type:`text`,value:r,onChange:e=>i(e.target.value),required:!0,autoComplete:`off`,placeholder:`prj_…`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})}),(0,M.jsx)(B,{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:(0,M.jsx)(`input`,{type:`text`,value:a,onChange:e=>o(e.target.value),required:!0,autoComplete:`off`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})}),(0,M.jsx)(B,{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:(0,M.jsx)(`input`,{type:`password`,value:s,onChange:e=>c(e.target.value),required:!0,autoComplete:`new-password`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})}),(0,M.jsxs)(Q,{children:[(0,M.jsx)(B,{label:`Environment`,description:`Which deployment environment's request logs to pull.`,children:(0,M.jsxs)(`select`,{value:l,onChange:e=>u(e.target.value),className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong focus:border-mono-500 focus:outline-none`,children:[(0,M.jsx)(`option`,{value:`production`,children:`production`}),(0,M.jsx)(`option`,{value:`preview`,children:`preview`})]})}),(0,M.jsx)(B,{label:`Display name (optional)`,description:`Friendly label shown in the dashboard. Defaults to the Vercel project ID.`,children:(0,M.jsx)(`input`,{type:`text`,value:d,onChange:e=>f(e.target.value),autoComplete:`off`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`})})]})]})}function B({label:e,description:t,required:n,children:r}){return(0,M.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,M.jsxs)(`span`,{className:`text-label-14-strong text-strong`,children:[e,n?(0,M.jsx)(`span`,{className:`ml-1 text-negative-400`,children:`*`}):null]}),r,(0,M.jsx)(`span`,{className:`text-label-13 text-secondary`,children:t})]})}var V=`https://github.com/Canonry/canonry/blob/main`,H=`${V}/skills/canonry/references/server-side-traffic.md`,U=`${V}/docs/cloudflare-traffic-setup.md`,W=`1.1.1`,G=`https://github.com/Canonry/canonry/releases/download/wp-traffic-logger-v${W}/canonry-traffic-logger-${W}.zip`;function K(e){return`The ${e} is stored in ~/.canonry/config.yaml on the Canonry server and never sent back to the dashboard.`}var q=`Never ask me to paste a password, token, or key into this chat. When a command needs one, give me the exact command to run myself, or read it from a file I point you to.`;function J(e,t){try{let n=new URL(e.trim());return n.protocol!==`https:`&&n.protocol!==`http:`?null:`${n.origin}${n.pathname.replace(/\/+$/,``)}/wp-admin/${t}`}catch{return null}}function Y(e,t){let n=C(e),r=J(t,`plugin-install.php?tab=upload`),i=J(t,`profile.php#application-passwords-section`);return{docsUrl:`${H}#connecting-a-wordpress-source`,steps:[{title:`Download the Canonry Traffic Logger plugin`,link:{label:`Download v${W} (.zip)`,href:G}},{title:`Upload and activate it in wp-admin`,detail:`Plugins → Add New → Upload Plugin, then Activate.`,...r?{link:{label:`Open the upload page`,href:r}}:{}},{title:`Create an Application Password`,detail:`Users → Profile → Application Passwords. Name it “Canonry” and copy the password it shows once.`,...i?{link:{label:`Open your profile`,href:i}}:{}},{title:`Using a page cache or CDN? Exclude AI crawlers from it`,detail:`Cached pages never reach the plugin, so crawler visits go uncounted.`,link:{label:`User agents to exclude`,href:`${H}#connecting-a-wordpress-source`}}],agentRequest:`Help me connect my WordPress site to the Canonry project "${e}" for server-side traffic.
|
|
2
|
+
|
|
3
|
+
Follow the WordPress section of the Canonry docs: ${H}#connecting-a-wordpress-source
|
|
4
|
+
|
|
5
|
+
1. Ask me for the site URL and a WordPress admin username.
|
|
6
|
+
2. Walk me through installing the Canonry Traffic Logger plugin: download ${G}, then upload and activate it under Plugins → Add New → Upload Plugin. If you have shell or WP-CLI access to the site, you may install it yourself after I approve.
|
|
7
|
+
3. Have me create an Application Password under Users → Profile → Application Passwords.
|
|
8
|
+
4. Ask whether the site uses a page cache or CDN. If it does, tell me exactly which AI user agents to exclude from it, using the list in the docs.
|
|
9
|
+
5. Give me the exact command to connect: cnry traffic connect wordpress ${n} --url <site-url> --username <user> --app-password '<app-password>'
|
|
10
|
+
6. After it connects, run cnry traffic sources ${n} --format json and cnry doctor --project ${n} --check 'traffic.source.*' --format json, and tell me in plain words whether events are arriving.
|
|
11
|
+
|
|
12
|
+
${q}`}}function fe(e){let t=C(e);return{docsUrl:`${H}#connecting-a-vercel-source`,steps:[{title:`Create a Vercel access token`,detail:`Give it access to the team that owns the project. Tokens can expire, so pick a long lifetime.`,link:{label:`Open Vercel tokens`,href:`https://vercel.com/account/tokens`}},{title:`Find the project ID and team ID`,detail:`Both are in the project’s Settings → General, or in .vercel/project.json (projectId and orgId) after vercel link.`}],agentRequest:`Help me connect my Vercel project to the Canonry project "${e}" for server-side traffic.
|
|
13
|
+
|
|
14
|
+
Follow the Vercel section of the Canonry docs: ${H}#connecting-a-vercel-source
|
|
15
|
+
|
|
16
|
+
1. Find the Vercel project ID and team ID. If this repo is linked, read projectId and orgId from .vercel/project.json. Otherwise ask me.
|
|
17
|
+
2. Have me create an access token at https://vercel.com/account/tokens, scoped to that team, and save it to a file only I can read.
|
|
18
|
+
3. Connect with: cnry traffic connect vercel ${t} --project-id <prj_...> --team-id <team_...> --token-file <path>
|
|
19
|
+
4. Confirm the source with cnry traffic sources ${t} --format json and cnry doctor --project ${t} --check 'traffic.source.*' --format json. Vercel keeps about 14 days of request logs, so tell me before starting any history backfill.
|
|
20
|
+
|
|
21
|
+
${q}`}}function pe(e,t){let n=C(e),r=t.trim(),i=`https://console.cloud.google.com/iam-admin/serviceaccounts${r?`?project=${encodeURIComponent(r)}`:``}`;return{docsUrl:`${H}#connecting-a-cloud-run-source`,steps:[{title:`Create a service account in the Google Cloud project`,detail:`Grant it the Logs Viewer role (roles/logging.viewer). Nothing broader is needed.`,link:{label:`Open service accounts`,href:i}},{title:`Create a JSON key for it`,detail:`Keys → Add key → Create new key → JSON. Upload the file below.`}],agentRequest:`Help me connect my Cloud Run service to the Canonry project "${e}" for server-side traffic.
|
|
22
|
+
|
|
23
|
+
Follow the Cloud Run section of the Canonry docs: ${H}#connecting-a-cloud-run-source
|
|
24
|
+
|
|
25
|
+
1. Ask me for the Google Cloud project ID and, if there is more than one, the Cloud Run service name and region.
|
|
26
|
+
2. If gcloud is installed and signed in, propose the exact commands to create a service account with only roles/logging.viewer and download a JSON key, and run them after I approve. Otherwise walk me through it in the Cloud Console.
|
|
27
|
+
3. Connect with: cnry traffic connect cloud-run ${n} --gcp-project <project-id> --service-account-key <path/to/key.json> (add --service and --location to narrow it).
|
|
28
|
+
4. Confirm with cnry doctor --project ${n} --check 'traffic.source.*' --format json and tell me in plain words whether logs are readable.
|
|
29
|
+
|
|
30
|
+
${q}`}}function me(e){let t=C(e);return{docsUrl:U,steps:[{title:`Check your request volume first`,detail:`The Worker runs on every request to your zone. A busy site can pass the Workers free allowance of 100,000 requests a day.`,link:{label:`How to size it`,href:`${U}#before-you-start-size-the-request-volume`}},{title:`Find your zone ID and account ID`,detail:`Both are on the zone’s Overview page in the Cloudflare dashboard, under API.`,link:{label:`Open Cloudflare`,href:`https://dash.cloudflare.com/`}},{title:`Run the connect command where Canonry runs`,detail:`cnry traffic connect cloudflare ${t} --zone-id <zone-id> --account-id <account-id>`}],agentRequest:`Help me connect my Cloudflare zone to the Canonry project "${e}" for server-side traffic.
|
|
31
|
+
|
|
32
|
+
Follow the Canonry Cloudflare guide: ${U}
|
|
33
|
+
|
|
34
|
+
1. Before anything else, estimate the zone's daily request volume with me, as the guide's "size the request volume" section shows, and tell me whether it fits the Workers plan I am on.
|
|
35
|
+
2. Ask me for the zone ID and account ID, and whether I want direct push or Queue pull. Recommend one and say why.
|
|
36
|
+
3. Run cnry traffic connect cloudflare ${t} --zone-id <zone-id> --account-id <account-id> (plus the flags for the mode I chose). It writes the Worker and its config without deploying. Show me what it wrote.
|
|
37
|
+
4. Deploy only after I approve, and attach the route with Fail open exactly as the guide says.
|
|
38
|
+
5. Smoke-check with cnry traffic events ${t} --source <source-id> --format json and tell me whether events are arriving.
|
|
39
|
+
|
|
40
|
+
${q}`}}function X({request:e,docsUrl:t}){let[i,a]=(0,j.useState)(!1),s=async()=>{try{await navigator.clipboard.writeText(e),a(!0),window.setTimeout(()=>a(!1),1800)}catch{ne({tone:`negative`,title:`Could not copy the setup request`,detail:`Follow the steps below, or open the setup guide instead.`})}};return(0,M.jsxs)(`section`,{"aria-labelledby":`traffic-agent-heading`,className:`material-base px-4 py-3`,children:[(0,M.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-3 gap-y-2`,children:[(0,M.jsx)(o,{className:`size-4 text-positive`,"aria-hidden":`true`}),(0,M.jsx)(`h3`,{id:`traffic-agent-heading`,className:`flex-1 text-heading-14 text-heading`,children:`Have your agent set this up`}),(0,M.jsxs)(y,{type:`button`,variant:`secondary`,size:`sm`,onClick:()=>{s()},children:[i?(0,M.jsx)(u,{className:`size-3.5`,"aria-hidden":`true`}):(0,M.jsx)(r,{className:`size-3.5`,"aria-hidden":`true`}),(0,M.jsx)(`span`,{"aria-live":`polite`,children:i?`Copied`:`Copy setup request`})]})]}),(0,M.jsxs)(`p`,{className:`mt-1.5 text-copy-13 text-secondary`,children:[`Paste it into Claude Code, Codex, or any agent with a terminal. It follows the`,` `,(0,M.jsxs)(`a`,{href:t,target:`_blank`,rel:`noreferrer`,className:`text-link underline-offset-4 hover:underline`,children:[`setup guide`,(0,M.jsx)(n,{className:`ml-0.5 inline size-3`,"aria-hidden":`true`})]}),` `,`and never asks you to paste secrets into the chat.`]})]})}function Z({steps:e,heading:t=`Or do it yourself`}){return(0,M.jsxs)(`section`,{"aria-labelledby":`traffic-steps-heading`,children:[(0,M.jsx)(`h3`,{id:`traffic-steps-heading`,className:`text-heading-14 text-heading`,children:t}),(0,M.jsx)(`ol`,{className:`mt-3 flex flex-col gap-3`,children:e.map((e,t)=>(0,M.jsxs)(`li`,{className:`flex gap-3`,children:[(0,M.jsx)(`span`,{"aria-hidden":`true`,className:`flex size-6 shrink-0 items-center justify-center rounded-full border border-default bg-surface-subtle text-label-12-strong tabular-nums text-secondary`,children:t+1}),(0,M.jsxs)(`div`,{className:`min-w-0 pt-0.5`,children:[(0,M.jsx)(`p`,{className:`text-copy-14 text-heading`,children:e.title}),e.detail?(0,M.jsx)(`p`,{className:`mt-0.5 text-copy-13 text-secondary ${e.detail.startsWith(`cnry `)?`break-all font-mono`:``}`,children:e.detail}):null,e.link?(0,M.jsxs)(`a`,{href:e.link.href,target:`_blank`,rel:`noreferrer`,className:`mt-1 inline-flex items-center gap-1 text-label-13-strong text-link underline-offset-4 hover:underline`,children:[e.link.label,(0,M.jsx)(n,{className:`size-3`,"aria-hidden":`true`})]}):null]})]},e.title))})]})}function Q({children:e}){return(0,M.jsxs)(`details`,{className:`group`,children:[(0,M.jsxs)(`summary`,{className:`cursor-pointer list-none text-label-14-strong text-secondary hover:text-heading`,children:[(0,M.jsx)(`span`,{className:`group-open:hidden`,children:`Show more options`}),(0,M.jsx)(`span`,{className:`hidden group-open:inline`,children:`Hide more options`})]}),(0,M.jsx)(`div`,{className:`mt-4 flex flex-col gap-5`,children:e})]})}function he({projectName:e,onBack:t,onClose:r}){let i=me(e);return(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(N,{title:`Connect a Cloudflare zone`,description:(0,M.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[`A small Worker on your zone reports AI crawler visits. It is set up from the terminal.`,(0,M.jsx)(x,{text:`Setting it up deploys a Worker to your Cloudflare account, so it runs from the Canonry CLI on the machine where Canonry runs, never from the browser.`})]}),onBack:t}),(0,M.jsxs)(`div`,{className:`-mr-1 mt-6 min-h-0 flex-1 overflow-y-auto pr-1`,children:[(0,M.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[(0,M.jsx)(X,{request:i.agentRequest,docsUrl:i.docsUrl}),(0,M.jsx)(Z,{steps:i.steps})]}),(0,M.jsxs)(`div`,{className:`mt-6 flex items-center justify-end gap-2 border-t border-default pt-4`,children:[(0,M.jsx)(y,{type:`button`,variant:`ghost`,size:`sm`,onClick:r,children:`Close`}),(0,M.jsx)(y,{type:`button`,size:`sm`,asChild:!0,children:(0,M.jsxs)(`a`,{href:i.docsUrl,target:`_blank`,rel:`noreferrer`,children:[`Open the setup guide`,(0,M.jsx)(n,{className:`size-3.5`,"aria-hidden":`true`})]})})]})]})]})}function ge(e){if(!e)return`never`;let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/6e4);if(n<1)return`just now`;if(n<60)return`${n}m ago`;let r=Math.floor(n/60);return r<24?`${r}h ago`:`${Math.floor(r/24)}d ago`}function $(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}K`:e.toLocaleString()}function _e({projectName:e,heading:n=!0}){let[r,i]=(0,j.useState)(!1),a=(0,j.useRef)(null),o=se(e),s=o.data?.sources??[],c=e=>{a.current=e,i(!0)};return(0,M.jsxs)(`section`,{"aria-labelledby":n?`server-traffic-heading`:void 0,"aria-label":n?void 0:`Server traffic`,children:[(0,M.jsxs)(`div`,{className:`section-head section-head-inline`,children:[(0,M.jsx)(`div`,{children:n?(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(`h2`,{id:`server-traffic-heading`,className:`text-heading-20 text-heading`,children:`Server traffic`}),(0,M.jsx)(`p`,{className:`page-subtitle`,children:`AI crawler hits and referral sessions from your server logs.`})]}):null}),!_()&&(0,M.jsxs)(y,{type:`button`,variant:`outline`,size:`sm`,onClick:e=>c(e.currentTarget),children:[(0,M.jsx)(t,{className:`size-3.5`}),`Connect a source`]})]}),o.isLoading?(0,M.jsx)(S,{className:`p-6 text-center text-label-14 text-muted`,children:`Loading sources…`}):s.length===0?(0,M.jsxs)(S,{className:`p-8 text-center`,children:[(0,M.jsxs)(`p`,{className:`text-copy-14 text-neutral`,children:[`No traffic sources connected for `,e,`.`]}),!_()&&(0,M.jsx)(`p`,{className:`mt-1 text-copy-14 text-secondary`,children:`Connect a source to start collecting traffic.`})]}):(0,M.jsx)(ve,{projectName:e,sources:s}),!_()&&(0,M.jsx)(le,{open:r,onOpenChange:i,onClosed:()=>{a.current?.isConnected&&a.current.focus()},projectName:e})]})}function ve({projectName:e,sources:t}){let n=h(),r=m({queries:t.map(t=>({...re({client:v,path:{name:e,id:t.id}}),staleTime:3e4}))}),i=t.map((e,t)=>({source:e,detail:r[t]?.data,isLoading:r[t]?.isLoading??!1}));return(0,M.jsx)(`div`,{className:`material-base overflow-hidden`,children:(0,M.jsxs)(`table`,{className:`w-full text-label-14`,children:[(0,M.jsx)(`caption`,{className:`sr-only`,children:`Server traffic sources for the last 24 hours`}),(0,M.jsx)(`thead`,{className:`bg-bg-elevated/50 text-label-12-strong normal-case text-muted`,children:(0,M.jsxs)(`tr`,{children:[(0,M.jsx)(`th`,{className:`px-4 py-2 text-left`,children:`Source`}),(0,M.jsx)(`th`,{className:`px-4 py-2 text-left`,children:`Status`}),(0,M.jsx)(`th`,{className:`px-4 py-2 text-left`,children:`Last sync`}),(0,M.jsx)(`th`,{className:`px-4 py-2 text-right`,children:`Content crawls`}),(0,M.jsx)(`th`,{className:`px-4 py-2 text-right`,children:`Infra crawls`}),(0,M.jsx)(`th`,{className:`px-4 py-2 text-right`,children:`AI fetches`}),(0,M.jsx)(`th`,{className:`px-4 py-2 text-right`,children:`AI referrals`}),(0,M.jsx)(`th`,{className:`px-4 py-2 text-right`,children:(0,M.jsx)(`span`,{className:`sr-only`,children:`Detail`})})]})}),(0,M.jsx)(`tbody`,{className:`divide-y divide-mono-800/60`,children:i.map(({source:t,detail:r,isLoading:i})=>(0,M.jsxs)(`tr`,{className:`cursor-pointer transition-colors hover:bg-bg-elevated/40 focus-within:bg-bg-elevated/40`,onClick:r=>{ae(r)&&n({to:`/traffic/$projectName/$sourceId`,params:{projectName:e,sourceId:t.id}})},children:[(0,M.jsx)(`td`,{className:`px-4 py-3`,children:(0,M.jsx)(g,{to:`/traffic/$projectName/$sourceId`,params:{projectName:e,sourceId:t.id},className:`text-label-14-strong text-heading hover:underline`,children:t.displayName})}),(0,M.jsxs)(`td`,{className:`px-4 py-3`,children:[(0,M.jsx)(ee,{tone:ce(t.status),children:t.status}),t.lastError?(0,M.jsx)(`p`,{className:`mt-1 max-w-[18rem] truncate text-copy-14 text-negative-400`,title:t.lastError,children:t.lastError}):null]}),(0,M.jsx)(`td`,{className:`px-4 py-3 text-neutral`,children:ge(t.lastSyncedAt)}),(0,M.jsx)(`td`,{className:`px-4 py-3 text-right tabular-nums text-heading`,title:r?`${r.totals24h.crawlerHits.toLocaleString(`en-US`)} total crawler hits`:void 0,children:i?`—`:$(r?.totals24h.crawlerContentHits??0)}),(0,M.jsx)(`td`,{className:`px-4 py-3 text-right tabular-nums text-muted`,children:i?`—`:$(r?.totals24h.crawlerInfraHits??0)}),(0,M.jsx)(`td`,{className:`px-4 py-3 text-right tabular-nums text-heading`,children:i?`—`:$(r?.totals24h.aiUserFetchHits??0)}),(0,M.jsx)(`td`,{className:`px-4 py-3 text-right tabular-nums text-heading`,children:i?`—`:$(r?.totals24h.aiReferralLandedHits??0)}),(0,M.jsx)(`td`,{className:`px-4 py-3 text-right`,children:(0,M.jsxs)(g,{to:`/traffic/$projectName/$sourceId`,params:{projectName:e,sourceId:t.id},className:`inline-flex items-center gap-1 text-label-14 text-secondary hover:text-heading`,children:[`View`,(0,M.jsx)(s,{className:`size-3.5`})]})})]},t.id))})]})})}export{_e as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{ft as t}from"./vendor-lucide-iE5MEh2-.js";import{r as n}from"./vendor-markdown-BBGbNklj.js";import{O as r}from"./vendor-tanstack-B90HW50P.js";import{B as i,Cn as a,Ea as o,Sn as s,Wt as c,_ as l,b as u,ka as d,r as f,t as p,v as m}from"./ToneBadge-DcwPruHr.js";import{t as h}from"./AccessControls-DzO5Y8v9.js";import{r as g}from"./account-context-CoJVqEXZ.js";import{t as _}from"./async-handler-Bj3TnIRw.js";import{d as v}from"./query-client-Tg1fZu4i.js";import{B as y,Et as b,Tt as x,V as S,_ as C,l as w,ot as T,rt as E,st as D,u as O,wt as k}from"./index-mqc2mWUR.js";var A=e(t(),1),j=n();function M({onSaved:e}){let[t,n]=(0,A.useState)(``),[r,i]=(0,A.useState)(``),[o,s]=(0,A.useState)(!1),[u,d]=(0,A.useState)(null),[p,h]=(0,A.useState)(!1),g=t.trim().length>0&&r.trim().length>0,y=typeof window>`u`?void 0:c(window.location,window.__CANONRY_CONFIG__?.basePath),b=y?m(y):void 0,x=y?l(y):void 0;async function S(){if(g){s(!0),d(null),h(!1);try{await a({clientId:t.trim(),clientSecret:r.trim()}),n(``),i(``),h(!0),v({title:`Google OAuth app updated`,detail:`Dashboard Google credentials were saved.`,tone:`positive`,dedupeKey:`settings:google-oauth`,dedupeMode:`replace`}),e()}catch(e){d(e instanceof Error?e.message:`Failed to update Google OAuth credentials`)}finally{s(!1)}}}return(0,j.jsxs)(`div`,{className:`mt-3 space-y-3`,children:[(0,j.jsxs)(`div`,{children:[(0,j.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,j.jsx)(`label`,{className:`text-label-14 text-secondary`,htmlFor:`google-client-id`,children:`Client ID`}),(0,j.jsxs)(`a`,{href:`https://console.cloud.google.com/apis/credentials`,target:`_blank`,rel:`noopener noreferrer`,className:`text-label-14 text-secondary hover:text-neutral underline underline-offset-2`,children:[`Google Cloud `,`↗`]})]}),(0,j.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-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`,placeholder:`Google OAuth client ID`,value:t,onChange:e=>n(e.target.value)})]}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`label`,{className:`text-label-14 text-secondary`,htmlFor:`google-client-secret`,children:`Client secret`}),(0,j.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-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`,placeholder:`Google OAuth client secret`,value:r,onChange:e=>i(e.target.value)})]}),b&&x&&(0,j.jsxs)(`div`,{className:`space-y-2`,children:[(0,j.jsx)(`p`,{className:`text-copy-14 text-secondary`,children:`Authorized redirect URIs`}),(0,j.jsxs)(`dl`,{className:`mt-1 space-y-2 text-label-12`,children:[(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{className:`text-muted`,children:`Search Console and Business Profile`}),(0,j.jsx)(`dd`,{children:(0,j.jsx)(`code`,{className:`block break-all text-strong`,children:b})})]}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{className:`text-muted`,children:`Google Ads and Tag Manager`}),(0,j.jsx)(`dd`,{children:(0,j.jsx)(`code`,{className:`block break-all text-strong`,children:x})})]})]})]}),u&&(0,j.jsx)(`p`,{className:`text-copy-14 text-negative-400`,children:u}),p&&(0,j.jsx)(`p`,{className:`text-copy-14 text-positive-400`,children:`Google OAuth credentials updated.`}),(0,j.jsx)(f,{type:`button`,size:`sm`,disabled:!g||o,onClick:_(S),children:o?`Saving…`:`Save Google OAuth app`})]})}function N({id:e,title:t,purpose:n,status:r,action:i,children:a}){return(0,j.jsxs)(`div`,{id:e,className:`scroll-mt-24 py-4`,children:[(0,j.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-x-4 gap-y-2`,children:[(0,j.jsxs)(`div`,{className:`min-w-0 grow basis-64`,children:[(0,j.jsx)(`h3`,{className:`text-copy-14-strong text-heading`,children:t}),(0,j.jsx)(`div`,{className:`mt-1 max-w-prose text-copy-14 text-secondary`,children:n})]}),(0,j.jsxs)(`div`,{className:`flex shrink-0 flex-wrap items-center gap-2`,children:[r,i]})]}),a]})}function P(e){let t=e.replace(/^Error:\s*/,``).replace(/\s+/g,` `).trim();return t?t.length>140?`${t.slice(0,137)}...`:t:`Unknown error`}function F(){let e=r(),[t,n]=(0,A.useState)(null),[a,s]=(0,A.useState)(null),[c,l]=(0,A.useState)(!1),[m,h]=(0,A.useState)(`localhost`),[g,y]=(0,A.useState)(`9222`),[b,x]=(0,A.useState)(!1),[S,w]=(0,A.useState)(!1),T=C(S,b);(0,A.useEffect)(()=>{let e=!0;return i().then(t=>{e&&(n(t),s(null))}).catch(t=>{if(!e)return;let n=o(t);n.includes(`501`)||s(n)}),()=>{e=!1}},[]);let E=(0,j.jsx)(f,{type:`button`,variant:`outline`,size:`sm`,disabled:b,onClick:()=>T.request(()=>{if(c)l(!1),w(!1);else{if(t?.endpoint)try{let e=new URL(t.endpoint);h(e.hostname),y(e.port||`9222`)}catch{s(`The saved browser endpoint could not be read. Enter its host and port.`)}l(!0)}}),children:c?`Cancel`:t?.connected?`Update endpoint`:`Configure`});return(0,j.jsxs)(N,{id:`browser-connection`,title:`ChatGPT in Chrome`,purpose:`Runs AI Visibility checks on ChatGPT through a Chrome browser you connect.`,status:(0,j.jsx)(p,{tone:t?.connected?`positive`:`caution`,children:t?.connected?`Connected`:`Not connected`}),action:E,children:[a?(0,j.jsxs)(`p`,{role:`alert`,className:`mt-2 max-w-prose text-copy-14 text-negative`,children:[`Could not check Chrome: `,P(a),`. Check that Chrome is running with remote debugging, then configure the endpoint.`]}):null,!t?.connected&&(0,j.jsxs)(`details`,{className:`mt-3`,children:[(0,j.jsx)(`summary`,{className:`cursor-pointer text-label-14 text-secondary hover:text-strong`,children:`How to connect Chrome`}),(0,j.jsxs)(`ol`,{className:`mt-2 ml-5 list-decimal space-y-2 text-copy-14 text-secondary`,children:[(0,j.jsx)(`li`,{children:`On the machine running Canonry, launch Chrome with remote debugging on port 9222 and a separate browser profile.`}),(0,j.jsx)(`li`,{children:`In that browser, open ChatGPT and sign in.`}),(0,j.jsx)(`li`,{children:`Choose Configure and save the host and port.`})]}),(0,j.jsxs)(`p`,{className:`mt-2 text-copy-14 text-secondary`,children:[`Chrome requires `,(0,j.jsx)(`code`,{children:`--remote-debugging-port=9222`}),` and `,(0,j.jsx)(`code`,{children:`--user-data-dir`}),` pointing to a separate profile. `,(0,j.jsx)(`a`,{className:`text-link underline`,href:`https://developer.chrome.com/docs/devtools/agents/get-started/configuration`,target:`_blank`,rel:`noopener noreferrer`,children:`Launch commands for your operating system`})]})]}),(t?.endpoint||t?.browserVersion||!!t?.targets?.length)&&(0,j.jsxs)(`details`,{className:`mt-3`,children:[(0,j.jsx)(`summary`,{className:`cursor-pointer text-label-14 text-secondary hover:text-strong`,children:`Connection details`}),(0,j.jsxs)(`dl`,{className:`definition-list mt-2`,children:[t?.endpoint&&(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:`Endpoint`}),(0,j.jsx)(`dd`,{className:`text-label-12-mono`,children:t.endpoint})]}),t?.browserVersion&&(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:`Browser`}),(0,j.jsx)(`dd`,{className:`text-label-12`,children:t.browserVersion})]}),t?.targets&&t.targets.length>0&&(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:`Tabs`}),(0,j.jsx)(`dd`,{children:t.targets.map(e=>(0,j.jsxs)(`span`,{className:`mr-2`,children:[e.name,`: `,e.alive?`● alive`:`○ idle`]},e.name))})]})]})]}),c&&(0,j.jsxs)(`form`,{className:`mt-3 flex flex-col gap-2`,onSubmit:_(async t=>{t.preventDefault(),x(!0);try{await u(m.trim(),Number(g)),O(e,d.cdpChatgpt);let t=await i();n(t),s(null),l(!1),w(!1),e.invalidateQueries({queryKey:[`settings`]}),v({title:`CDP endpoint saved`,detail:`${m.trim()}:${g} is now configured.`,tone:`positive`,dedupeKey:`settings:cdp`,dedupeMode:`replace`})}catch(e){s(o(e))}finally{x(!1)}}),children:[(0,j.jsxs)(`div`,{className:`flex gap-2`,children:[(0,j.jsx)(`input`,{className:`flex-1 rounded border border-strong bg-bg-elevated px-2 py-1 text-label-14 text-heading placeholder-mono-400 focus:outline-none focus:ring-1 focus:ring-mono-500`,placeholder:`localhost`,value:m,required:!0,disabled:b,onChange:e=>{h(e.target.value),w(!0)},"aria-label":`CDP host`}),(0,j.jsx)(`input`,{className:`w-24 rounded border border-strong bg-bg-elevated px-2 py-1 text-label-14 text-heading placeholder-mono-400 focus:outline-none focus:ring-1 focus:ring-mono-500`,placeholder:`9222`,type:`number`,min:`1`,max:`65535`,required:!0,disabled:b,value:g,onChange:e=>{y(e.target.value),w(!0)},"aria-label":`CDP port`})]}),(0,j.jsx)(`div`,{children:(0,j.jsx)(f,{type:`submit`,size:`sm`,disabled:b,children:b?`Saving…`:`Save endpoint`})})]}),T.dialog]})}function I(){return(0,j.jsx)(h,{title:`Settings`,children:(0,j.jsx)(L,{})})}function L(){let e=D(),{canWrite:t}=g(),{dashboard:n}=T(),r=n?.settings??e?.dashboard?.settings,i=E(!e,e?.health).data??e?.health??y,[a,o]=(0,A.useState)(!1),[c,l]=(0,A.useState)(!1),[u,d]=(0,A.useState)(``),[m,h]=(0,A.useState)(!1),[C,O]=(0,A.useState)(null);if(!r)return null;let P=n?.projects??e?.dashboard?.projects??[],I=r.google.state===`ready`,L=r.bing.state===`ready`;return(0,j.jsxs)(`div`,{className:`page-container`,children:[(0,j.jsx)(`div`,{className:`page-header`,children:(0,j.jsxs)(`div`,{className:`page-header-left`,children:[(0,j.jsx)(`h1`,{className:`page-title`,children:`Settings`}),(0,j.jsx)(`p`,{className:`page-subtitle`,children:`Connections and answer engines.`})]})}),(0,j.jsxs)(`div`,{className:`space-y-8`,children:[(0,j.jsx)(w,{projects:P.map(e=>e.project)}),(0,j.jsxs)(`section`,{"aria-labelledby":`search-connections-title`,className:`border-t border-default pt-6`,children:[(0,j.jsx)(`div`,{className:`section-head`,children:(0,j.jsx)(`h2`,{id:`search-connections-title`,className:`text-heading-16 text-heading`,children:`Search and browser connections`})}),(0,j.jsxs)(`div`,{className:`divide-y divide-default`,children:[(0,j.jsx)(N,{title:`Google OAuth`,purpose:`One app credential for Search Console, Business Profile, Google Ads and Tag Manager.`,status:(0,j.jsx)(p,{tone:I?`neutral`:`caution`,children:I?`Configured`:`Not configured`}),action:(0,j.jsx)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>o(!a),children:a?`Cancel`:I?`Update OAuth app`:`Configure Google OAuth`}),children:a&&(0,j.jsx)(M,{onSaved:()=>{o(!1)}})}),(0,j.jsx)(N,{title:`Bing Webmaster Tools`,purpose:`One API key for project Bing connections. OAuth is not required.`,status:(0,j.jsx)(p,{tone:L?`neutral`:`caution`,children:L?`Configured`:`Not configured`}),action:(0,j.jsx)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>l(!c),children:c?`Cancel`:L?`Update API key`:`Configure Bing`}),children:c&&(0,j.jsxs)(`div`,{className:`mt-3 max-w-xl space-y-2`,children:[(0,j.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,j.jsx)(`label`,{className:`text-label-14 text-secondary`,htmlFor:`bing-api-key`,children:`API key`}),(0,j.jsx)(`a`,{href:`https://www.bing.com/webmasters/`,target:`_blank`,rel:`noopener noreferrer`,className:`text-label-14 text-secondary hover:text-neutral underline underline-offset-2`,children:`Bing Webmaster Tools`})]}),(0,j.jsx)(`input`,{id:`bing-api-key`,type:`password`,className:`w-full rounded border border-strong bg-transparent px-2 py-1.5 text-label-14 text-strong placeholder-mono-400 focus:border-mono-500 focus:outline-none`,placeholder:`Bing Webmaster Tools API key`,value:u,onChange:e=>d(e.target.value)}),C&&(0,j.jsx)(`p`,{role:`alert`,className:`text-copy-14 text-negative-400`,children:C}),(0,j.jsx)(f,{type:`button`,size:`sm`,disabled:!u.trim()||m,onClick:_(async()=>{if(u.trim()){h(!0),O(null);try{await s(u.trim()),d(``),l(!1),v({title:`Bing API key updated`,detail:`Dashboard Bing credentials were saved.`,tone:`positive`,dedupeKey:`settings:bing`,dedupeMode:`replace`})}catch(e){O(e instanceof Error?e.message:`Failed to update Bing API key`)}finally{h(!1)}}}),children:m?`Saving…`:`Save Bing API key`})]})}),(0,j.jsx)(F,{})]})]}),(0,j.jsxs)(`section`,{"aria-labelledby":`service-health-title`,className:`border-t border-default pt-6`,children:[(0,j.jsx)(`div`,{className:`section-head`,children:(0,j.jsx)(`h2`,{id:`service-health-title`,className:`text-heading-16 text-heading`,children:`Service health`})}),(0,j.jsxs)(`div`,{className:`divide-y divide-default`,children:[(0,j.jsxs)(`div`,{className:`health-row py-3`,children:[(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`p`,{className:`text-copy-14-strong text-heading`,children:`API`}),i.apiStatus.state!==`ok`&&(0,j.jsx)(`p`,{className:`mt-1 whitespace-pre-line text-copy-14 text-secondary`,children:S(i.apiStatus)})]}),(0,j.jsx)(p,{tone:k(i.apiStatus),title:S(i.apiStatus),children:i.apiStatus.state===`ok`?`Healthy`:`Attention`})]}),(0,j.jsxs)(`div`,{className:`health-row py-3`,children:[(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`p`,{className:`text-copy-14-strong text-heading`,children:`Worker`}),i.workerStatus.state!==`ok`&&(0,j.jsx)(`p`,{className:`mt-1 whitespace-pre-line text-copy-14 text-secondary`,children:S(i.workerStatus)})]}),(0,j.jsx)(p,{tone:k(i.workerStatus),title:S(i.workerStatus),children:i.workerStatus.state===`ok`?`Healthy`:i.workerStatus.state===`disabled`?`Disabled`:`Attention`})]})]})]}),x(t)?(0,j.jsxs)(`section`,{"aria-labelledby":`feedback-title`,className:`border-t border-default pt-6`,children:[(0,j.jsx)(`div`,{className:`section-head`,children:(0,j.jsx)(`h2`,{id:`feedback-title`,className:`text-heading-16 text-heading`,children:`Feedback`})}),(0,j.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-x-4 gap-y-2 py-4`,children:[(0,j.jsx)(`p`,{className:`min-w-0 max-w-prose grow basis-64 text-copy-14 text-secondary`,children:`Ideas, problems or anything confusing go straight to the Canonry team. Feedback is also at the top of every page.`}),(0,j.jsx)(f,{type:`button`,variant:`outline`,size:`sm`,onClick:b,children:`Share feedback`})]})]}):null,(0,j.jsxs)(`details`,{className:`border-t border-default pt-6`,children:[(0,j.jsx)(`summary`,{className:`cursor-pointer text-label-14 text-secondary hover:text-strong`,children:`Self-hosting details`}),(0,j.jsxs)(`div`,{className:`mt-3 max-w-prose`,children:[(0,j.jsx)(`ul`,{className:`detail-list`,children:r.selfHostNotes.map(e=>(0,j.jsx)(`li`,{children:e},e))}),(0,j.jsx)(`p`,{className:`supporting-copy`,children:r.bootstrapNote})]})]})]})]})}export{I as SettingsPage};
|