@zenovay/cli 0.1.53 → 0.1.55

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.
Files changed (77) hide show
  1. package/dist/{ai-0_Fj-s69.js → ai-B2Q5_4I8.js} +1 -1
  2. package/dist/analytics-Dg7UtCHo.js +2 -0
  3. package/dist/bin.js +3 -3
  4. package/dist/{companies-SLdSyZlr.js → companies-COJh5d6p.js} +1 -1
  5. package/dist/{csv-emit-BjL_a4Hk.js → csv-emit-BuRZNWYM.js} +1 -1
  6. package/dist/{deploys-BUxMQNdU.js → deploys-D044xeG7.js} +1 -1
  7. package/dist/{devices-CuI5DQCF.js → devices-CKVbnV06.js} +1 -1
  8. package/dist/{doctor-CxtU2i5C.js → doctor-CF3D4SXm.js} +1 -1
  9. package/dist/{errors-DGmpLOKI.js → errors-CX-BTLp1.js} +1 -1
  10. package/dist/{export-BzuIMKTq.js → export-DCbp6_Ae.js} +1 -1
  11. package/dist/{funnel-e5I9PXCO.js → funnel-CBYMcT0x.js} +1 -1
  12. package/dist/geo-CZGN3jMJ.js +2 -0
  13. package/dist/globe-DtujZD0a.js +2 -0
  14. package/dist/{health-avCr8d4g.js → health-lTPnKNY9.js} +1 -1
  15. package/dist/{heatmaps-B4EIgsJB.js → heatmaps-Dbw4tjvl.js} +1 -1
  16. package/dist/{init-yaZypDtf.js → init-CkUt7rzH.js} +1 -1
  17. package/dist/{init-D6qfFHJW.js → init-DBCYWR0R.js} +1 -1
  18. package/dist/{insights-B1j-Xb7l.js → insights-mWJUgQim.js} +1 -1
  19. package/dist/{journeys-Bhni1s_j.js → journeys-DYHyPzD3.js} +1 -1
  20. package/dist/keybar-deep-link-DC31T3CP.js +1 -0
  21. package/dist/live-BV3Ke3Pe.js +1 -0
  22. package/dist/metric-card-COEIZmbN.js +1 -0
  23. package/dist/{pages-D4wGIILk.js → pages-B3Va-Uv4.js} +1 -1
  24. package/dist/{projects-WpLMA6OD.js → projects-0DoM_DNY.js} +1 -1
  25. package/dist/{query-BX4rrOV_.js → query-Cvxg7VGc.js} +1 -1
  26. package/dist/{retention-CRtzacoI.js → retention-C6UOSoTA.js} +1 -1
  27. package/dist/{revenue-D4xdtgW3.js → revenue-BoCu83Qb.js} +1 -1
  28. package/dist/{self-test-BEGQAxd6.js → self-test-C-K-IjCM.js} +1 -1
  29. package/dist/{sessions-BoV2tpmy.js → sessions-bW9Zq9Ie.js} +1 -1
  30. package/dist/{sources-KNLyYn1s.js → sources-COk75RfB.js} +1 -1
  31. package/dist/{stats-DAluMkCV.js → stats-Cljlonha.js} +1 -1
  32. package/dist/{themes-DDiCFNwd.js → themes-83q1v8-U.js} +1 -1
  33. package/dist/{uptime-C_eyrDoC.js → uptime-CRG5sMbO.js} +1 -1
  34. package/dist/{visitors-DbRze8fL.js → visitors-BywY9FlL.js} +1 -1
  35. package/dist/{vitals-CnmfwDz9.js → vitals-CogK3FkQ.js} +1 -1
  36. package/dist/watch-CAQFQ3c9.js +1 -0
  37. package/dist/{webhooks-forward-BpVuzTpH.js → webhooks-forward-C-cPrv2X.js} +1 -1
  38. package/dist/wizard-bin.js +1 -1
  39. package/package.json +1 -1
  40. package/dist/analytics-BzPbgxUz.js +0 -2
  41. package/dist/embedded-globe-ClP_lA3q.js +0 -1
  42. package/dist/geo-Ckzgg8Nz.js +0 -2
  43. package/dist/globe-B9zxVE5j.js +0 -2
  44. package/dist/globe-DaSl9ejK.js +0 -1
  45. package/dist/keybar-deep-link-C9xNYihD.js +0 -1
  46. package/dist/live-bC-2juBf.js +0 -1
  47. package/dist/sphere-globe-CvHshl9g.js +0 -1
  48. package/dist/watch-CFDlcLl_.js +0 -1
  49. /package/dist/{analytical-screen-nJlxAocC.js → analytical-screen-CRn5UoFi.js} +0 -0
  50. /package/dist/{annotation-BxgifdZn.js → annotation-GkAYwvze.js} +0 -0
  51. /package/dist/{api-keys-Q9lP4gE8.js → api-keys-DphyO-_Y.js} +0 -0
  52. /package/dist/{audit-Cz8sSmCb.js → audit-5ImaVfEy.js} +0 -0
  53. /package/dist/{commands-DNM6zbNf.js → commands-BX5I2UyT.js} +0 -0
  54. /package/dist/{completions-Dkd2mw5i.js → completions-C_hmoEps.js} +0 -0
  55. /package/dist/{csv-emit-BZVq1YR5.js → csv-emit-Dn3c0RCG.js} +0 -0
  56. /package/dist/{domains-Dqp3u2N1.js → domains-2z51Uxcq.js} +0 -0
  57. /package/dist/{events-tail-DrAY7_Zr.js → events-tail-pDYhVzFg.js} +0 -0
  58. /package/dist/{examples-CFatZcPz.js → examples-CwchsLMN.js} +0 -0
  59. /package/dist/{goals-Bls3-0Od.js → goals-xzqn8Yvu.js} +0 -0
  60. /package/dist/{health-CflD_ysx.js → health-9O6q4lla.js} +0 -0
  61. /package/dist/{home-BDDXwGy7.js → home-DAjqGgZH.js} +0 -0
  62. /package/dist/{integrations-U7bCP21o.js → integrations-eq4v-lwT.js} +0 -0
  63. /package/dist/{logout-Bj9vLF6-.js → logout-BiMIjAoN.js} +0 -0
  64. /package/dist/{notes-RXAEpOlc.js → notes-Cbj12dSg.js} +0 -0
  65. /package/dist/{plans--eG1V1XX.js → plans-JCNd2VsV.js} +0 -0
  66. /package/dist/{profile-CF7ChkCR.js → profile-BywGL64A.js} +0 -0
  67. /package/dist/{settings-DwWt5fMc.js → settings-goNP_z8b.js} +0 -0
  68. /package/dist/{share-B3DFNgTz.js → share-DGMIOBqH.js} +0 -0
  69. /package/dist/{team-BVzoYxOP.js → team-iZM-4GoJ.js} +0 -0
  70. /package/dist/{teams-DrpDNMX9.js → teams-B1hiN-6Z.js} +0 -0
  71. /package/dist/{telemetry-BpoBNhpE.js → telemetry-DtjF0p-6.js} +0 -0
  72. /package/dist/{tour-B_va1vor.js → tour-CLV_zTW9.js} +0 -0
  73. /package/dist/{ui-DzoMR7th.js → ui-Cey-h6wI.js} +0 -0
  74. /package/dist/{update-BykeQE-n.js → update-D3ycAP8L.js} +0 -0
  75. /package/dist/{usage-B4m_xh1T.js → usage-CHSMBpE4.js} +0 -0
  76. /package/dist/{use-TXJD8FsG.js → use-DnFCfgnI.js} +0 -0
  77. /package/dist/{webhooks-Ci5H77lC.js → webhooks-zrSDiOmL.js} +0 -0
@@ -1 +1 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{requireTier as r}from"./tier-DST3Yt2-.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import{resolveSiteId as l}from"./resolve-site-DSJR9vuz.js";import{EmptyState as u}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as d,openInBrowser as f}from"./keybar-deep-link-C9xNYihD.js";import{Box as p,Text as m,render as h,useApp as g,useInput as _}from"ink";import v,{useEffect as y,useState as b}from"react";import x from"ink-spinner";async function S(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getJourneys(d);return i({type:`journeys.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=h(v.createElement(C,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=g(),[l,h]=b(null),[S,C]=b(!0),[w,T]=b(null);if(_(e=>{if(e===`o`||e===`O`){f(d(`journeys`,{siteId:t}));return}e===`q`&&(a(),i(0))}),y(()=>{let n=!1;return(async()=>{try{let r=await e.getJourneys(t);n||(h(r.flows),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),S)return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`journeys · ${n}`}),v.createElement(o,{title:`Loading`,state:`busy`},v.createElement(p,null,v.createElement(m,{color:`magenta`},v.createElement(x,{type:`dots`})),v.createElement(m,null,` Computing flows…`))));if(w)return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`journeys · ${n}`}),v.createElement(u,{reason:`error`,headline:`Failed to load`,hint:w}));if(!l||l.length===0)return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`journeys · ${n}`}),v.createElement(u,{reason:`no-data`,headline:`No journeys yet`,hint:`Need at least 2 page-views per session to compute flows`}));let E=Math.max(...l.map(e=>e.count),1),D=12;return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`journeys · ${n}`}),v.createElement(o,{title:`Top page transitions (${l.length})`},l.map((e,t)=>{let n=Math.max(1,Math.round(e.count/E*D));return v.createElement(p,{key:t,flexDirection:`row`},v.createElement(m,null,e.from.padEnd(22).slice(0,22)),v.createElement(m,{color:`cyan`},` → `),v.createElement(m,null,e.to.padEnd(22).slice(0,22)),v.createElement(m,{color:`magenta`},` `,`█`.repeat(n),`░`.repeat(D-n)),v.createElement(m,{color:`gray`},` ${e.count}`))})),v.createElement(c,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{S as journeysCommand};
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{requireTier as r}from"./tier-DST3Yt2-.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import{resolveSiteId as l}from"./resolve-site-DSJR9vuz.js";import{EmptyState as u}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as d,openInBrowser as f}from"./keybar-deep-link-DC31T3CP.js";import{Box as p,Text as m,render as h,useApp as g,useInput as _}from"ink";import v,{useEffect as y,useState as b}from"react";import x from"ink-spinner";async function S(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getJourneys(d);return i({type:`journeys.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=h(v.createElement(C,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=g(),[l,h]=b(null),[S,C]=b(!0),[w,T]=b(null);if(_(e=>{if(e===`o`||e===`O`){f(d(`journeys`,{siteId:t}));return}e===`q`&&(a(),i(0))}),y(()=>{let n=!1;return(async()=>{try{let r=await e.getJourneys(t);n||(h(r.flows),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),S)return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`journeys · ${n}`}),v.createElement(o,{title:`Loading`,state:`busy`},v.createElement(p,null,v.createElement(m,{color:`magenta`},v.createElement(x,{type:`dots`})),v.createElement(m,null,` Computing flows…`))));if(w)return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`journeys · ${n}`}),v.createElement(u,{reason:`error`,headline:`Failed to load`,hint:w}));if(!l||l.length===0)return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`journeys · ${n}`}),v.createElement(u,{reason:`no-data`,headline:`No journeys yet`,hint:`Need at least 2 page-views per session to compute flows`}));let E=Math.max(...l.map(e=>e.count),1),D=12;return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`journeys · ${n}`}),v.createElement(o,{title:`Top page transitions (${l.length})`},l.map((e,t)=>{let n=Math.max(1,Math.round(e.count/E*D));return v.createElement(p,{key:t,flexDirection:`row`},v.createElement(m,null,e.from.padEnd(22).slice(0,22)),v.createElement(m,{color:`cyan`},` → `),v.createElement(m,null,e.to.padEnd(22).slice(0,22)),v.createElement(m,{color:`magenta`},` `,`█`.repeat(n),`░`.repeat(D-n)),v.createElement(m,{color:`gray`},` ${e.count}`))})),v.createElement(c,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{S as journeysCommand};
@@ -0,0 +1 @@
1
+ import e from"open";async function t(t){await e(t)}const n=process.env.ZENOVAY_APP_BASE||`https://app.zenovay.com`;function r(e,t={}){let r=new URL(n),i={analytics:`analytics`,overview:`analytics`,watch:`analytics`,stats:`analytics`,live:`analytics`,sources:`analytics`,pages:`analytics`,devices:`analytics`,geo:`analytics`,visitors:`analytics`,globe:`globe`,vitals:`performance`,revenue:`revenue`,sessions:`sessions`,heatmaps:`heatmaps`,funnels:`insights`,funnel:`insights`,journeys:`journeys`,retention:`retention`,uptime:`uptime`,insights:`insights`,companies:`companies`,errors:`errors`};if(t.siteId&&e in i)return r.pathname=`/domains/${encodeURIComponent(t.siteId)}`,r.searchParams.set(`tab`,i[e]),r.toString();switch(e){case`analytics`:case`overview`:case`watch`:r.pathname=`/analytics`;break;case`live`:r.pathname=`/analytics/live`;break;case`sources`:r.pathname=`/analytics`,r.searchParams.set(`tab`,`sources`);break;case`pages`:r.pathname=`/analytics`,r.searchParams.set(`tab`,`pages`);break;case`devices`:r.pathname=`/analytics`,r.searchParams.set(`tab`,`devices`);break;case`geo`:r.pathname=`/analytics`,r.searchParams.set(`tab`,`geo`);break;case`visitors`:r.pathname=`/analytics`,r.searchParams.set(`tab`,`profiles`);break;case`globe`:r.pathname=`/domains`;break;case`stats`:r.pathname=`/analytics`;break;case`vitals`:r.pathname=`/web-vitals`;break;case`revenue`:r.pathname=`/revenue`;break;case`sessions`:r.pathname=`/sessions`;break;case`heatmaps`:r.pathname=`/heatmaps`;break;case`funnels`:case`funnel`:r.pathname=`/funnels`;break;case`journeys`:r.pathname=`/journeys`;break;case`retention`:r.pathname=`/retention`;break;case`uptime`:r.pathname=`/uptime`;break;case`insights`:r.pathname=`/insights`;break;case`companies`:r.pathname=`/companies`;break;case`errors`:r.pathname=`/errors`;break;case`domains`:r.pathname=`/websites`;break;case`api-keys`:r.pathname=`/api-keys`;break;case`team`:r.pathname=`/team`;break;case`settings`:r.pathname=`/settings`;break;case`plans`:case`billing`:r.pathname=`/billing`;break;case`integrations`:r.pathname=`/integrations`;break;case`goals`:r.pathname=`/goals`;break;case`notes`:r.pathname=`/notes`;break;case`audit`:r.pathname=`/audit`;break;case`share`:r.pathname=`/settings/share`;break;case`alerts`:r.pathname=`/alerts`;break;case`agency`:r.pathname=`/agency`;break;case`profile`:r.pathname=`/profile`;break;case`usage`:r.pathname=`/usage`;break;case`deploys`:r.pathname=`/deploys`;break;case`webhooks`:r.pathname=`/webhooks`;break;default:r.pathname=`/`}return t.siteId&&r.searchParams.set(`site`,t.siteId),r.toString()}export{r as deepLinkFor,t as openInBrowser};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import"./formatter-DutfcQAc.js";import{emit$1 as r,isHeadless as i}from"./emit-DBYk96TD.js";import{Panel as a}from"./panel-B_yDcIcn.js";import{Banner as o}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as s}from"./keybar-DsYTkKZX.js";import"./sparkline-BZ0eMB-w.js";import{ChatPanel as c}from"./chat-panel-C_yjPXnw.js";import{resolveSiteId as l}from"./resolve-site-DSJR9vuz.js";import{EmptyState as u}from"./empty-state-CJxa1jUN.js";import{MetricCard as d}from"./metric-card-COEIZmbN.js";import{deepLinkFor as f,openInBrowser as p}from"./keybar-deep-link-DC31T3CP.js";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";async function C(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await l(c,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await c.getLive(u);return r({type:`live.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(w,{api:c,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:l}=_(),[g,C]=x(null),[w,T]=x(!0),[E,D]=x(null),[O,k]=x(!1);if(v(e=>{if(!O){if(e===`/`){k(!0);return}if(e===`o`||e===`O`){p(f(`live`,{siteId:t}));return}e===`q`&&(l(),i(0))}}),b(()=>{if(O)return;let n=!1,r=async()=>{try{let r=await e.getLive(t);n||(C(r),T(!1),D(null))}catch(e){n||(D(e.message),T(!1))}};r();let i=setInterval(r,2e3);return()=>{n=!0,clearInterval(i)}},[e,t,O]),O)return y.createElement(c,{cliVersion:r,api:e,dashboardContext:{commandName:`live`,siteId:t,siteLabel:n,metricsSnapshot:g},onClose:()=>k(!1)});if(w)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:`live · ${n}`}),y.createElement(a,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Connecting…`))));if(E&&!g)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:`live · ${n}`}),y.createElement(u,{reason:`error`,headline:`Failed to load`,hint:E}));let A=process.stdout.columns??80,j=Math.max(20,Math.min(40,Math.floor(A/3)));return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:`live · ${n}`}),y.createElement(d,{title:`Active now`,value:g?.activeVisitors??0,format:`number`,width:j}),y.createElement(a,{title:`Recent events`},!g||g.recentEvents.length===0?y.createElement(h,{color:`gray`},`— waiting for events —`):g.recentEvents.slice(0,15).map((e,t)=>y.createElement(m,{key:t},y.createElement(h,{color:`cyan`},(e.type??`pageview`).padEnd(10)),y.createElement(h,null,e.path.padEnd(36).slice(0,36)),y.createElement(h,{color:`gray`},e.country??`—`)))),y.createElement(s,{items:[{key:`/`,label:`ask AI`},{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{C as liveCommand};
@@ -0,0 +1 @@
1
+ import{useTheme as e}from"./panel-B_yDcIcn.js";import{spark as t}from"./sparkline-BZ0eMB-w.js";import{Box as n,Text as r}from"ink";import i from"react";function a(e,t){if(typeof e==`string`)return e;switch(t){case`percent`:{let t=Math.abs(e)<=1?e*100:e;return`${t.toFixed(1)}%`}case`duration`:{if(e<60)return`${Math.round(e)}s`;let t=Math.floor(e/60),n=Math.round(e%60);return`${t}m ${n.toString().padStart(2,`0`)}s`}case`currency`:{let t=e/100;return`$${t.toLocaleString(void 0,{minimumFractionDigits:0,maximumFractionDigits:2})}`}case`number`:default:return e.toLocaleString()}}const o=[`• `,`•• `,`•••`,` ••`,` •`,` `];function s(){let[e,t]=i.useState(0);return i.useEffect(()=>{let e=setInterval(()=>{t(e=>(e+1)%o.length)},180);return()=>clearInterval(e)},[]),e}function c({title:c,value:l,series:u,delta:d,format:f=`number`,loading:p=!1,emptyHint:m,width:h}){let{theme:g}=e(),_=s(),v=i.createElement(r,{color:g.typography.label.color,dimColor:g.typography.label.dim},c.toUpperCase()),y=({children:e})=>i.createElement(n,{flexDirection:`column`,width:h,marginRight:2,minHeight:3},e);if(p)return i.createElement(y,null,v,i.createElement(r,{color:g.accent},o[_]));let b=typeof l==`number`?l:Number(l),x=(l===``||l===`—`||typeof l==`number`&&!Number.isFinite(b))&&(!u||u.length===0);if(x)return i.createElement(y,null,v,i.createElement(r,{color:g.dim},m??`no data yet`));let S=a(l,f),C=typeof h==`number`?Math.max(8,h-4):16,w=u&&u.length>0?t(u,C):``,T=null;if(typeof d==`number`&&Number.isFinite(d)){let e=Math.abs(d*100);T=e<.5?i.createElement(r,{color:g.dim},` `,`→ `,e.toFixed(1),`%`):d>0?i.createElement(r,{color:g.success},` `,`↑ `,e.toFixed(1),`%`):i.createElement(r,{color:g.error},` `,`↓ `,e.toFixed(1),`%`)}return i.createElement(y,null,v,i.createElement(r,{color:g.typography.headline.color,bold:g.typography.headline.bold},S),w?i.createElement(n,{flexDirection:`row`},i.createElement(r,{color:g.accent},w),T):T?i.createElement(n,{flexDirection:`row`},T):i.createElement(n,{height:1}))}export{c as MetricCard};
@@ -1 +1 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./formatter-DutfcQAc.js";import{emit$1 as r,isHeadless as i}from"./emit-DBYk96TD.js";import{Panel as a}from"./panel-B_yDcIcn.js";import{Banner as o}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as s}from"./keybar-DsYTkKZX.js";import{resolveSiteId as c}from"./resolve-site-DSJR9vuz.js";import{DataTable as l}from"./data-table-BpbyyNSA.js";import{EmptyState as u}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as d,openInBrowser as f}from"./keybar-deep-link-C9xNYihD.js";import{Box as p,Text as m,render as h,useApp as g,useInput as _}from"ink";import v,{useEffect as y,useState as b}from"react";import x from"ink-spinner";async function S(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getPages(u);return r({type:`pages.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=h(v.createElement(C,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=g(),[h,S]=b(null),[C,w]=b(!0),[T,E]=b(null);if(_(e=>{if(e===`o`||e===`O`){f(d(`pages`,{siteId:t}));return}e===`q`&&(c(),i(0))}),y(()=>{let n=!1;return(async()=>{try{let r=await e.getPages(t);n||(S(r),w(!1))}catch(e){n||(E(e.message),w(!1))}})(),()=>{n=!0}},[e,t]),C)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`pages · ${n}`}),v.createElement(a,{title:`Loading`,state:`busy`},v.createElement(p,null,v.createElement(m,{color:`magenta`},v.createElement(x,{type:`dots`})),v.createElement(m,null,` Fetching pages…`))));if(T)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`pages · ${n}`}),v.createElement(u,{reason:`error`,headline:`Failed to load`,hint:T}));if(!h||h.length===0)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`pages · ${n}`}),v.createElement(u,{reason:`no-data`,headline:`No pages yet`,hint:`Visit your site to send the first event`}));let D=[{key:`path`,label:`path`,width:36},{key:`views`,label:`views`,align:`right`,width:8},{key:`uniqueVisitors`,label:`unique`,align:`right`,width:8},{key:`avgTime`,label:`avg time`,align:`right`,width:9,format:e=>typeof e==`number`?`${Math.round(e/1e3)}s`:`—`},{key:`bounceRate`,label:`bounce`,align:`right`,width:7,format:e=>typeof e==`number`?`${(e*100).toFixed(0)}%`:`—`}];return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`pages · ${n}`}),v.createElement(a,{title:`Top pages (${h.length})`},v.createElement(l,{columns:D,data:h,zebra:!0})),v.createElement(s,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{S as pagesCommand};
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./formatter-DutfcQAc.js";import{emit$1 as r,isHeadless as i}from"./emit-DBYk96TD.js";import{Panel as a}from"./panel-B_yDcIcn.js";import{Banner as o}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as s}from"./keybar-DsYTkKZX.js";import{resolveSiteId as c}from"./resolve-site-DSJR9vuz.js";import{DataTable as l}from"./data-table-BpbyyNSA.js";import{EmptyState as u}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as d,openInBrowser as f}from"./keybar-deep-link-DC31T3CP.js";import{Box as p,Text as m,render as h,useApp as g,useInput as _}from"ink";import v,{useEffect as y,useState as b}from"react";import x from"ink-spinner";async function S(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getPages(u);return r({type:`pages.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=h(v.createElement(C,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=g(),[h,S]=b(null),[C,w]=b(!0),[T,E]=b(null);if(_(e=>{if(e===`o`||e===`O`){f(d(`pages`,{siteId:t}));return}e===`q`&&(c(),i(0))}),y(()=>{let n=!1;return(async()=>{try{let r=await e.getPages(t);n||(S(r),w(!1))}catch(e){n||(E(e.message),w(!1))}})(),()=>{n=!0}},[e,t]),C)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`pages · ${n}`}),v.createElement(a,{title:`Loading`,state:`busy`},v.createElement(p,null,v.createElement(m,{color:`magenta`},v.createElement(x,{type:`dots`})),v.createElement(m,null,` Fetching pages…`))));if(T)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`pages · ${n}`}),v.createElement(u,{reason:`error`,headline:`Failed to load`,hint:T}));if(!h||h.length===0)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`pages · ${n}`}),v.createElement(u,{reason:`no-data`,headline:`No pages yet`,hint:`Visit your site to send the first event`}));let D=[{key:`path`,label:`path`,width:36},{key:`views`,label:`views`,align:`right`,width:8},{key:`uniqueVisitors`,label:`unique`,align:`right`,width:8},{key:`avgTime`,label:`avg time`,align:`right`,width:9,format:e=>typeof e==`number`?`${Math.round(e/1e3)}s`:`—`},{key:`bounceRate`,label:`bounce`,align:`right`,width:7,format:e=>typeof e==`number`?`${(e*100).toFixed(0)}%`:`—`}];return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`pages · ${n}`}),v.createElement(a,{title:`Top pages (${h.length})`},v.createElement(l,{columns:D,data:h,zebra:!0})),v.createElement(s,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{S as pagesCommand};
@@ -1,2 +1,2 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as a}from"./resolve-site-DSJR9vuz.js";import{DataTable as o}from"./data-table-BpbyyNSA.js";import{runAnalyticalScreen as s}from"./analytical-screen-nJlxAocC.js";import{Text as c}from"ink";import l from"react";function u(){let e=process.stdout.columns??80,t=Math.max(40,e-4-18),n=1,r=t-n,i=Math.max(8,Math.floor(r*.3)),a=Math.max(8,Math.floor(r*.32)),o=Math.max(4,Math.floor(r*.1)),s=Math.max(6,Math.floor(r*.12)),c=Math.max(4,r-i-a-o-s);return{current:n,name:i,domain:a,tier:o,pageviews24h:s,id:c}}async function d(d){let f=await e(),p=await t({strict:!1}),m=new n({config:f,cliVersion:d.cliVersion,token:p}),h,g;try{({siteId:h,site:g}=await a(m,{explicit:d.siteId,headless:!!(d.json||d.csv||d.tsv||d.ndjson),cliVersion:d.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let _=i(d),v=u(),y=[{key:`isCurrent`,label:``,width:v.current,format:e=>e?`*`:` `},{key:`name`,label:`project`,width:v.name},{key:`domain`,label:`domain`,width:v.domain,format:e=>String(e??`—`)},{key:`tier`,label:`tier`,width:v.tier},{key:`pageviews24h`,label:`24h pv`,width:v.pageviews24h,align:`right`},{key:`id`,label:`id`,width:v.id}];return s({cliVersion:d.cliVersion,title:`projects · ${p?.teamId??`—`}`,commandName:`projects`,authToken:p?.accessToken??null,refreshIntervalMs:0,fetcher:e=>m.getProjects(h,e),format:_,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.projects)process.stdout.write(JSON.stringify(t)+`
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as a}from"./resolve-site-DSJR9vuz.js";import{DataTable as o}from"./data-table-BpbyyNSA.js";import{runAnalyticalScreen as s}from"./analytical-screen-CRn5UoFi.js";import{Text as c}from"ink";import l from"react";function u(){let e=process.stdout.columns??80,t=Math.max(40,e-4-18),n=1,r=t-n,i=Math.max(8,Math.floor(r*.3)),a=Math.max(8,Math.floor(r*.32)),o=Math.max(4,Math.floor(r*.1)),s=Math.max(6,Math.floor(r*.12)),c=Math.max(4,r-i-a-o-s);return{current:n,name:i,domain:a,tier:o,pageviews24h:s,id:c}}async function d(d){let f=await e(),p=await t({strict:!1}),m=new n({config:f,cliVersion:d.cliVersion,token:p}),h,g;try{({siteId:h,site:g}=await a(m,{explicit:d.siteId,headless:!!(d.json||d.csv||d.tsv||d.ndjson),cliVersion:d.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let _=i(d),v=u(),y=[{key:`isCurrent`,label:``,width:v.current,format:e=>e?`*`:` `},{key:`name`,label:`project`,width:v.name},{key:`domain`,label:`domain`,width:v.domain,format:e=>String(e??`—`)},{key:`tier`,label:`tier`,width:v.tier},{key:`pageviews24h`,label:`24h pv`,width:v.pageviews24h,align:`right`},{key:`id`,label:`id`,width:v.id}];return s({cliVersion:d.cliVersion,title:`projects · ${p?.teamId??`—`}`,commandName:`projects`,authToken:p?.accessToken??null,refreshIntervalMs:0,fetcher:e=>m.getProjects(h,e),format:_,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.projects)process.stdout.write(JSON.stringify(t)+`
2
2
  `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(r(e.projects,[`id`,`name`,`domain`,`tier`,`pageviews24h`,`isCurrent`],t))},keybindings:{s:{label:`switch project (logout + login)`,handler:()=>{process.stderr.write("To switch project: run `zenovay logout` then `zenovay login`.\n")}}},panels:[{id:`projects`,title:`Projects`,render:e=>e.projects.length===0?l.createElement(c,{color:`gray`},`— no projects yet —`):l.createElement(o,{data:e.projects,columns:y,headerStyle:`accent`})}]})}export{d as projectsCommand};
@@ -1,4 +1,4 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{requireTier as r}from"./tier-DST3Yt2-.js";import{formatTabular as i,selectFormat as a}from"./formatter-DutfcQAc.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./progress-row-BpAXjJPL.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./sparkline-BZ0eMB-w.js";import{resolveSiteId as c}from"./resolve-site-DSJR9vuz.js";import{DataTable as l}from"./data-table-BpbyyNSA.js";import"./bar-DWT-1xOE.js";import"./ui-DzoMR7th.js";import{Box as u,Text as d,useApp as f,useInput as p}from"ink";import m,{useMemo as h,useState as g}from"react";import _ from"ink-text-input";function v({api:e,siteId:t,maxRows:n}){let{exit:r}=f(),[i,a]=g(``),[c,v]=g(null),[y,b]=g(null),[x,S]=g(!1),[C,w]=g([]);p((e,t)=>{t.escape&&r()});let T=async i=>{if(i.trim()){if(i.trim()===`\\q`||i.trim()===`exit`||i.trim()===`quit`){r();return}w(e=>[...e,i]),S(!0),b(null);try{let r=await e.runSqlQuery(t,i,{maxRows:n});v(r)}catch(e){b(e.message),v(null)}finally{S(!1),a(``)}}},E=h(()=>c?c.columns.map(e=>({key:e,label:e,width:18,format:e=>e==null?`∅`:String(e).slice(0,18)})):[],[c]);return m.createElement(u,{flexDirection:`column`},m.createElement(s,{version:`query`}),m.createElement(o,{title:`History`,state:`idle`},C.length===0?m.createElement(d,{color:`gray`},`— no queries yet — Esc or \\q to exit —`):C.slice(-5).map((e,t)=>m.createElement(d,{key:t,color:`gray`},`> ${e.slice(0,80)}${e.length>80?`…`:``}`))),m.createElement(u,null,m.createElement(d,{color:`magenta`},`sql`,`>`,` `),m.createElement(_,{value:i,onChange:a,onSubmit:T})),x?m.createElement(d,{color:`gray`},`running…`):null,y?m.createElement(o,{title:`Error`,state:`err`},m.createElement(d,{color:`red`},y)):null,c?m.createElement(o,{title:`${c.row_count} rows · ${c.duration_ms}ms${c.truncated?` · truncated`:``}`,state:`ok`},c.row_count===0?m.createElement(d,{color:`gray`},`— empty —`):m.createElement(l,{data:c.rows.slice(0,50),columns:E,headerStyle:`accent`})):null)}async function y(o){let s=await e(),l=await t({strict:!1}),u=new n({config:s,cliVersion:o.cliVersion,token:l});try{await r(u,`scale`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(u,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=o.maxRows??1e3,p=a(o);if(o.sql)try{let e=await u.runSqlQuery(d,o.sql,{maxRows:f});if(p===`json`)process.stdout.write(JSON.stringify(e,null,2)),process.stdout.write(`
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{requireTier as r}from"./tier-DST3Yt2-.js";import{formatTabular as i,selectFormat as a}from"./formatter-DutfcQAc.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./progress-row-BpAXjJPL.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./sparkline-BZ0eMB-w.js";import{resolveSiteId as c}from"./resolve-site-DSJR9vuz.js";import{DataTable as l}from"./data-table-BpbyyNSA.js";import"./bar-DWT-1xOE.js";import"./ui-Cey-h6wI.js";import{Box as u,Text as d,useApp as f,useInput as p}from"ink";import m,{useMemo as h,useState as g}from"react";import _ from"ink-text-input";function v({api:e,siteId:t,maxRows:n}){let{exit:r}=f(),[i,a]=g(``),[c,v]=g(null),[y,b]=g(null),[x,S]=g(!1),[C,w]=g([]);p((e,t)=>{t.escape&&r()});let T=async i=>{if(i.trim()){if(i.trim()===`\\q`||i.trim()===`exit`||i.trim()===`quit`){r();return}w(e=>[...e,i]),S(!0),b(null);try{let r=await e.runSqlQuery(t,i,{maxRows:n});v(r)}catch(e){b(e.message),v(null)}finally{S(!1),a(``)}}},E=h(()=>c?c.columns.map(e=>({key:e,label:e,width:18,format:e=>e==null?`∅`:String(e).slice(0,18)})):[],[c]);return m.createElement(u,{flexDirection:`column`},m.createElement(s,{version:`query`}),m.createElement(o,{title:`History`,state:`idle`},C.length===0?m.createElement(d,{color:`gray`},`— no queries yet — Esc or \\q to exit —`):C.slice(-5).map((e,t)=>m.createElement(d,{key:t,color:`gray`},`> ${e.slice(0,80)}${e.length>80?`…`:``}`))),m.createElement(u,null,m.createElement(d,{color:`magenta`},`sql`,`>`,` `),m.createElement(_,{value:i,onChange:a,onSubmit:T})),x?m.createElement(d,{color:`gray`},`running…`):null,y?m.createElement(o,{title:`Error`,state:`err`},m.createElement(d,{color:`red`},y)):null,c?m.createElement(o,{title:`${c.row_count} rows · ${c.duration_ms}ms${c.truncated?` · truncated`:``}`,state:`ok`},c.row_count===0?m.createElement(d,{color:`gray`},`— empty —`):m.createElement(l,{data:c.rows.slice(0,50),columns:E,headerStyle:`accent`})):null)}async function y(o){let s=await e(),l=await t({strict:!1}),u=new n({config:s,cliVersion:o.cliVersion,token:l});try{await r(u,`scale`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(u,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=o.maxRows??1e3,p=a(o);if(o.sql)try{let e=await u.runSqlQuery(d,o.sql,{maxRows:f});if(p===`json`)process.stdout.write(JSON.stringify(e,null,2)),process.stdout.write(`
2
2
  `);else if(p===`ndjson`)for(let t of e.rows)process.stdout.write(JSON.stringify(t)+`
3
3
  `);else if(p===`csv`||p===`tsv`)process.stdout.write(i(e.rows,e.columns,p));else{let t=e.columns.map(t=>Math.max(t.length,...e.rows.map(e=>String(e[t]??``).length))),n=`+`+t.map(e=>`-`.repeat(e+2)).join(`+`)+`+`;process.stdout.write(n+`
4
4
  `),process.stdout.write(`|`+e.columns.map((e,n)=>` ${e.padEnd(t[n]??0)} `).join(`|`)+`|
@@ -1 +1 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{requireTier as r}from"./tier-DST3Yt2-.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import{resolveSiteId as l}from"./resolve-site-DSJR9vuz.js";import{EmptyState as u}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as d,openInBrowser as f}from"./keybar-deep-link-C9xNYihD.js";import{Box as p,Text as m,render as h,useApp as g,useInput as _}from"ink";import v,{useEffect as y,useState as b}from"react";import x from"ink-spinner";function S(e){return e>=.6?`magenta`:e>=.4?`cyan`:e>=.2?`blue`:`gray`}function C(e){return!Number.isFinite(e)||e===0?` — `:` ${(e*100).toFixed(0).padStart(3)}% `}async function w(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getRetention(d);return i({type:`retention.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=h(v.createElement(T,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const T=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=g(),[l,h]=b(null),[w,T]=b(!0),[E,D]=b(null);return _(e=>{if(e===`o`||e===`O`){f(d(`retention`,{siteId:t}));return}e===`q`&&(a(),i(0))}),y(()=>{let n=!1;return(async()=>{try{let r=await e.getRetention(t);n||(h(r.cohorts),T(!1))}catch(e){n||(D(e.message),T(!1))}})(),()=>{n=!0}},[e,t]),w?v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(o,{title:`Loading`,state:`busy`},v.createElement(p,null,v.createElement(m,{color:`magenta`},v.createElement(x,{type:`dots`})),v.createElement(m,null,` Crunching cohorts…`)))):E?v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(u,{reason:`error`,headline:`Failed to load`,hint:E})):!l||l.length===0?v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(u,{reason:`no-data`,headline:`No retention data yet`,hint:`Retention needs at least 30 days of traffic`})):v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(o,{title:`Cohort retention (D1 / D7 / D30)`},v.createElement(p,{flexDirection:`row`},v.createElement(m,{bold:!0},`cohort`.padEnd(12)),v.createElement(m,{bold:!0},` D1 `),v.createElement(m,{bold:!0},` D7 `),v.createElement(m,{bold:!0},` D30 `)),l.map(e=>v.createElement(p,{key:e.date,flexDirection:`row`},v.createElement(m,null,e.date.padEnd(12).slice(0,12)),v.createElement(m,{color:S(e.day1)},C(e.day1)),v.createElement(m,{color:S(e.day7)},C(e.day7)),v.createElement(m,{color:S(e.day30)},C(e.day30))))),v.createElement(c,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{w as retentionCommand};
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{requireTier as r}from"./tier-DST3Yt2-.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import{resolveSiteId as l}from"./resolve-site-DSJR9vuz.js";import{EmptyState as u}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as d,openInBrowser as f}from"./keybar-deep-link-DC31T3CP.js";import{Box as p,Text as m,render as h,useApp as g,useInput as _}from"ink";import v,{useEffect as y,useState as b}from"react";import x from"ink-spinner";function S(e){return e>=.6?`magenta`:e>=.4?`cyan`:e>=.2?`blue`:`gray`}function C(e){return!Number.isFinite(e)||e===0?` — `:` ${(e*100).toFixed(0).padStart(3)}% `}async function w(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getRetention(d);return i({type:`retention.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=h(v.createElement(T,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const T=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=g(),[l,h]=b(null),[w,T]=b(!0),[E,D]=b(null);return _(e=>{if(e===`o`||e===`O`){f(d(`retention`,{siteId:t}));return}e===`q`&&(a(),i(0))}),y(()=>{let n=!1;return(async()=>{try{let r=await e.getRetention(t);n||(h(r.cohorts),T(!1))}catch(e){n||(D(e.message),T(!1))}})(),()=>{n=!0}},[e,t]),w?v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(o,{title:`Loading`,state:`busy`},v.createElement(p,null,v.createElement(m,{color:`magenta`},v.createElement(x,{type:`dots`})),v.createElement(m,null,` Crunching cohorts…`)))):E?v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(u,{reason:`error`,headline:`Failed to load`,hint:E})):!l||l.length===0?v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(u,{reason:`no-data`,headline:`No retention data yet`,hint:`Retention needs at least 30 days of traffic`})):v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(o,{title:`Cohort retention (D1 / D7 / D30)`},v.createElement(p,{flexDirection:`row`},v.createElement(m,{bold:!0},`cohort`.padEnd(12)),v.createElement(m,{bold:!0},` D1 `),v.createElement(m,{bold:!0},` D7 `),v.createElement(m,{bold:!0},` D30 `)),l.map(e=>v.createElement(p,{key:e.date,flexDirection:`row`},v.createElement(m,null,e.date.padEnd(12).slice(0,12)),v.createElement(m,{color:S(e.day1)},C(e.day1)),v.createElement(m,{color:S(e.day7)},C(e.day7)),v.createElement(m,{color:S(e.day30)},C(e.day30))))),v.createElement(c,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{w as retentionCommand};
@@ -1,2 +1,2 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./progress-row-BpAXjJPL.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import{spark as a}from"./sparkline-BZ0eMB-w.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as o}from"./resolve-site-DSJR9vuz.js";import"./data-table-BpbyyNSA.js";import"./bar-DWT-1xOE.js";import{deepLinkFor as s,openInBrowser as c}from"./keybar-deep-link-C9xNYihD.js";import{runAnalyticalScreen as l}from"./analytical-screen-nJlxAocC.js";import"./ui-DzoMR7th.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){let n=e/100,r=new Intl.NumberFormat(`en-US`,{minimumFractionDigits:0,maximumFractionDigits:0}).format(n),i=(t||`USD`).toUpperCase();return i===`USD`?`$${r}`:i===`EUR`?`€${r}`:i===`GBP`?`£${r}`:`${r} ${i}`}async function m(m){let h=await e(),g=await t({strict:!1}),_=new n({config:h,cliVersion:m.cliVersion,token:g}),v,y;try{({siteId:v,site:y}=await o(_,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let b=i(m),x=m.range??`30d`;return l({cliVersion:m.cliVersion,title:`revenue · ${v} · ${x}`,commandName:`revenue`,ai:{api:_,siteId:v,siteLabel:y?.url?y.url.replace(/^https?:\/\//,``).replace(/\/$/,``):y?.name??v},authToken:g?.accessToken??null,refreshIntervalMs:m.watch?5*6e4:0,fetcher:e=>_.getRevenue(v,x,e),format:b,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`revenue`,{siteId:v}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./progress-row-BpAXjJPL.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import{spark as a}from"./sparkline-BZ0eMB-w.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as o}from"./resolve-site-DSJR9vuz.js";import"./data-table-BpbyyNSA.js";import"./bar-DWT-1xOE.js";import{deepLinkFor as s,openInBrowser as c}from"./keybar-deep-link-DC31T3CP.js";import{runAnalyticalScreen as l}from"./analytical-screen-CRn5UoFi.js";import"./ui-Cey-h6wI.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){let n=e/100,r=new Intl.NumberFormat(`en-US`,{minimumFractionDigits:0,maximumFractionDigits:0}).format(n),i=(t||`USD`).toUpperCase();return i===`USD`?`$${r}`:i===`EUR`?`€${r}`:i===`GBP`?`£${r}`:`${r} ${i}`}async function m(m){let h=await e(),g=await t({strict:!1}),_=new n({config:h,cliVersion:m.cliVersion,token:g}),v,y;try{({siteId:v,site:y}=await o(_,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let b=i(m),x=m.range??`30d`;return l({cliVersion:m.cliVersion,title:`revenue · ${v} · ${x}`,commandName:`revenue`,ai:{api:_,siteId:v,siteLabel:y?.url?y.url.replace(/^https?:\/\//,``).replace(/\/$/,``):y?.name??v},authToken:g?.accessToken??null,refreshIntervalMs:m.watch?5*6e4:0,fetcher:e=>_.getRevenue(v,x,e),format:b,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`revenue`,{siteId:v}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
2
  `);return}process.stdout.write(r(e.series,[`bucket`,`amount`,`currency`,`transactions`],t))},panels:[{id:`totals`,title:`Top line`,render:e=>f.createElement(u,{flexDirection:`column`},f.createElement(d,null,f.createElement(d,{color:`green`,bold:!0},p(e.totalAmount,e.currency)),` `,f.createElement(d,{color:`gray`},`total · `,e.totalTransactions,` transactions`)),typeof e.mrr==`number`?f.createElement(d,null,f.createElement(d,{bold:!0},`MRR `),f.createElement(d,{color:`magenta`},p(e.mrr,e.currency)),typeof e.arpu==`number`?f.createElement(d,{color:`gray`},` · ARPU `,p(e.arpu,e.currency)):null):null)},{id:`series`,title:`Daily (${x})`,render:e=>{let t=e.series.map(e=>e.amount);if(t.length===0)return f.createElement(d,{color:`gray`},`— no transactions —`);let n=Math.max(...t,1);return f.createElement(u,{flexDirection:`column`},f.createElement(d,{color:`magenta`},a(t,Math.min(60,t.length*2))),f.createElement(d,{color:`gray`},`peak: `,p(n,e.currency),` ·`,` `,`avg: `,p(e.totalAmount/Math.max(1,t.length),e.currency)))}},{id:`window`,title:`Window`,render:e=>f.createElement(d,{color:`gray`},new Date(e.windowStart).toISOString().slice(0,10),` →`,` `,new Date(e.windowEnd).toISOString().slice(0,10))}]})}export{m as revenueCommand};
@@ -1,7 +1,7 @@
1
1
  import{spawn as e}from"node:child_process";import t from"chalk";const n=3e4,r=4,i=1e3;function a(e,t){let n=e.requires;if(!n)return null;if(n.auth!==!1&&!t.authenticated)return`not authenticated`;if(n.tier&&t.currentTier){let e={free:0,pro:1,scale:2,enterprise:3},r=e[t.currentTier]??0,i=e[n.tier]??99}return n.multipleTeams&&!t.hasMultipleTeams?`requires 2+ teams`:n.freeTeam&&!t.hasFreeTeam?`requires a Free-tier team`:null}function o(t,n,r,i){return new Promise(a=>{let o=e(`node`,[t,...n],{env:{...process.env,ZENOVAY_NO_UPDATE_CHECK:`1`,...i},stdio:[`ignore`,`pipe`,`pipe`]}),s=``,c=``,l=!1,u=setTimeout(()=>{l=!0;try{o.kill(`SIGKILL`)}catch{}},r);o.stdout?.on(`data`,e=>{s+=e.toString(`utf8`),s.length>1048576&&(s=s.slice(0,1048576))}),o.stderr?.on(`data`,e=>{c+=e.toString(`utf8`),c.length>1048576&&(c=c.slice(0,1048576))}),o.on(`error`,e=>{clearTimeout(u),a({stdout:s,stderr:c+`\n[spawn error: ${e.message}]`,exitCode:-1,timedOut:l})}),o.on(`close`,e=>{clearTimeout(u),a({stdout:s,stderr:c,exitCode:e??0,timedOut:l})})})}async function s(e,t){let r=Date.now(),s=a(e,t.env);if(s)return{name:e.name,category:e.category,status:`skip`,durationMs:0,reason:s};if(e.inProcess)try{let t=await e.inProcess(),n=Date.now()-r;return t.ok?{name:e.name,category:e.category,status:`pass`,durationMs:n,...t.detail?{detail:t.detail}:{}}:{name:e.name,category:e.category,status:`fail`,durationMs:n,reason:t.reason}}catch(t){return{name:e.name,category:e.category,status:`fail`,durationMs:Date.now()-r,reason:t.message}}let c=e.name===`stack-leak.bad-net`?{ZENOVAY_API_BASE:`http://127.0.0.1:1`}:void 0,l=t.timeoutMs??n,u=await o(t.binPath,e.command,l,c),d=Date.now()-r;if(u.timedOut)return{name:e.name,category:e.category,status:`fail`,durationMs:d,reason:`timeout (${Math.round(l/1e3)}s)`,...t.verbose?{rawStdout:u.stdout.slice(0,i),rawStderr:u.stderr.slice(0,i)}:{}};let f;try{f=e.assert(u.stdout,u.stderr,u.exitCode)}catch(n){return{name:e.name,category:e.category,status:`fail`,durationMs:d,reason:`assert threw: ${n.message}`,...t.verbose?{rawStdout:u.stdout.slice(0,i),rawStderr:u.stderr.slice(0,i)}:{}}}return f.ok?{name:e.name,category:e.category,status:`pass`,durationMs:d,...f.detail?{detail:f.detail}:{},...t.verbose?{rawStdout:u.stdout.slice(0,i),rawStderr:u.stderr.slice(0,i)}:{}}:{name:e.name,category:e.category,status:`fail`,durationMs:d,reason:f.reason,...t.verbose?{rawStdout:u.stdout.slice(0,i),rawStderr:u.stderr.slice(0,i)}:{}}}async function c(e,t){let n=Date.now(),i=Math.max(1,t.parallel??r),a=Array(e.length).fill(void 0),o=[];for(let n=0;n<e.length;n++){let r=e[n];r&&(t.quick&&!r.quick||o.push(n))}let c=0,l=[],u=async()=>{for(;;){let n=c;if(c+=1,n>=o.length)return;let r=o[n];if(r===void 0)return;let i=e[r];if(!i)continue;let l=await s(i,t);a[r]=l,t.onResult?.(l)}};for(let e=0;e<i;e++)l.push(u());await Promise.all(l);let d=[];for(let e of a)e&&d.push(e);let f=d.filter(e=>e.status===`pass`).length,p=d.filter(e=>e.status===`fail`).length,m=d.filter(e=>e.status===`skip`).length;return{results:d,total:d.length,pass:f,fail:p,skip:m,durationMs:Date.now()-n}}async function l(e){let t={currentTier:null,hasMultipleTeams:!1,hasFreeTeam:!1,authenticated:!1};try{let{readToken:n}=await import(`./token-store-BliA7lF_.js`),{readConfig:r}=await import(`./config-i0nb93yX.js`),{ApiV2Client:i}=await import(`./api-v2-BlZLQy11.js`),a=await n({strict:!1}).catch(()=>null);if(!a)return t;t.authenticated=!0;let o=await r(),s=new i({config:o,cliVersion:e,token:a}),c=await s.me();if(c.team?.plan){let e=c.team.plan.toLowerCase();(e===`free`||e===`pro`||e===`scale`||e===`enterprise`)&&(t.currentTier=e)}c.teams&&c.teams.length>=2&&(t.hasMultipleTeams=!0),(c.teams&&c.teams.some(e=>e.plan?.toLowerCase()===`free`)||t.currentTier===`free`)&&(t.hasFreeTeam=!0)}catch{}return t}function u(e){let t=e.trim();if(!t)return{ok:!1,reason:`empty stdout`};try{return{ok:!0,value:JSON.parse(t)}}catch{let e=t.split(`
2
2
  `).filter(e=>e.trim().startsWith(`{`)||e.trim().startsWith(`[`)).pop();if(e)try{return{ok:!0,value:JSON.parse(e)}}catch{}return{ok:!1,reason:`stdout not JSON (got ${t.length} bytes)`}}}function d(e,t,n){if(n!==0)return{ok:!1,reason:`exit ${n}`};let r=u(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}}function f(e,t,n){if(n!==0){let r=[e,t];for(let e of r)if(e.includes(`tier_insufficient`))return{ok:!0,detail:{gated:!0}};return{ok:!1,reason:`exit ${n} — ${(t||e).slice(0,80)}`}}let r=u(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}}function p(e){if(typeof e!=`object`||!e)return!1;let t=e;if(Array.isArray(t.items)||Array.isArray(t.rows)||Array.isArray(t.data))return!0;if(typeof t.data==`object`&&t.data!==null){let e=t.data;if(Array.isArray(e.items)||Array.isArray(e.rows))return!0}return!1}const m=[{name:`analytics`,category:`ANALYTICS`,command:[`analytics`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.visitors??a.data?.visitors,s=a.pageviews??a.data?.pageviews;return{ok:!0,detail:{visitors:o??null,pageviews:s??null}}},quick:!0},{name:`overview`,category:`ANALYTICS`,command:[`overview`,`--json`],assert:d},{name:`pages`,category:`ANALYTICS`,command:[`pages`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.items??a.data?.items;return{ok:!0,detail:{rows:o?.length??0}}},quick:!0},{name:`sources`,category:`ANALYTICS`,command:[`sources`,`--json`],assert:d,quick:!0},{name:`devices`,category:`ANALYTICS`,command:[`devices`,`--json`],assert:d},{name:`geo`,category:`ANALYTICS`,command:[`geo`,`--json`],assert:d},{name:`live`,category:`ANALYTICS`,command:[`live`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);if(i.ok&&typeof i.value==`object`&&i.value!==null){let e=i.value,t=e.bounceRate??e.data?.bounceRate;if(typeof t==`number`&&(t<0||t>1))return{ok:!1,reason:`bounceRate semantics violated (got ${t}, expected 0..1)`}}return{ok:!0}}},{name:`revenue`,category:`ANALYTICS`,command:[`revenue`,`--json`],assert:d},{name:`funnels`,category:`ANALYTICS`,command:[`funnels`,`--json`],assert:f,requires:{tier:`pro`}},{name:`home`,category:`ANALYTICS`,command:[`home`,`--json`],assert:d},{name:`usage`,category:`ANALYTICS`,command:[`usage`,`--json`],assert:d,quick:!0},{name:`stats`,category:`ANALYTICS`,command:[`stats`,`--json`],assert:d},{name:`retention`,category:`BEHAVIOR`,command:[`retention`,`--json`],assert:f,requires:{tier:`pro`}},{name:`uptime`,category:`BEHAVIOR`,command:[`uptime`,`--json`],assert:f,requires:{tier:`pro`}},{name:`sessions`,category:`BEHAVIOR`,command:[`sessions`,`--json`],assert:f,requires:{tier:`pro`}},{name:`heatmaps`,category:`BEHAVIOR`,command:[`heatmaps`,`--json`],assert:f,requires:{tier:`pro`}},{name:`journeys`,category:`BEHAVIOR`,command:[`journeys`,`--json`],assert:f,requires:{tier:`pro`}},{name:`insights`,category:`INTELLIGENCE`,command:[`insights`,`--json`],assert:f,requires:{tier:`pro`}},{name:`domains list`,category:`MANAGE`,command:[`domains`,`list`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);return!i.ok||!p(i.value)?{ok:!1,reason:`expected list shape ({items|rows|data})`}:{ok:!0}},quick:!0},{name:`api-keys list`,category:`MANAGE`,command:[`api-keys`,`list`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);return!i.ok||!p(i.value)?{ok:!1,reason:`expected list shape`}:{ok:!0}}},{name:`team list`,category:`MANAGE`,command:[`team`,`list`,`--json`],assert:f,requires:{tier:`pro`}},{name:`webhooks list`,category:`MANAGE`,command:[`webhooks`,`list`,`--json`],assert:d},{name:`profile show`,category:`ACCOUNT`,command:[`profile`,`show`,`--json`],assert:d,quick:!0},{name:`plans info`,category:`ACCOUNT`,command:[`plans`,`info`,`--json`],assert:d},{name:`settings get`,category:`ACCOUNT`,command:[`settings`,`get`,`--json`],assert:d},{name:`integrations list`,category:`ACCOUNT`,command:[`integrations`,`list`,`--json`],assert:d},{name:`goals list`,category:`ACCOUNT`,command:[`goals`,`list`,`--json`],assert:f,requires:{tier:`pro`}},{name:`notes list`,category:`ACCOUNT`,command:[`notes`,`list`,`--json`],assert:d},{name:`audit list`,category:`ACCOUNT`,command:[`audit`,`list`,`--json`],assert:f,requires:{tier:`pro`}},{name:`share url`,category:`ACCOUNT`,command:[`share`,`url`,`--json`],assert:(e,t,n)=>n!==0&&n!==1&&n!==2?{ok:!1,reason:`unexpected exit ${n}`}:{ok:!0}},{name:`teams list`,category:`ACCOUNT`,command:[`teams`,`list`,`--json`],assert:d},{name:`health`,category:`OPERATIONS`,command:[`health`,`--json`],assert:(e,t,n)=>{let r=u(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}},quick:!0},{name:`commands`,category:`OPERATIONS`,command:[`commands`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.commands;return!Array.isArray(o)||o.length===0?{ok:!1,reason:`commands tree empty`}:{ok:!0,detail:{commands:o.length}}}},{name:`themes`,category:`OPERATIONS`,command:[`themes`,`--json`],assert:d},{name:`projects`,category:`OPERATIONS`,command:[`projects`,`--json`],assert:d},{name:`idor.cross-team`,category:`SECURITY`,command:[`domains`,`list`,`--site-id`,`00000000-0000-0000-0000-000000000001`,`--json`],assert:(e,t,n)=>{let r=e+t;return/forbidden|not_found|tier_insufficient|auth_required|auth_invalid/.test(r)?{ok:!0,detail:{rejected:!0}}:r.includes(`"items"`)||r.includes(`"rows"`)?{ok:!1,reason:`expected forbidden/not_found, got data`}:{ok:!0,detail:{rejected:`empty`}}},requires:{multipleTeams:!0},dev:!0},{name:`idor.bad-uuid`,category:`SECURITY`,command:[`analytics`,`--site-id`,`00000000-0000-0000-0000-000000000000`,`--json`],assert:(e,t,n)=>{let r=e+t;return/not_found|forbidden|auth_/.test(r)?{ok:!0,detail:{rejected:!0}}:/error|invalid|"code":/i.test(r)?{ok:!0,detail:{rejected:`error-shaped`}}:{ok:!1,reason:`silent zeros — expected not_found`}},quick:!0,dev:!0},{name:`tier-gate.retention`,category:`SECURITY`,command:[`retention`,`--json`],assert:(e,t,n)=>{let r=e+t;return r.includes(`tier_insufficient`)?{ok:!0,detail:{gated:`tier_insufficient`}}:/upgrade_required|tier_required/.test(r)?{ok:!0,detail:{gated:`legacy-or-transitional`}}:/"code":\s*"forbidden"/.test(r)&&/tier|upgrade|plan/i.test(r)?{ok:!0,detail:{gated:`forbidden+tier-message`}}:n===0&&!/"type"\s*:\s*"error"/.test(r)?{ok:!0,detail:{gated:`pass-through (Pro+ access)`}}:{ok:!1,reason:`gate did not behave as expected (no tier envelope and no clean pass-through)`}},dev:!0},{name:`stack-leak.bad-net`,category:`SECURITY`,command:[`analytics`,`--json`],assert:(e,t,n)=>{let r=e+t;return/\/Users\//.test(r)||/node:internal\//.test(r)?{ok:!1,reason:`stack trace leaked filesystem path`}:{ok:!0}},quick:!0},{name:`token-perms`,category:`SECURITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{stat:e}=await import(`node:fs/promises`),t=await import(`node:path`),n=process.env.HOME??process.env.USERPROFILE??``,r=process.env.XDG_CONFIG_HOME??t.join(n,`.config`),i=process.platform===`win32`?t.join(process.env.APPDATA??t.join(n,`AppData`,`Roaming`),`zenovay`,`auth.json`):t.join(r,`zenovay`,`auth.json`);try{let t=await e(i);if(process.platform===`win32`)return{ok:!0,detail:{mode:`win32-skip`}};let n=t.mode&511;return n===384?{ok:!0,detail:{mode:`0600`}}:{ok:!1,reason:`auth.json mode ${n.toString(8)} != 0600`}}catch(e){let t=e.code;return t===`ENOENT`?{ok:!0,detail:{mode:`no-auth-file`}}:{ok:!1,reason:e.message}}},quick:!0},{name:`secret-scrub`,category:`SECURITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{SECRET_PATTERNS:e,scrubSecrets:t}=await import(`./secrets-c-NB_plk.js`),n=[{name:`openai-proj`,sample:`sk-proj-abcdefghijklmnopqrstuvwxyz0123456789`},{name:`anthropic`,sample:`sk-ant-abcdefghijklmnopqrstuvwxyz0123456789`},{name:`openai-sk`,sample:`sk-abcdefghijklmnopqrstuvwxyz0123`},{name:`github-pat-new`,sample:`github_pat_`+`a`.repeat(82)},{name:`github-pat`,sample:`ghp_`+`a`.repeat(36)},{name:`github-oauth`,sample:`gho_`+`a`.repeat(36)},{name:`aws-access-key`,sample:`AKIAABCDEFGHIJKLMNOP`},{name:`stripe-live`,sample:`sk_live_`+`a`.repeat(28)},{name:`stripe-test`,sample:`pk_test_`+`a`.repeat(28)},{name:`stripe-restricted`,sample:`rk_live_`+`a`.repeat(28)},{name:`stripe-webhook`,sample:`whsec_`+`a`.repeat(28)},{name:`slack-bot`,sample:`xoxb-1234567890-abcdef`},{name:`google-api`,sample:`AIza`+`a`.repeat(35)},{name:`jwt`,sample:`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTYifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`},{name:`private-key-rsa`,sample:`-----BEGIN RSA PRIVATE KEY-----`},{name:`private-key-pkcs8`,sample:`-----BEGIN PRIVATE KEY-----`},{name:`supabase-jwt`,sample:`eyJhbGciOi`+`a`.repeat(40)},{name:`resend-api`,sample:`re_`+`a`.repeat(20)},{name:`gitlab-pat`,sample:`glpat-`+`a`.repeat(20)},{name:`shopify`,sample:`shpat_`+`a`.repeat(32)},{name:`service-role-key`,sample:`service_role: "`+`a`.repeat(40)+`"`}],r=n.map(e=>`${e.name}=${e.sample}`).join(`
3
3
  `),i=t(r),a=n.filter(e=>i.includes(`[REDACTED:${e.name}]`)).length,o=e.length,s=Math.max(18,o-4);return a>=s?{ok:!0,detail:{matched:a,total:o}}:{ok:!1,reason:`${a}/${o} patterns redacted (need >= ${s})`}},quick:!0},{name:`help-line-count`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=e.split(`
4
- `).length;return r<90?{ok:!0,detail:{lines:r}}:{ok:!1,reason:`${r} lines (target < 90)`}},dev:!0},{name:`help-no-wave-markers`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=/\b(?:Wave\s*\d|W\d|V2\.1)\b/i,i=e.match(r);return i?{ok:!1,reason:`found marker: ${i[0]}`}:{ok:!0}},dev:!0},{name:`help-has-groups`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=[`ANALYTICS`,`BEHAVIOR`,`MANAGE`,`ACCOUNT`,`OPERATIONS`],i=r.filter(t=>!e.includes(t));return i.length===0?{ok:!0,detail:{found:r}}:{ok:!1,reason:`missing groups: ${i.join(`, `)}`}},dev:!0},{name:`examples-coverage`,category:`DISCOVERABILITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{EXAMPLES:e}=await import(`./examples-CFatZcPz.js`),t=Object.keys(e).length;return t>=25?{ok:!0,detail:{commands:t}}:{ok:!1,reason:`${t} commands have examples (need >= 25)`}},dev:!0},{name:`envelope-shape`,category:`DISCOVERABILITY`,command:[`commands`,`--json`],assert:(e,t,n)=>{if(n!==0)return{ok:!1,reason:`exit ${n}`};let r=u(e);if(!r.ok)return{ok:!1,reason:r.reason};let i=r.value,a=typeof i.version==`string`&&Array.isArray(i.commands);return a?{ok:!0,detail:{commands:i.commands.length}}:{ok:!1,reason:`commands payload missing version+commands`}},dev:!0}],h=m.length;async function g(e){let t=process.argv[1]??process.execPath,n=!!e.full||process.env.ZENOVAY_SELF_TEST_FULL===`1`,r=m.filter(e=>n||!e.dev);e.quick&&(r=r.filter(e=>e.quick));let i=await l(e.cliVersion);return e.json?_({...e,binPath:t,env:i,catalog:r}):b({...e,binPath:t,env:i,catalog:r})}async function _(e){let t=await c(e.catalog,{binPath:e.binPath,quick:e.quick??!1,verbose:e.verbose??!1,parallel:e.parallel,env:e.env,onResult:e=>{let t={type:`self-test.result`,name:e.name,category:e.category,status:e.status,durationMs:e.durationMs,...e.detail?{detail:e.detail}:{},...e.reason?{reason:e.reason}:{},...e.rawStdout?{rawStdout:e.rawStdout}:{},...e.rawStderr?{rawStderr:e.rawStderr}:{}};process.stdout.write(`${JSON.stringify(t)}\n`)}});return process.stdout.write(`${JSON.stringify({type:`self-test.summary`,total:t.total,pass:t.pass,fail:t.fail,skip:t.skip,durationMs:t.durationMs,cliVersion:e.cliVersion,env:e.env})}\n`),t.fail>0?1:0}const v=26,y=8;async function b(e){S(e.cliVersion,e.quick??!1,e.catalog.length);let t=new Map,n=0,r=null,i=new Map;for(let t of e.catalog)i.set(t.category,(i.get(t.category)??0)+1);let a=await c(e.catalog,{binPath:e.binPath,quick:e.quick??!1,verbose:e.verbose??!1,parallel:e.parallel,env:e.env,onResult:a=>{for(t.set(a.name,a);n<e.catalog.length;){let a=e.catalog[n];if(!a)break;let o=t.get(a.name);if(!o)break;r!==a.category&&(C(a.category,i.get(a.category)??0),r=a.category),w(a,o),t.delete(a.name),n+=1}}});return T(a),a.fail>0?1:0}function x(){return Math.max(60,process.stdout.columns??80)}function S(e,n,r){let i=Math.min(120,x()),a=i-2,o=`ZENOVAY · v${e}`,s=`self-test · ${n?`quick`:`full`} · ${r} test${r===1?``:`s`}`,c=`╭─ `+o+` `+`─`.repeat(Math.max(0,a-o.length-4))+`╮`,l=`│ `+s+` `.repeat(Math.max(0,a-s.length-2))+`│`,u=`╰`+`─`.repeat(a)+`╯`;process.stdout.write(t.cyan(c)+`
4
+ `).length;return r<90?{ok:!0,detail:{lines:r}}:{ok:!1,reason:`${r} lines (target < 90)`}},dev:!0},{name:`help-no-wave-markers`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=/\b(?:Wave\s*\d|W\d|V2\.1)\b/i,i=e.match(r);return i?{ok:!1,reason:`found marker: ${i[0]}`}:{ok:!0}},dev:!0},{name:`help-has-groups`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=[`ANALYTICS`,`BEHAVIOR`,`MANAGE`,`ACCOUNT`,`OPERATIONS`],i=r.filter(t=>!e.includes(t));return i.length===0?{ok:!0,detail:{found:r}}:{ok:!1,reason:`missing groups: ${i.join(`, `)}`}},dev:!0},{name:`examples-coverage`,category:`DISCOVERABILITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{EXAMPLES:e}=await import(`./examples-CwchsLMN.js`),t=Object.keys(e).length;return t>=25?{ok:!0,detail:{commands:t}}:{ok:!1,reason:`${t} commands have examples (need >= 25)`}},dev:!0},{name:`envelope-shape`,category:`DISCOVERABILITY`,command:[`commands`,`--json`],assert:(e,t,n)=>{if(n!==0)return{ok:!1,reason:`exit ${n}`};let r=u(e);if(!r.ok)return{ok:!1,reason:r.reason};let i=r.value,a=typeof i.version==`string`&&Array.isArray(i.commands);return a?{ok:!0,detail:{commands:i.commands.length}}:{ok:!1,reason:`commands payload missing version+commands`}},dev:!0}],h=m.length;async function g(e){let t=process.argv[1]??process.execPath,n=!!e.full||process.env.ZENOVAY_SELF_TEST_FULL===`1`,r=m.filter(e=>n||!e.dev);e.quick&&(r=r.filter(e=>e.quick));let i=await l(e.cliVersion);return e.json?_({...e,binPath:t,env:i,catalog:r}):b({...e,binPath:t,env:i,catalog:r})}async function _(e){let t=await c(e.catalog,{binPath:e.binPath,quick:e.quick??!1,verbose:e.verbose??!1,parallel:e.parallel,env:e.env,onResult:e=>{let t={type:`self-test.result`,name:e.name,category:e.category,status:e.status,durationMs:e.durationMs,...e.detail?{detail:e.detail}:{},...e.reason?{reason:e.reason}:{},...e.rawStdout?{rawStdout:e.rawStdout}:{},...e.rawStderr?{rawStderr:e.rawStderr}:{}};process.stdout.write(`${JSON.stringify(t)}\n`)}});return process.stdout.write(`${JSON.stringify({type:`self-test.summary`,total:t.total,pass:t.pass,fail:t.fail,skip:t.skip,durationMs:t.durationMs,cliVersion:e.cliVersion,env:e.env})}\n`),t.fail>0?1:0}const v=26,y=8;async function b(e){S(e.cliVersion,e.quick??!1,e.catalog.length);let t=new Map,n=0,r=null,i=new Map;for(let t of e.catalog)i.set(t.category,(i.get(t.category)??0)+1);let a=await c(e.catalog,{binPath:e.binPath,quick:e.quick??!1,verbose:e.verbose??!1,parallel:e.parallel,env:e.env,onResult:a=>{for(t.set(a.name,a);n<e.catalog.length;){let a=e.catalog[n];if(!a)break;let o=t.get(a.name);if(!o)break;r!==a.category&&(C(a.category,i.get(a.category)??0),r=a.category),w(a,o),t.delete(a.name),n+=1}}});return T(a),a.fail>0?1:0}function x(){return Math.max(60,process.stdout.columns??80)}function S(e,n,r){let i=Math.min(120,x()),a=i-2,o=`ZENOVAY · v${e}`,s=`self-test · ${n?`quick`:`full`} · ${r} test${r===1?``:`s`}`,c=`╭─ `+o+` `+`─`.repeat(Math.max(0,a-o.length-4))+`╮`,l=`│ `+s+` `.repeat(Math.max(0,a-s.length-2))+`│`,u=`╰`+`─`.repeat(a)+`╯`;process.stdout.write(t.cyan(c)+`
5
5
  `),process.stdout.write(t.cyan(l)+`
6
6
  `),process.stdout.write(t.cyan(u)+`
7
7
 
@@ -1 +1 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{requireTier as r}from"./tier-DST3Yt2-.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import{resolveSiteId as l}from"./resolve-site-DSJR9vuz.js";import{DataTable as u}from"./data-table-BpbyyNSA.js";import{EmptyState as d}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as f,openInBrowser as p}from"./keybar-deep-link-C9xNYihD.js";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";function C(e){if(!e||e<=0)return`—`;let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return`${n}m ${(t%60).toString().padStart(2,`0`)}s`}function w(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.max(0,Math.floor((Date.now()-t)/1e3));return n<60?`${n}s`:n<3600?`${Math.floor(n/60)}m`:n<86400?`${Math.floor(n/3600)}h`:`${Math.floor(n/86400)}d`}async function T(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getSessions(d);return i({type:`sessions.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const E=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=_(),[l,g]=x(null),[T,E]=x(!0),[D,O]=x(null);if(v(e=>{if(e===`o`||e===`O`){p(f(`sessions`,{siteId:t}));return}e===`q`&&(a(),i(0))}),b(()=>{let n=!1;return(async()=>{try{let r=await e.getSessions(t);n||(g(r),E(!1))}catch(e){n||(O(e.message),E(!1))}})(),()=>{n=!0}},[e,t]),T)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(o,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching sessions…`))));if(D)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(d,{reason:`error`,headline:`Failed to load`,hint:D}));if(!l||l.length===0)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(d,{reason:`no-data`,headline:`No replays yet`,hint:`Enable session replay in your site settings`}));let k=[{key:`id`,label:`session id`,width:24},{key:`visitor`,label:`visitor`,width:18},{key:`duration`,label:`duration`,align:`right`,width:9,format:e=>C(e)},{key:`startedAt`,label:`when`,align:`right`,width:6,format:e=>w(String(e))},{key:`pageCount`,label:`events`,align:`right`,width:7},{key:`deviceType`,label:`device`,width:8,format:e=>String(e??`—`)}];return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(o,{title:`Recent sessions (${l.length})`},y.createElement(u,{columns:k,data:l,zebra:!0})),y.createElement(m,{marginTop:1},y.createElement(h,{color:`gray`},`Open any session for replay at https://app.zenovay.com/replay`)),y.createElement(c,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{T as sessionsCommand};
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{requireTier as r}from"./tier-DST3Yt2-.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import{resolveSiteId as l}from"./resolve-site-DSJR9vuz.js";import{DataTable as u}from"./data-table-BpbyyNSA.js";import{EmptyState as d}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as f,openInBrowser as p}from"./keybar-deep-link-DC31T3CP.js";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";function C(e){if(!e||e<=0)return`—`;let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return`${n}m ${(t%60).toString().padStart(2,`0`)}s`}function w(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.max(0,Math.floor((Date.now()-t)/1e3));return n<60?`${n}s`:n<3600?`${Math.floor(n/60)}m`:n<86400?`${Math.floor(n/3600)}h`:`${Math.floor(n/86400)}d`}async function T(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getSessions(d);return i({type:`sessions.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const E=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=_(),[l,g]=x(null),[T,E]=x(!0),[D,O]=x(null);if(v(e=>{if(e===`o`||e===`O`){p(f(`sessions`,{siteId:t}));return}e===`q`&&(a(),i(0))}),b(()=>{let n=!1;return(async()=>{try{let r=await e.getSessions(t);n||(g(r),E(!1))}catch(e){n||(O(e.message),E(!1))}})(),()=>{n=!0}},[e,t]),T)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(o,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching sessions…`))));if(D)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(d,{reason:`error`,headline:`Failed to load`,hint:D}));if(!l||l.length===0)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(d,{reason:`no-data`,headline:`No replays yet`,hint:`Enable session replay in your site settings`}));let k=[{key:`id`,label:`session id`,width:24},{key:`visitor`,label:`visitor`,width:18},{key:`duration`,label:`duration`,align:`right`,width:9,format:e=>C(e)},{key:`startedAt`,label:`when`,align:`right`,width:6,format:e=>w(String(e))},{key:`pageCount`,label:`events`,align:`right`,width:7},{key:`deviceType`,label:`device`,width:8,format:e=>String(e??`—`)}];return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(o,{title:`Recent sessions (${l.length})`},y.createElement(u,{columns:k,data:l,zebra:!0})),y.createElement(m,{marginTop:1},y.createElement(h,{color:`gray`},`Open any session for replay at https://app.zenovay.com/replay`)),y.createElement(c,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{T as sessionsCommand};
@@ -1,2 +1,2 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as a}from"./resolve-site-DSJR9vuz.js";import{DataTable as o}from"./data-table-BpbyyNSA.js";import{deepLinkFor as s,openInBrowser as c}from"./keybar-deep-link-C9xNYihD.js";import{runAnalyticalScreen as l}from"./analytical-screen-nJlxAocC.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){let n=Math.round(e/100*t);return`█`.repeat(n)+`░`.repeat(Math.max(0,t-n))}function m(e){return e==null?{glyph:`·`,color:`gray`}:e>.5?{glyph:`▲`,color:`green`}:e<-.5?{glyph:`▼`,color:`red`}:{glyph:`→`,color:`gray`}}async function h(h){let g=await e(),_=await t({strict:!1}),v=new n({config:g,cliVersion:h.cliVersion,token:_}),y,b;try{({siteId:y,site:b}=await a(v,{explicit:h.siteId,headless:!!(h.json||h.csv||h.tsv||h.ndjson),cliVersion:h.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let x=i(h),S=h.period??`30d`,C=[{key:`source`,label:`source`,width:22},{key:`channel`,label:`channel`,width:10,format:e=>String(e??`—`)},{key:`visitors`,label:`visitors`,width:8,align:`right`},{key:`delta`,label:`Δ`,width:6,align:`right`,format:e=>typeof e==`number`?`${e>0?`+`:``}${(e*100).toFixed(1)}%`:`—`}];return l({cliVersion:h.cliVersion,title:`sources · ${y} · ${S}`,commandName:`sources`,authToken:_?.accessToken??null,refreshIntervalMs:6e4,fetcher:e=>v.getSources(y,S,h.compare,e),format:x,ai:{api:v,siteId:y,siteLabel:b?.url?b.url.replace(/^https?:\/\//,``).replace(/\/$/,``):b?.name??y},keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`sources`,{siteId:y}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as a}from"./resolve-site-DSJR9vuz.js";import{DataTable as o}from"./data-table-BpbyyNSA.js";import{deepLinkFor as s,openInBrowser as c}from"./keybar-deep-link-DC31T3CP.js";import{runAnalyticalScreen as l}from"./analytical-screen-CRn5UoFi.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){let n=Math.round(e/100*t);return`█`.repeat(n)+`░`.repeat(Math.max(0,t-n))}function m(e){return e==null?{glyph:`·`,color:`gray`}:e>.5?{glyph:`▲`,color:`green`}:e<-.5?{glyph:`▼`,color:`red`}:{glyph:`→`,color:`gray`}}async function h(h){let g=await e(),_=await t({strict:!1}),v=new n({config:g,cliVersion:h.cliVersion,token:_}),y,b;try{({siteId:y,site:b}=await a(v,{explicit:h.siteId,headless:!!(h.json||h.csv||h.tsv||h.ndjson),cliVersion:h.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let x=i(h),S=h.period??`30d`,C=[{key:`source`,label:`source`,width:22},{key:`channel`,label:`channel`,width:10,format:e=>String(e??`—`)},{key:`visitors`,label:`visitors`,width:8,align:`right`},{key:`delta`,label:`Δ`,width:6,align:`right`,format:e=>typeof e==`number`?`${e>0?`+`:``}${(e*100).toFixed(1)}%`:`—`}];return l({cliVersion:h.cliVersion,title:`sources · ${y} · ${S}`,commandName:`sources`,authToken:_?.accessToken??null,refreshIntervalMs:6e4,fetcher:e=>v.getSources(y,S,h.compare,e),format:x,ai:{api:v,siteId:y,siteLabel:b?.url?b.url.replace(/^https?:\/\//,``).replace(/\/$/,``):b?.name??y},keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`sources`,{siteId:y}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
2
  `);return}process.stdout.write(r(e.sources,[`source`,`channel`,`visitors`,`conversions`,`revenue`,`delta`],t))},panels:[{id:`summary`,title:`Total`,render:e=>f.createElement(d,null,f.createElement(d,{bold:!0},e.totalVisitors.toLocaleString()),` `,f.createElement(d,{color:`gray`},`visitors · `,e.sources.length,` sources`))},{id:`channels`,title:`By channel`,render:e=>{if(e.sources.length===0)return f.createElement(d,{color:`gray`},`— no source data —`);let t=e.totalVisitors||1,n=[...e.sources].sort((e,t)=>t.visitors-e.visitors).slice(0,12);return f.createElement(u,{flexDirection:`column`},n.map((e,n)=>{let r=e.visitors/t*100,i=m(e.delta);return f.createElement(u,{key:`${e.source}-${n}`},f.createElement(d,null,f.createElement(d,{color:`cyan`},e.source.padEnd(20).slice(0,20)),` `,f.createElement(d,{color:`magenta`},p(r,30)),` `,f.createElement(d,null,e.visitors.toString().padStart(6),` `),f.createElement(d,{color:`gray`},`(`,r.toFixed(1),`%)`),` `,f.createElement(d,{color:i.color},i.glyph)))}))}},{id:`table`,title:`Detail`,render:e=>e.sources.length===0?f.createElement(d,{color:`gray`},`— —`):f.createElement(o,{data:e.sources.slice(0,20),columns:C,headerStyle:`accent`})}]})}export{h as sourcesCommand};
@@ -1,2 +1,2 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as a}from"./resolve-site-DSJR9vuz.js";import{DataTable as o}from"./data-table-BpbyyNSA.js";import{runAnalyticalScreen as s}from"./analytical-screen-nJlxAocC.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){return`${(e*100).toFixed(1)}%`}function f(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.floor(e/60)}m ${Math.round(e%60)}s`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(p),b=p.range??`24h`,x=[{key:`url`,label:`page`,width:40,format:e=>String(e??`—`)},{key:`views`,label:`views`,width:8,align:`right`}],S=[{key:`country`,label:`country`,width:8},{key:`visitors`,label:`visitors`,width:8,align:`right`}];return s({cliVersion:p.cliVersion,title:`stats · ${_} · ${b}`,commandName:`stats`,ai:{api:g,siteId:_,siteLabel:v?.url?v.url.replace(/^https?:\/\//,``).replace(/\/$/,``):v?.name??_},authToken:h?.accessToken??null,refreshIntervalMs:p.watch?6e4:0,fetcher:e=>g.getStats(_,b,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as a}from"./resolve-site-DSJR9vuz.js";import{DataTable as o}from"./data-table-BpbyyNSA.js";import{runAnalyticalScreen as s}from"./analytical-screen-CRn5UoFi.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){return`${(e*100).toFixed(1)}%`}function f(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.floor(e/60)}m ${Math.round(e%60)}s`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(p),b=p.range??`24h`,x=[{key:`url`,label:`page`,width:40,format:e=>String(e??`—`)},{key:`views`,label:`views`,width:8,align:`right`}],S=[{key:`country`,label:`country`,width:8},{key:`visitors`,label:`visitors`,width:8,align:`right`}];return s({cliVersion:p.cliVersion,title:`stats · ${_} · ${b}`,commandName:`stats`,ai:{api:g,siteId:_,siteLabel:v?.url?v.url.replace(/^https?:\/\//,``).replace(/\/$/,``):v?.name??_},authToken:h?.accessToken??null,refreshIntervalMs:p.watch?6e4:0,fetcher:e=>g.getStats(_,b,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
2
  `);return}process.stdout.write(r([{range:b,visitors:e.visitors,pageviews:e.pageviews,sessions:e.sessions,bounceRate:d(e.bounceRate),avgSession:f(e.avgSessionSec)}],[`range`,`visitors`,`pageviews`,`sessions`,`bounceRate`,`avgSession`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.visitors.toLocaleString()),u.createElement(l,{color:`gray`},` visitors `),u.createElement(l,{bold:!0},e.pageviews.toLocaleString()),u.createElement(l,{color:`gray`},` pageviews `),u.createElement(l,{bold:!0},e.sessions.toLocaleString()),u.createElement(l,{color:`gray`},` sessions`)),u.createElement(l,{color:`gray`},`bounce `,d(e.bounceRate),` · avg session `,f(e.avgSessionSec)))},{id:`pages`,title:`Top pages`,render:e=>e.topPages.length===0?u.createElement(l,{color:`gray`},`— no pages —`):u.createElement(o,{data:e.topPages.slice(0,10),columns:x,headerStyle:`accent`})},{id:`countries`,title:`Top countries`,render:e=>e.topCountries.length===0?u.createElement(l,{color:`gray`},`— no country data —`):u.createElement(o,{data:e.topCountries.slice(0,10),columns:S,headerStyle:`accent`})}]})}export{p as statsCommand};
@@ -1,4 +1,4 @@
1
- import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./panel-B_yDcIcn.js";import{Banner as a}from"./banner-3iSWTDFy.js";import"./progress-row-BpAXjJPL.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./sparkline-BZ0eMB-w.js";import"./data-table-BpbyyNSA.js";import"./bar-DWT-1xOE.js";import"./ui-DzoMR7th.js";import{promises as o}from"node:fs";import{Box as s,Text as c,render as l}from"ink";import u from"react";const d=[{name:`mocha`,theme:n,mode:`dark`},{name:`latte`,theme:t,mode:`light`},{name:`dracula`,theme:e,mode:`dark`},{name:`tokyoNight`,theme:i,mode:`dark`},{name:`nord`,theme:r,mode:`dark`}],f=[`name`,`bg`,`fg`,`muted`,`accent`,`accent2`,`success`,`warn`,`error`,`border`,`dim`];function p({name:e,theme:t,mode:n}){let r=[t.accent,t.accent2,t.success,t.warn,t.error];return u.createElement(s,{flexDirection:`row`},u.createElement(c,{bold:!0},e.padEnd(14)),u.createElement(c,{color:`gray`},n.padEnd(7)),r.map((e,t)=>u.createElement(c,{key:t,color:e},`████`,` `)),u.createElement(c,{color:`gray`},t.bg))}function m({themes:e}){return u.createElement(s,{flexDirection:`column`},u.createElement(a,{version:`themes`}),u.createElement(s,{marginTop:1,marginBottom:1},u.createElement(c,{color:`gray`},e.length,` themes — pass --theme <name> to any command, or set in your config.`)),u.createElement(s,{flexDirection:`column`},u.createElement(s,null,u.createElement(c,{bold:!0},`name`.padEnd(14)),u.createElement(c,{bold:!0},`mode`.padEnd(7)),u.createElement(c,{bold:!0},`swatch`.padEnd(28)),u.createElement(c,{bold:!0},`bg`)),e.map(({name:e,theme:t,mode:n})=>u.createElement(p,{key:e,name:e,theme:t,mode:n}))))}async function h(e){if(e.validate){let t;try{let n=await o.readFile(e.validate,`utf8`);t=JSON.parse(n)}catch(t){return process.stderr.write(`✗ Failed to read ${e.validate}: ${t.message}\n`),1}let n=f.filter(e=>t[e]==null);return n.length>0?(process.stderr.write(`✗ Missing required tokens: ${n.join(`, `)}\n`),e.json&&process.stdout.write(JSON.stringify({ok:!1,missing:n},null,2)+`
1
+ import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./panel-B_yDcIcn.js";import{Banner as a}from"./banner-3iSWTDFy.js";import"./progress-row-BpAXjJPL.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./sparkline-BZ0eMB-w.js";import"./data-table-BpbyyNSA.js";import"./bar-DWT-1xOE.js";import"./ui-Cey-h6wI.js";import{promises as o}from"node:fs";import{Box as s,Text as c,render as l}from"ink";import u from"react";const d=[{name:`mocha`,theme:n,mode:`dark`},{name:`latte`,theme:t,mode:`light`},{name:`dracula`,theme:e,mode:`dark`},{name:`tokyoNight`,theme:i,mode:`dark`},{name:`nord`,theme:r,mode:`dark`}],f=[`name`,`bg`,`fg`,`muted`,`accent`,`accent2`,`success`,`warn`,`error`,`border`,`dim`];function p({name:e,theme:t,mode:n}){let r=[t.accent,t.accent2,t.success,t.warn,t.error];return u.createElement(s,{flexDirection:`row`},u.createElement(c,{bold:!0},e.padEnd(14)),u.createElement(c,{color:`gray`},n.padEnd(7)),r.map((e,t)=>u.createElement(c,{key:t,color:e},`████`,` `)),u.createElement(c,{color:`gray`},t.bg))}function m({themes:e}){return u.createElement(s,{flexDirection:`column`},u.createElement(a,{version:`themes`}),u.createElement(s,{marginTop:1,marginBottom:1},u.createElement(c,{color:`gray`},e.length,` themes — pass --theme <name> to any command, or set in your config.`)),u.createElement(s,{flexDirection:`column`},u.createElement(s,null,u.createElement(c,{bold:!0},`name`.padEnd(14)),u.createElement(c,{bold:!0},`mode`.padEnd(7)),u.createElement(c,{bold:!0},`swatch`.padEnd(28)),u.createElement(c,{bold:!0},`bg`)),e.map(({name:e,theme:t,mode:n})=>u.createElement(p,{key:e,name:e,theme:t,mode:n}))))}async function h(e){if(e.validate){let t;try{let n=await o.readFile(e.validate,`utf8`);t=JSON.parse(n)}catch(t){return process.stderr.write(`✗ Failed to read ${e.validate}: ${t.message}\n`),1}let n=f.filter(e=>t[e]==null);return n.length>0?(process.stderr.write(`✗ Missing required tokens: ${n.join(`, `)}\n`),e.json&&process.stdout.write(JSON.stringify({ok:!1,missing:n},null,2)+`
2
2
  `),1):(process.stdout.write(`✔ Valid theme (${f.length} tokens present).\n`),e.json&&process.stdout.write(JSON.stringify({ok:!0,theme:t},null,2)+`
3
3
  `),0)}if(e.json)return process.stdout.write(JSON.stringify({themes:d.map(({name:e,theme:t,mode:n})=>({name:e,mode:n,background:t.bg,foreground:t.fg,accent:t.accent}))},null,2)+`
4
4
  `),0;let{waitUntilExit:t}=l(u.createElement(m,{themes:d}));return await t(),0}export{h as themesCommand};
@@ -1 +1 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{requireTier as r}from"./tier-DST3Yt2-.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import{resolveSiteId as l}from"./resolve-site-DSJR9vuz.js";import{DataTable as u}from"./data-table-BpbyyNSA.js";import{EmptyState as d}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as f,openInBrowser as p}from"./keybar-deep-link-C9xNYihD.js";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";function C(e){return e===`up`?{glyph:`● up`,color:`green`}:e===`down`?{glyph:`● down`,color:`red`}:{glyph:`○ unknown`,color:`gray`}}function w(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.round((t-Date.now())/(1e3*60*60*24));return`${n}d`}async function T(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getUptime(d);return i({type:`uptime.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const E=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=_(),[l,g]=x(null),[T,E]=x(!0),[D,O]=x(null);if(v(e=>{if(e===`o`||e===`O`){p(f(`uptime`,{siteId:t}));return}e===`q`&&(a(),i(0))}),b(()=>{let n=!1;return(async()=>{try{let r=await e.getUptime(t);n||(g(r.monitors),E(!1))}catch(e){n||(O(e.message),E(!1))}})(),()=>{n=!0}},[e,t]),T)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(o,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching monitors…`))));if(D)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(d,{reason:`error`,headline:`Failed to load`,hint:D}));if(!l||l.length===0)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(d,{reason:`no-data`,headline:`No monitors configured`,hint:`Add one at app.zenovay.com/uptime`}));let k=[{key:`url`,label:`monitor`,width:36},{key:`status`,label:`status`,width:12,format:e=>C(String(e)).glyph},{key:`p95ms`,label:`p95 ms`,align:`right`,width:8,format:e=>typeof e==`number`?String(e):`—`},{key:`sslExpiry`,label:`ssl exp`,align:`right`,width:7,format:e=>w(e)}];return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(o,{title:`Monitors (${l.length})`},y.createElement(u,{columns:k,data:l,zebra:!0})),y.createElement(c,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{T as uptimeCommand};
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{requireTier as r}from"./tier-DST3Yt2-.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import{resolveSiteId as l}from"./resolve-site-DSJR9vuz.js";import{DataTable as u}from"./data-table-BpbyyNSA.js";import{EmptyState as d}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as f,openInBrowser as p}from"./keybar-deep-link-DC31T3CP.js";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";function C(e){return e===`up`?{glyph:`● up`,color:`green`}:e===`down`?{glyph:`● down`,color:`red`}:{glyph:`○ unknown`,color:`gray`}}function w(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.round((t-Date.now())/(1e3*60*60*24));return`${n}d`}async function T(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getUptime(d);return i({type:`uptime.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const E=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=_(),[l,g]=x(null),[T,E]=x(!0),[D,O]=x(null);if(v(e=>{if(e===`o`||e===`O`){p(f(`uptime`,{siteId:t}));return}e===`q`&&(a(),i(0))}),b(()=>{let n=!1;return(async()=>{try{let r=await e.getUptime(t);n||(g(r.monitors),E(!1))}catch(e){n||(O(e.message),E(!1))}})(),()=>{n=!0}},[e,t]),T)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(o,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching monitors…`))));if(D)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(d,{reason:`error`,headline:`Failed to load`,hint:D}));if(!l||l.length===0)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(d,{reason:`no-data`,headline:`No monitors configured`,hint:`Add one at app.zenovay.com/uptime`}));let k=[{key:`url`,label:`monitor`,width:36},{key:`status`,label:`status`,width:12,format:e=>C(String(e)).glyph},{key:`p95ms`,label:`p95 ms`,align:`right`,width:8,format:e=>typeof e==`number`?String(e):`—`},{key:`sslExpiry`,label:`ssl exp`,align:`right`,width:7,format:e=>w(e)}];return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(o,{title:`Monitors (${l.length})`},y.createElement(u,{columns:k,data:l,zebra:!0})),y.createElement(c,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{T as uptimeCommand};
@@ -1,2 +1,2 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import{brailleSpark as a,spark as o}from"./sparkline-BZ0eMB-w.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as s}from"./resolve-site-DSJR9vuz.js";import{DataTable as c}from"./data-table-BpbyyNSA.js";import{deepLinkFor as l,openInBrowser as u}from"./keybar-deep-link-C9xNYihD.js";import{runAnalyticalScreen as d}from"./analytical-screen-nJlxAocC.js";import{Box as f,Text as p}from"ink";import m from"react";function h(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function g(e){let t=e,n=t.events??t.timeseries;return Array.isArray(n)&&n.length>0?o(n,8):`▁▁▁▁▁▁▁▁`}function _(e){let t=e;if(typeof t.sessionDurationSec==`number`)return t.sessionDurationSec;if(typeof t.sessionDurationMs==`number`)return Math.floor(t.sessionDurationMs/1e3);if(typeof t.durationMs==`number`)return Math.floor(t.durationMs/1e3);if(typeof t.duration==`number`)return Math.floor(t.duration/1e3);let n=Date.parse(e.startedAt);return Number.isNaN(n)?0:Math.max(0,Math.floor((Date.now()-n)/1e3))}async function v(o){let v=await e(),y=await t({strict:!1}),b=new n({config:v,cliVersion:o.cliVersion,token:y}),x,S;try{({siteId:x,site:S}=await s(b,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let C=i(o),w=o.limit??50,T=typeof o.minDuration==`number`&&o.minDuration>0?o.minDuration:0,E=e=>T<=0?e:e.filter(e=>_(e)>=T),D=6e4,O=e=>{let t=Date.parse(e.startedAt);return Number.isFinite(t)&&Date.now()-t<D},k=[{key:`startedAt`,label:``,width:5,format:(e,t)=>O(t)?`● new`:``},{key:`startedAt`,label:`when`,width:6,format:e=>h(String(e))},{key:`country`,label:`country`,width:7,format:e=>String(e??`—`)},{key:`city`,label:`city`,width:14,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`page`,label:`page`,width:26,format:e=>String(e??`—`)},{key:`id`,label:`24h`,width:8,format:(e,t)=>g(t)}];return d({cliVersion:o.cliVersion,title:`visitors · ${x}`,commandName:`visitors`,ai:{api:b,siteId:x,siteLabel:S?.url?S.url.replace(/^https?:\/\//,``).replace(/\/$/,``):S?.name??x},authToken:y?.accessToken??null,refreshIntervalMs:1e4,fetcher:e=>b.getVisitors(x,{limit:w},e),format:C,keybindings:{o:{label:`open in browser`,handler:()=>{u(l(`visitors`,{siteId:x}))}}},headlessEmit:(e,t)=>{let n={...e,visitors:E(e.visitors)};if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(n,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import{brailleSpark as a,spark as o}from"./sparkline-BZ0eMB-w.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as s}from"./resolve-site-DSJR9vuz.js";import{DataTable as c}from"./data-table-BpbyyNSA.js";import{deepLinkFor as l,openInBrowser as u}from"./keybar-deep-link-DC31T3CP.js";import{runAnalyticalScreen as d}from"./analytical-screen-CRn5UoFi.js";import{Box as f,Text as p}from"ink";import m from"react";function h(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function g(e){let t=e,n=t.events??t.timeseries;return Array.isArray(n)&&n.length>0?o(n,8):`▁▁▁▁▁▁▁▁`}function _(e){let t=e;if(typeof t.sessionDurationSec==`number`)return t.sessionDurationSec;if(typeof t.sessionDurationMs==`number`)return Math.floor(t.sessionDurationMs/1e3);if(typeof t.durationMs==`number`)return Math.floor(t.durationMs/1e3);if(typeof t.duration==`number`)return Math.floor(t.duration/1e3);let n=Date.parse(e.startedAt);return Number.isNaN(n)?0:Math.max(0,Math.floor((Date.now()-n)/1e3))}async function v(o){let v=await e(),y=await t({strict:!1}),b=new n({config:v,cliVersion:o.cliVersion,token:y}),x,S;try{({siteId:x,site:S}=await s(b,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let C=i(o),w=o.limit??50,T=typeof o.minDuration==`number`&&o.minDuration>0?o.minDuration:0,E=e=>T<=0?e:e.filter(e=>_(e)>=T),D=6e4,O=e=>{let t=Date.parse(e.startedAt);return Number.isFinite(t)&&Date.now()-t<D},k=[{key:`startedAt`,label:``,width:5,format:(e,t)=>O(t)?`● new`:``},{key:`startedAt`,label:`when`,width:6,format:e=>h(String(e))},{key:`country`,label:`country`,width:7,format:e=>String(e??`—`)},{key:`city`,label:`city`,width:14,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`page`,label:`page`,width:26,format:e=>String(e??`—`)},{key:`id`,label:`24h`,width:8,format:(e,t)=>g(t)}];return d({cliVersion:o.cliVersion,title:`visitors · ${x}`,commandName:`visitors`,ai:{api:b,siteId:x,siteLabel:S?.url?S.url.replace(/^https?:\/\//,``).replace(/\/$/,``):S?.name??x},authToken:y?.accessToken??null,refreshIntervalMs:1e4,fetcher:e=>b.getVisitors(x,{limit:w},e),format:C,keybindings:{o:{label:`open in browser`,handler:()=>{u(l(`visitors`,{siteId:x}))}}},headlessEmit:(e,t)=>{let n={...e,visitors:E(e.visitors)};if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(n,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
2
  `);return}let i=[`startedAt`,`country`,`city`,`device`,`page`];process.stdout.write(r(n.visitors,i,t))},panels:[{id:`live`,title:`Now`,render:e=>{let t=E(e.visitors),n=[...t].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)),r=n[0],i=Array(24*6).fill(0),o=Date.now();for(let e of t){let t=o-new Date(e.startedAt).getTime(),n=Math.floor(t/(10*60*1e3));n>=0&&n<i.length&&(i[i.length-1-n]+=1)}return m.createElement(f,{flexDirection:`column`},m.createElement(p,{bold:!0},t.length,` live`),m.createElement(p,{color:`gray`},a(i,40)),r?m.createElement(p,{color:`gray`},`top: `,r.city??r.country??`—`,` · `,r.page??`—`):null)}},{id:`visitors`,title:`Active sessions`,render:e=>{let t=E(e.visitors),n=[...t].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)).slice(0,w);return n.length===0?m.createElement(p,{color:`gray`},`— no visitors yet —`):m.createElement(c,{columns:k,data:n,headerStyle:`accent`})}}]})}export{v as visitorsCommand};
@@ -1,2 +1,2 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as a}from"./resolve-site-DSJR9vuz.js";import{DataTable as o}from"./data-table-BpbyyNSA.js";import{deepLinkFor as s,openInBrowser as c}from"./keybar-deep-link-C9xNYihD.js";import{runAnalyticalScreen as l}from"./analytical-screen-nJlxAocC.js";import{Box as u,Text as d}from"ink";import f from"react";const p={lcp:{good:2500,poor:4e3},inp:{good:200,poor:500},cls:{good:.1,poor:.25},ttfb:{good:800,poor:1800},fcp:{good:1800,poor:3e3}};function m(e,t){let n=p[e];return t<=n.good?{label:`good`,color:`green`}:t<=n.poor?{label:`needs`,color:`yellow`}:{label:`poor`,color:`red`}}function h(e,t){return e===`cls`?t.toFixed(3):t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`}async function g(p){let g=await e(),_=await t({strict:!1}),v=new n({config:g,cliVersion:p.cliVersion,token:_}),y,b;try{({siteId:y,site:b}=await a(v,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let x=i(p),S=[{key:`url`,label:`url`,width:32},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,label:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`lcp`,e.p75):`—`},{key:`inp`,label:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`inp`,e.p75):`—`},{key:`cls`,label:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`cls`,e.p75):`—`},{key:`samples`,label:`n`,width:6,align:`right`}];return l({cliVersion:p.cliVersion,title:`vitals · ${y}`,commandName:`vitals`,ai:{api:v,siteId:y,siteLabel:b?.url?b.url.replace(/^https?:\/\//,``).replace(/\/$/,``):b?.name??y},authToken:_?.accessToken??null,refreshIntervalMs:p.watch?5*6e4:0,fetcher:e=>v.getVitals(y,{url:p.url,device:p.device,window:p.window},e),format:x,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`vitals`,{siteId:y}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./chat-panel-C_yjPXnw.js";import{resolveSiteId as a}from"./resolve-site-DSJR9vuz.js";import{DataTable as o}from"./data-table-BpbyyNSA.js";import{deepLinkFor as s,openInBrowser as c}from"./keybar-deep-link-DC31T3CP.js";import{runAnalyticalScreen as l}from"./analytical-screen-CRn5UoFi.js";import{Box as u,Text as d}from"ink";import f from"react";const p={lcp:{good:2500,poor:4e3},inp:{good:200,poor:500},cls:{good:.1,poor:.25},ttfb:{good:800,poor:1800},fcp:{good:1800,poor:3e3}};function m(e,t){let n=p[e];return t<=n.good?{label:`good`,color:`green`}:t<=n.poor?{label:`needs`,color:`yellow`}:{label:`poor`,color:`red`}}function h(e,t){return e===`cls`?t.toFixed(3):t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`}async function g(p){let g=await e(),_=await t({strict:!1}),v=new n({config:g,cliVersion:p.cliVersion,token:_}),y,b;try{({siteId:y,site:b}=await a(v,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let x=i(p),S=[{key:`url`,label:`url`,width:32},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,label:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`lcp`,e.p75):`—`},{key:`inp`,label:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`inp`,e.p75):`—`},{key:`cls`,label:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`cls`,e.p75):`—`},{key:`samples`,label:`n`,width:6,align:`right`}];return l({cliVersion:p.cliVersion,title:`vitals · ${y}`,commandName:`vitals`,ai:{api:v,siteId:y,siteLabel:b?.url?b.url.replace(/^https?:\/\//,``).replace(/\/$/,``):b?.name??y},authToken:_?.accessToken??null,refreshIntervalMs:p.watch?5*6e4:0,fetcher:e=>v.getVitals(y,{url:p.url,device:p.device,window:p.window},e),format:x,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`vitals`,{siteId:y}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
2
  `);return}process.stdout.write(r(e.vitals,[`url`,`device`,`samples`],t))},panels:[{id:`summary`,title:`Site-wide p75`,render:e=>{let t=t=>{let n=0,r=0;for(let i of e.vitals){let e=i[t]?.p75;typeof e==`number`&&(n+=e*i.samples,r+=i.samples)}return r>0?n/r:0},n=[`lcp`,`inp`,`cls`,`ttfb`,`fcp`];return f.createElement(u,{flexDirection:`column`},n.map(e=>{let n=t(e),r=m(e,n);return f.createElement(d,{key:e},f.createElement(d,{color:r.color},`● `),f.createElement(d,{bold:!0},e.toUpperCase().padEnd(5)),` `,f.createElement(d,null,h(e,n).padStart(8)),` `,f.createElement(d,{color:r.color},r.label))}))}},{id:`pages`,title:`Per-page`,render:e=>e.vitals.length===0?f.createElement(d,{color:`gray`},`— no vitals data yet —`):f.createElement(o,{data:e.vitals.slice(0,15),columns:S,headerStyle:`accent`})}]})}export{g as vitalsCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{parseSseStream as r}from"./client-DTXWADkX.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import{spark as l}from"./sparkline-BZ0eMB-w.js";import{resolveSiteId as u}from"./resolve-site-DSJR9vuz.js";import{EmptyState as d}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as f,openInBrowser as p}from"./keybar-deep-link-DC31T3CP.js";import{z as m}from"zod";import{Box as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useState as S}from"react";import C from"ink-spinner";import w from"ink-text-input";const T=Math.PI*2;function E(e){let t=e,n=Math.PI*Math.sin(e);for(let e=0;e<6;e++){let e=2*t+Math.sin(2*t)-n,r=2+2*Math.cos(2*t);if(r===0)break;t-=e/r}return t}function D(e,t){if(e<-90||e>90||t<-180||t>180)return null;let n=e*Math.PI/180,r=t*Math.PI/180,i=E(n),a=r*Math.cos(i)/Math.PI,o=Math.sin(i);return{x:a,y:o}}function O(e){if(e)return!0;let t=process.env;if(t.NO_COLOR||t.ZENOVAY_GLOBE===`ascii`)return!0;let n=(t.LANG||t.LC_ALL||t.LC_CTYPE||``).toLowerCase();return!!(n&&!n.includes(`utf`))}function k(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function A(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function j(e){let t=e.dw/2,n=e.dh/2,r=e.dw/2-1,i=e.dh/2-1,a=Math.max(e.dw,e.dh)*2;for(let o=0;o<a;o++){let s=o/a*T,c=Math.round(t+r*Math.cos(s)),l=Math.round(n+i*Math.sin(s));A(e,c,l)}}function M(e){let t=Math.floor(e.dh/2);for(let n=0;n<e.dw;n+=4)A(e,n,t)}function N(e,t){let n=e.dw/2,r=e.dh/2,i=e.dw/2-1,a=e.dh/2-1;for(let o of t){let t=D(o.lat,o.lng);if(!t)continue;let s=Math.round(n+t.x*i),c=Math.round(r-t.y*a);A(e,s,c),A(e,s+1,c),A(e,s,c+1),A(e,s+1,c+1)}}const P=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function F(e,t,n){let r=0;for(let i=0;i<P.length;i++){let[a,o]=P[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function I(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`.`:r<=4?`:`:r<=6?`*`:`#`}function L({data:e,width:t=80,height:n=20,asciiOnly:r}){let i=O(r),a=k(t,n);j(a),M(a),N(a,e);let o=[];for(let e=0;e<n;e++){let n=``;for(let r=0;r<t;r++)n+=i?I(a,r,e):F(a,r,e);o.push(n)}return b.createElement(h,{flexDirection:`column`},o.map((e,t)=>b.createElement(g,{key:t,color:`magenta`},e)),b.createElement(g,{color:`gray`},e.length,` live · `,i?`ascii mode`:`braille mode`))}const R=m.object({siteId:m.string().optional(),window:m.string().optional(),totalVisitors:m.number().optional(),visitors:m.object({count:m.number().optional(),series:m.array(m.number()).optional()}).optional(),topPages:m.array(m.object({path:m.string(),views:m.number().optional(),count:m.number().optional()})).optional(),sources:m.array(m.object({source:m.string(),visitors:m.number()})).optional()}).passthrough();async function z(r){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:r.cliVersion,token:s}),l;try{({siteId:l}=await u(c,{explicit:r.siteId,headless:!!r.json,cliVersion:r.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(a(r)){let e=await c.getDashboardSnapshot(l);return i({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=_(b.createElement(B,{api:c,siteId:l,intervalMs:r.intervalMs??15e3,cliVersion:r.cliVersion,onExit:n=>{t(),e(n)}}))})}const B=({api:e,siteId:t,intervalMs:n,cliVersion:i,onExit:a})=>{let{exit:l}=v(),[u,m]=S(null),[_,w]=S(null),[T,E]=S(null),[D,O]=S([]),[k,A]=S(!0),[j,M]=S(null),[N,P]=S(1),[F,I]=S(!1),[z,B]=S(!1);y((e,n)=>{if(e===`o`||e===`O`){p(f(`watch`,{siteId:t}));return}if(e===`q`){l(),a(0);return}if(e===`?`||e===`/`){B(e=>!e);return}if(e===`g`){I(e=>!e);return}if(n.tab){P(e=>{let t=n.shift?(e+4)%6+1:e%6+1;return t});return}(e===`1`||e===`2`||e===`3`||e===`4`||e===`5`||e===`6`)&&P(Number(e))});let[J,Y]=S(!1);if(x(()=>{let r=!1,i=async()=>{try{let n=await e.getDashboardSnapshot(t);if(r)return;let i=R.safeParse(n);if(!i.success){Y(!0),A(!1);return}Y(!1);let a=i.data,o={visitors:a.visitors??(typeof a.totalVisitors==`number`?{count:a.totalVisitors}:void 0),topPages:a.topPages?.map(e=>({path:e.path,views:e.views??e.count??0})),sources:a.sources};m(o),e.getVitals(t).then(e=>{r||w(e)},()=>{}),e.getGoals(t).then(e=>{r||E(e)},()=>{}),A(!1),M(null)}catch(e){r||M(e.message)}};i();let a=setInterval(i,n);return()=>{r=!0,clearInterval(a)}},[e,t,n]),x(()=>{let n=new AbortController;return(async()=>{try{let i=await e.openEventsStream(t,n.signal);for await(let e of r(i))e.type===`error`&&O(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>n.abort()},[e,t]),k)return b.createElement(h,{flexDirection:`column`},b.createElement(s,{version:i,subtitle:`watch · ${t}`}),b.createElement(o,{title:`Loading`,state:`busy`},b.createElement(h,null,b.createElement(g,{color:`magenta`},b.createElement(C,{type:`dots`})),b.createElement(g,null,` Fetching snapshot…`))));if(j&&!u)return b.createElement(h,{flexDirection:`column`},b.createElement(s,{version:i,subtitle:`watch · ${t}`}),b.createElement(o,{title:`Error`,state:`err`},b.createElement(g,{color:`red`},j)));if(J&&!u)return b.createElement(h,{flexDirection:`column`},b.createElement(s,{version:i,subtitle:`watch · ${t}`}),b.createElement(d,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let X=process.stdout.columns??80,Z=Math.max(20,Math.floor(X/3)-1),Q=[];return b.createElement(h,{flexDirection:`column`},b.createElement(s,{version:i,subtitle:`watch · ${t}${F?` · globe`:``}`}),b.createElement(h,{flexDirection:`row`},b.createElement(h,{flexDirection:`column`},F?b.createElement(o,{title:`Live globe`,focused:N===1,width:Z},b.createElement(L,{data:Q,width:Math.max(40,Z-4),height:12})):b.createElement(H,{snapshot:u,focused:N===1,width:Z}),b.createElement(G,{events:D,focused:N===4,width:Z})),b.createElement(h,{flexDirection:`column`},b.createElement(U,{snapshot:u,focused:N===2,width:Z}),b.createElement(K,{vitals:_,focused:N===5,width:Z})),b.createElement(h,{flexDirection:`column`},b.createElement(W,{snapshot:u,focused:N===3,width:Z}),b.createElement(q,{goals:T,focused:N===6,width:Z}))),z?b.createElement(V,{api:e,siteId:t,width:X-2}):null,b.createElement(c,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:F?`panels`:`globe`},{key:`?/`,label:z?`close chat`:`ai chat`},{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))},V=({api:e,siteId:t,width:n})=>{let[i,a]=S(``),[s,c]=S([]),[l,u]=S(!1),[d,f]=S(``),[p,m]=S(null),_=async n=>{let i=n.trim();if(!i||l)return;m(null),a(``);let o=[...s,{role:`user`,content:i}];c(o),u(!0),f(``);try{let n=o.map(e=>({role:e.role,content:e.content})),i=await e.openAiStream(`chat`,{messages:n,siteId:t},void 0),a=``;for await(let e of r(i))if(e.type===`delta`)a+=e.content,f(a);else if(e.type===`error`)m(`${e.code}: ${e.message}`);else if(e.type===`done`)break;c([...o,{role:`assistant`,content:a}]),f(``)}catch(e){m(e instanceof Error?e.message:`chat failed`)}finally{u(!1)}};return b.createElement(h,{marginTop:1},b.createElement(o,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:n},b.createElement(h,{flexDirection:`column`},s.slice(-6).map((e,t)=>b.createElement(h,{key:t,flexDirection:`column`,marginBottom:1},b.createElement(g,{color:e.role===`user`?`cyan`:`magenta`,bold:!0},e.role===`user`?`you`:`zenovay`),b.createElement(g,null,e.content))),l&&d?b.createElement(h,{flexDirection:`column`,marginBottom:1},b.createElement(g,{color:`magenta`,bold:!0},`zenovay`),b.createElement(g,null,d)):null,p?b.createElement(g,{color:`red`},`✗ `,p):null,b.createElement(h,null,b.createElement(g,{color:`cyan`},l?`⠋ `:`▸ `),b.createElement(w,{value:i,onChange:a,onSubmit:_,placeholder:l?`streaming…`:`ask anything about your analytics`})))))},H=({snapshot:e,focused:t,width:n})=>{let r=e?.visitors?.count??0,i=e?.visitors?.series??[];return b.createElement(o,{title:`Visitors`,focused:t,width:n},b.createElement(g,{bold:!0},r.toString()),b.createElement(g,{color:`gray`},i.length>0?l(i,Math.max(8,n-6)):`— no data —`))},U=({snapshot:e,focused:t,width:n})=>{let r=e?.topPages?.slice(0,5)??[];return b.createElement(o,{title:`Top pages`,focused:t,width:n},r.length===0?b.createElement(g,{color:`gray`},`— no data —`):r.map(e=>b.createElement(h,{key:e.path},b.createElement(g,null,e.path.padEnd(n-10).slice(0,n-10)),b.createElement(g,{color:`gray`},` `,e.views))))},W=({snapshot:e,focused:t,width:n})=>{let r=e?.sources?.slice(0,5)??[];return b.createElement(o,{title:`Sources`,focused:t,width:n},r.length===0?b.createElement(g,{color:`gray`},`— no data —`):r.map(e=>b.createElement(h,{key:e.source},b.createElement(g,null,e.source.padEnd(n-10).slice(0,n-10)),b.createElement(g,{color:`gray`},` `,e.visitors))))},G=({events:e,focused:t,width:n})=>b.createElement(o,{title:`Events`,focused:t,width:n},e.length===0?b.createElement(g,{color:`gray`},`— waiting —`):e.slice(-10).map((e,t)=>b.createElement(g,{key:t},e.slice(0,n-4)))),K=({vitals:e,focused:t,width:n})=>{let r=(e,t,n)=>b.createElement(h,{key:e},b.createElement(g,{bold:!0},e.padEnd(6)),b.createElement(g,{color:`gray`},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return b.createElement(o,{title:`Vitals`,focused:t,width:n},r(`LCP`,e?.lcpP75,`ms`),r(`INP`,e?.inpP75,`ms`),r(`CLS`,e?.clsP75?e.clsP75*1e3:void 0,`/1k`),r(`TTFB`,e?.ttfbP75,`ms`),r(`FCP`,e?.fcpP75,`ms`))},q=({goals:e,focused:t,width:n})=>{let r=e?.goals?.slice(0,5)??[];return b.createElement(o,{title:`Goals`,focused:t,width:n},r.length===0?b.createElement(g,{color:`gray`},`— no data —`):r.map(e=>b.createElement(h,{key:e.name},b.createElement(g,null,e.name.padEnd(n-10).slice(0,n-10)),b.createElement(g,{color:`gray`},` `,e.completions))))};export{z as watchCommand};
@@ -1,3 +1,3 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{Panel as r}from"./panel-B_yDcIcn.js";import{Banner as i}from"./banner-3iSWTDFy.js";import"./progress-row-BpAXjJPL.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./sparkline-BZ0eMB-w.js";import"./data-table-BpbyyNSA.js";import"./bar-DWT-1xOE.js";import"./ui-DzoMR7th.js";import{Box as a,Text as o,render as s,useApp as c,useInput as l}from"ink";import u,{useEffect as d,useState as f}from"react";async function p(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]),i=await crypto.subtle.sign(`HMAC`,r,n.encode(t));return Array.from(new Uint8Array(i),e=>e.toString(16).padStart(2,`0`)).join(``)}function m({stats:e}){return u.createElement(r,{title:`webhooks forward`,state:e.connected?`ok`:`busy`},u.createElement(a,{flexDirection:`column`},u.createElement(o,null,u.createElement(o,{color:`gray`},`public URL `),u.createElement(o,{color:`cyan`},e.publicUrl)),u.createElement(o,null,u.createElement(o,{color:`gray`},`→ forwarding to `),u.createElement(o,{color:`magenta`},e.wsUrl)),u.createElement(o,null,e.connected?u.createElement(o,{color:`green`},`● connected`):u.createElement(o,{color:`yellow`},`○ connecting…`),u.createElement(o,{color:`gray`},` · `,e.total,` requests · `,e.ok,` ok · `),u.createElement(o,{color:e.err>0?`red`:`gray`},e.err,` err`),e.lastStatus===null?null:u.createElement(o,{color:`gray`},` · last: HTTP `,e.lastStatus)),e.lastError?u.createElement(o,{color:`red`},`last error: `,e.lastError.slice(0,80)):null))}async function h(r){let h=await e(),g=await t({strict:!1});if(!g?.accessToken)return process.stderr.write("Not authenticated. Run `zenovay login` first.\n"),2;let _=r.siteId??g.teamId??``;if(!_)return process.stderr.write(`No site selected — pass --site-id or set ZENOVAY_SITE.
1
+ import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{Panel as r}from"./panel-B_yDcIcn.js";import{Banner as i}from"./banner-3iSWTDFy.js";import"./progress-row-BpAXjJPL.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./sparkline-BZ0eMB-w.js";import"./data-table-BpbyyNSA.js";import"./bar-DWT-1xOE.js";import"./ui-Cey-h6wI.js";import{Box as a,Text as o,render as s,useApp as c,useInput as l}from"ink";import u,{useEffect as d,useState as f}from"react";async function p(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]),i=await crypto.subtle.sign(`HMAC`,r,n.encode(t));return Array.from(new Uint8Array(i),e=>e.toString(16).padStart(2,`0`)).join(``)}function m({stats:e}){return u.createElement(r,{title:`webhooks forward`,state:e.connected?`ok`:`busy`},u.createElement(a,{flexDirection:`column`},u.createElement(o,null,u.createElement(o,{color:`gray`},`public URL `),u.createElement(o,{color:`cyan`},e.publicUrl)),u.createElement(o,null,u.createElement(o,{color:`gray`},`→ forwarding to `),u.createElement(o,{color:`magenta`},e.wsUrl)),u.createElement(o,null,e.connected?u.createElement(o,{color:`green`},`● connected`):u.createElement(o,{color:`yellow`},`○ connecting…`),u.createElement(o,{color:`gray`},` · `,e.total,` requests · `,e.ok,` ok · `),u.createElement(o,{color:e.err>0?`red`:`gray`},e.err,` err`),e.lastStatus===null?null:u.createElement(o,{color:`gray`},` · last: HTTP `,e.lastStatus)),e.lastError?u.createElement(o,{color:`red`},`last error: `,e.lastError.slice(0,80)):null))}async function h(r){let h=await e(),g=await t({strict:!1});if(!g?.accessToken)return process.stderr.write("Not authenticated. Run `zenovay login` first.\n"),2;let _=r.siteId??g.teamId??``;if(!_)return process.stderr.write(`No site selected — pass --site-id or set ZENOVAY_SITE.
2
2
  `),2;if(!r.to)return process.stderr.write(`Missing --to <url> (e.g. --to localhost:3000/webhook).
3
3
  `),2;let v=r.to.match(/^https?:\/\//)?r.to:`http://${r.to}`,y=new n({config:h,cliVersion:r.cliVersion,token:g}),b;try{b=await y.createTunnel(_,r.to)}catch(e){return process.stderr.write(`Failed to register tunnel: ${e.message}\n`),1}let x=r.sign?r.secret??b.tunnelKey:null,S=()=>{let{exit:e}=c(),[t,n]=f({total:0,ok:0,err:0,lastStatus:null,lastError:null,publicUrl:b.publicUrl,wsUrl:b.wsUrl,connected:!1});return l((t,n)=>{(t===`q`||n.escape)&&e()}),d(()=>{let e=new AbortController,t=async e=>{try{let t={...e.headers};delete t.host,delete t[`content-length`],x&&(t[`X-Zenovay-Signature`]=`sha256=${await p(x,e.body)}`);let r=await fetch(v,{method:e.method,headers:t,body:e.method===`GET`||e.method===`HEAD`?void 0:e.body}),i=await r.text(),a={};return r.headers.forEach((e,t)=>{a[t]=e}),n(e=>({...e,total:e.total+1,ok:e.ok+(r.ok?1:0),err:e.err+(r.ok?0:1),lastStatus:r.status,lastError:r.ok?null:`HTTP ${r.status}`})),{status:r.status,headers:a,body:i}}catch(e){let t=e instanceof Error?e.message:String(e);return n(e=>({...e,total:e.total+1,err:e.err+1,lastError:t})),{status:502,body:JSON.stringify({error:`cli_local_failed`,detail:t})}}};return(async()=>{let r=y.tunnelClient(b.wsUrl);n(e=>({...e,connected:!0}));try{await r.start(t,e.signal)}catch(e){n(t=>({...t,connected:!1,lastError:e.message}))}})(),()=>{e.abort()}},[]),u.createElement(a,{flexDirection:`column`},u.createElement(i,{version:`webhooks forward`}),u.createElement(m,{stats:t}),u.createElement(o,{color:`gray`},`target: `,v,` `,r.sign?`· HMAC-signed`:``),u.createElement(o,{color:`gray`},`[q | Esc] quit`))},{waitUntilExit:C}=s(u.createElement(S,null));return await C(),0}export{h as webhooksForwardCommand};
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import(`./init-D6qfFHJW.js`).then(async({initCommand:e})=>{let{readFileSync:t}=await import(`node:fs`),n=await import(`node:path`),{fileURLToPath:r}=await import(`node:url`),i=n.dirname(r(import.meta.url)),a=JSON.parse(t(n.join(i,`..`,`package.json`),`utf8`)),o=process.argv.slice(2),s=o.includes(`--json`),c=o.includes(`--yes`),l=o.includes(`--skip-mcp`),u=o.includes(`--skip-verify`),d=await e({cliVersion:a.version,cwd:process.cwd(),json:s,yes:c,skipMcp:l,skipVerify:u});process.exit(d)});
2
+ import(`./init-DBCYWR0R.js`).then(async({initCommand:e})=>{let{readFileSync:t}=await import(`node:fs`),n=await import(`node:path`),{fileURLToPath:r}=await import(`node:url`),i=n.dirname(r(import.meta.url)),a=JSON.parse(t(n.join(i,`..`,`package.json`),`utf8`)),o=process.argv.slice(2),s=o.includes(`--json`),c=o.includes(`--yes`),l=o.includes(`--skip-mcp`),u=o.includes(`--skip-verify`),d=await e({cliVersion:a.version,cwd:process.cwd(),json:s,yes:c,skipMcp:l,skipVerify:u});process.exit(d)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenovay/cli",
3
- "version": "0.1.53",
3
+ "version": "0.1.55",
4
4
  "description": "Zenovay CLI — AI install wizard + full terminal analytics dashboard",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import{ApiError as t}from"./api-BD_nTdOq.js";import{readToken as n}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as r}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import"./sparkline-BZ0eMB-w.js";import{ChatPanel as l}from"./chat-panel-C_yjPXnw.js";import{resolveSiteId as u}from"./resolve-site-DSJR9vuz.js";import{stripUrlPrefix as d}from"./fmt-gMsty5jy.js";import{DataTable as f}from"./data-table-BpbyyNSA.js";import{EmptyState as p}from"./empty-state-CJxa1jUN.js";import{EmbeddedGlobe as m,MetricCard as h}from"./embedded-globe-ClP_lA3q.js";import{Bar as g}from"./bar-DWT-1xOE.js";import{deepLinkFor as _,openInBrowser as ee}from"./keybar-deep-link-C9xNYihD.js";import"./sphere-globe-CvHshl9g.js";import{Box as v,Text as y,render as b,useApp as x,useInput as S}from"ink";import C,{useEffect as w,useState as T}from"react";import E from"ink-spinner";function D(e){if(!(e instanceof t))return!1;let n=e.status;if(n===401||n===403||n===404)return!0;let r=e.body,i=r?.code;return i===`forbidden`||i===`not_found`||i===`auth_required`||i===`auth_invalid`||i===`tier_insufficient`}function O(e,t){return e.catch(e=>{if(D(e))throw e;return t})}async function k(t){let o=await e(),s=await n({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new r({config:o,cliVersion:t.cliVersion,token:s}),l,d;try{({siteId:l,site:d}=await u(c,{explicit:t.siteId,headless:!!t.json,cliVersion:t.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??l;if(a(t))try{let e=await j(c,l,`24h`);if(t.csv||t.tsv){let{writeCsv:n}=await import(`./csv-emit-BjL_a4Hk.js`);return n(e.topPages,[`path`,`views`,`uniqueVisitors`,`avgTime`,`bounceRate`],t.tsv?`tsv`:`csv`)}if(t.ndjson){for(let t of e.topPages)process.stdout.write(JSON.stringify(t)+`
2
- `);return 0}return i({type:`overview.snapshot`,data:e}),0}catch(e){let{emitErrorEnvelope:n}=await import(`./error-codes-BeJw1P4i.js`);return n(e,{command:`analytics`,cliVersion:t.cliVersion})}return new Promise(e=>{let{unmount:n}=b(C.createElement(M,{api:c,siteId:l,siteLabel:f,cliVersion:t.cliVersion,onExit:t=>{n(),e(t)}}))})}function A(e){return e===`24h`?`7d`:e}async function j(e,t,n){let[r,i,a,o,s]=await Promise.all([O(e.getStats(t,n),null),O(e.getPages(t),[]),O(e.getSources(t,A(n),`prev`),null),O(e.getGeo(t),null),O(e.getDevices(t),null)]),c=i.reduce((e,t)=>e+t.views,0),l=(r?.daily??[]).map(e=>e.visitors),u=(r?.daily??[]).map(e=>e.pageviews),d=Math.floor(l.length/2),f=l.slice(0,d).reduce((e,t)=>e+t,0),p=u.slice(0,d).reduce((e,t)=>e+t,0),m=(a?.sources??[]).filter(e=>e.channel!==`other`||!e.source.includes(`/`)).slice(0,6).map(e=>({name:e.source,visitors:e.visitors,delta:e.delta??null}));return{visitors:r?.visitors??0,pageviews:r?.pageviews??c,bounceRate:r?.bounceRate??null,avgSession:r?.avgSessionSec??null,series:l,pageviewsSeries:u,prevVisitors:f,prevPageviews:p,topPages:i.slice(0,10),channels:m,countries:(o?.countries??[]).slice(0,8),browsers:(s?.browsers??[]).slice(0,5),devices:(s?.devices??[]).slice(0,5)}}const M=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=x(),[u,b]=T(null),[D,O]=T(!0),[k,A]=T(null),[M,N]=T(`24h`),[P,F]=T(t),[I,L]=T(n),[R,z]=T(!1),[B,V]=T([]),[H,U]=T(!1);S(async t=>{if(!H){if(t===`/`){U(!0);return}if(t===`o`||t===`O`){ee(_(`overview`,{siteId:P}));return}if(t===`q`){a(),i(0);return}if(t===`1`){N(`24h`);return}if(t===`2`){N(`7d`);return}if(t===`3`){N(`30d`);return}if(t===`4`){N(`90d`);return}if(t===`s`){if(B.length===0)try{let t=await e.getSites();V(t)}catch{}z(e=>!e);return}}}),w(()=>{let t=!1;return O(!0),(async()=>{try{let n=await j(e,P,M);t||(b(n),O(!1))}catch(e){t||(A(e.message),O(!1))}})(),()=>{t=!0}},[e,P,M]);let W=()=>C.createElement(o,{title:`Switch site`,state:`idle`},B.length===0?C.createElement(y,{color:`gray`},`Loading your sites…`):B.map(e=>C.createElement(v,{key:e.id},C.createElement(y,{color:e.id===P?`cyan`:`gray`},e.id===P?`› `:` `),C.createElement(y,{bold:e.id===P},e.name),C.createElement(y,{color:`gray`},` (`,e.url.replace(/^https?:\/\//,``).replace(/\/$/,``),`)`))),C.createElement(v,{marginTop:1},C.createElement(y,{color:`gray`},`Press `),C.createElement(y,{color:`cyan`},`[number]`),C.createElement(y,{color:`gray`},` to pick, `),C.createElement(y,{color:`cyan`},`[s]`),C.createElement(y,{color:`gray`},` to close.`)));S(e=>{if(H||!R)return;let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=B.length){let e=B[t-1];F(e.id),L(e.url.replace(/^https?:\/\//,``).replace(/\/$/,``)),z(!1)}});let G=`overview · ${I} · ${M}`,K=[{key:`q`,label:`quit`},{key:`/`,label:`ask AI`},{key:`o`,label:`open in browser`},{key:`s`,label:`site`},{key:`1-4`,label:`range (24h/7d/30d/90d)`}];if(H)return C.createElement(l,{cliVersion:r,api:e,dashboardContext:{commandName:`overview`,siteId:P,siteLabel:I,metricsSnapshot:u},onClose:()=>U(!1)});if(D)return C.createElement(v,{flexDirection:`column`},C.createElement(s,{version:r,subtitle:G}),C.createElement(o,{title:`Loading`,state:`busy`},C.createElement(v,null,C.createElement(y,{color:`cyan`},C.createElement(E,{type:`dots`})),C.createElement(y,null,` Fetching dashboard…`))),R?W():null);if(k)return C.createElement(v,{flexDirection:`column`},C.createElement(s,{version:r,subtitle:G}),C.createElement(p,{reason:`error`,headline:`Failed to load`,hint:k}),R?W():null,C.createElement(c,{items:K}));if(!u||u.visitors===0&&u.pageviews===0&&u.topPages.length===0)return C.createElement(v,{flexDirection:`column`},C.createElement(s,{version:r,subtitle:G}),C.createElement(p,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event — or press [s] to switch to a different site, or [1-4] to widen the time range.`}),R?W():null,C.createElement(c,{items:K}));let q=process.stdout.columns??80,J=Math.max(18,Math.floor(q/4)-1),Y=Math.max(28,Math.floor(q/2)-2),X=[{key:`path`,label:`path`,width:32,format:e=>d(String(e??``))},{key:`views`,label:`views`,align:`right`,width:8},{key:`uniqueVisitors`,label:`visitors`,align:`right`,width:8},{key:`avgTime`,label:`avg time`,align:`right`,width:9,format:e=>typeof e==`number`?`${Math.round(e/1e3)}s`:`—`},{key:`bounceRate`,label:`bounce`,align:`right`,width:7,format:e=>typeof e==`number`?`${(e*100).toFixed(0)}%`:`—`}],Z=u.prevVisitors>0?(u.visitors-u.prevVisitors)/u.prevVisitors:void 0,Q=u.prevPageviews>0?(u.pageviews-u.prevPageviews)/u.prevPageviews:void 0,te=Math.max(1,...u.channels.map(e=>e.visitors)),ne=Math.max(1,...u.countries.map(e=>e.visitors)),re=Math.max(1,...u.browsers.map(e=>e.visitors)),ie=Math.max(1,...u.devices.map(e=>e.visitors)),$=Math.max(8,Math.floor(Y/3)),ae=q>=70,oe=u.countries.flatMap(e=>Array(Math.min(e.visitors,8)).fill({country:e.country}));return C.createElement(v,{flexDirection:`column`},C.createElement(s,{version:r,subtitle:G}),C.createElement(v,{flexDirection:`row`},C.createElement(h,{title:`Visitors`,value:u.visitors,format:`number`,width:J,series:u.series,...typeof Z==`number`?{delta:Z}:{}}),C.createElement(h,{title:`Pageviews`,value:u.pageviews,format:`number`,width:J,series:u.pageviewsSeries,...typeof Q==`number`?{delta:Q}:{}}),C.createElement(h,{title:`Bounce rate`,value:u.bounceRate??``,emptyHint:`—`,format:`percent`,width:J}),C.createElement(h,{title:`Avg session`,value:u.avgSession??``,emptyHint:`—`,format:`duration`,width:J})),ae?C.createElement(o,{title:`Globe`},C.createElement(m,{events:oe,width:Math.max(60,q-4),height:12})):null,C.createElement(v,{flexDirection:`row`,flexWrap:`wrap`},C.createElement(v,{width:Y,flexDirection:`column`},C.createElement(o,{title:`Channels`},u.channels.length===0?C.createElement(y,{color:`gray`},`No channel data yet.`):u.channels.map(e=>C.createElement(v,{key:e.name,flexDirection:`row`},C.createElement(v,{width:12},C.createElement(y,null,e.name)),C.createElement(g,{value:e.visitors,max:te,width:$,showPercent:!1,...typeof e.delta==`number`?{delta:e.delta}:{}}),C.createElement(y,{color:`gray`},` `,e.visitors))))),C.createElement(v,{width:Y,flexDirection:`column`},C.createElement(o,{title:`Top countries`},u.countries.length===0?C.createElement(y,{color:`gray`},`No geo data yet.`):u.countries.map(e=>C.createElement(v,{key:e.country,flexDirection:`row`},C.createElement(v,{width:5},C.createElement(y,null,e.country)),C.createElement(g,{value:e.visitors,max:ne,width:$,showPercent:!1}),C.createElement(y,{color:`gray`},` `,e.visitors)))))),C.createElement(v,{flexDirection:`row`,flexWrap:`wrap`},C.createElement(v,{width:Y,flexDirection:`column`},C.createElement(o,{title:`Top browsers`},u.browsers.length===0?C.createElement(y,{color:`gray`},`No browser data yet.`):u.browsers.map(e=>C.createElement(v,{key:e.name,flexDirection:`row`},C.createElement(v,{width:12},C.createElement(y,null,e.name)),C.createElement(g,{value:e.visitors,max:re,width:$,showPercent:!1}),C.createElement(y,{color:`gray`},` `,e.visitors))))),C.createElement(v,{width:Y,flexDirection:`column`},C.createElement(o,{title:`Top devices`},u.devices.length===0?C.createElement(y,{color:`gray`},`No device data yet.`):u.devices.map(e=>C.createElement(v,{key:e.name,flexDirection:`row`},C.createElement(v,{width:12},C.createElement(y,null,e.name)),C.createElement(g,{value:e.visitors,max:ie,width:$,showPercent:!1}),C.createElement(y,{color:`gray`},` `,e.visitors)))))),C.createElement(o,{title:`Top pages (${M})`},u.topPages.length===0?C.createElement(y,{color:`gray`},`No pages with data in this window yet.`):C.createElement(f,{columns:X,data:u.topPages,zebra:!0})),R?W():null,C.createElement(c,{items:K}))};async function N(e){return k(e)}export{N as analyticsCommand};
@@ -1 +0,0 @@
1
- import{useTheme as e}from"./panel-B_yDcIcn.js";import{spark as t}from"./sparkline-BZ0eMB-w.js";import{SphereGlobe as n,scatterCountryDots as r}from"./sphere-globe-CvHshl9g.js";import{Box as i,Text as a}from"ink";import o,{useMemo as s}from"react";function c(e,t){if(typeof e==`string`)return e;switch(t){case`percent`:{let t=Math.abs(e)<=1?e*100:e;return`${t.toFixed(1)}%`}case`duration`:{if(e<60)return`${Math.round(e)}s`;let t=Math.floor(e/60),n=Math.round(e%60);return`${t}m ${n.toString().padStart(2,`0`)}s`}case`currency`:{let t=e/100;return`$${t.toLocaleString(void 0,{minimumFractionDigits:0,maximumFractionDigits:2})}`}case`number`:default:return e.toLocaleString()}}const l=[`• `,`•• `,`•••`,` ••`,` •`,` `];function u(){let[e,t]=o.useState(0);return o.useEffect(()=>{let e=setInterval(()=>{t(e=>(e+1)%l.length)},180);return()=>clearInterval(e)},[]),e}function d({title:n,value:r,series:s,delta:d,format:f=`number`,loading:p=!1,emptyHint:m,width:h}){let{theme:g}=e(),_=u(),v=o.createElement(a,{color:g.typography.label.color,dimColor:g.typography.label.dim},n.toUpperCase()),y=({children:e})=>o.createElement(i,{flexDirection:`column`,width:h,marginRight:2,minHeight:3},e);if(p)return o.createElement(y,null,v,o.createElement(a,{color:g.accent},l[_]));let b=typeof r==`number`?r:Number(r),x=(r===``||r===`—`||typeof r==`number`&&!Number.isFinite(b))&&(!s||s.length===0);if(x)return o.createElement(y,null,v,o.createElement(a,{color:g.dim},m??`no data yet`));let S=c(r,f),C=typeof h==`number`?Math.max(8,h-4):16,w=s&&s.length>0?t(s,C):``,T=null;if(typeof d==`number`&&Number.isFinite(d)){let e=Math.abs(d*100);T=e<.5?o.createElement(a,{color:g.dim},` `,`→ `,e.toFixed(1),`%`):d>0?o.createElement(a,{color:g.success},` `,`↑ `,e.toFixed(1),`%`):o.createElement(a,{color:g.error},` `,`↓ `,e.toFixed(1),`%`)}return o.createElement(y,null,v,o.createElement(a,{color:g.typography.headline.color,bold:g.typography.headline.bold},S),w?o.createElement(i,{flexDirection:`row`},o.createElement(a,{color:g.accent},w),T):T?o.createElement(i,{flexDirection:`row`},T):o.createElement(i,{height:1}))}const f=(()=>{let e=process.env.LANG??``;if(e===`C`||e===`POSIX`)return!0;let t=process.env.TERM??``;return!!(/^(linux|dumb)$/.test(t)||process.env.ZENOVAY_GLOBE===`ascii`)})();function p(e){let t=new Map;for(let n of e){if(!n.country)continue;let e=n.country.toUpperCase();t.set(e,(t.get(e)??0)+1)}let n=[];for(let[e,i]of t){let t=r(e,Math.min(i,8));for(let e of t)n.push({lat:e.lat,lng:e.lng,freshness:1})}return n}function m(e,t){if(e.width!==t.width||e.height!==t.height||e.events.length!==t.events.length)return!1;let n=Math.min(e.events.length,5);for(let r=0;r<n;r++)if(e.events[r]?.country!==t.events[r]?.country)return!1;return!0}const h=({events:e,width:t,height:r})=>{let i=s(()=>p(e),[e]);return o.createElement(n,{visitors:i,width:t,height:r,rotationDeg:20,tiltDeg:20,gridlines:!0,asciiOnly:f})},g=o.memo(h,m);export{g as EmbeddedGlobe,d as MetricCard};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./formatter-DutfcQAc.js";import{emit$1 as r,isHeadless as i}from"./emit-DBYk96TD.js";import{Panel as a}from"./panel-B_yDcIcn.js";import{Banner as o}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as s}from"./keybar-DsYTkKZX.js";import{resolveSiteId as c}from"./resolve-site-DSJR9vuz.js";import{DataTable as l}from"./data-table-BpbyyNSA.js";import{EmptyState as u}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as d,openInBrowser as f}from"./keybar-deep-link-C9xNYihD.js";import{Globe as p}from"./globe-DaSl9ejK.js";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";async function C(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getGeo(u);if(a.csv||a.tsv){let{writeCsv:t}=await import(`./csv-emit-BjL_a4Hk.js`);return t(e.countries,[`country`,`visitors`],a.tsv?`tsv`:`csv`)}if(a.ndjson){for(let t of e.countries)process.stdout.write(JSON.stringify(t)+`
2
- `);return 0}return r({type:`geo.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(w,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=_(),[g,C]=x(null),[w,T]=x(!0),[E,D]=x(null);if(v(e=>{if(e===`o`||e===`O`){f(d(`geo`,{siteId:t}));return}e===`q`&&(c(),i(0))}),b(()=>{let n=!1;return(async()=>{try{let r=await e.getGeo(t);n||(C(r),T(!1))}catch(e){n||(D(e.message),T(!1))}})(),()=>{n=!0}},[e,t]),w)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:`geo · ${n}`}),y.createElement(a,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching geo…`))));if(E)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:`geo · ${n}`}),y.createElement(u,{reason:`error`,headline:`Failed to load`,hint:E}));let O=!g||g.countries.length===0&&g.cities.length===0;if(O)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:`geo · ${n}`}),y.createElement(u,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let k=[{key:`country`,label:`country`,width:18},{key:`visitors`,label:`visitors`,align:`right`,width:8}],A=[{key:`city`,label:`city`,width:20},{key:`country`,label:`country`,width:12},{key:`visitors`,label:`visitors`,align:`right`,width:8}],j=process.stdout.columns??80;return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:`geo · ${n}`}),y.createElement(m,{flexDirection:`row`},y.createElement(a,{title:`Countries`},g.countries.length===0?y.createElement(h,{color:`gray`},`— —`):y.createElement(l,{columns:k,data:g.countries.slice(0,15),zebra:!0})),y.createElement(a,{title:`Globe`},y.createElement(p,{data:[],width:Math.max(36,j-60),height:12}))),y.createElement(a,{title:`Cities`},g.cities.length===0?y.createElement(h,{color:`gray`},`— —`):y.createElement(l,{columns:A,data:g.cities.slice(0,20),zebra:!0})),y.createElement(s,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{C as geoCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import"./formatter-DutfcQAc.js";import{emit$1 as r,isHeadless as i}from"./emit-DBYk96TD.js";import{Panel as a,useTheme as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import{ChatPanel as l}from"./chat-panel-C_yjPXnw.js";import{resolveSiteId as u}from"./resolve-site-DSJR9vuz.js";import{EmptyState as d}from"./empty-state-CJxa1jUN.js";import{Bar as f}from"./bar-DWT-1xOE.js";import{SphereGlobe as p,infoFor as m,scatterCountryDots as h}from"./sphere-globe-CvHshl9g.js";import{Box as g,Text as _,render as v,useApp as y,useInput as ee}from"ink";import b,{useEffect as x,useMemo as S,useRef as te,useState as C}from"react";import w from"ink-spinner";import T from"open";async function E(e,t,n){let r=await e.getGeo(t).catch(()=>({countries:[],cities:[]})),i=(r.countries??[]).map(e=>{let t=m(e.country),r=n.get(e.country)??0;return{code:e.country,visitors:e.visitors,lat:t?.lat,lng:t?.lng,freshness:e.visitors>r?1:.4}});return{countries:i,totalVisitors:i.reduce((e,t)=>e+t.visitors,0),unknownCount:i.filter(e=>typeof e.lat!=`number`).reduce((e,t)=>e+t.visitors,0),lastFetchedAt:Date.now()}}async function D(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:a.cliVersion,token:s}),l,d;try{({siteId:l,site:d}=await u(c,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??l;if(a.browser){let e=`https://app.zenovay.com/domains/${encodeURIComponent(l)}?tab=globe`;a.json?process.stdout.write(JSON.stringify({openedUrl:e})+`
2
- `):process.stdout.write(`\n Opening Mapbox globe in your default browser:\n ${e}\n\n`);try{await T(e)}catch{}return 0}if(i(a)){let e=await E(c,l,new Map);return r({type:`globe.snapshot`,data:{countries:e.countries,total:e.totalVisitors,unknownCount:e.unknownCount}}),0}return new Promise(e=>{let{unmount:t}=v(b.createElement(j,{api:c,siteId:l,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const O=5e3,k=60,A=1,ne=80,j=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:u}=y(),{theme:v}=o(),[D,j]=C(null),[re,M]=C(!0),[N,P]=C(null),[ie,F]=C(0),[I,L]=C(!1),[R,ae]=C(20),[oe,z]=C(1),[B,V]=C(0),H=te(new Map),[U,W]=C(!1);ee(n=>{if(!U){if(n===`/`){W(!0);return}if(n===`q`){u(),i(0);return}if(n===` `){L(e=>!e);return}if(n===`+`||n===`=`){z(e=>Math.min(1.6,e+.1));return}if(n===`-`||n===`_`){z(e=>Math.max(.7,e-.1));return}if(n===`t`){ae(e=>(e+15)%60);return}if(n===`j`){V(e=>e+1);return}if(n===`k`){V(e=>Math.max(0,e-1));return}if(n===`w`){let e=`https://app.zenovay.com/domains/${encodeURIComponent(t)}?tab=globe`;T(e).catch(()=>{});return}if(n===`o`&&D){let e=D.countries[B];e?.lng!==void 0&&(F(-e.lng),L(!0));return}n===`r`&&(async()=>{try{let n=await E(e,t,H.current);H.current=new Map(n.countries.map(e=>[e.code,e.visitors])),j(n)}catch(e){P(e.message)}})()}}),x(()=>{let n=!1,r=null,i=async()=>{try{let r=await E(e,t,H.current);if(n)return;H.current=new Map(r.countries.map(e=>[e.code,e.visitors])),j(r),M(!1)}catch(e){n||(P(e.message),M(!1))}n||(r=setTimeout(i,O))};return i(),()=>{n=!0,r&&clearTimeout(r)}},[e,t]),x(()=>{if(I)return;let e=setInterval(()=>{F(e=>(e+A)%360)},k);return()=>clearInterval(e)},[I]);let G=S(()=>{if(!D)return[];let e=[];for(let t of D.countries){if(typeof t.lat!=`number`||typeof t.lng!=`number`)continue;let n=Math.min(ne,Math.max(3,t.visitors*5));for(let r of h(t.code,n))e.push({lat:r.lat,lng:r.lng,freshness:t.freshness})}return e},[D]),K=S(()=>{if(!D)return[];let e=D.countries[Math.min(B,D.countries.length-1)];return!e||typeof e.lat!=`number`?[]:h(e.code,Math.min(80,Math.max(8,e.visitors*4)))},[D,B]),q=`globe · ${n} · live`,J=[{key:`q`,label:`quit`},{key:`j/k`,label:`select country`},{key:`o`,label:`orbit to selected`},{key:`space`,label:I?`resume`:`pause`},{key:`t`,label:`tilt ${R}°`},{key:`+/-`,label:`zoom`},{key:`w`,label:`open Mapbox view in browser`},{key:`r`,label:`refresh`},{key:`/`,label:`ask AI`}];if(U)return b.createElement(l,{cliVersion:r,api:e,dashboardContext:{commandName:`globe`,siteId:t,siteLabel:n,metricsSnapshot:D},onClose:()=>W(!1)});if(re)return b.createElement(g,{flexDirection:`column`},b.createElement(s,{version:r,subtitle:q}),b.createElement(a,{title:`Loading`,state:`busy`},b.createElement(g,null,b.createElement(_,{color:`cyan`},b.createElement(w,{type:`dots`})),b.createElement(_,null,` Spinning up Earth…`))));if(N)return b.createElement(g,{flexDirection:`column`},b.createElement(s,{version:r,subtitle:q}),b.createElement(d,{reason:`error`,headline:`Failed to load`,hint:N}),b.createElement(c,{items:J}));if(!D||D.countries.length===0&&D.unknownCount===0)return b.createElement(g,{flexDirection:`column`},b.createElement(s,{version:r,subtitle:q}),b.createElement(d,{reason:`no-data`,headline:`No geolocated visitors yet`,hint:`Visit your site to populate the map.`}),b.createElement(c,{items:J}));let se=process.stdout.columns??100,Y=36,ce=Math.max(40,Math.min(90,se-Y-4)),X=Math.round(ce*oe),Z=Math.round(X*.5),Q=D.countries.slice(0,12),le=Math.max(1,...Q.map(e=>e.visitors)),ue=Math.max(1,Math.floor((Date.now()-D.lastFetchedAt)/1e3)),$=D.countries[Math.min(B,D.countries.length-1)],de=$?m($.code):null;return b.createElement(g,{flexDirection:`column`},b.createElement(s,{version:r,subtitle:q}),$?b.createElement(g,{flexDirection:`row`,marginBottom:1},b.createElement(g,{width:2}),b.createElement(g,{borderStyle:`round`,borderColor:v.warn,paddingX:1},b.createElement(_,{color:v.warn,bold:!0},de?.name??$.code),b.createElement(_,{color:v.dim},` · `),b.createElement(_,{color:v.fg},$.visitors,` visitor`,$.visitors===1?``:`s`))):null,b.createElement(g,{flexDirection:`row`},b.createElement(g,{flexDirection:`column`,marginRight:2},b.createElement(p,{visitors:G,highlight:K,width:X,height:Z,rotationDeg:ie,tiltDeg:R}),b.createElement(g,{marginTop:1},b.createElement(_,{color:v.dim},D.totalVisitors,` visitors · `,D.countries.length,` countries`,D.unknownCount>0?` · ${D.unknownCount} unmapped`:``,` · `,I?`rotation paused`:`↻ ${A}°/${k}ms`,` · refreshed `,ue,`s ago`))),b.createElement(g,{flexDirection:`column`,width:Y},b.createElement(a,{title:`Live by country`},Q.map((e,t)=>{let n=t===Math.min(B,D.countries.length-1),r=e.freshness>.7,i=n?v.warn:r?v.success:v.fg;return b.createElement(g,{key:e.code,flexDirection:`row`},b.createElement(g,{width:2},b.createElement(_,{color:v.warn},n?`›`:` `)),b.createElement(g,{width:3},b.createElement(_,{color:i,bold:n},e.code)),b.createElement(f,{value:e.visitors,max:le,width:14,showPercent:!1}),b.createElement(g,{width:6},b.createElement(_,{color:v.muted},String(e.visitors).padStart(5))))})),D.countries.length>12?b.createElement(g,{marginTop:1},b.createElement(_,{color:v.muted},`+`,D.countries.length-12,` more (j/k to scroll)`)):null)),b.createElement(c,{items:J}))};export{D as globeCommand};
@@ -1 +0,0 @@
1
- import{Box as e,Text as t}from"ink";import n from"react";const r=Math.PI*2;function i(e){let t=e,n=Math.PI*Math.sin(e);for(let e=0;e<6;e++){let e=2*t+Math.sin(2*t)-n,r=2+2*Math.cos(2*t);if(r===0)break;t-=e/r}return t}function a(e,t){if(e<-90||e>90||t<-180||t>180)return null;let n=e*Math.PI/180,r=t*Math.PI/180,a=i(n),o=r*Math.cos(a)/Math.PI,s=Math.sin(a);return{x:o,y:s}}function o(e){if(e)return!0;let t=process.env;if(t.NO_COLOR||t.ZENOVAY_GLOBE===`ascii`)return!0;let n=(t.LANG||t.LC_ALL||t.LC_CTYPE||``).toLowerCase();return!!(n&&!n.includes(`utf`))}function s(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function c(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function l(e){let t=e.dw/2,n=e.dh/2,i=e.dw/2-1,a=e.dh/2-1,o=Math.max(e.dw,e.dh)*2;for(let s=0;s<o;s++){let l=s/o*r,u=Math.round(t+i*Math.cos(l)),d=Math.round(n+a*Math.sin(l));c(e,u,d)}}function u(e){let t=Math.floor(e.dh/2);for(let n=0;n<e.dw;n+=4)c(e,n,t)}function d(e,t){let n=e.dw/2,r=e.dh/2,i=e.dw/2-1,o=e.dh/2-1;for(let s of t){let t=a(s.lat,s.lng);if(!t)continue;let l=Math.round(n+t.x*i),u=Math.round(r-t.y*o);c(e,l,u),c(e,l+1,u),c(e,l,u+1),c(e,l+1,u+1)}}const f=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function p(e,t,n){let r=0;for(let i=0;i<f.length;i++){let[a,o]=f[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function m(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`.`:r<=4?`:`:r<=6?`*`:`#`}function h({data:r,width:i=80,height:a=20,asciiOnly:c}){let f=o(c),h=s(i,a);l(h),u(h),d(h,r);let g=[];for(let e=0;e<a;e++){let t=``;for(let n=0;n<i;n++)t+=f?m(h,n,e):p(h,n,e);g.push(t)}return n.createElement(e,{flexDirection:`column`},g.map((e,r)=>n.createElement(t,{key:r,color:`magenta`},e)),n.createElement(t,{color:`gray`},r.length,` live · `,f?`ascii mode`:`braille mode`))}export{h as Globe};
@@ -1 +0,0 @@
1
- import e from"open";async function t(t){await e(t)}const n=process.env.ZENOVAY_APP_BASE||`https://app.zenovay.com`;function r(e,t={}){let r=new URL(n);switch(e){case`analytics`:case`overview`:case`watch`:r.pathname=`/analytics`;break;case`live`:r.pathname=`/analytics/live`;break;case`sources`:r.pathname=`/analytics`,r.searchParams.set(`tab`,`sources`);break;case`pages`:r.pathname=`/analytics`,r.searchParams.set(`tab`,`pages`);break;case`devices`:r.pathname=`/analytics`,r.searchParams.set(`tab`,`devices`);break;case`geo`:r.pathname=`/analytics`,r.searchParams.set(`tab`,`geo`);break;case`visitors`:r.pathname=`/analytics`,r.searchParams.set(`tab`,`profiles`);break;case`globe`:r.pathname=`/analytics/globe`;break;case`stats`:r.pathname=`/analytics`;break;case`vitals`:r.pathname=`/web-vitals`;break;case`revenue`:r.pathname=`/revenue`;break;case`sessions`:r.pathname=`/sessions`;break;case`heatmaps`:r.pathname=`/heatmaps`;break;case`funnels`:case`funnel`:r.pathname=`/funnels`;break;case`journeys`:r.pathname=`/journeys`;break;case`retention`:r.pathname=`/retention`;break;case`uptime`:r.pathname=`/uptime`;break;case`insights`:r.pathname=`/insights`;break;case`companies`:r.pathname=`/companies`;break;case`errors`:r.pathname=`/errors`;break;case`domains`:r.pathname=`/websites`;break;case`api-keys`:r.pathname=`/api-keys`;break;case`team`:r.pathname=`/team`;break;case`settings`:r.pathname=`/settings`;break;case`plans`:case`billing`:r.pathname=`/billing`;break;case`integrations`:r.pathname=`/integrations`;break;case`goals`:r.pathname=`/goals`;break;case`notes`:r.pathname=`/notes`;break;case`audit`:r.pathname=`/audit`;break;case`share`:r.pathname=`/settings/share`;break;case`alerts`:r.pathname=`/alerts`;break;case`agency`:r.pathname=`/agency`;break;case`profile`:r.pathname=`/profile`;break;case`usage`:r.pathname=`/usage`;break;case`deploys`:r.pathname=`/deploys`;break;case`webhooks`:r.pathname=`/webhooks`;break;default:r.pathname=`/`}return t.siteId&&r.searchParams.set(`site`,t.siteId),r.toString()}export{r as deepLinkFor,t as openInBrowser};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import"./telemetry-urcJlNpJ.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import"./client-DTXWADkX.js";import"./formatter-DutfcQAc.js";import{emit$1 as r,isHeadless as i}from"./emit-DBYk96TD.js";import{Panel as a}from"./panel-B_yDcIcn.js";import{Banner as o}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as s}from"./keybar-DsYTkKZX.js";import"./sparkline-BZ0eMB-w.js";import{ChatPanel as c}from"./chat-panel-C_yjPXnw.js";import{resolveSiteId as l}from"./resolve-site-DSJR9vuz.js";import{EmptyState as u}from"./empty-state-CJxa1jUN.js";import{EmbeddedGlobe as d,MetricCard as f}from"./embedded-globe-ClP_lA3q.js";import{deepLinkFor as p,openInBrowser as m}from"./keybar-deep-link-C9xNYihD.js";import"./sphere-globe-CvHshl9g.js";import{Box as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useState as S}from"react";import C from"ink-spinner";async function w(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await l(c,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await c.getLive(u);return r({type:`live.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=_(b.createElement(T,{api:c,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const T=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:l}=v(),[_,w]=S(null),[T,E]=S(!0),[D,O]=S(null),[k,A]=S(!1);if(y(e=>{if(!k){if(e===`/`){A(!0);return}if(e===`o`||e===`O`){m(p(`live`,{siteId:t}));return}e===`q`&&(l(),i(0))}}),x(()=>{if(k)return;let n=!1,r=async()=>{try{let r=await e.getLive(t);n||(w(r),E(!1),O(null))}catch(e){n||(O(e.message),E(!1))}};r();let i=setInterval(r,2e3);return()=>{n=!0,clearInterval(i)}},[e,t,k]),k)return b.createElement(c,{cliVersion:r,api:e,dashboardContext:{commandName:`live`,siteId:t,siteLabel:n,metricsSnapshot:_},onClose:()=>A(!1)});if(T)return b.createElement(h,{flexDirection:`column`},b.createElement(o,{version:r,subtitle:`live · ${n}`}),b.createElement(a,{title:`Loading`,state:`busy`},b.createElement(h,null,b.createElement(g,{color:`magenta`},b.createElement(C,{type:`dots`})),b.createElement(g,null,` Connecting…`))));if(D&&!_)return b.createElement(h,{flexDirection:`column`},b.createElement(o,{version:r,subtitle:`live · ${n}`}),b.createElement(u,{reason:`error`,headline:`Failed to load`,hint:D}));let j=process.stdout.columns??80,M=Math.max(20,Math.min(40,Math.floor(j/3)));return b.createElement(h,{flexDirection:`column`},b.createElement(o,{version:r,subtitle:`live · ${n}`}),b.createElement(h,{flexDirection:`row`},b.createElement(f,{title:`Active now`,value:_?.activeVisitors??0,format:`number`,width:M}),b.createElement(a,{title:`Globe`,width:Math.max(40,j-M-4)},b.createElement(d,{events:_?.recentEvents??[],width:Math.max(36,j-M-10),height:10}))),b.createElement(a,{title:`Recent events`},!_||_.recentEvents.length===0?b.createElement(g,{color:`gray`},`— waiting for events —`):_.recentEvents.slice(0,15).map((e,t)=>b.createElement(h,{key:t},b.createElement(g,{color:`cyan`},(e.type??`pageview`).padEnd(10)),b.createElement(g,null,e.path.padEnd(36).slice(0,36)),b.createElement(g,{color:`gray`},e.country??`—`)))),b.createElement(s,{items:[{key:`/`,label:`ask AI`},{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{w as liveCommand};
@@ -1 +0,0 @@
1
- import{useTheme as e}from"./panel-B_yDcIcn.js";import{Box as t,Text as n}from"ink";import r from"react";const i={DZ:{lat:28.0339,lng:1.6596,name:`Algeria`,spread:8},EG:{lat:26.8206,lng:30.8025,name:`Egypt`,spread:6},ET:{lat:9.145,lng:40.4897,name:`Ethiopia`,spread:6},GH:{lat:7.9465,lng:-1.0232,name:`Ghana`,spread:3},KE:{lat:-.0236,lng:37.9062,name:`Kenya`,spread:4},MA:{lat:31.7917,lng:-7.0926,name:`Morocco`,spread:5},NG:{lat:9.082,lng:8.6753,name:`Nigeria`,spread:5},ZA:{lat:-30.5595,lng:22.9375,name:`South Africa`,spread:7},TZ:{lat:-6.369,lng:34.8888,name:`Tanzania`,spread:5},UG:{lat:1.3733,lng:32.2903,name:`Uganda`,spread:3},TN:{lat:33.8869,lng:9.5375,name:`Tunisia`,spread:3},SN:{lat:14.4974,lng:-14.4524,name:`Senegal`,spread:3},CI:{lat:7.54,lng:-5.5471,name:`Côte d'Ivoire`,spread:3},CM:{lat:7.3697,lng:12.3547,name:`Cameroon`,spread:4},AO:{lat:-11.2027,lng:17.8739,name:`Angola`,spread:6},MZ:{lat:-18.6657,lng:35.5296,name:`Mozambique`,spread:6},ZW:{lat:-19.0154,lng:29.1549,name:`Zimbabwe`,spread:4},ZM:{lat:-13.1339,lng:27.8493,name:`Zambia`,spread:5},RW:{lat:-1.9403,lng:29.8739,name:`Rwanda`,spread:1.5},MG:{lat:-18.7669,lng:46.8691,name:`Madagascar`,spread:5},LY:{lat:26.3351,lng:17.2283,name:`Libya`,spread:8},SD:{lat:12.8628,lng:30.2176,name:`Sudan`,spread:7},US:{lat:39.0902,lng:-98.5795,name:`United States`,spread:18},CA:{lat:56.1304,lng:-106.3468,name:`Canada`,spread:22},MX:{lat:23.6345,lng:-102.5528,name:`Mexico`,spread:9},BR:{lat:-10.235,lng:-51.9253,name:`Brazil`,spread:18},AR:{lat:-38.4161,lng:-63.6167,name:`Argentina`,spread:11},CL:{lat:-35.6751,lng:-71.543,name:`Chile`,spread:11},CO:{lat:4.5709,lng:-74.2973,name:`Colombia`,spread:6},PE:{lat:-9.19,lng:-75.0152,name:`Peru`,spread:7},VE:{lat:6.4238,lng:-66.5897,name:`Venezuela`,spread:6},EC:{lat:-1.8312,lng:-78.1834,name:`Ecuador`,spread:3},BO:{lat:-16.2902,lng:-63.5887,name:`Bolivia`,spread:6},UY:{lat:-32.5228,lng:-55.7658,name:`Uruguay`,spread:2.5},PY:{lat:-23.4425,lng:-58.4438,name:`Paraguay`,spread:4},GT:{lat:15.7835,lng:-90.2308,name:`Guatemala`,spread:2},CU:{lat:21.5218,lng:-77.7812,name:`Cuba`,spread:3},DO:{lat:18.7357,lng:-70.1627,name:`Dominican Republic`,spread:1.5},CR:{lat:9.7489,lng:-83.7534,name:`Costa Rica`,spread:1.2},PA:{lat:8.538,lng:-80.7821,name:`Panama`,spread:1.5},HN:{lat:15.2,lng:-86.2419,name:`Honduras`,spread:2},PR:{lat:18.2208,lng:-66.5901,name:`Puerto Rico`,spread:.6},JM:{lat:18.1096,lng:-77.2975,name:`Jamaica`,spread:.7},TT:{lat:10.6918,lng:-61.2225,name:`Trinidad and Tobago`,spread:.6},GB:{lat:55.3781,lng:-3.436,name:`United Kingdom`,spread:3},IE:{lat:53.4129,lng:-8.2439,name:`Ireland`,spread:2},FR:{lat:46.6034,lng:1.8883,name:`France`,spread:4},DE:{lat:51.1657,lng:10.4515,name:`Germany`,spread:3.5},IT:{lat:41.8719,lng:12.5674,name:`Italy`,spread:3.5},ES:{lat:40.4637,lng:-3.7492,name:`Spain`,spread:4},PT:{lat:39.3999,lng:-8.2245,name:`Portugal`,spread:2},NL:{lat:52.1326,lng:5.2913,name:`Netherlands`,spread:1.2},BE:{lat:50.5039,lng:4.4699,name:`Belgium`,spread:1},CH:{lat:46.8182,lng:8.2275,name:`Switzerland`,spread:1.4},AT:{lat:47.5162,lng:14.5501,name:`Austria`,spread:2},PL:{lat:51.9194,lng:19.1451,name:`Poland`,spread:3.5},CZ:{lat:49.8175,lng:15.473,name:`Czechia`,spread:1.8},SE:{lat:60.1282,lng:18.6435,name:`Sweden`,spread:5},NO:{lat:60.472,lng:8.4689,name:`Norway`,spread:5},FI:{lat:61.9241,lng:25.7482,name:`Finland`,spread:4},DK:{lat:56.2639,lng:9.5018,name:`Denmark`,spread:1.5},IS:{lat:64.9631,lng:-19.0208,name:`Iceland`,spread:3},GR:{lat:39.0742,lng:21.8243,name:`Greece`,spread:3},TR:{lat:38.9637,lng:35.2433,name:`Turkey`,spread:6},RO:{lat:45.9432,lng:24.9668,name:`Romania`,spread:3},HU:{lat:47.1625,lng:19.5033,name:`Hungary`,spread:2},UA:{lat:48.3794,lng:31.1656,name:`Ukraine`,spread:5},RU:{lat:61.524,lng:80,name:`Russia`,spread:28},BG:{lat:42.7339,lng:25.4858,name:`Bulgaria`,spread:2},HR:{lat:45.1,lng:15.2,name:`Croatia`,spread:2},RS:{lat:44.0165,lng:21.0059,name:`Serbia`,spread:2},SK:{lat:48.669,lng:19.699,name:`Slovakia`,spread:1.8},SI:{lat:46.1512,lng:14.9955,name:`Slovenia`,spread:1.2},LT:{lat:55.1694,lng:23.8813,name:`Lithuania`,spread:1.5},LV:{lat:56.8796,lng:24.6032,name:`Latvia`,spread:1.5},EE:{lat:58.5953,lng:25.0136,name:`Estonia`,spread:1.5},BY:{lat:53.7098,lng:27.9534,name:`Belarus`,spread:3},MD:{lat:47.4116,lng:28.3699,name:`Moldova`,spread:1.2},AL:{lat:41.1533,lng:20.1683,name:`Albania`,spread:1},MK:{lat:41.6086,lng:21.7453,name:`North Macedonia`,spread:1},BA:{lat:43.9159,lng:17.6791,name:`Bosnia and Herzegovina`,spread:1.2},ME:{lat:42.7087,lng:19.3744,name:`Montenegro`,spread:.8},XK:{lat:42.6026,lng:20.903,name:`Kosovo`,spread:.7},LU:{lat:49.8153,lng:6.1296,name:`Luxembourg`,spread:.4},MT:{lat:35.9375,lng:14.3754,name:`Malta`,spread:.3},CY:{lat:35.1264,lng:33.4299,name:`Cyprus`,spread:.6},CN:{lat:35.8617,lng:104.1954,name:`China`,spread:18},JP:{lat:36.2048,lng:138.2529,name:`Japan`,spread:5},KR:{lat:35.9078,lng:127.7669,name:`South Korea`,spread:2},IN:{lat:20.5937,lng:78.9629,name:`India`,spread:12},ID:{lat:-2.7893,lng:113.9213,name:`Indonesia`,spread:12},PH:{lat:12.8797,lng:121.774,name:`Philippines`,spread:5},VN:{lat:14.0583,lng:108.2772,name:`Vietnam`,spread:5},TH:{lat:15.87,lng:100.9925,name:`Thailand`,spread:4},MY:{lat:4.2105,lng:101.9758,name:`Malaysia`,spread:4},SG:{lat:1.3521,lng:103.8198,name:`Singapore`,spread:.3},PK:{lat:30.3753,lng:69.3451,name:`Pakistan`,spread:6},BD:{lat:23.685,lng:90.3563,name:`Bangladesh`,spread:3},LK:{lat:7.8731,lng:80.7718,name:`Sri Lanka`,spread:2},MM:{lat:21.9162,lng:95.956,name:`Myanmar`,spread:6},KH:{lat:12.5657,lng:104.991,name:`Cambodia`,spread:3},LA:{lat:19.8563,lng:102.4955,name:`Laos`,spread:3},NP:{lat:28.3949,lng:84.124,name:`Nepal`,spread:3},IR:{lat:32.4279,lng:53.688,name:`Iran`,spread:7},IQ:{lat:33.2232,lng:43.6793,name:`Iraq`,spread:4},IL:{lat:31.0461,lng:34.8516,name:`Israel`,spread:1},SA:{lat:23.8859,lng:45.0792,name:`Saudi Arabia`,spread:8},AE:{lat:23.4241,lng:53.8478,name:`UAE`,spread:2},QA:{lat:25.3548,lng:51.1839,name:`Qatar`,spread:.6},KW:{lat:29.3117,lng:47.4818,name:`Kuwait`,spread:.8},OM:{lat:21.4735,lng:55.9754,name:`Oman`,spread:4},JO:{lat:30.5852,lng:36.2384,name:`Jordan`,spread:2},LB:{lat:33.8547,lng:35.8623,name:`Lebanon`,spread:.7},SY:{lat:34.8021,lng:38.9968,name:`Syria`,spread:3},YE:{lat:15.5527,lng:48.5164,name:`Yemen`,spread:4},AF:{lat:33.9391,lng:67.71,name:`Afghanistan`,spread:5},KZ:{lat:48.0196,lng:66.9237,name:`Kazakhstan`,spread:13},UZ:{lat:41.3775,lng:64.5853,name:`Uzbekistan`,spread:5},TM:{lat:38.9697,lng:59.5563,name:`Turkmenistan`,spread:5},KG:{lat:41.2044,lng:74.7661,name:`Kyrgyzstan`,spread:3},TJ:{lat:38.861,lng:71.2761,name:`Tajikistan`,spread:3},AZ:{lat:40.1431,lng:47.5769,name:`Azerbaijan`,spread:2},GE:{lat:42.3154,lng:43.3569,name:`Georgia`,spread:2},AM:{lat:40.0691,lng:45.0382,name:`Armenia`,spread:1.2},HK:{lat:22.3193,lng:114.1694,name:`Hong Kong`,spread:.3},TW:{lat:23.6978,lng:120.9605,name:`Taiwan`,spread:1.5},AU:{lat:-25.2744,lng:133.7751,name:`Australia`,spread:18},NZ:{lat:-40.9006,lng:174.886,name:`New Zealand`,spread:5},PG:{lat:-6.314,lng:143.9555,name:`Papua New Guinea`,spread:5},FJ:{lat:-16.578,lng:179.4144,name:`Fiji`,spread:1}},a=Object.fromEntries(Object.entries(i).map(([e,t])=>[e,{lat:t.lat,lng:t.lng}]));function o(e){return!e||e.length!==2?null:i[e.toUpperCase()]??null}function s(e,t){let n=o(e);if(!n||t<=0)return[];let r=[],i=0;for(let t=0;t<e.length;t++)i=i*31+e.charCodeAt(t)>>>0;for(let e=0;e<t;e++){i=i+1831565813>>>0;let e=i;e=Math.imul(e^e>>>15,e|1)>>>0,e=(e^e+(Math.imul(e^e>>>7,e|61)>>>0))>>>0;let t=((e^e>>>14)>>>0)/4294967296;i=i+2246822507>>>0;let a=i;a=Math.imul(a^a>>>15,a|1)>>>0,a=(a^a+(Math.imul(a^a>>>7,a|61)>>>0))>>>0;let o=((a^a>>>14)>>>0)/4294967296,s=n.spread*Math.sqrt(t),c=o*2*Math.PI;r.push({lat:n.lat+s*Math.sin(c)*.7,lng:n.lng+s*Math.cos(c)/Math.max(.3,Math.cos(n.lat*Math.PI/180))})}return r}const c=360,l=180,u=new Uint8Array(c*l),d=new Uint8Array(c*l),f=[`__OCEAN__`];function p(e){let t=(e%360+360)%360;return Math.floor(t)}function m(e){return Math.max(0,Math.min(l-1,Math.floor(90-e)))}function h(e,t,n){let r=m(e),i=p(t);u[r*c+i]=1,d[r*c+i]=n}for(let e of Object.keys(i)){let t=i[e];f.push(e);let n=f.length-1,r=Math.max(.5,t.spread*.85),a=Math.max(.25,Math.cos(t.lat*Math.PI/180)),o=Math.max(.5,t.spread/a),s=Math.floor(t.lat-r),c=Math.ceil(t.lat+r),l=Math.floor(t.lng-o),u=Math.ceil(t.lng+o);for(let e=s;e<=c;e++)for(let i=l;i<=u;i++){let a=(e-t.lat)/r,s=(i-t.lng)/o;s*s+a*a>1||h(e,i,n)}}const g=new Uint8Array(u);for(let e=1;e<l-1;e++)for(let t=0;t<c;t++){if(u[e*c+t])continue;let n=0,r=0;for(let i=-1;i<=1;i++)for(let a=-1;a<=1;a++){if(i===0&&a===0)continue;let o=(t+a+c)%c;u[(e+i)*c+o]&&(n++,r||=d[(e+i)*c+o]??0)}n>=4&&(g[e*c+t]=1,d[e*c+t]=r)}u.set(g);const _=new Uint8Array(c*l);for(let e=0;e<l;e++)for(let t=0;t<c;t++){let n=d[e*c+t];if(!n)continue;let r=e>0?d[(e-1)*c+t]:0,i=e<l-1?d[(e+1)*c+t]:0,a=d[e*c+(t-1+c)%c],o=d[e*c+(t+1)%c];(r!==n||i!==n||a!==n||o!==n)&&(_[e*c+t]=1)}function v(e,t){if(e<-90||e>90)return 0;let n=Math.max(0,Math.min(l-1,Math.floor(90-e))),r=(t%360+360)%360,i=Math.floor(r);return u[n*c+i]===1?1:0}function y(e,t){if(e<-90||e>90)return 0;let n=Math.max(0,Math.min(l-1,Math.floor(90-e))),r=(t%360+360)%360,i=Math.floor(r);return _[n*c+i]===1?1:0}function b(e){return e*Math.PI/180}function x(e,t){let n=b(e),r=b(t);return{x:Math.cos(n)*Math.sin(r),y:Math.sin(n),z:Math.cos(n)*Math.cos(r)}}function S(e,t){let n=Math.cos(t),r=Math.sin(t);return{x:n*e.x+r*e.z,y:e.y,z:-r*e.x+n*e.z}}function C(e,t){let n=Math.cos(t),r=Math.sin(t);return{x:e.x,y:n*e.y-r*e.z,z:r*e.y+n*e.z}}function w(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function T(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function E(e,t,n,r){let i=r*r;for(let a=-r;a<=r;a++)for(let o=-r;o<=r;o++)o*o+a*a<=i&&T(e,Math.round(t+o),Math.round(n+a))}const D=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function O(e,t,n){let r=0;for(let i=0;i<D.length;i++){let[a,o]=D[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function k(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`·`:r<=5?`○`:`●`}function A(e){if(e)return!0;let t=process.env;if(t.NO_COLOR||t.ZENOVAY_GLOBE===`ascii`)return!0;let n=(t.LANG||t.LC_ALL||t.LC_CTYPE||``).toLowerCase();return!!(n&&!n.includes(`utf`))}function j(e,t,n){if(e.z<0)return null;let r=t/2,i=n/2,a=Math.min(t,n/2)*.95;return{x:r+e.x*a,y:i-e.y*a}}function M(e){let t=e.dw/2,n=e.dh/2,r=Math.min(e.dw,e.dh/2)*.95,i=Math.round(2*Math.PI*r);for(let a=0;a<i;a++){let o=a/i*2*Math.PI,s=Math.round(t+r*Math.cos(o)),c=Math.round(n+r*Math.sin(o));T(e,s,c)}}function N(e,t,n){for(let r of[-60,-30,0,30,60])for(let i=-180;i<=180;i+=4){let a=C(S(x(r,i),t),n),o=j(a,e.dw,e.dh);o&&T(e,Math.round(o.x),Math.round(o.y))}for(let r=-180;r<180;r+=30)for(let i=-85;i<=85;i+=4){let a=C(S(x(i,r),t),n),o=j(a,e.dw,e.dh);o&&T(e,Math.round(o.x),Math.round(o.y))}}function P({visitors:i,highlight:a,width:o=50,height:s=25,rotationDeg:c=0,tiltDeg:l=20,gridlines:u=!0,asciiOnly:d}){let{theme:f}=e(),p=A(d),m=w(o,s),h=w(o,s),g=w(o,s),_=w(o,s),D=w(o,s),P=b(c),F=b(-l);M(m),u&&N(m,P,F);{let e=h.dw/2,t=h.dh/2,n=Math.min(h.dw,h.dh/2)*.95,r=Math.cos(P),i=Math.sin(P),a=Math.cos(F),o=Math.sin(F);for(let s=0;s<h.dh;s++){let c=(t-s)/n;if(!(c<-1||c>1))for(let t=0;t<h.dw;t++){let l=(t-e)/n,u=l*l+c*c;if(u>1)continue;let d=Math.sqrt(1-u),f=l,p=c,m=a*p+o*d,_=-o*p+a*d,b=r*f-i*_,x=i*f+r*_,S=Math.asin(m)*(180/Math.PI),C=Math.atan2(b,x)*(180/Math.PI);v(S,C)&&(T(h,t,s),y(S,C)&&T(g,t,s))}}}for(let e of i){let t=C(S(x(e.lat,e.lng),P),F),n=j(t,_.dw,_.dh);if(!n)continue;let r=typeof e.freshness==`number`?e.freshness:.5;E(_,n.x,n.y,r>.7?2:1)}if(a&&a.length>0)for(let e of a){let t=C(S(x(e.lat,e.lng),P),F),n=j(t,D.dw,D.dh);if(!n)continue;E(D,n.x,n.y,2)}let I=[];for(let e=0;e<s;e++){let i=[],a=null,s=(e,t)=>{a&&a.color===e?a.text+=t:(a={color:e,text:t},i.push(a))};for(let t=0;t<o;t++){let n=p?k(D,t,e):O(D,t,e);if(n!==` `){s(f.warn,n);continue}let r=p?k(_,t,e):O(_,t,e);if(r!==` `){s(f.accent,r);continue}let a=p?k(g,t,e):O(g,t,e);if(a!==` `){s(f.fg,a);continue}let o=p?k(h,t,e):O(h,t,e);if(o!==` `){s(f.success,o);continue}let c=p?k(m,t,e):O(m,t,e);if(c!==` `){s(f.muted,c);continue}let l=i.length>0?i[i.length-1]:void 0;s(l?l.color:f.muted,` `)}I.push(r.createElement(t,{key:e},r.createElement(n,null,i.map((e,t)=>r.createElement(n,{key:t,color:e.color,bold:!0},e.text)))))}return r.createElement(t,{flexDirection:`column`},I)}export{P as SphereGlobe,o as infoFor,s as scatterCountryDots};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-Dn_Cl0cD.js";import"./api-BD_nTdOq.js";import{readToken as t}from"./token-store-DWXh9r3Z.js";import{ApiV2Client as n}from"./api-v2-q-vnosdb.js";import{parseSseStream as r}from"./client-DTXWADkX.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import{spark as l}from"./sparkline-BZ0eMB-w.js";import{resolveSiteId as u}from"./resolve-site-DSJR9vuz.js";import{EmptyState as d}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as f,openInBrowser as p}from"./keybar-deep-link-C9xNYihD.js";import{Globe as m}from"./globe-DaSl9ejK.js";import{z as h}from"zod";import{Box as g,Text as _,render as v,useApp as y,useInput as b}from"ink";import x,{useEffect as S,useState as C}from"react";import w from"ink-spinner";import T from"ink-text-input";const E=h.object({siteId:h.string().optional(),window:h.string().optional(),totalVisitors:h.number().optional(),visitors:h.object({count:h.number().optional(),series:h.array(h.number()).optional()}).optional(),topPages:h.array(h.object({path:h.string(),views:h.number().optional(),count:h.number().optional()})).optional(),sources:h.array(h.object({source:h.string(),visitors:h.number()})).optional()}).passthrough();async function D(r){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:r.cliVersion,token:s}),l;try{({siteId:l}=await u(c,{explicit:r.siteId,headless:!!r.json,cliVersion:r.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(a(r)){let e=await c.getDashboardSnapshot(l);return i({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=v(x.createElement(O,{api:c,siteId:l,intervalMs:r.intervalMs??15e3,cliVersion:r.cliVersion,onExit:n=>{t(),e(n)}}))})}const O=({api:e,siteId:t,intervalMs:n,cliVersion:i,onExit:a})=>{let{exit:l}=y(),[u,h]=C(null),[v,T]=C(null),[D,O]=C(null),[I,L]=C([]),[R,z]=C(!0),[B,V]=C(null),[H,U]=C(1),[W,G]=C(!1),[K,q]=C(!1);b((e,n)=>{if(e===`o`||e===`O`){p(f(`watch`,{siteId:t}));return}if(e===`q`){l(),a(0);return}if(e===`?`||e===`/`){q(e=>!e);return}if(e===`g`){G(e=>!e);return}if(n.tab){U(e=>{let t=n.shift?(e+4)%6+1:e%6+1;return t});return}(e===`1`||e===`2`||e===`3`||e===`4`||e===`5`||e===`6`)&&U(Number(e))});let[J,Y]=C(!1);if(S(()=>{let r=!1,i=async()=>{try{let n=await e.getDashboardSnapshot(t);if(r)return;let i=E.safeParse(n);if(!i.success){Y(!0),z(!1);return}Y(!1);let a=i.data,o={visitors:a.visitors??(typeof a.totalVisitors==`number`?{count:a.totalVisitors}:void 0),topPages:a.topPages?.map(e=>({path:e.path,views:e.views??e.count??0})),sources:a.sources};h(o),e.getVitals(t).then(e=>{r||T(e)},()=>{}),e.getGoals(t).then(e=>{r||O(e)},()=>{}),z(!1),V(null)}catch(e){r||V(e.message)}};i();let a=setInterval(i,n);return()=>{r=!0,clearInterval(a)}},[e,t,n]),S(()=>{let n=new AbortController;return(async()=>{try{let i=await e.openEventsStream(t,n.signal);for await(let e of r(i))e.type===`error`&&L(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>n.abort()},[e,t]),R)return x.createElement(g,{flexDirection:`column`},x.createElement(s,{version:i,subtitle:`watch · ${t}`}),x.createElement(o,{title:`Loading`,state:`busy`},x.createElement(g,null,x.createElement(_,{color:`magenta`},x.createElement(w,{type:`dots`})),x.createElement(_,null,` Fetching snapshot…`))));if(B&&!u)return x.createElement(g,{flexDirection:`column`},x.createElement(s,{version:i,subtitle:`watch · ${t}`}),x.createElement(o,{title:`Error`,state:`err`},x.createElement(_,{color:`red`},B)));if(J&&!u)return x.createElement(g,{flexDirection:`column`},x.createElement(s,{version:i,subtitle:`watch · ${t}`}),x.createElement(d,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let X=process.stdout.columns??80,Z=Math.max(20,Math.floor(X/3)-1),Q=[];return x.createElement(g,{flexDirection:`column`},x.createElement(s,{version:i,subtitle:`watch · ${t}${W?` · globe`:``}`}),x.createElement(g,{flexDirection:`row`},x.createElement(g,{flexDirection:`column`},W?x.createElement(o,{title:`Live globe`,focused:H===1,width:Z},x.createElement(m,{data:Q,width:Math.max(40,Z-4),height:12})):x.createElement(A,{snapshot:u,focused:H===1,width:Z}),x.createElement(N,{events:I,focused:H===4,width:Z})),x.createElement(g,{flexDirection:`column`},x.createElement(j,{snapshot:u,focused:H===2,width:Z}),x.createElement(P,{vitals:v,focused:H===5,width:Z})),x.createElement(g,{flexDirection:`column`},x.createElement(M,{snapshot:u,focused:H===3,width:Z}),x.createElement(F,{goals:D,focused:H===6,width:Z}))),K?x.createElement(k,{api:e,siteId:t,width:X-2}):null,x.createElement(c,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:W?`panels`:`globe`},{key:`?/`,label:K?`close chat`:`ai chat`},{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))},k=({api:e,siteId:t,width:n})=>{let[i,a]=C(``),[s,c]=C([]),[l,u]=C(!1),[d,f]=C(``),[p,m]=C(null),h=async n=>{let i=n.trim();if(!i||l)return;m(null),a(``);let o=[...s,{role:`user`,content:i}];c(o),u(!0),f(``);try{let n=o.map(e=>({role:e.role,content:e.content})),i=await e.openAiStream(`chat`,{messages:n,siteId:t},void 0),a=``;for await(let e of r(i))if(e.type===`delta`)a+=e.content,f(a);else if(e.type===`error`)m(`${e.code}: ${e.message}`);else if(e.type===`done`)break;c([...o,{role:`assistant`,content:a}]),f(``)}catch(e){m(e instanceof Error?e.message:`chat failed`)}finally{u(!1)}};return x.createElement(g,{marginTop:1},x.createElement(o,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:n},x.createElement(g,{flexDirection:`column`},s.slice(-6).map((e,t)=>x.createElement(g,{key:t,flexDirection:`column`,marginBottom:1},x.createElement(_,{color:e.role===`user`?`cyan`:`magenta`,bold:!0},e.role===`user`?`you`:`zenovay`),x.createElement(_,null,e.content))),l&&d?x.createElement(g,{flexDirection:`column`,marginBottom:1},x.createElement(_,{color:`magenta`,bold:!0},`zenovay`),x.createElement(_,null,d)):null,p?x.createElement(_,{color:`red`},`✗ `,p):null,x.createElement(g,null,x.createElement(_,{color:`cyan`},l?`⠋ `:`▸ `),x.createElement(T,{value:i,onChange:a,onSubmit:h,placeholder:l?`streaming…`:`ask anything about your analytics`})))))},A=({snapshot:e,focused:t,width:n})=>{let r=e?.visitors?.count??0,i=e?.visitors?.series??[];return x.createElement(o,{title:`Visitors`,focused:t,width:n},x.createElement(_,{bold:!0},r.toString()),x.createElement(_,{color:`gray`},i.length>0?l(i,Math.max(8,n-6)):`— no data —`))},j=({snapshot:e,focused:t,width:n})=>{let r=e?.topPages?.slice(0,5)??[];return x.createElement(o,{title:`Top pages`,focused:t,width:n},r.length===0?x.createElement(_,{color:`gray`},`— no data —`):r.map(e=>x.createElement(g,{key:e.path},x.createElement(_,null,e.path.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:`gray`},` `,e.views))))},M=({snapshot:e,focused:t,width:n})=>{let r=e?.sources?.slice(0,5)??[];return x.createElement(o,{title:`Sources`,focused:t,width:n},r.length===0?x.createElement(_,{color:`gray`},`— no data —`):r.map(e=>x.createElement(g,{key:e.source},x.createElement(_,null,e.source.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:`gray`},` `,e.visitors))))},N=({events:e,focused:t,width:n})=>x.createElement(o,{title:`Events`,focused:t,width:n},e.length===0?x.createElement(_,{color:`gray`},`— waiting —`):e.slice(-10).map((e,t)=>x.createElement(_,{key:t},e.slice(0,n-4)))),P=({vitals:e,focused:t,width:n})=>{let r=(e,t,n)=>x.createElement(g,{key:e},x.createElement(_,{bold:!0},e.padEnd(6)),x.createElement(_,{color:`gray`},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return x.createElement(o,{title:`Vitals`,focused:t,width:n},r(`LCP`,e?.lcpP75,`ms`),r(`INP`,e?.inpP75,`ms`),r(`CLS`,e?.clsP75?e.clsP75*1e3:void 0,`/1k`),r(`TTFB`,e?.ttfbP75,`ms`),r(`FCP`,e?.fcpP75,`ms`))},F=({goals:e,focused:t,width:n})=>{let r=e?.goals?.slice(0,5)??[];return x.createElement(o,{title:`Goals`,focused:t,width:n},r.length===0?x.createElement(_,{color:`gray`},`— no data —`):r.map(e=>x.createElement(g,{key:e.name},x.createElement(_,null,e.name.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:`gray`},` `,e.completions))))};export{D as watchCommand};
File without changes