@zenovay/cli 0.1.19 → 0.1.20

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-4Yo74A1a.js → ai-BtL-3tWv.js} +1 -1
  2. package/dist/{analytical-screen-DI8ahq4z.js → analytical-screen-DdnG-A8U.js} +1 -1
  3. package/dist/bin.js +2 -2
  4. package/dist/companies-Ck1YXksb.js +2 -0
  5. package/dist/{data-table-CDTM2qS0.js → data-table-B1FiGp8c.js} +1 -1
  6. package/dist/deploys-BDcSODZT.js +2 -0
  7. package/dist/devices-DiBMDyfc.js +1 -0
  8. package/dist/{doctor-CjpTOujh.js → doctor-Cewej993.js} +1 -1
  9. package/dist/{empty-state-CNtcEPJ9.js → empty-state-BUlTM7wA.js} +1 -1
  10. package/dist/errors-DHpw3PO2.js +2 -0
  11. package/dist/{events-tail-CtoMkdkb.js → events-tail-BlMK84c8.js} +1 -1
  12. package/dist/funnel-Z3HHRLwg.js +3 -0
  13. package/dist/geo-PyqvcLvy.js +1 -0
  14. package/dist/gradient-93CUjfDW.js +3 -0
  15. package/dist/{health-DBiKIoYL.js → health-BioDPveS.js} +1 -1
  16. package/dist/{health-Bn_Bw6c_.js → health-DBXPCNzJ.js} +1 -1
  17. package/dist/heatmaps-CrOP0_TX.js +1 -0
  18. package/dist/{init-HBcPrM1L.js → init-CZTDJ-vf.js} +3 -3
  19. package/dist/init-DbWxI6M2.js +1 -0
  20. package/dist/insights-yI1UgyRG.js +1 -0
  21. package/dist/journeys-DegXpwij.js +1 -0
  22. package/dist/{keybar-DUC7w1HQ.js → keybar-CoNHlPOn.js} +1 -1
  23. package/dist/live-BeZkd7mo.js +1 -0
  24. package/dist/{metric-card-W4GayhPO.js → metric-card--FhiQMgt.js} +1 -1
  25. package/dist/overview-CGTlmjQy.js +1 -0
  26. package/dist/pages-CEcLNfKb.js +1 -0
  27. package/dist/panel-BNI8Q_9k.js +1 -0
  28. package/dist/projects-DnzI_z_C.js +2 -0
  29. package/dist/prompt-CnNQNqeK.js +1 -0
  30. package/dist/query-DlhhP3PE.js +8 -0
  31. package/dist/{resolve-site-B54mr0Bh.js → resolve-site-IXvBPhrx.js} +1 -1
  32. package/dist/retention-xuYAxg4L.js +1 -0
  33. package/dist/revenue-CUHv5LCn.js +2 -0
  34. package/dist/sessions-DXxeC1Om.js +1 -0
  35. package/dist/sources-Bs-T6MjS.js +2 -0
  36. package/dist/stats-DWj2oLhf.js +2 -0
  37. package/dist/themes-DbjOibiR.js +4 -0
  38. package/dist/ui-Bw_RHAeN.js +1 -0
  39. package/dist/uptime-DQUNMxBI.js +1 -0
  40. package/dist/{use-DOxo6QgS.js → use-DSsSDVW7.js} +1 -1
  41. package/dist/vitals-B23CXo61.js +2 -0
  42. package/dist/{watch-CawlqYPo.js → watch-D12Fz1UB.js} +1 -1
  43. package/dist/webhooks-forward-9COAtWRu.js +3 -0
  44. package/dist/wizard-bin.js +1 -1
  45. package/package.json +1 -1
  46. package/dist/companies-f2shersJ.js +0 -2
  47. package/dist/deploys-CudLAqUS.js +0 -2
  48. package/dist/devices-B4_ouB05.js +0 -1
  49. package/dist/errors-CEJ43Vd4.js +0 -2
  50. package/dist/funnel-CK0vfgfb.js +0 -3
  51. package/dist/geo-CInOewrI.js +0 -1
  52. package/dist/heatmaps-DfVR48Km.js +0 -1
  53. package/dist/init-BMNuKlUT.js +0 -1
  54. package/dist/insights-Dd0HWA_M.js +0 -1
  55. package/dist/journeys-CCrSFXhO.js +0 -1
  56. package/dist/live-CUExJ1O5.js +0 -1
  57. package/dist/overview-CNuR2Mx9.js +0 -1
  58. package/dist/pages-CdoPyNQH.js +0 -1
  59. package/dist/panel-DZqvtaao.js +0 -1
  60. package/dist/projects-Cb8Jk1rh.js +0 -2
  61. package/dist/prompt-DEng-me1.js +0 -3
  62. package/dist/query-BDppYLwt.js +0 -8
  63. package/dist/retention-B-fiW8Un.js +0 -1
  64. package/dist/revenue-D0DkXtgI.js +0 -2
  65. package/dist/sessions-DYb8v1LG.js +0 -1
  66. package/dist/sources-2Zhm5ihV.js +0 -2
  67. package/dist/stats-Bf3LR7aS.js +0 -2
  68. package/dist/themes-Ty85UcjT.js +0 -4
  69. package/dist/ui-BtZp4Eh8.js +0 -1
  70. package/dist/uptime-I4CzdPZv.js +0 -1
  71. package/dist/vitals-XBfK3I8H.js +0 -2
  72. package/dist/webhooks-forward-DcnCiBcP.js +0 -3
  73. /package/dist/{completions-hFMu39uk.js → completions-CnHbpLqp.js} +0 -0
  74. /package/dist/{logout-B_-6rZdK.js → logout-B3V_2DRZ.js} +0 -0
  75. /package/dist/{sparkline-B6ueqPAB.js → sparkline-ut0Tvv-E.js} +0 -0
  76. /package/dist/{tier-Ceoo7ndQ.js → tier-DJvWU86k.js} +0 -0
  77. /package/dist/{update-5mypMXp6.js → update-wMGBdUT-.js} +0 -0
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-BNI8Q_9k.js";import{Banner as a}from"./prompt-CnNQNqeK.js";import{Keybar as o}from"./keybar-CoNHlPOn.js";import{resolveSiteId as s}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{EmptyState as l}from"./empty-state-BUlTM7wA.js";import{requireTier as u}from"./tier-DJvWU86k.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";async function b(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new c({config:a,cliVersion:i.cliVersion,token:o});try{await u(l,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await s(l,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let m=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(r(i)){let e=await l.getJourneys(d);return n({type:`journeys.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:l,siteId:d,siteLabel:m,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:s})=>{let{exit:c}=m(),[u,p]=v(null),[b,x]=v(!0),[S,C]=v(null);if(h(e=>{e===`q`&&(c(),s(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getJourneys(t);n||(p(r.flows),x(!1))}catch(e){n||(C(e.message),x(!1))}})(),()=>{n=!0}},[e,t]),b)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`journeys · ${n}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Computing flows…`))));if(S)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`journeys · ${n}`}),g.createElement(l,{reason:`error`,headline:`Failed to load`,hint:S}));if(!u||u.length===0)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`journeys · ${n}`}),g.createElement(l,{reason:`no-data`,headline:`No journeys yet`,hint:`Need at least 2 page-views per session to compute flows`}));let w=Math.max(...u.map(e=>e.count),1),T=12;return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`journeys · ${n}`}),g.createElement(i,{title:`Top page transitions (${u.length})`},u.map((e,t)=>{let n=Math.max(1,Math.round(e.count/w*T));return g.createElement(d,{key:t,flexDirection:`row`},g.createElement(f,null,e.from.padEnd(22).slice(0,22)),g.createElement(f,{color:`cyan`},` → `),g.createElement(f,null,e.to.padEnd(22).slice(0,22)),g.createElement(f,{color:`magenta`},` `,`█`.repeat(n),`░`.repeat(T-n)),g.createElement(f,{color:`gray`},` ${e.count}`))})),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{b as journeysCommand};
@@ -1 +1 @@
1
- import{useTheme as e}from"./panel-DZqvtaao.js";import{Box as t,Text as n}from"ink";import r from"react";function i({items:i}){let{theme:a}=e();return r.createElement(t,{flexDirection:`row`},i.map((e,i)=>r.createElement(t,{key:`${e.key}-${i}`,flexDirection:`row`},i>0?r.createElement(n,{color:a.dim},` `):null,r.createElement(n,{color:a.muted},`[`),r.createElement(n,{color:a.accent},e.key),r.createElement(n,{color:a.muted},` `,e.label),r.createElement(n,{color:a.muted},`]`))))}export{i as Keybar};
1
+ import{useTheme as e}from"./panel-BNI8Q_9k.js";import{Box as t,Text as n}from"ink";import r from"react";function i({items:i}){let{theme:a}=e();return r.createElement(t,{flexDirection:`row`},i.map((e,i)=>r.createElement(t,{key:`${e.key}-${i}`,flexDirection:`row`},i>0?r.createElement(n,{color:a.dim},` `):null,r.createElement(n,{color:a.muted},`[`),r.createElement(n,{color:a.accent},e.key),r.createElement(n,{color:a.muted},` `,e.label),r.createElement(n,{color:a.muted},`]`))))}export{i as Keybar};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-BNI8Q_9k.js";import{Banner as a}from"./prompt-CnNQNqeK.js";import{Keybar as o}from"./keybar-CoNHlPOn.js";import"./sparkline-ut0Tvv-E.js";import{resolveSiteId as s}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{EmptyState as l}from"./empty-state-BUlTM7wA.js";import{Globe as u}from"./globe-1bi4DjwJ.js";import{MetricCard as d}from"./metric-card--FhiQMgt.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new c({config:a,cliVersion:i.cliVersion,token:o}),u,d;try{({siteId:u,site:d}=await s(l,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(r(i)){let e=await l.getLive(u);return n({type:`live.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:l,siteId:u,siteLabel:f,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:s})=>{let{exit:c}=h(),[m,x]=y(null),[S,C]=y(!0),[w,T]=y(null);if(g(e=>{e===`q`&&(c(),s(0))}),v(()=>{let n=!1,r=async()=>{try{let r=await e.getLive(t);n||(x(r),C(!1),T(null))}catch(e){n||(T(e.message),C(!1))}};r();let i=setInterval(r,2e3);return()=>{n=!0,clearInterval(i)}},[e,t]),S)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`live · ${n}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Connecting…`))));if(w&&!m)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`live · ${n}`}),_.createElement(l,{reason:`error`,headline:`Failed to load`,hint:w}));let E=process.stdout.columns??80,D=Math.max(20,Math.min(40,Math.floor(E/3)));return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`live · ${n}`}),_.createElement(f,{flexDirection:`row`},_.createElement(d,{title:`Active now`,value:m?.activeVisitors??0,format:`number`,width:D}),_.createElement(i,{title:`Globe`,width:Math.max(40,E-D-4)},_.createElement(u,{data:[],width:Math.max(36,E-D-10),height:10}))),_.createElement(i,{title:`Recent events`},!m||m.recentEvents.length===0?_.createElement(p,{color:`gray`},`— waiting for events —`):m.recentEvents.slice(0,15).map((e,t)=>_.createElement(f,{key:t},_.createElement(p,{color:`cyan`},(e.type??`pageview`).padEnd(10)),_.createElement(p,null,e.path.padEnd(36).slice(0,36)),_.createElement(p,{color:`gray`},e.country??`—`)))),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{x as liveCommand};
@@ -1 +1 @@
1
- import{Panel as e,useTheme as t}from"./panel-DZqvtaao.js";import{spark as n}from"./sparkline-B6ueqPAB.js";import{Box as r,Text as i}from"ink";import a from"react";function o(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 s=[`• `,`•• `,`•••`,` ••`,` •`,` `];function c(){let[e,t]=a.useState(0);return a.useEffect(()=>{let e=setInterval(()=>{t(e=>(e+1)%s.length)},180);return()=>clearInterval(e)},[]),e}function l({title:l,value:u,series:d,delta:f,format:p=`number`,loading:m=!1,emptyHint:h,width:g}){let{theme:_}=t(),v=c(),y=a.createElement(i,{color:_.typography.label.color,dimColor:_.typography.label.dim},l.toUpperCase());if(m)return a.createElement(e,{width:g},y,a.createElement(i,{color:_.accent},s[v]));let b=typeof u==`number`?u:Number(u),x=(u===``||u===`—`||typeof u==`number`&&!Number.isFinite(b))&&(!d||d.length===0);if(x)return a.createElement(e,{width:g},y,a.createElement(i,{color:_.dim},h??`no data yet`));let S=o(u,p),C=typeof g==`number`?Math.max(8,g-6):16,w=d&&d.length>0?n(d,C):``,T=null;if(typeof f==`number`&&Number.isFinite(f)){let e=Math.abs(f*100);T=e<.5?a.createElement(i,{color:_.dim},` `,`→ `,e.toFixed(1),`%`):f>0?a.createElement(i,{color:_.success},` `,`↑ `,e.toFixed(1),`%`):a.createElement(i,{color:_.error},` `,`↓ `,e.toFixed(1),`%`)}return a.createElement(e,{width:g},y,a.createElement(i,{color:_.typography.headline.color,bold:_.typography.headline.bold},S),w?a.createElement(r,{flexDirection:`row`},a.createElement(i,{color:_.accent},w),T):T?a.createElement(r,{flexDirection:`row`},T):null)}export{l as MetricCard};
1
+ import{Panel as e,useTheme as t}from"./panel-BNI8Q_9k.js";import{spark as n}from"./sparkline-ut0Tvv-E.js";import{Box as r,Text as i}from"ink";import a from"react";function o(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 s=[`• `,`•• `,`•••`,` ••`,` •`,` `];function c(){let[e,t]=a.useState(0);return a.useEffect(()=>{let e=setInterval(()=>{t(e=>(e+1)%s.length)},180);return()=>clearInterval(e)},[]),e}function l({title:l,value:u,series:d,delta:f,format:p=`number`,loading:m=!1,emptyHint:h,width:g}){let{theme:_}=t(),v=c(),y=a.createElement(i,{color:_.typography.label.color,dimColor:_.typography.label.dim},l.toUpperCase());if(m)return a.createElement(e,{width:g},y,a.createElement(i,{color:_.accent},s[v]));let b=typeof u==`number`?u:Number(u),x=(u===``||u===`—`||typeof u==`number`&&!Number.isFinite(b))&&(!d||d.length===0);if(x)return a.createElement(e,{width:g},y,a.createElement(i,{color:_.dim},h??`no data yet`));let S=o(u,p),C=typeof g==`number`?Math.max(8,g-6):16,w=d&&d.length>0?n(d,C):``,T=null;if(typeof f==`number`&&Number.isFinite(f)){let e=Math.abs(f*100);T=e<.5?a.createElement(i,{color:_.dim},` `,`→ `,e.toFixed(1),`%`):f>0?a.createElement(i,{color:_.success},` `,`↑ `,e.toFixed(1),`%`):a.createElement(i,{color:_.error},` `,`↓ `,e.toFixed(1),`%`)}return a.createElement(e,{width:g},y,a.createElement(i,{color:_.typography.headline.color,bold:_.typography.headline.bold},S),w?a.createElement(r,{flexDirection:`row`},a.createElement(i,{color:_.accent},w),T):T?a.createElement(r,{flexDirection:`row`},T):null)}export{l as MetricCard};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-BNI8Q_9k.js";import{Banner as a}from"./prompt-CnNQNqeK.js";import{Keybar as o}from"./keybar-CoNHlPOn.js";import"./sparkline-ut0Tvv-E.js";import{resolveSiteId as s}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{EmptyState as l}from"./empty-state-BUlTM7wA.js";import{DataTable as u}from"./data-table-B1FiGp8c.js";import{MetricCard as d}from"./metric-card--FhiQMgt.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new c({config:a,cliVersion:i.cliVersion,token:o}),u,d;try{({siteId:u,site:d}=await s(l,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(r(i)){let e=await S(l,u);return n({type:`overview.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(C,{api:l,siteId:u,siteLabel:f,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}async function S(e,t){let[n,r]=await Promise.all([e.getStats(t,`24h`).catch(()=>null),e.getPages(t).catch(()=>[])]),i=r.reduce((e,t)=>e+t.views,0);return{visitors:n?.visitors??0,pageviews:n?.pageviews??i,bounceRate:n?.bounceRate??null,avgSession:n?.avgSessionSec??null,series:[],topPages:r.slice(0,10)}}const C=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:s})=>{let{exit:c}=h(),[m,x]=y(null),[C,w]=y(!0),[T,E]=y(null);if(g(e=>{e===`q`&&(c(),s(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await S(e,t);n||(x(r),w(!1))}catch(e){n||(E(e.message),w(!1))}})(),()=>{n=!0}},[e,t]),C)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`overview · ${n}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching dashboard…`))));if(T)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`overview · ${n}`}),_.createElement(l,{reason:`error`,headline:`Failed to load`,hint:T}));if(!m||m.visitors===0&&m.pageviews===0&&m.topPages.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`overview · ${n}`}),_.createElement(l,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let D=process.stdout.columns??80,O=Math.max(18,Math.floor(D/4)-1),k=[{key:`path`,label:`path`,width:32},{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)}%`:`—`}];return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`overview · ${n}`}),_.createElement(f,{flexDirection:`row`},_.createElement(d,{title:`Visitors`,value:m.visitors,format:`number`,width:O}),_.createElement(d,{title:`Pageviews`,value:m.pageviews,format:`number`,width:O}),_.createElement(d,{title:`Bounce rate`,value:m.bounceRate??``,emptyHint:`—`,format:`percent`,width:O}),_.createElement(d,{title:`Avg session`,value:m.avgSession??``,emptyHint:`—`,format:`duration`,width:O})),_.createElement(i,{title:`Top pages`},m.topPages.length===0?_.createElement(p,{color:`gray`},`— no pages yet —`):_.createElement(u,{columns:k,data:m.topPages,zebra:!0})),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{x as overviewCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-BNI8Q_9k.js";import{Banner as a}from"./prompt-CnNQNqeK.js";import{Keybar as o}from"./keybar-CoNHlPOn.js";import{resolveSiteId as s}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{EmptyState as l}from"./empty-state-BUlTM7wA.js";import{DataTable as u}from"./data-table-B1FiGp8c.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";async function b(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new c({config:a,cliVersion:i.cliVersion,token:o}),u,d;try{({siteId:u,site:d}=await s(l,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(r(i)){let e=await l.getPages(u);return n({type:`pages.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:l,siteId:u,siteLabel:f,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:s})=>{let{exit:c}=m(),[p,b]=v(null),[x,S]=v(!0),[C,w]=v(null);if(h(e=>{e===`q`&&(c(),s(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getPages(t);n||(b(r),S(!1))}catch(e){n||(w(e.message),S(!1))}})(),()=>{n=!0}},[e,t]),x)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`pages · ${n}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Fetching pages…`))));if(C)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`pages · ${n}`}),g.createElement(l,{reason:`error`,headline:`Failed to load`,hint:C}));if(!p||p.length===0)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`pages · ${n}`}),g.createElement(l,{reason:`no-data`,headline:`No pages yet`,hint:`Visit your site to send the first event`}));let T=[{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 g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`pages · ${n}`}),g.createElement(i,{title:`Top pages (${p.length})`},g.createElement(u,{columns:T,data:p,zebra:!0})),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{b as pagesCommand};
@@ -0,0 +1 @@
1
+ import{Box as e,Text as t}from"ink";import n,{createContext as r,useContext as i,useEffect as a,useState as o}from"react";const s={xs:1,sm:2,md:3,lg:5,xl:8},c=e=>({headline:{color:e.fg,bold:!0},title:{color:e.fg,bold:!0},body:{color:e.fg},label:{color:e.dim,dim:!0,uppercase:!0},mono:{color:e.fg},caption:{color:e.muted}}),l={name:`mocha`,bg:`#1E1E2E`,fg:`#CDD6F4`,muted:`#6C7086`,accent:`#7DD3FC`,accent2:`#FDA4AF`,success:`#A6E3A1`,warn:`#F9E2AF`,error:`#F38BA8`,border:`#45475A`,dim:`#585B70`,spacing:s,radius:`round`,typography:c({fg:`#CDD6F4`,muted:`#6C7086`,accent:`#7DD3FC`,dim:`#585B70`})},u={name:`latte`,bg:`#EFF1F5`,fg:`#4C4F69`,muted:`#8C8FA1`,accent:`#7287FD`,accent2:`#EA76CB`,success:`#40A02B`,warn:`#DF8E1D`,error:`#D20F39`,border:`#BCC0CC`,dim:`#ACB0BE`,spacing:s,radius:`round`,typography:c({fg:`#4C4F69`,muted:`#8C8FA1`,accent:`#7287FD`,dim:`#ACB0BE`})},d={name:`dracula`,bg:`#282A36`,fg:`#F8F8F2`,muted:`#6272A4`,accent:`#BD93F9`,accent2:`#FF79C6`,success:`#50FA7B`,warn:`#F1FA8C`,error:`#FF5555`,border:`#44475A`,dim:`#6272A4`,spacing:s,radius:`round`,typography:c({fg:`#F8F8F2`,muted:`#6272A4`,accent:`#BD93F9`,dim:`#6272A4`})},f={name:`tokyoNight`,bg:`#1A1B26`,fg:`#C0CAF5`,muted:`#565F89`,accent:`#7AA2F7`,accent2:`#BB9AF7`,success:`#9ECE6A`,warn:`#E0AF68`,error:`#F7768E`,border:`#3B4261`,dim:`#414868`,spacing:s,radius:`round`,typography:c({fg:`#C0CAF5`,muted:`#565F89`,accent:`#7AA2F7`,dim:`#414868`})},p={name:`nord`,bg:`#2E3440`,fg:`#D8DEE9`,muted:`#4C566A`,accent:`#88C0D0`,accent2:`#81A1C1`,success:`#A3BE8C`,warn:`#EBCB8B`,error:`#BF616A`,border:`#3B4252`,dim:`#434C5E`,spacing:s,radius:`round`,typography:c({fg:`#D8DEE9`,muted:`#4C566A`,accent:`#88C0D0`,dim:`#434C5E`})},m={from:`#7D56F4`,to:`#FF5FD1`},h=r({theme:l});function g(){return i(h)}function _(e,t,n){if(n)return e.accent;switch(t){case`busy`:return e.accent;case`ok`:return e.success;case`warn`:return e.warn;case`err`:return e.error;case`idle`:default:return e.border}}function v(){let e=process.stdout.columns;return typeof e==`number`&&e>0?e:80}function y({title:r,state:i=`idle`,pillColor:a,width:o,focused:s=!1,density:c=`comfortable`,children:l}){let{theme:u}=g(),d=_(u,i,s),f=o??v(),p=a??d,m=c===`compact`?``:` `,h=`╭─ `,y=` ─╮`,b=r??``,x=r?b.length:0,S=r?h.length+x+y.length:4,C=Math.max(2,f-S),w=r?n.createElement(e,{flexDirection:`row`},n.createElement(t,{color:d},h),n.createElement(t,{color:p,bold:!0},b),n.createElement(t,{color:d},y,`─`.repeat(C))):n.createElement(e,{flexDirection:`row`},n.createElement(t,{color:d},`╭`,`─`.repeat(Math.max(2,f-2)),`╮`)),T=n.createElement(e,{flexDirection:`row`},n.createElement(t,{color:d},`╰`,`─`.repeat(Math.max(2,f-2)),`╯`));return n.createElement(e,{flexDirection:`column`},w,n.createElement(e,{flexDirection:`row`},n.createElement(t,{color:d},`│`,m),n.createElement(e,{flexDirection:`column`,flexGrow:1},l),n.createElement(t,{color:d},m,`│`)),T)}export{m as BRAND_GRADIENT,y as Panel,d as dracula,u as latte,l as mocha,p as nord,f as tokyoNight,g as useTheme};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-BNI8Q_9k.js";import"./prompt-CnNQNqeK.js";import"./gradient-93CUjfDW.js";import"./keybar-CoNHlPOn.js";import"./sparkline-ut0Tvv-E.js";import{runAnalyticalScreen as i}from"./analytical-screen-DdnG-A8U.js";import{Table as a}from"./ui-Bw_RHAeN.js";import{resolveSiteId as o}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as s}from"./api-v2-CRj-zoG9.js";import{Box as c,Text as l}from"ink";import u from"react";async function d(d){let f=await e(),p=await t({strict:!1}),m=new s({config:f,cliVersion:d.cliVersion,token:p}),h,g;try{({siteId:h,site:g}=await o(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 _=r(d),v=[{key:`isCurrent`,header:``,width:2,format:e=>e?`*`:` `},{key:`name`,header:`project`,width:26},{key:`domain`,header:`domain`,width:28,format:e=>String(e??`—`)},{key:`tier`,header:`tier`,width:10},{key:`pageviews24h`,header:`24h pv`,width:8,align:`right`},{key:`id`,header:`id`,width:38,format:e=>String(e).slice(0,38)}];return i({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
+ `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(n(e.projects,[`id`,`name`,`domain`,`tier`,`pageviews24h`,`isCurrent`],t))},panels:[{id:`summary`,title:`Tracked sites`,render:e=>{let t=e.projects.find(e=>e.isCurrent);return u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.projects.length),u.createElement(l,{color:`gray`},` projects`)),t?u.createElement(l,{color:`gray`},`current: `,u.createElement(l,{color:`cyan`},t.name),` `,`(`,t.domain??`—`,`, `,t.tier,`)`):u.createElement(l,{color:`gray`},`no current project bound to this token`))}},{id:`list`,title:`List`,render:e=>e.projects.length===0?u.createElement(l,{color:`gray`},`— no projects yet —`):u.createElement(a,{data:e.projects,columns:v})},{id:`hint`,title:`Switch`,render:()=>u.createElement(l,{color:`gray`},"To switch project: run `zenovay logout` then `zenovay login` (V2.1 adds a faster /switch flow).")}]})}export{d as projectsCommand};
@@ -0,0 +1 @@
1
+ import{useTheme as e}from"./panel-BNI8Q_9k.js";import{Box as t,Text as n,useInput as r}from"ink";import i,{useCallback as a,useState as o}from"react";import s from"ink-select-input";import c from"ink-text-input";function l(){let e=process.stdout.columns;return typeof e==`number`&&e>0?e:80}function u({version:r,subtitle:a}){let{theme:o}=e(),s=l(),c=`ZENOVAY`,u=`v${r}`,d=`╭─ `,f=` · `,p=` `,m=`─╮`,h=d.length+c.length+f.length+u.length+p.length+m.length,g=Math.max(2,s-h),_=`─`.repeat(g),v=`─`.repeat(Math.max(2,s-2)),y=a??``,b=y.slice(0,Math.max(0,s-4)),x=` `.repeat(Math.max(1,s-2-1-b.length-1));return i.createElement(t,{flexDirection:`column`},i.createElement(t,{flexDirection:`row`},i.createElement(n,{color:o.border},d),i.createElement(n,{color:o.accent,bold:!0},c),i.createElement(n,{color:o.dim},f,u),i.createElement(n,{color:o.border},p,_,m)),a?i.createElement(t,{flexDirection:`row`},i.createElement(n,{color:o.border},`│ `),i.createElement(n,{color:o.fg},b),i.createElement(n,{color:o.border},x,`│`)):null,i.createElement(t,{flexDirection:`row`},i.createElement(n,{color:o.border},`╰`,v,`╯`)))}function d({hints:t}){let{theme:r}=e();return i.createElement(n,{color:r.dim},t)}function f({items:r,onSelect:c}){let{theme:l}=e(),[u,f]=o(r[0]),p=a(e=>{c(e.value)},[c]),m=a(e=>{f(e)},[]);return i.createElement(t,{flexDirection:`column`},i.createElement(s,{items:r.map((e,t)=>({key:`${t}`,label:e.label,value:e.value})),onSelect:e=>{let t=r.find(t=>t.value===e.value);t&&p(t)},onHighlight:e=>{let t=r.find(t=>t.value===e.value);t&&m(t)}}),u?.description?i.createElement(t,{marginTop:1},i.createElement(n,{color:l.muted},u.description)):null,i.createElement(t,{marginTop:1},i.createElement(d,{hints:`[↑↓/jk nav] [enter select]`})))}function p({question:r,onSubmit:a,placeholder:s,mask:l}){let{theme:u}=e(),[f,p]=o(``);return i.createElement(t,{flexDirection:`column`},i.createElement(t,null,i.createElement(n,{color:u.fg},r,` `),i.createElement(c,{value:f,onChange:p,onSubmit:e=>a(e),placeholder:s,mask:l?`•`:void 0})),i.createElement(d,{hints:`[enter submit]`}))}export{u as Banner,f as Select,p as TextInput};
@@ -0,0 +1,8 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import{Panel as i}from"./panel-BNI8Q_9k.js";import{Banner as a}from"./prompt-CnNQNqeK.js";import"./gradient-93CUjfDW.js";import"./keybar-CoNHlPOn.js";import"./sparkline-ut0Tvv-E.js";import{Table as o}from"./ui-Bw_RHAeN.js";import{resolveSiteId as s}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{requireTier as l}from"./tier-DJvWU86k.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(),[s,c]=g(``),[l,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),c(``)}}},E=h(()=>l?l.columns.map(e=>({key:e,header:e,width:18,format:e=>e==null?`∅`:String(e).slice(0,18)})):[],[l]);return m.createElement(u,{flexDirection:`column`},m.createElement(a,{version:`query`}),m.createElement(i,{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:s,onChange:c,onSubmit:T})),x?m.createElement(d,{color:`gray`},`running…`):null,y?m.createElement(i,{title:`Error`,state:`err`},m.createElement(d,{color:`red`},y)):null,l?m.createElement(i,{title:`${l.row_count} rows · ${l.duration_ms}ms${l.truncated?` · truncated`:``}`,state:`ok`},l.row_count===0?m.createElement(d,{color:`gray`},`— empty —`):m.createElement(o,{data:l.rows.slice(0,50),columns:E})):null)}async function y(i){let a=await e(),o=await t({strict:!1}),u=new c({config:a,cliVersion:i.cliVersion,token:o});try{await l(u,`scale`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await s(u,{explicit:i.siteId,headless:!!(i.json||i.csv||i.tsv||i.ndjson),cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=i.maxRows??1e3,p=r(i);if(i.sql)try{let e=await u.runSqlQuery(d,i.sql,{maxRows:f});if(p===`json`)process.stdout.write(JSON.stringify(e,null,2)),process.stdout.write(`
2
+ `);else if(p===`ndjson`)for(let t of e.rows)process.stdout.write(JSON.stringify(t)+`
3
+ `);else if(p===`csv`||p===`tsv`)process.stdout.write(n(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
+ `),process.stdout.write(`|`+e.columns.map((e,n)=>` ${e.padEnd(t[n]??0)} `).join(`|`)+`|
5
+ `),process.stdout.write(n+`
6
+ `);for(let n of e.rows.slice(0,200))process.stdout.write(`|`+e.columns.map((e,r)=>` ${String(n[e]??``).padEnd(t[r]??0)} `).join(`|`)+`|
7
+ `);process.stdout.write(n+`
8
+ `),process.stdout.write(`${e.row_count} rows · ${e.duration_ms}ms${e.truncated?` · truncated`:``}\n`)}return 0}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}let{render:h}=await import(`ink`);return await h(m.createElement(v,{api:u,siteId:d,maxRows:f})).waitUntilExit(),0}export{y as queryCommand};
@@ -1,2 +1,2 @@
1
- import{readConfig as e,updateConfig as t}from"./config-CZ9IzjIH.js";import{Panel as n}from"./panel-DZqvtaao.js";import{Banner as r,Select as i}from"./prompt-DEng-me1.js";import{Box as a,Text as o,render as s}from"ink";import c from"react";async function l(n,r){if(r.explicit&&r.explicit.trim())return{siteId:r.explicit.trim(),saved:!1};let i=await e(),a;try{a=await n.getSites()}catch(e){if(i.defaultSiteId)return{siteId:i.defaultSiteId,saved:!1};throw Error(`Could not fetch your sites (${e.message}). Pass --site-id <ID> to bypass.`)}if(i.defaultSiteId){let e=a.find(e=>e.id===i.defaultSiteId);if(e)return{siteId:e.id,site:e,saved:!1};await t({defaultSiteId:void 0,defaultSiteName:void 0})}if(a.length===0)throw Error("No sites in your account. Run `zenovay init` to add one, or create one at app.zenovay.com.");if(a.length===1){let e=a[0];return await t({defaultSiteId:e.id,defaultSiteName:e.name}),{siteId:e.id,site:e,saved:!0}}if(r.headless||!process.stdout.isTTY){let e=a.map(e=>` ${e.name.padEnd(24)} ${e.url.padEnd(36)} ${e.id}`).join(`
1
+ import{readConfig as e,updateConfig as t}from"./config-CZ9IzjIH.js";import{Panel as n}from"./panel-BNI8Q_9k.js";import{Banner as r,Select as i}from"./prompt-CnNQNqeK.js";import{Box as a,Text as o,render as s}from"ink";import c from"react";async function l(n,r){if(r.explicit&&r.explicit.trim())return{siteId:r.explicit.trim(),saved:!1};let i=await e(),a;try{a=await n.getSites()}catch(e){if(i.defaultSiteId)return{siteId:i.defaultSiteId,saved:!1};throw Error(`Could not fetch your sites (${e.message}). Pass --site-id <ID> to bypass.`)}if(i.defaultSiteId){let e=a.find(e=>e.id===i.defaultSiteId);if(e)return{siteId:e.id,site:e,saved:!1};await t({defaultSiteId:void 0,defaultSiteName:void 0})}if(a.length===0)throw Error("No sites in your account. Run `zenovay init` to add one, or create one at app.zenovay.com.");if(a.length===1){let e=a[0];return await t({defaultSiteId:e.id,defaultSiteName:e.name}),{siteId:e.id,site:e,saved:!0}}if(r.headless||!process.stdout.isTTY){let e=a.map(e=>` ${e.name.padEnd(24)} ${e.url.padEnd(36)} ${e.id}`).join(`
2
2
  `);throw Error(`Multiple sites found — pick one:\n${e}\n\nPass --site-id <ID>, set ZENOVAY_SITE=<ID>, or run \`zenovay use <domain>\` to set a default.`)}let o=await u(a,r.cliVersion);return await t({defaultSiteId:o.id,defaultSiteName:o.name}),{siteId:o.id,site:o,saved:!0}}function u(e,t=`0`){return new Promise((n,r)=>{let i,a=e=>{i?.(),n(e)},o=()=>{i?.(),r(Error(`Site selection cancelled`))},l=s(c.createElement(d,{sites:e,cliVersion:t,onPick:a,onCancel:o}));i=l.unmount})}const d=({sites:e,cliVersion:t,onPick:s})=>{let l=e.map(e=>({label:`${e.name.padEnd(28)} ${e.url.replace(/^https?:\/\//,``).padEnd(28)}`,value:e,description:e.trackingCode?`tracking: ${e.trackingCode}`:void 0}));return c.createElement(a,{flexDirection:`column`},c.createElement(r,{version:t,subtitle:`pick a site`}),c.createElement(n,{title:`Which site?`,state:`idle`},c.createElement(a,{marginBottom:1},c.createElement(o,{color:`gray`},"We'll save your pick as the default — re-run with `zenovay use --reset` to change it.")),c.createElement(i,{items:l,onSelect:s})))};export{l as resolveSiteId};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-BNI8Q_9k.js";import{Banner as a}from"./prompt-CnNQNqeK.js";import{Keybar as o}from"./keybar-CoNHlPOn.js";import{resolveSiteId as s}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{EmptyState as l}from"./empty-state-BUlTM7wA.js";import{requireTier as u}from"./tier-DJvWU86k.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";function b(e){return e>=.6?`magenta`:e>=.4?`cyan`:e>=.2?`blue`:`gray`}function x(e){return!Number.isFinite(e)||e===0?` — `:` ${(e*100).toFixed(0).padStart(3)}% `}async function S(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new c({config:a,cliVersion:i.cliVersion,token:o});try{await u(l,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await s(l,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let m=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(r(i)){let e=await l.getRetention(d);return n({type:`retention.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(C,{api:l,siteId:d,siteLabel:m,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:s})=>{let{exit:c}=m(),[u,p]=v(null),[S,C]=v(!0),[w,T]=v(null);return h(e=>{e===`q`&&(c(),s(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getRetention(t);n||(p(r.cohorts),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),S?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`retention · ${n}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Crunching cohorts…`)))):w?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`retention · ${n}`}),g.createElement(l,{reason:`error`,headline:`Failed to load`,hint:w})):!u||u.length===0?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`retention · ${n}`}),g.createElement(l,{reason:`no-data`,headline:`No retention data yet`,hint:`Retention needs at least 30 days of traffic`})):g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:r,subtitle:`retention · ${n}`}),g.createElement(i,{title:`Cohort retention (D1 / D7 / D30)`},g.createElement(d,{flexDirection:`row`},g.createElement(f,{bold:!0},`cohort`.padEnd(12)),g.createElement(f,{bold:!0},` D1 `),g.createElement(f,{bold:!0},` D7 `),g.createElement(f,{bold:!0},` D30 `)),u.map(e=>g.createElement(d,{key:e.date,flexDirection:`row`},g.createElement(f,null,e.date.padEnd(12).slice(0,12)),g.createElement(f,{color:b(e.day1)},x(e.day1)),g.createElement(f,{color:b(e.day7)},x(e.day7)),g.createElement(f,{color:b(e.day30)},x(e.day30))))),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{S as retentionCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-BNI8Q_9k.js";import"./prompt-CnNQNqeK.js";import"./gradient-93CUjfDW.js";import"./keybar-CoNHlPOn.js";import{spark as i}from"./sparkline-ut0Tvv-E.js";import{runAnalyticalScreen as a}from"./analytical-screen-DdnG-A8U.js";import"./ui-Bw_RHAeN.js";import{resolveSiteId as o}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as s}from"./api-v2-CRj-zoG9.js";import{Box as c,Text as l}from"ink";import u from"react";function d(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 f(f){let p=await e(),m=await t({strict:!1}),h=new s({config:p,cliVersion:f.cliVersion,token:m}),g,_;try{({siteId:g,site:_}=await o(h,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let v=r(f),y=f.range??`30d`;return a({cliVersion:f.cliVersion,title:`revenue · ${g} · ${y}`,commandName:`revenue`,authToken:m?.accessToken??null,refreshIntervalMs:f.watch?5*6e4:0,fetcher:e=>h.getRevenue(g,y,e),format: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
+ `);return}process.stdout.write(n(e.series,[`bucket`,`amount`,`currency`,`transactions`],t))},panels:[{id:`totals`,title:`Top line`,render:e=>u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{color:`green`,bold:!0},d(e.totalAmount,e.currency)),` `,u.createElement(l,{color:`gray`},`total · `,e.totalTransactions,` transactions`)),typeof e.mrr==`number`?u.createElement(l,null,u.createElement(l,{bold:!0},`MRR `),u.createElement(l,{color:`magenta`},d(e.mrr,e.currency)),typeof e.arpu==`number`?u.createElement(l,{color:`gray`},` · ARPU `,d(e.arpu,e.currency)):null):null)},{id:`series`,title:`Daily (${y})`,render:e=>{let t=e.series.map(e=>e.amount);if(t.length===0)return u.createElement(l,{color:`gray`},`— no transactions —`);let n=Math.max(...t,1);return u.createElement(c,{flexDirection:`column`},u.createElement(l,{color:`magenta`},i(t,Math.min(60,t.length*2))),u.createElement(l,{color:`gray`},`peak: `,d(n,e.currency),` ·`,` `,`avg: `,d(e.totalAmount/Math.max(1,t.length),e.currency)))}},{id:`window`,title:`Window`,render:e=>u.createElement(l,{color:`gray`},new Date(e.windowStart).toISOString().slice(0,10),` →`,` `,new Date(e.windowEnd).toISOString().slice(0,10))}]})}export{f as revenueCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-BNI8Q_9k.js";import{Banner as a}from"./prompt-CnNQNqeK.js";import{Keybar as o}from"./keybar-CoNHlPOn.js";import{resolveSiteId as s}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{EmptyState as l}from"./empty-state-BUlTM7wA.js";import{DataTable as u}from"./data-table-B1FiGp8c.js";import{requireTier as d}from"./tier-DJvWU86k.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";function x(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 S(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 C(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new c({config:a,cliVersion:i.cliVersion,token:o});try{await d(l,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let u,f;try{({siteId:u,site:f}=await s(l,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??u;if(r(i)){let e=await l.getSessions(u);return n({type:`sessions.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(w,{api:l,siteId:u,siteLabel:p,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:s})=>{let{exit:c}=h(),[d,m]=y(null),[C,w]=y(!0),[T,E]=y(null);if(g(e=>{e===`q`&&(c(),s(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getSessions(t);n||(m(r),w(!1))}catch(e){n||(E(e.message),w(!1))}})(),()=>{n=!0}},[e,t]),C)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`sessions · ${n}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching sessions…`))));if(T)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`sessions · ${n}`}),_.createElement(l,{reason:`error`,headline:`Failed to load`,hint:T}));if(!d||d.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`sessions · ${n}`}),_.createElement(l,{reason:`no-data`,headline:`No replays yet`,hint:`Enable session replay in your site settings`}));let D=[{key:`id`,label:`session id`,width:24},{key:`visitor`,label:`visitor`,width:18},{key:`duration`,label:`duration`,align:`right`,width:9,format:e=>x(e)},{key:`startedAt`,label:`when`,align:`right`,width:6,format:e=>S(String(e))},{key:`pageCount`,label:`events`,align:`right`,width:7},{key:`deviceType`,label:`device`,width:8,format:e=>String(e??`—`)}];return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`sessions · ${n}`}),_.createElement(i,{title:`Recent sessions (${d.length})`},_.createElement(u,{columns:D,data:d,zebra:!0})),_.createElement(f,{marginTop:1},_.createElement(p,{color:`gray`},`Open any session for replay at https://app.zenovay.com/replay`)),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{C as sessionsCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-BNI8Q_9k.js";import"./prompt-CnNQNqeK.js";import"./gradient-93CUjfDW.js";import"./keybar-CoNHlPOn.js";import"./sparkline-ut0Tvv-E.js";import{runAnalyticalScreen as i}from"./analytical-screen-DdnG-A8U.js";import{Table as a}from"./ui-Bw_RHAeN.js";import{resolveSiteId as o}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as s}from"./api-v2-CRj-zoG9.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e,t){let n=Math.round(e/100*t);return`█`.repeat(n)+`░`.repeat(Math.max(0,t-n))}function f(e){return e==null?{glyph:`·`,color:`gray`}:e>.5?{glyph:`▲`,color:`green`}:e<-.5?{glyph:`▼`,color:`red`}:{glyph:`→`,color:`gray`}}async function p(p){let m=await e(),h=await t({strict:!1}),g=new s({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await o(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=r(p),b=p.period??`30d`,x=[{key:`source`,header:`source`,width:22},{key:`channel`,header:`channel`,width:10,format:e=>String(e??`—`)},{key:`visitors`,header:`visitors`,width:8,align:`right`},{key:`delta`,header:`Δ`,width:6,align:`right`,format:e=>typeof e==`number`?`${e>0?`+`:``}${(e*100).toFixed(1)}%`:`—`}];return i({cliVersion:p.cliVersion,title:`sources · ${_} · ${b}`,commandName:`sources`,authToken:h?.accessToken??null,refreshIntervalMs:6e4,fetcher:e=>g.getSources(_,b,p.compare,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
+ `);return}process.stdout.write(n(e.sources,[`source`,`channel`,`visitors`,`conversions`,`revenue`,`delta`],t))},panels:[{id:`summary`,title:`Total`,render:e=>u.createElement(l,null,u.createElement(l,{bold:!0},e.totalVisitors.toLocaleString()),` `,u.createElement(l,{color:`gray`},`visitors · `,e.sources.length,` sources`))},{id:`channels`,title:`By channel`,render:e=>{if(e.sources.length===0)return u.createElement(l,{color:`gray`},`— no source data —`);let t=e.totalVisitors||1,n=[...e.sources].sort((e,t)=>t.visitors-e.visitors).slice(0,12);return u.createElement(c,{flexDirection:`column`},n.map((e,n)=>{let r=e.visitors/t*100,i=f(e.delta);return u.createElement(c,{key:`${e.source}-${n}`},u.createElement(l,null,u.createElement(l,{color:`cyan`},e.source.padEnd(20).slice(0,20)),` `,u.createElement(l,{color:`magenta`},d(r,30)),` `,u.createElement(l,null,e.visitors.toString().padStart(6),` `),u.createElement(l,{color:`gray`},`(`,r.toFixed(1),`%)`),` `,u.createElement(l,{color:i.color},i.glyph)))}))}},{id:`table`,title:`Detail`,render:e=>e.sources.length===0?u.createElement(l,{color:`gray`},`— —`):u.createElement(a,{data:e.sources.slice(0,20),columns:x})}]})}export{p as sourcesCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-BNI8Q_9k.js";import"./prompt-CnNQNqeK.js";import"./gradient-93CUjfDW.js";import"./keybar-CoNHlPOn.js";import"./sparkline-ut0Tvv-E.js";import{runAnalyticalScreen as i}from"./analytical-screen-DdnG-A8U.js";import{Table as a}from"./ui-Bw_RHAeN.js";import{resolveSiteId as o}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as s}from"./api-v2-CRj-zoG9.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 s({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await o(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=r(p),b=p.range??`24h`,x=[{key:`url`,header:`page`,width:40,format:e=>String(e??`—`)},{key:`views`,header:`views`,width:8,align:`right`}],S=[{key:`country`,header:`country`,width:8},{key:`visitors`,header:`visitors`,width:8,align:`right`}];return i({cliVersion:p.cliVersion,title:`stats · ${_} · ${b}`,commandName:`stats`,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
+ `);return}process.stdout.write(n([{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(a,{data:e.topPages.slice(0,10),columns:x})},{id:`countries`,title:`Top countries`,render:e=>e.topCountries.length===0?u.createElement(l,{color:`gray`},`— no country data —`):u.createElement(a,{data:e.topCountries.slice(0,10),columns:S})}]})}export{p as statsCommand};
@@ -0,0 +1,4 @@
1
+ import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./panel-BNI8Q_9k.js";import{Banner as a}from"./prompt-CnNQNqeK.js";import"./gradient-93CUjfDW.js";import"./keybar-CoNHlPOn.js";import"./sparkline-ut0Tvv-E.js";import"./ui-Bw_RHAeN.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
+ `),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
+ `),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
+ `),0;let{waitUntilExit:t}=l(u.createElement(m,{themes:d}));return await t(),0}export{h as themesCommand};
@@ -0,0 +1 @@
1
+ import{useTheme as e}from"./panel-BNI8Q_9k.js";import{BrandGradient as t}from"./gradient-93CUjfDW.js";import{Box as n,Text as r,useInput as i}from"ink";import a,{useMemo as o,useState as s}from"react";import"diff";function c(e,t){return e.length<=t?e:t<=1?e.slice(0,t):`${e.slice(0,t-1)}…`}function l(e,t,n){if(e.length>=t)return c(e,t);let r=t-e.length;if(n===`right`)return` `.repeat(r)+e;if(n===`center`){let t=Math.floor(r/2),n=r-t;return` `.repeat(t)+e+` `.repeat(n)}return e+` `.repeat(r)}function u(e,t){return e.map(e=>{if(typeof e.width==`number`&&e.width>0)return e.width;let n=e.header.length;for(let r of t){let t=r[e.key],i=e.format?e.format(t,r):String(t??``);i.length>n&&(n=i.length)}return Math.max(3,n)})}function d({columns:i,data:o,zebra:s=!1}){let{theme:c}=e(),d=u(i,o),f=d.reduce((e,t)=>e+t,0)+i.length*3+1,p=(e,t,n)=>{let r=e;return d.forEach((e,i)=>{r+=`─`.repeat(e+2),r+=i===d.length-1?n:t}),r},m=p(`╭`,`┬`,`╮`),h=p(`├`,`┼`,`┤`),g=p(`╰`,`┴`,`╯`),_=i.map((e,t)=>l(e.header,d[t]??e.header.length,e.align??`left`)).join(` │ `);return a.createElement(n,{flexDirection:`column`,width:f},a.createElement(r,{color:c.border},m),a.createElement(n,{flexDirection:`row`},a.createElement(r,{color:c.border},`│ `),a.createElement(t,null,_),a.createElement(r,{color:c.border},` │`)),a.createElement(r,{color:c.border},h),o.map((e,t)=>{let o=s&&t%2==1,u=o?c.muted:c.fg,f=i.map((t,n)=>{let r=e[t.key],i=t.format?t.format(r,e):String(r??``);return l(i,d[n]??i.length,t.align??`left`)}).join(` │ `);return a.createElement(n,{key:t,flexDirection:`row`},a.createElement(r,{color:c.border},`│ `),a.createElement(r,{color:u},f),a.createElement(r,{color:c.border},` │`))}),a.createElement(r,{color:c.border},g))}export{d as Table};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-BNI8Q_9k.js";import{Banner as a}from"./prompt-CnNQNqeK.js";import{Keybar as o}from"./keybar-CoNHlPOn.js";import{resolveSiteId as s}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{EmptyState as l}from"./empty-state-BUlTM7wA.js";import{DataTable as u}from"./data-table-B1FiGp8c.js";import{requireTier as d}from"./tier-DJvWU86k.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";function x(e){return e===`up`?{glyph:`● up`,color:`green`}:e===`down`?{glyph:`● down`,color:`red`}:{glyph:`○ unknown`,color:`gray`}}function S(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 C(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new c({config:a,cliVersion:i.cliVersion,token:o});try{await d(l,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let u,f;try{({siteId:u,site:f}=await s(l,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??u;if(r(i)){let e=await l.getUptime(u);return n({type:`uptime.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(w,{api:l,siteId:u,siteLabel:p,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:s})=>{let{exit:c}=h(),[d,m]=y(null),[C,w]=y(!0),[T,E]=y(null);if(g(e=>{e===`q`&&(c(),s(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getUptime(t);n||(m(r.monitors),w(!1))}catch(e){n||(E(e.message),w(!1))}})(),()=>{n=!0}},[e,t]),C)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`uptime · ${n}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching monitors…`))));if(T)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`uptime · ${n}`}),_.createElement(l,{reason:`error`,headline:`Failed to load`,hint:T}));if(!d||d.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`uptime · ${n}`}),_.createElement(l,{reason:`no-data`,headline:`No monitors configured`,hint:`Add one at app.zenovay.com/uptime`}));let D=[{key:`url`,label:`monitor`,width:36},{key:`status`,label:`status`,width:12,format:e=>x(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=>S(e)}];return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:r,subtitle:`uptime · ${n}`}),_.createElement(i,{title:`Monitors (${d.length})`},_.createElement(u,{columns:D,data:d,zebra:!0})),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{C as uptimeCommand};
@@ -1,4 +1,4 @@
1
- import{readConfig as e,updateConfig as t}from"./config-CZ9IzjIH.js";import{ApiClient as n,readToken as r}from"./api-DXmhz2DM.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import{resolveSiteId as i}from"./resolve-site-B54mr0Bh.js";async function a(a){if(a.reset)return await t({defaultSiteId:void 0,defaultSiteName:void 0}),process.stdout.write(`Default site cleared.
1
+ import{readConfig as e,updateConfig as t}from"./config-CZ9IzjIH.js";import{ApiClient as n,readToken as r}from"./api-DXmhz2DM.js";import"./panel-BNI8Q_9k.js";import"./prompt-CnNQNqeK.js";import{resolveSiteId as i}from"./resolve-site-IXvBPhrx.js";async function a(a){if(a.reset)return await t({defaultSiteId:void 0,defaultSiteName:void 0}),process.stdout.write(`Default site cleared.
2
2
  `),0;if(a.show){let t=await e();return t.defaultSiteId?process.stdout.write(a.json?`${JSON.stringify({defaultSiteId:t.defaultSiteId,defaultSiteName:t.defaultSiteName??null})}\n`:`Default site: ${t.defaultSiteName??t.defaultSiteId} (${t.defaultSiteId})\n`):process.stdout.write(a.json?`{"defaultSiteId":null}
3
3
  `:`No default site set.
4
4
  `),0}let s=await e(),c=await r({strict:!1});if(!c&&!process.env.ZENOVAY_API_TOKEN)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:s,cliVersion:a.cliVersion,token:c});if(a.match&&a.match.trim()){let e=a.match.trim().toLowerCase(),n=await l.getSites(),r=n.find(e=>e.id===a.match||e.trackingCode===a.match||e.url===a.match),i=r??n.find(t=>o(t.url).includes(e)||t.name.toLowerCase().includes(e));return i?(await t({defaultSiteId:i.id,defaultSiteName:i.name}),process.stdout.write(`Default site → ${i.name} (${i.url})\n`),0):(process.stderr.write(`No site matched "${a.match}". Your sites:\n${n.map(e=>` ${e.name} — ${e.url} — ${e.id}`).join(`
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-BNI8Q_9k.js";import"./prompt-CnNQNqeK.js";import"./gradient-93CUjfDW.js";import"./keybar-CoNHlPOn.js";import"./sparkline-ut0Tvv-E.js";import{runAnalyticalScreen as i}from"./analytical-screen-DdnG-A8U.js";import{Table as a}from"./ui-Bw_RHAeN.js";import{resolveSiteId as o}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as s}from"./api-v2-CRj-zoG9.js";import{Box as c,Text as l}from"ink";import u from"react";const d={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 f(e,t){let n=d[e];return t<=n.good?{label:`good`,color:`green`}:t<=n.poor?{label:`needs`,color:`yellow`}:{label:`poor`,color:`red`}}function p(e,t){return e===`cls`?t.toFixed(3):t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`}async function m(d){let m=await e(),h=await t({strict:!1}),g=new s({config:m,cliVersion:d.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await o(g,{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 y=r(d),b=[{key:`url`,header:`url`,width:32},{key:`device`,header:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,header:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`lcp`,e.p75):`—`},{key:`inp`,header:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`inp`,e.p75):`—`},{key:`cls`,header:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`cls`,e.p75):`—`},{key:`samples`,header:`n`,width:6,align:`right`}];return i({cliVersion:d.cliVersion,title:`vitals · ${_}`,commandName:`vitals`,authToken:h?.accessToken??null,refreshIntervalMs:d.watch?5*6e4:0,fetcher:e=>g.getVitals(_,{url:d.url,device:d.device,window:d.window},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
+ `);return}process.stdout.write(n(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 u.createElement(c,{flexDirection:`column`},n.map(e=>{let n=t(e),r=f(e,n);return u.createElement(l,{key:e},u.createElement(l,{color:r.color},`● `),u.createElement(l,{bold:!0},e.toUpperCase().padEnd(5)),` `,u.createElement(l,null,p(e,n).padStart(8)),` `,u.createElement(l,{color:r.color},r.label))}))}},{id:`pages`,title:`Per-page`,render:e=>e.vitals.length===0?u.createElement(l,{color:`gray`},`— no vitals data yet —`):u.createElement(a,{data:e.vitals.slice(0,15),columns:b})}]})}export{m as vitalsCommand};
@@ -1 +1 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{parseSseStream as n}from"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import{emit as r,isHeadless as i}from"./emit-BmfLGjqr.js";import{Panel as a}from"./panel-DZqvtaao.js";import{Banner as o}from"./prompt-DEng-me1.js";import{Keybar as s}from"./keybar-DUC7w1HQ.js";import{spark as c}from"./sparkline-B6ueqPAB.js";import{EmptyState as l}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as u}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as d}from"./api-v2-CRj-zoG9.js";import{Globe as f}from"./globe-1bi4DjwJ.js";import{z as p}from"zod";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";import C from"ink-text-input";const w=p.object({siteId:p.string().optional(),window:p.string().optional(),totalVisitors:p.number().optional(),visitors:p.object({count:p.number().optional(),series:p.array(p.number()).optional()}).optional(),topPages:p.array(p.object({path:p.string(),views:p.number().optional(),count:p.number().optional()})).optional(),sources:p.array(p.object({source:p.string(),visitors:p.number()})).optional()}).passthrough();async function T(n){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new d({config:a,cliVersion:n.cliVersion,token:o}),c;try{({siteId:c}=await u(s,{explicit:n.siteId,headless:!!n.json,cliVersion:n.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(i(n)){let e=await s.getDashboardSnapshot(c);return r({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:s,siteId:c,intervalMs:n.intervalMs??15e3,cliVersion:n.cliVersion,onExit:n=>{t(),e(n)}}))})}const E=({api:e,siteId:t,intervalMs:r,cliVersion:i,onExit:c})=>{let{exit:u}=_(),[d,p]=x(null),[g,C]=x(null),[T,E]=x(null),[P,F]=x([]),[I,L]=x(!0),[R,z]=x(null),[B,V]=x(1),[H,U]=x(!1),[W,G]=x(!1);v((e,t)=>{if(e===`q`){u(),c(0);return}if(e===`?`||e===`/`){G(e=>!e);return}if(e===`g`){U(e=>!e);return}if(t.tab){V(e=>{let n=t.shift?(e+4)%6+1:e%6+1;return n});return}(e===`1`||e===`2`||e===`3`||e===`4`||e===`5`||e===`6`)&&V(Number(e))});let[K,q]=x(!1);if(b(()=>{let n=!1,i=async()=>{try{let r=await e.getDashboardSnapshot(t);if(n)return;let i=w.safeParse(r);if(!i.success){q(!0),L(!1);return}q(!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};p(o),e.getVitals(t).then(e=>{n||C(e)},()=>{}),e.getGoals(t).then(e=>{n||E(e)},()=>{}),L(!1),z(null)}catch(e){n||z(e.message)}};i();let a=setInterval(i,r);return()=>{n=!0,clearInterval(a)}},[e,t,r]),b(()=>{let r=new AbortController;return(async()=>{try{let i=await e.openEventsStream(t,r.signal);for await(let e of n(i))e.type===`error`&&F(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>r.abort()},[e,t]),I)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}`}),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 snapshot…`))));if(R&&!d)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}`}),y.createElement(a,{title:`Error`,state:`err`},y.createElement(h,{color:`red`},R)));if(K&&!d)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}`}),y.createElement(l,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let J=process.stdout.columns??80,Y=Math.max(20,Math.floor(J/3)-1),X=[];return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}${H?` · globe`:``}`}),y.createElement(m,{flexDirection:`row`},y.createElement(m,{flexDirection:`column`},H?y.createElement(a,{title:`Live globe`,focused:B===1,width:Y},y.createElement(f,{data:X,width:Math.max(40,Y-4),height:12})):y.createElement(O,{snapshot:d,focused:B===1,width:Y}),y.createElement(j,{events:P,focused:B===4,width:Y})),y.createElement(m,{flexDirection:`column`},y.createElement(k,{snapshot:d,focused:B===2,width:Y}),y.createElement(M,{vitals:g,focused:B===5,width:Y})),y.createElement(m,{flexDirection:`column`},y.createElement(A,{snapshot:d,focused:B===3,width:Y}),y.createElement(N,{goals:T,focused:B===6,width:Y}))),W?y.createElement(D,{api:e,siteId:t,width:J-2}):null,y.createElement(s,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:H?`panels`:`globe`},{key:`?/`,label:W?`close chat`:`ai chat`},{key:`q`,label:`quit`}]}))},D=({api:e,siteId:t,width:r})=>{let[i,o]=x(``),[s,c]=x([]),[l,u]=x(!1),[d,f]=x(``),[p,g]=x(null),_=async r=>{let i=r.trim();if(!i||l)return;g(null),o(``);let a=[...s,{role:`user`,content:i}];c(a),u(!0),f(``);try{let r=a.map(e=>({role:e.role,content:e.content})),i=await e.openAiStream(`chat`,{messages:r,siteId:t},void 0),o=``;for await(let e of n(i))if(e.type===`delta`)o+=e.content,f(o);else if(e.type===`error`)g(`${e.code}: ${e.message}`);else if(e.type===`done`)break;c([...a,{role:`assistant`,content:o}]),f(``)}catch(e){g(e instanceof Error?e.message:`chat failed`)}finally{u(!1)}};return y.createElement(m,{marginTop:1},y.createElement(a,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:r},y.createElement(m,{flexDirection:`column`},s.slice(-6).map((e,t)=>y.createElement(m,{key:t,flexDirection:`column`,marginBottom:1},y.createElement(h,{color:e.role===`user`?`cyan`:`magenta`,bold:!0},e.role===`user`?`you`:`zenovay`),y.createElement(h,null,e.content))),l&&d?y.createElement(m,{flexDirection:`column`,marginBottom:1},y.createElement(h,{color:`magenta`,bold:!0},`zenovay`),y.createElement(h,null,d)):null,p?y.createElement(h,{color:`red`},`✗ `,p):null,y.createElement(m,null,y.createElement(h,{color:`cyan`},l?`⠋ `:`▸ `),y.createElement(C,{value:i,onChange:o,onSubmit:_,placeholder:l?`streaming…`:`ask anything about your analytics`})))))},O=({snapshot:e,focused:t,width:n})=>{let r=e?.visitors?.count??0,i=e?.visitors?.series??[];return y.createElement(a,{title:`Visitors`,focused:t,width:n},y.createElement(h,{bold:!0},r.toString()),y.createElement(h,{color:`gray`},i.length>0?c(i,Math.max(8,n-6)):`— no data —`))},k=({snapshot:e,focused:t,width:n})=>{let r=e?.topPages?.slice(0,5)??[];return y.createElement(a,{title:`Top pages`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.path},y.createElement(h,null,e.path.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.views))))},A=({snapshot:e,focused:t,width:n})=>{let r=e?.sources?.slice(0,5)??[];return y.createElement(a,{title:`Sources`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.source},y.createElement(h,null,e.source.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.visitors))))},j=({events:e,focused:t,width:n})=>y.createElement(a,{title:`Events`,focused:t,width:n},e.length===0?y.createElement(h,{color:`gray`},`— waiting —`):e.slice(-10).map((e,t)=>y.createElement(h,{key:t},e.slice(0,n-4)))),M=({vitals:e,focused:t,width:n})=>{let r=(e,t,n)=>y.createElement(m,{key:e},y.createElement(h,{bold:!0},e.padEnd(6)),y.createElement(h,{color:`gray`},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return y.createElement(a,{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`))},N=({goals:e,focused:t,width:n})=>{let r=e?.goals?.slice(0,5)??[];return y.createElement(a,{title:`Goals`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.name},y.createElement(h,null,e.name.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.completions))))};export{T as watchCommand};
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{parseSseStream as n}from"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import{emit as r,isHeadless as i}from"./emit-BmfLGjqr.js";import{Panel as a}from"./panel-BNI8Q_9k.js";import{Banner as o}from"./prompt-CnNQNqeK.js";import{Keybar as s}from"./keybar-CoNHlPOn.js";import{spark as c}from"./sparkline-ut0Tvv-E.js";import{resolveSiteId as l}from"./resolve-site-IXvBPhrx.js";import{ApiV2Client as u}from"./api-v2-CRj-zoG9.js";import{EmptyState as d}from"./empty-state-BUlTM7wA.js";import{Globe as f}from"./globe-1bi4DjwJ.js";import{z as p}from"zod";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";import C from"ink-text-input";const w=p.object({siteId:p.string().optional(),window:p.string().optional(),totalVisitors:p.number().optional(),visitors:p.object({count:p.number().optional(),series:p.array(p.number()).optional()}).optional(),topPages:p.array(p.object({path:p.string(),views:p.number().optional(),count:p.number().optional()})).optional(),sources:p.array(p.object({source:p.string(),visitors:p.number()})).optional()}).passthrough();async function T(n){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new u({config:a,cliVersion:n.cliVersion,token:o}),c;try{({siteId:c}=await l(s,{explicit:n.siteId,headless:!!n.json,cliVersion:n.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(i(n)){let e=await s.getDashboardSnapshot(c);return r({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:s,siteId:c,intervalMs:n.intervalMs??15e3,cliVersion:n.cliVersion,onExit:n=>{t(),e(n)}}))})}const E=({api:e,siteId:t,intervalMs:r,cliVersion:i,onExit:c})=>{let{exit:l}=_(),[u,p]=x(null),[g,C]=x(null),[T,E]=x(null),[P,F]=x([]),[I,L]=x(!0),[R,z]=x(null),[B,V]=x(1),[H,U]=x(!1),[W,G]=x(!1);v((e,t)=>{if(e===`q`){l(),c(0);return}if(e===`?`||e===`/`){G(e=>!e);return}if(e===`g`){U(e=>!e);return}if(t.tab){V(e=>{let n=t.shift?(e+4)%6+1:e%6+1;return n});return}(e===`1`||e===`2`||e===`3`||e===`4`||e===`5`||e===`6`)&&V(Number(e))});let[K,q]=x(!1);if(b(()=>{let n=!1,i=async()=>{try{let r=await e.getDashboardSnapshot(t);if(n)return;let i=w.safeParse(r);if(!i.success){q(!0),L(!1);return}q(!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};p(o),e.getVitals(t).then(e=>{n||C(e)},()=>{}),e.getGoals(t).then(e=>{n||E(e)},()=>{}),L(!1),z(null)}catch(e){n||z(e.message)}};i();let a=setInterval(i,r);return()=>{n=!0,clearInterval(a)}},[e,t,r]),b(()=>{let r=new AbortController;return(async()=>{try{let i=await e.openEventsStream(t,r.signal);for await(let e of n(i))e.type===`error`&&F(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>r.abort()},[e,t]),I)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}`}),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 snapshot…`))));if(R&&!u)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}`}),y.createElement(a,{title:`Error`,state:`err`},y.createElement(h,{color:`red`},R)));if(K&&!u)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}`}),y.createElement(d,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let J=process.stdout.columns??80,Y=Math.max(20,Math.floor(J/3)-1),X=[];return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}${H?` · globe`:``}`}),y.createElement(m,{flexDirection:`row`},y.createElement(m,{flexDirection:`column`},H?y.createElement(a,{title:`Live globe`,focused:B===1,width:Y},y.createElement(f,{data:X,width:Math.max(40,Y-4),height:12})):y.createElement(O,{snapshot:u,focused:B===1,width:Y}),y.createElement(j,{events:P,focused:B===4,width:Y})),y.createElement(m,{flexDirection:`column`},y.createElement(k,{snapshot:u,focused:B===2,width:Y}),y.createElement(M,{vitals:g,focused:B===5,width:Y})),y.createElement(m,{flexDirection:`column`},y.createElement(A,{snapshot:u,focused:B===3,width:Y}),y.createElement(N,{goals:T,focused:B===6,width:Y}))),W?y.createElement(D,{api:e,siteId:t,width:J-2}):null,y.createElement(s,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:H?`panels`:`globe`},{key:`?/`,label:W?`close chat`:`ai chat`},{key:`q`,label:`quit`}]}))},D=({api:e,siteId:t,width:r})=>{let[i,o]=x(``),[s,c]=x([]),[l,u]=x(!1),[d,f]=x(``),[p,g]=x(null),_=async r=>{let i=r.trim();if(!i||l)return;g(null),o(``);let a=[...s,{role:`user`,content:i}];c(a),u(!0),f(``);try{let r=a.map(e=>({role:e.role,content:e.content})),i=await e.openAiStream(`chat`,{messages:r,siteId:t},void 0),o=``;for await(let e of n(i))if(e.type===`delta`)o+=e.content,f(o);else if(e.type===`error`)g(`${e.code}: ${e.message}`);else if(e.type===`done`)break;c([...a,{role:`assistant`,content:o}]),f(``)}catch(e){g(e instanceof Error?e.message:`chat failed`)}finally{u(!1)}};return y.createElement(m,{marginTop:1},y.createElement(a,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:r},y.createElement(m,{flexDirection:`column`},s.slice(-6).map((e,t)=>y.createElement(m,{key:t,flexDirection:`column`,marginBottom:1},y.createElement(h,{color:e.role===`user`?`cyan`:`magenta`,bold:!0},e.role===`user`?`you`:`zenovay`),y.createElement(h,null,e.content))),l&&d?y.createElement(m,{flexDirection:`column`,marginBottom:1},y.createElement(h,{color:`magenta`,bold:!0},`zenovay`),y.createElement(h,null,d)):null,p?y.createElement(h,{color:`red`},`✗ `,p):null,y.createElement(m,null,y.createElement(h,{color:`cyan`},l?`⠋ `:`▸ `),y.createElement(C,{value:i,onChange:o,onSubmit:_,placeholder:l?`streaming…`:`ask anything about your analytics`})))))},O=({snapshot:e,focused:t,width:n})=>{let r=e?.visitors?.count??0,i=e?.visitors?.series??[];return y.createElement(a,{title:`Visitors`,focused:t,width:n},y.createElement(h,{bold:!0},r.toString()),y.createElement(h,{color:`gray`},i.length>0?c(i,Math.max(8,n-6)):`— no data —`))},k=({snapshot:e,focused:t,width:n})=>{let r=e?.topPages?.slice(0,5)??[];return y.createElement(a,{title:`Top pages`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.path},y.createElement(h,null,e.path.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.views))))},A=({snapshot:e,focused:t,width:n})=>{let r=e?.sources?.slice(0,5)??[];return y.createElement(a,{title:`Sources`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.source},y.createElement(h,null,e.source.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.visitors))))},j=({events:e,focused:t,width:n})=>y.createElement(a,{title:`Events`,focused:t,width:n},e.length===0?y.createElement(h,{color:`gray`},`— waiting —`):e.slice(-10).map((e,t)=>y.createElement(h,{key:t},e.slice(0,n-4)))),M=({vitals:e,focused:t,width:n})=>{let r=(e,t,n)=>y.createElement(m,{key:e},y.createElement(h,{bold:!0},e.padEnd(6)),y.createElement(h,{color:`gray`},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return y.createElement(a,{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`))},N=({goals:e,focused:t,width:n})=>{let r=e?.goals?.slice(0,5)??[];return y.createElement(a,{title:`Goals`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.name},y.createElement(h,null,e.name.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.completions))))};export{T as watchCommand};
@@ -0,0 +1,3 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{Panel as n}from"./panel-BNI8Q_9k.js";import{Banner as r}from"./prompt-CnNQNqeK.js";import"./gradient-93CUjfDW.js";import"./keybar-CoNHlPOn.js";import"./sparkline-ut0Tvv-E.js";import"./ui-Bw_RHAeN.js";import{ApiV2Client as i}from"./api-v2-CRj-zoG9.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(n,{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(n){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 _=n.siteId??g.teamId??``;if(!_)return process.stderr.write(`No site selected — pass --site-id or set ZENOVAY_SITE.
2
+ `),2;if(!n.to)return process.stderr.write(`Missing --to <url> (e.g. --to localhost:3000/webhook).
3
+ `),2;let v=n.to.match(/^https?:\/\//)?n.to:`http://${n.to}`,y=new i({config:h,cliVersion:n.cliVersion,token:g}),b;try{b=await y.createTunnel(_,n.to)}catch(e){return process.stderr.write(`Failed to register tunnel: ${e.message}\n`),1}let x=n.sign?n.secret??b.tunnelKey:null,S=()=>{let{exit:e}=c(),[t,i]=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 n=await fetch(v,{method:e.method,headers:t,body:e.method===`GET`||e.method===`HEAD`?void 0:e.body}),r=await n.text(),a={};return n.headers.forEach((e,t)=>{a[t]=e}),i(e=>({...e,total:e.total+1,ok:e.ok+(n.ok?1:0),err:e.err+(n.ok?0:1),lastStatus:n.status,lastError:n.ok?null:`HTTP ${n.status}`})),{status:n.status,headers:a,body:r}}catch(e){let t=e instanceof Error?e.message:String(e);return i(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 n=y.tunnelClient(b.wsUrl);i(e=>({...e,connected:!0}));try{await n.start(t,e.signal)}catch(e){i(t=>({...t,connected:!1,lastError:e.message}))}})(),()=>{e.abort()}},[]),u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:`webhooks forward`}),u.createElement(m,{stats:t}),u.createElement(o,{color:`gray`},`target: `,v,` `,n.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-BMNuKlUT.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-DbWxI6M2.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.19",
3
+ "version": "0.1.20",
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-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{requireTier as l}from"./tier-Ceoo7ndQ.js";import{Box as u,Text as d}from"ink";import f from"react";function p(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 m(e){return e==null?`—`:e>=500?`Enterprise`:e>=50?`Growth`:`SMB`}async function h(h){let g=await e(),_=await t({strict:!1}),v=new c({config:g,cliVersion:h.cliVersion,token:_});try{await l(v,`scale`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let y;try{({siteId:y}=await s(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 b=r(h),x=h.window??`24h`,S=h.limit??100,C=[{key:`lastSeenAt`,header:`when`,width:6,format:e=>p(String(e))},{key:`name`,header:`company`,width:24,format:e=>String(e).slice(0,24)},{key:`employeeCount`,header:`tier`,width:11,format:e=>m(typeof e==`number`?e:null)},{key:`industry`,header:`industry`,width:18,format:e=>String(e??`—`).slice(0,18)},{key:`visitCount`,header:`visits`,width:6,align:`right`},{key:`isNew`,header:``,width:5,format:e=>e?`NEW`:``}];return i({cliVersion:h.cliVersion,title:`companies · ${y} · ${x}`,commandName:`companies`,authToken:_?.accessToken??null,refreshIntervalMs:h.watch?3e4:0,fetcher:e=>v.getCompaniesSnapshot(y,{window:x,limit:S},e),format:b,headlessEmit:(e,t)=>{let r=h.newOnly?e.companies.filter(e=>e.isNew):e.companies;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of r)process.stdout.write(JSON.stringify(e)+`
2
- `);else process.stdout.write(JSON.stringify({companies:r,total:r.length},null,2));return}process.stdout.write(n(r,[`name`,`domain`,`industry`,`employeeCount`,`visitCount`,`firstSeenAt`,`lastSeenAt`,`isNew`],t))},panels:[{id:`summary`,title:`Now`,render:e=>{let t=e.companies.filter(e=>e.isNew).length,n=e.companies.filter(e=>(e.employeeCount??0)>=500).length;return f.createElement(u,{flexDirection:`column`},f.createElement(d,null,f.createElement(d,{bold:!0},e.total),f.createElement(d,{color:`gray`},` companies in `,x)),f.createElement(d,{color:`gray`},f.createElement(d,{color:`green`},`● `,t,` new`),` · `,n,` enterprise`))}},{id:`feed`,title:`Feed`,render:e=>{let t=h.newOnly?e.companies.filter(e=>e.isNew):e.companies;return t.length===0?f.createElement(o,{reason:`no-data`,headline:`No ${h.newOnly?`new `:``}companies in window`,hint:`B2B identification fires when a tracked visitor matches a known company IP/domain.`}):f.createElement(a,{data:t.slice(0,30),columns:C})}}]})}export{h as companiesCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{Box as l,Text as u}from"ink";import d from"react";function f(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`}async function p(p){if(p.connect){let t=await e(),n=t.apiBase.replace(`api.zenovay.com`,`app.zenovay.com`),r=`${n}/settings/integrations/github`;return process.stdout.write(`\n Connect GitHub to Zenovay:\n ${r}\n\n Open this URL in your browser. Zenovay re-uses the same GitHub\n OAuth app you already authorized for login (auth-zenovay), so\n no separate "Zenovay Deploys" app is needed. Pick the repos you\n want to track and deploys will appear here automatically.\n\n`),0}let m=await e(),h=await t({strict:!1}),g=new c({config:m,cliVersion:p.cliVersion,token:h}),_;try{({siteId:_}=await s(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 v=r(p),y=p.limit??50,b=[{key:`pushed_at`,header:`when`,width:6,format:e=>f(String(e))},{key:`branch`,header:`branch`,width:14,format:e=>String(e??`—`).slice(0,14)},{key:`commit_sha`,header:`commit`,width:9,format:e=>String(e).slice(0,8)},{key:`commit_author`,header:`author`,width:16,format:e=>String(e??`—`).slice(0,16)},{key:`commit_message`,header:`message`,width:40,format:e=>String(e??`—`).slice(0,40)},{key:`show_on_chart`,header:`chart`,width:5,format:e=>e?`●`:`○`}];return i({cliVersion:p.cliVersion,title:`deploys · ${_}`,commandName:`deploys`,authToken:h?.accessToken??null,refreshIntervalMs:0,fetcher:e=>g.getDeploys(_,{branch:p.branch,since:p.since,limit:y},e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.deploys)process.stdout.write(JSON.stringify(t)+`
2
- `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(n(e.deploys,[`pushed_at`,`branch`,`commit_sha`,`commit_author`,`commit_message`,`repository`,`commit_url`,`show_on_chart`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>{let t=e.deploys.filter(e=>e.show_on_chart).length,n=new Set(e.deploys.map(e=>e.repository).filter(e=>!!e));return d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},e.total),d.createElement(u,{color:`gray`},` commits`,p.branch?` · branch=${p.branch}`:``)),d.createElement(u,{color:`gray`},d.createElement(u,{color:`magenta`},`● `,t,` on chart`),d.createElement(u,null,` · `),d.createElement(u,null,n.size,` `,n.size===1?`repo`:`repos`)))}},{id:`list`,title:`Recent`,render:e=>e.deploys.length===0?d.createElement(o,{reason:`no-data`,headline:`No commits yet`,hint:"Run `zenovay deploys --connect` to wire up the GitHub integration."}):d.createElement(a,{data:e.deploys.slice(0,30),columns:b})}]})}export{p as deploysCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{DataTable as u}from"./data-table-CDTM2qS0.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";async function b(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o}),u;try{({siteId:u}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getDevices(u);return n({type:`devices.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:s,siteId:u,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=m(),[l,p]=v(null),[b,x]=v(!0),[S,C]=v(null);if(h(e=>{e===`q`&&(c(),r(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getDevices(t);n||(p(r),x(!1))}catch(e){n||(C(e.message),x(!1))}})(),()=>{n=!0}},[e,t]),b)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`devices · ${t}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Fetching breakdown…`))));if(S)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`devices · ${t}`}),g.createElement(s,{reason:`error`,headline:`Failed to load`,hint:S}));let w=!l||l.devices.length===0&&l.browsers.length===0&&l.os.length===0;if(w)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`devices · ${t}`}),g.createElement(s,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let T=[{key:`name`,label:`name`,width:16},{key:`visitors`,label:`visitors`,align:`right`,width:8}];return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`devices · ${t}`}),g.createElement(d,{flexDirection:`row`},g.createElement(i,{title:`Devices`},l.devices.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(u,{columns:T,data:l.devices,zebra:!0})),g.createElement(i,{title:`Browsers`},l.browsers.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(u,{columns:T,data:l.browsers,zebra:!0})),g.createElement(i,{title:`OS`},l.os.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(u,{columns:T,data:l.os,zebra:!0}))),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{b as devicesCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import{spark as i}from"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as a}from"./analytical-screen-DI8ahq4z.js";import{Table as o}from"./ui-BtZp4Eh8.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function m(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`}async function h(h){let g=await e(),_=await t({strict:!1}),v=new l({config:g,cliVersion:h.cliVersion,token:_}),y;try{({siteId:y}=await c(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 b=r(h),x=h.window??`24h`,S=h.limit??100,C=[{key:`ts`,header:`when`,width:6,format:e=>m(String(e))},{key:`class`,header:`class`,width:18,format:e=>String(e)},{key:`message`,header:`message`,width:42,format:e=>p(String(e??``),42)},{key:`page`,header:`page`,width:24,format:e=>String(e??`—`)},{key:`device`,header:`device`,width:8,format:e=>String(e??`—`)}];return a({cliVersion:h.cliVersion,title:`errors · ${y} · ${x}`,commandName:`errors`,authToken:_?.accessToken??null,refreshIntervalMs:h.watch?3e4:0,fetcher:e=>v.getErrors(y,{window:x,limit:S},e),format:b,headlessEmit:(e,t)=>{let r=h.search?e.errors.filter(e=>e.class.toLowerCase().includes(h.search.toLowerCase())||e.message.toLowerCase().includes(h.search.toLowerCase())):e.errors;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of r)process.stdout.write(JSON.stringify(e)+`
2
- `);else process.stdout.write(JSON.stringify({errors:r,total:r.length},null,2));return}process.stdout.write(n(r,[`ts`,`class`,`message`,`page`,`device`,`fingerprint`],t))},panels:[{id:`summary`,title:`Recent errors`,render:e=>{let t=h.search?e.errors.filter(e=>e.class.toLowerCase().includes(h.search.toLowerCase())||e.message.toLowerCase().includes(h.search.toLowerCase())):e.errors,n=new Map,r=Date.now(),a=60;for(let e of t){let t=new Date(e.ts).getTime(),i=Math.floor((r-t)/(60*1e3));if(i<0||i>=a)continue;let o=n.get(e.class)??Array(a).fill(0),s=a-1-i;o[s]+=1,n.set(e.class,o)}let o=[...n.entries()].sort((e,t)=>t[1].reduce((e,t)=>e+t,0)-e[1].reduce((e,t)=>e+t,0)).slice(0,6);return f.createElement(u,{flexDirection:`column`},f.createElement(d,null,f.createElement(d,{bold:!0},t.length),f.createElement(d,{color:`gray`},` errors in `,x)),o.length===0?null:f.createElement(u,{flexDirection:`column`,marginTop:1},o.map(([e,t])=>f.createElement(d,{key:e},f.createElement(d,{color:`red`},e.padEnd(20).slice(0,20)),` `,f.createElement(d,{color:`gray`},i(t,30))))))}},{id:`table`,title:`Detail`,render:e=>{let t=h.search?e.errors.filter(e=>e.class.toLowerCase().includes(h.search.toLowerCase())||e.message.toLowerCase().includes(h.search.toLowerCase())):e.errors;return t.length===0?f.createElement(s,{reason:`no-data`,headline:h.search?`No errors match "${h.search}"`:`No errors in window`,hint:h.search?`Try widening the time window or removing the search filter.`:`Nothing broken — or your tracker hasn't captured any JS exceptions yet.`}):f.createElement(o,{data:t.slice(0,30),columns:C})}}]})}export{h as errorsCommand};
@@ -1,3 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{requireTier as l}from"./tier-Ceoo7ndQ.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){let n=Math.round(e*t);return`█`.repeat(Math.max(0,Math.min(t,n)))+`░`.repeat(Math.max(0,t-n))}async function m(m){let g=await e(),_=await t({strict:!1}),v=new c({config:g,cliVersion:m.cliVersion,token:_});try{await l(v,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let y;try{({siteId:y}=await s(v,{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=r(m);if(!m.funnelId){let e=[{key:`name`,header:`name`,width:30},{key:`stepCount`,header:`steps`,width:6,align:`right`},{key:`id`,header:`id`,width:36,format:e=>String(e).slice(0,36)}];return i({cliVersion:m.cliVersion,title:`funnels · ${y}`,commandName:`funnels`,authToken:_?.accessToken??null,refreshIntervalMs:0,fetcher:e=>v.listFunnels(y,e),format:b,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
- `);return}process.stdout.write(n(e.funnels,[`id`,`name`,`stepCount`],t))},panels:[{id:`funnels`,title:`Funnels`,render:t=>t.funnels.length===0?f.createElement(o,{reason:`no-data`,headline:`No funnels defined`,hint:`Create a funnel in the dashboard at app.zenovay.com to track conversion steps here.`}):f.createElement(a,{data:t.funnels,columns:e})},{id:`hint`,title:`Next`,render:()=>f.createElement(d,{color:`gray`},"Run `zenovay funnel <id>` for drop-off detail.")}]})}let x=m.window??`30d`;return i({cliVersion:m.cliVersion,title:`funnel · ${m.funnelId} · ${x}`,commandName:`funnel`,authToken:_?.accessToken??null,refreshIntervalMs:0,fetcher:e=>v.getFunnel(y,m.funnelId,x,e),format:b,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
3
- `);return}process.stdout.write(n(e.steps,[`id`,`name`,`visitors`,`conversions`],t))},panels:[{id:`overview`,title:h(`Overview`),render:e=>f.createElement(u,{flexDirection:`column`},f.createElement(d,{bold:!0},e.name),f.createElement(d,{color:`gray`},e.totalEntries.toLocaleString(),` entries · `,e.totalCompletions.toLocaleString(),` completed (`,(e.conversionRate*100).toFixed(1),`%)`))},{id:`flow`,title:`Flow`,render:e=>{let t=e.totalEntries||1;return f.createElement(u,{flexDirection:`column`},e.steps.map((n,r)=>{let i=n.visitors/t,a=e.steps[r-1],o=a?a.visitors-n.visitors:0,s=a?o/Math.max(1,a.visitors)*100:0;return f.createElement(u,{key:n.id,flexDirection:`column`},a?f.createElement(d,{color:`red`},` `,`↓ drop `,o.toLocaleString(),` (`,s.toFixed(1),`%)`):null,f.createElement(d,null,f.createElement(d,{bold:!0},`${r+1}. ${n.name}`.padEnd(22).slice(0,22)),` `,f.createElement(d,{color:`magenta`},p(i,30)),` `,f.createElement(d,null,(i*100).toFixed(1).padStart(5),`% `),f.createElement(d,{color:`gray`},n.visitors.toLocaleString())))}))}}]})}function h(e){return e}export{m as funnelCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{DataTable as u}from"./data-table-CDTM2qS0.js";import{Globe as d}from"./globe-1bi4DjwJ.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o}),u;try{({siteId:u}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getGeo(u);return n({type:`geo.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:s,siteId:u,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,m]=y(null),[x,S]=y(!0),[C,w]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getGeo(t);n||(m(r),S(!1))}catch(e){n||(w(e.message),S(!1))}})(),()=>{n=!0}},[e,t]),x)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`geo · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching geo…`))));if(C)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`geo · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:C}));let T=!l||l.countries.length===0&&l.cities.length===0;if(T)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`geo · ${t}`}),_.createElement(s,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let E=[{key:`country`,label:`country`,width:18},{key:`visitors`,label:`visitors`,align:`right`,width:8}],D=[{key:`city`,label:`city`,width:20},{key:`country`,label:`country`,width:12},{key:`visitors`,label:`visitors`,align:`right`,width:8}],O=process.stdout.columns??80;return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`geo · ${t}`}),_.createElement(f,{flexDirection:`row`},_.createElement(i,{title:`Countries`},l.countries.length===0?_.createElement(p,{color:`gray`},`— —`):_.createElement(u,{columns:E,data:l.countries.slice(0,15),zebra:!0})),_.createElement(i,{title:`Globe`},_.createElement(d,{data:[],width:Math.max(36,O-60),height:12}))),_.createElement(i,{title:`Cities`},l.cities.length===0?_.createElement(p,{color:`gray`},`— —`):_.createElement(u,{columns:D,data:l.cities.slice(0,20),zebra:!0})),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{x as geoCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{DataTable as d}from"./data-table-CDTM2qS0.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getHeatmaps(d);return n({type:`heatmaps.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,u]=y(null),[m,x]=y(!0),[S,C]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getHeatmaps(t);n||(u(r),x(!1))}catch(e){n||(C(e.message),x(!1))}})(),()=>{n=!0}},[e,t]),m)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`heatmaps · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching heatmaps…`))));if(S)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`heatmaps · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:S}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`heatmaps · ${t}`}),_.createElement(s,{reason:`no-data`,headline:`No heatmaps yet`,hint:`Enable heatmaps in your site settings`}));let w=[{key:`url`,label:`page`,width:36},{key:`type`,label:`type`,width:12},{key:`captureCount`,label:`captures`,align:`right`,width:10},{key:`createdAt`,label:`first seen`,width:24}];return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`heatmaps · ${t}`}),_.createElement(i,{title:`Heatmaps (${l.length})`},_.createElement(d,{columns:w,data:l,zebra:!0})),_.createElement(f,{marginTop:1},_.createElement(p,{color:`gray`},`Open any heatmap at https://app.zenovay.com/heatmaps`)),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{x as heatmapsCommand};
@@ -1 +0,0 @@
1
- import"./config-CZ9IzjIH.js";import"./api-DXmhz2DM.js";import{initCommand as e}from"./init-HBcPrM1L.js";import"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import"./emit-BmfLGjqr.js";import"./login-DvMRHd3J.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";export{e as initCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";function b(e){return e===`critical`?`err`:e===`warning`?`warn`:`ok`}function x(e){return e===`anomaly`?`⚡ anomaly`:e===`recommendation`?`✦ recommendation`:`↗ trend`}async function S(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getInsights(d);return n({type:`insights.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(C,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=m(),[l,u]=v(null),[p,S]=v(!0),[C,w]=v(null);return h(e=>{e===`q`&&(c(),r(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getInsights(t);n||(u(r),S(!1))}catch(e){n||(w(e.message),S(!1))}})(),()=>{n=!0}},[e,t]),p?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`insights · ${t}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Fetching insights…`)))):C?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`insights · ${t}`}),g.createElement(s,{reason:`error`,headline:`Failed to load`,hint:C})):!l||l.length===0?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`insights · ${t}`}),g.createElement(s,{reason:`no-data`,headline:`No insights yet`,hint:`Insights are generated nightly — check back tomorrow`})):g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`insights · ${t}`}),l.map((e,t)=>g.createElement(i,{key:t,title:`${x(e.kind)} · ${e.severity}`,state:b(e.severity)},g.createElement(f,{bold:!0},e.title),e.body?g.createElement(f,{color:`gray`},e.body):null)),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{S as insightsCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";async function b(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getJourneys(d);return n({type:`journeys.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=m(),[l,u]=v(null),[p,b]=v(!0),[x,S]=v(null);if(h(e=>{e===`q`&&(c(),r(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getJourneys(t);n||(u(r.flows),b(!1))}catch(e){n||(S(e.message),b(!1))}})(),()=>{n=!0}},[e,t]),p)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`journeys · ${t}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Computing flows…`))));if(x)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`journeys · ${t}`}),g.createElement(s,{reason:`error`,headline:`Failed to load`,hint:x}));if(!l||l.length===0)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`journeys · ${t}`}),g.createElement(s,{reason:`no-data`,headline:`No journeys yet`,hint:`Need at least 2 page-views per session to compute flows`}));let C=Math.max(...l.map(e=>e.count),1),w=12;return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`journeys · ${t}`}),g.createElement(i,{title:`Top page transitions (${l.length})`},l.map((e,t)=>{let n=Math.max(1,Math.round(e.count/C*w));return g.createElement(d,{key:t,flexDirection:`row`},g.createElement(f,null,e.from.padEnd(22).slice(0,22)),g.createElement(f,{color:`cyan`},` → `),g.createElement(f,null,e.to.padEnd(22).slice(0,22)),g.createElement(f,{color:`magenta`},` `,`█`.repeat(n),`░`.repeat(w-n)),g.createElement(f,{color:`gray`},` ${e.count}`))})),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{b as journeysCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{Globe as u}from"./globe-1bi4DjwJ.js";import{MetricCard as d}from"./metric-card-W4GayhPO.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o}),u;try{({siteId:u}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getLive(u);return n({type:`live.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:s,siteId:u,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,m]=y(null),[x,S]=y(!0),[C,w]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1,r=async()=>{try{let r=await e.getLive(t);n||(m(r),S(!1),w(null))}catch(e){n||(w(e.message),S(!1))}};r();let i=setInterval(r,2e3);return()=>{n=!0,clearInterval(i)}},[e,t]),x)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`live · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Connecting…`))));if(C&&!l)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`live · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:C}));let T=process.stdout.columns??80,E=Math.max(20,Math.min(40,Math.floor(T/3)));return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`live · ${t}`}),_.createElement(f,{flexDirection:`row`},_.createElement(d,{title:`Active now`,value:l?.activeVisitors??0,format:`number`,width:E}),_.createElement(i,{title:`Globe`,width:Math.max(40,T-E-4)},_.createElement(u,{data:[],width:Math.max(36,T-E-10),height:10}))),_.createElement(i,{title:`Recent events`},!l||l.recentEvents.length===0?_.createElement(p,{color:`gray`},`— waiting for events —`):l.recentEvents.slice(0,15).map((e,t)=>_.createElement(f,{key:t},_.createElement(p,{color:`cyan`},(e.type??`pageview`).padEnd(10)),_.createElement(p,null,e.path.padEnd(36).slice(0,36)),_.createElement(p,{color:`gray`},e.country??`—`)))),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{x as liveCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{DataTable as u}from"./data-table-CDTM2qS0.js";import{MetricCard as d}from"./metric-card-W4GayhPO.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o}),u;try{({siteId:u}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await S(s,u);return n({type:`overview.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(C,{api:s,siteId:u,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}async function S(e,t){let[n,r]=await Promise.all([e.getStats(t,`24h`).catch(()=>null),e.getPages(t).catch(()=>[])]),i=r.reduce((e,t)=>e+t.views,0);return{visitors:n?.visitors??0,pageviews:n?.pageviews??i,bounceRate:n?.bounceRate??null,avgSession:n?.avgSessionSec??null,series:[],topPages:r.slice(0,10)}}const C=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,m]=y(null),[x,C]=y(!0),[w,T]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await S(e,t);n||(m(r),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),x)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`overview · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching dashboard…`))));if(w)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`overview · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:w}));if(!l||l.visitors===0&&l.pageviews===0&&l.topPages.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`overview · ${t}`}),_.createElement(s,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let E=process.stdout.columns??80,D=Math.max(18,Math.floor(E/4)-1),O=[{key:`path`,label:`path`,width:32},{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)}%`:`—`}];return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`overview · ${t}`}),_.createElement(f,{flexDirection:`row`},_.createElement(d,{title:`Visitors`,value:l.visitors,format:`number`,width:D}),_.createElement(d,{title:`Pageviews`,value:l.pageviews,format:`number`,width:D}),_.createElement(d,{title:`Bounce rate`,value:l.bounceRate??``,emptyHint:`—`,format:`percent`,width:D}),_.createElement(d,{title:`Avg session`,value:l.avgSession??``,emptyHint:`—`,format:`duration`,width:D})),_.createElement(i,{title:`Top pages`},l.topPages.length===0?_.createElement(p,{color:`gray`},`— no pages yet —`):_.createElement(u,{columns:O,data:l.topPages,zebra:!0})),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{x as overviewCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{DataTable as u}from"./data-table-CDTM2qS0.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";async function b(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o}),u;try{({siteId:u}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getPages(u);return n({type:`pages.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:s,siteId:u,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=m(),[l,p]=v(null),[b,x]=v(!0),[S,C]=v(null);if(h(e=>{e===`q`&&(c(),r(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getPages(t);n||(p(r),x(!1))}catch(e){n||(C(e.message),x(!1))}})(),()=>{n=!0}},[e,t]),b)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`pages · ${t}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Fetching pages…`))));if(S)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`pages · ${t}`}),g.createElement(s,{reason:`error`,headline:`Failed to load`,hint:S}));if(!l||l.length===0)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`pages · ${t}`}),g.createElement(s,{reason:`no-data`,headline:`No pages yet`,hint:`Visit your site to send the first event`}));let w=[{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 g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`pages · ${t}`}),g.createElement(i,{title:`Top pages (${l.length})`},g.createElement(u,{columns:w,data:l,zebra:!0})),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{b as pagesCommand};
@@ -1 +0,0 @@
1
- import{Box as e,Text as t}from"ink";import n,{createContext as r,useContext as i,useEffect as a,useState as o}from"react";const s={xs:1,sm:2,md:3,lg:5,xl:8},c=e=>({headline:{color:e.accent,bold:!0},title:{color:e.fg,bold:!0},body:{color:e.fg},label:{color:e.dim,dim:!0,uppercase:!0},mono:{color:e.fg},caption:{color:e.muted}}),l={name:`mocha`,bg:`#1E1E2E`,fg:`#CDD6F4`,muted:`#6C7086`,accent:`#A6ADFF`,accent2:`#F5C2E7`,success:`#A6E3A1`,warn:`#F9E2AF`,error:`#F38BA8`,border:`#45475A`,dim:`#585B70`,spacing:s,radius:`round`,typography:c({fg:`#CDD6F4`,muted:`#6C7086`,accent:`#A6ADFF`,dim:`#585B70`})},u={name:`latte`,bg:`#EFF1F5`,fg:`#4C4F69`,muted:`#8C8FA1`,accent:`#7287FD`,accent2:`#EA76CB`,success:`#40A02B`,warn:`#DF8E1D`,error:`#D20F39`,border:`#BCC0CC`,dim:`#ACB0BE`,spacing:s,radius:`round`,typography:c({fg:`#4C4F69`,muted:`#8C8FA1`,accent:`#7287FD`,dim:`#ACB0BE`})},d={name:`dracula`,bg:`#282A36`,fg:`#F8F8F2`,muted:`#6272A4`,accent:`#BD93F9`,accent2:`#FF79C6`,success:`#50FA7B`,warn:`#F1FA8C`,error:`#FF5555`,border:`#44475A`,dim:`#6272A4`,spacing:s,radius:`round`,typography:c({fg:`#F8F8F2`,muted:`#6272A4`,accent:`#BD93F9`,dim:`#6272A4`})},f={name:`tokyoNight`,bg:`#1A1B26`,fg:`#C0CAF5`,muted:`#565F89`,accent:`#7AA2F7`,accent2:`#BB9AF7`,success:`#9ECE6A`,warn:`#E0AF68`,error:`#F7768E`,border:`#3B4261`,dim:`#414868`,spacing:s,radius:`round`,typography:c({fg:`#C0CAF5`,muted:`#565F89`,accent:`#7AA2F7`,dim:`#414868`})},p={name:`nord`,bg:`#2E3440`,fg:`#D8DEE9`,muted:`#4C566A`,accent:`#88C0D0`,accent2:`#81A1C1`,success:`#A3BE8C`,warn:`#EBCB8B`,error:`#BF616A`,border:`#3B4252`,dim:`#434C5E`,spacing:s,radius:`round`,typography:c({fg:`#D8DEE9`,muted:`#4C566A`,accent:`#88C0D0`,dim:`#434C5E`})},m={from:`#7D56F4`,to:`#FF5FD1`},h=r({theme:l});function g(){return i(h)}function _(e,t,n){if(n)return e.accent;switch(t){case`busy`:return e.accent;case`ok`:return e.success;case`warn`:return e.warn;case`err`:return e.error;case`idle`:default:return e.border}}function v(){let e=process.stdout.columns;return typeof e==`number`&&e>0?e:80}function y({title:r,state:i=`idle`,pillColor:a,width:o,focused:s=!1,density:c=`comfortable`,children:l}){let{theme:u}=g(),d=_(u,i,s),f=o??v(),p=a??d,m=c===`compact`?``:` `,h=`╭─ `,y=` ─╮`,b=r??``,x=r?b.length:0,S=r?h.length+x+y.length:4,C=Math.max(2,f-S),w=r?n.createElement(e,{flexDirection:`row`},n.createElement(t,{color:d},h),n.createElement(t,{color:p,bold:!0},b),n.createElement(t,{color:d},y,`─`.repeat(C))):n.createElement(e,{flexDirection:`row`},n.createElement(t,{color:d},`╭`,`─`.repeat(Math.max(2,f-2)),`╮`)),T=n.createElement(e,{flexDirection:`row`},n.createElement(t,{color:d},`╰`,`─`.repeat(Math.max(2,f-2)),`╯`));return n.createElement(e,{flexDirection:`column`},w,n.createElement(e,{flexDirection:`row`},n.createElement(t,{color:d},`│`,m),n.createElement(e,{flexDirection:`column`,flexGrow:1},l),n.createElement(t,{color:d},m,`│`)),T)}export{m as BRAND_GRADIENT,y as Panel,d as dracula,u as latte,l as mocha,p as nord,f as tokyoNight,g as useTheme};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{Box as l,Text as u}from"ink";import d from"react";async function f(f){let p=await e(),m=await t({strict:!1}),h=new c({config:p,cliVersion:f.cliVersion,token:m}),g;try{({siteId:g}=await s(h,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let _=r(f),v=[{key:`isCurrent`,header:``,width:2,format:e=>e?`*`:` `},{key:`name`,header:`project`,width:26},{key:`domain`,header:`domain`,width:28,format:e=>String(e??`—`)},{key:`tier`,header:`tier`,width:10},{key:`pageviews24h`,header:`24h pv`,width:8,align:`right`},{key:`id`,header:`id`,width:38,format:e=>String(e).slice(0,38)}];return i({cliVersion:f.cliVersion,title:`projects · ${m?.teamId??`—`}`,commandName:`projects`,authToken:m?.accessToken??null,refreshIntervalMs:0,fetcher:e=>h.getProjects(g,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
- `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(n(e.projects,[`id`,`name`,`domain`,`tier`,`pageviews24h`,`isCurrent`],t))},panels:[{id:`summary`,title:`Tracked sites`,render:e=>{let t=e.projects.find(e=>e.isCurrent);return d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},e.projects.length),d.createElement(u,{color:`gray`},` projects`)),t?d.createElement(u,{color:`gray`},`current: `,d.createElement(u,{color:`cyan`},t.name),` `,`(`,t.domain??`—`,`, `,t.tier,`)`):d.createElement(u,{color:`gray`},`no current project bound to this token`))}},{id:`list`,title:`List`,render:e=>e.projects.length===0?d.createElement(o,{reason:`no-data`,headline:`No projects yet`,hint:"Run `zenovay init` to install the tracker on your first site."}):d.createElement(a,{data:e.projects,columns:v})},{id:`hint`,title:`Switch`,render:()=>d.createElement(u,{color:`gray`},"To switch project: run `zenovay logout` then `zenovay login` (V2.1 adds a faster /switch flow).")}]})}export{f as projectsCommand};
@@ -1,3 +0,0 @@
1
- import{BRAND_GRADIENT as e,useTheme as t}from"./panel-DZqvtaao.js";import{Box as n,Text as r,useInput as i}from"ink";import a,{useCallback as o,useState as s}from"react";import c from"ink-select-input";import l from"ink-text-input";function u(e){let t=e.replace(`#`,``).trim(),n=t.length===3?t.split(``).map(e=>e+e).join(``):t,r=parseInt(n.slice(0,2),16),i=parseInt(n.slice(2,4),16),a=parseInt(n.slice(4,6),16);return{r:Number.isNaN(r)?0:r,g:Number.isNaN(i)?0:i,b:Number.isNaN(a)?0:a}}function d({r:e,g:t,b:n}){let r=e=>{let t=Math.max(0,Math.min(255,Math.round(e)));return t.toString(16).padStart(2,`0`)};return`#${r(e)}${r(t)}${r(n)}`}function f(e,t,n){return{r:e.r+(t.r-e.r)*n,g:e.g+(t.g-e.g)*n,b:e.b+(t.b-e.b)*n}}function p(e,t,n,i){if(e.length===0)return[];if(e.length===1)return[a.createElement(r,{key:`${i}-0`,color:d(t)},e)];let o=Array.from(e),s=o.length-1;return o.map((e,o)=>{let c=o/s,l=d(f(t,n,c));return a.createElement(r,{key:`${i}-${o}`,color:l},e)})}function m({from:e,to:t,children:n}){let i=u(e),o=u(t),s=n.split(`
2
- `),c=[];return s.forEach((e,t)=>{t>0&&c.push(a.createElement(r,{key:`nl-${t}`},`
3
- `));let n=p(e,i,o,`l${t}`);c.push(...n)}),a.createElement(r,null,c)}function h({children:t}){return a.createElement(m,{from:e.from,to:e.to},t)}function g(){let e=process.stdout.columns;return typeof e==`number`&&e>0?e:80}function _({version:e,subtitle:i}){let{theme:o}=t(),s=g(),c=`ZENOVAY · v${e}`,l=`╭─ `,u=` `,d=`─╮`,f=l.length+c.length+u.length+d.length,p=Math.max(2,s-f),m=`─`.repeat(p),_=`─`.repeat(Math.max(2,s-2)),v=i??``,y=v.slice(0,Math.max(0,s-4)),b=` `.repeat(Math.max(1,s-2-1-y.length-1));return a.createElement(n,{flexDirection:`column`},a.createElement(n,{flexDirection:`row`},a.createElement(r,{color:o.border},l),a.createElement(h,null,c),a.createElement(r,{color:o.border},u,m,d)),i?a.createElement(n,{flexDirection:`row`},a.createElement(r,{color:o.border},`│ `),a.createElement(r,{color:o.muted},y),a.createElement(r,{color:o.border},b,`│`)):null,a.createElement(n,{flexDirection:`row`},a.createElement(r,{color:o.border},`╰`,_,`╯`)))}function v({hints:e}){let{theme:n}=t();return a.createElement(r,{color:n.dim},e)}function y({items:e,onSelect:i}){let{theme:l}=t(),[u,d]=s(e[0]),f=o(e=>{i(e.value)},[i]),p=o(e=>{d(e)},[]);return a.createElement(n,{flexDirection:`column`},a.createElement(c,{items:e.map((e,t)=>({key:`${t}`,label:e.label,value:e.value})),onSelect:t=>{let n=e.find(e=>e.value===t.value);n&&f(n)},onHighlight:t=>{let n=e.find(e=>e.value===t.value);n&&p(n)}}),u?.description?a.createElement(n,{marginTop:1},a.createElement(r,{color:l.muted},u.description)):null,a.createElement(n,{marginTop:1},a.createElement(v,{hints:`[↑↓/jk nav] [enter select]`})))}function b({question:e,onSubmit:i,placeholder:o,mask:c}){let{theme:u}=t(),[d,f]=s(``);return a.createElement(n,{flexDirection:`column`},a.createElement(n,null,a.createElement(r,{color:u.fg},e,` `),a.createElement(l,{value:d,onChange:f,onSubmit:e=>i(e),placeholder:o,mask:c?`•`:void 0})),a.createElement(v,{hints:`[enter submit]`}))}export{_ as Banner,h as BrandGradient,y as Select,b as TextInput};
@@ -1,8 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{Table as o}from"./ui-BtZp4Eh8.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{requireTier as l}from"./tier-Ceoo7ndQ.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(),[s,c]=g(``),[l,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),c(``)}}},E=h(()=>l?l.columns.map(e=>({key:e,header:e,width:18,format:e=>e==null?`∅`:String(e).slice(0,18)})):[],[l]);return m.createElement(u,{flexDirection:`column`},m.createElement(a,{version:`query`}),m.createElement(i,{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:s,onChange:c,onSubmit:T})),x?m.createElement(d,{color:`gray`},`running…`):null,y?m.createElement(i,{title:`Error`,state:`err`},m.createElement(d,{color:`red`},y)):null,l?m.createElement(i,{title:`${l.row_count} rows · ${l.duration_ms}ms${l.truncated?` · truncated`:``}`,state:`ok`},l.row_count===0?m.createElement(d,{color:`gray`},`— empty —`):m.createElement(o,{data:l.rows.slice(0,50),columns:E})):null)}async function y(i){let a=await e(),o=await t({strict:!1}),u=new c({config:a,cliVersion:i.cliVersion,token:o});try{await l(u,`scale`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await s(u,{explicit:i.siteId,headless:!!(i.json||i.csv||i.tsv||i.ndjson),cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=i.maxRows??1e3,p=r(i);if(i.sql)try{let e=await u.runSqlQuery(d,i.sql,{maxRows:f});if(p===`json`)process.stdout.write(JSON.stringify(e,null,2)),process.stdout.write(`
2
- `);else if(p===`ndjson`)for(let t of e.rows)process.stdout.write(JSON.stringify(t)+`
3
- `);else if(p===`csv`||p===`tsv`)process.stdout.write(n(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
- `),process.stdout.write(`|`+e.columns.map((e,n)=>` ${e.padEnd(t[n]??0)} `).join(`|`)+`|
5
- `),process.stdout.write(n+`
6
- `);for(let n of e.rows.slice(0,200))process.stdout.write(`|`+e.columns.map((e,r)=>` ${String(n[e]??``).padEnd(t[r]??0)} `).join(`|`)+`|
7
- `);process.stdout.write(n+`
8
- `),process.stdout.write(`${e.row_count} rows · ${e.duration_ms}ms${e.truncated?` · truncated`:``}\n`)}return 0}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}let{render:h}=await import(`ink`);return await h(m.createElement(v,{api:u,siteId:d,maxRows:f})).waitUntilExit(),0}export{y as queryCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";function b(e){return e>=.6?`magenta`:e>=.4?`cyan`:e>=.2?`blue`:`gray`}function x(e){return!Number.isFinite(e)||e===0?` — `:` ${(e*100).toFixed(0).padStart(3)}% `}async function S(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getRetention(d);return n({type:`retention.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(C,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=m(),[l,u]=v(null),[p,S]=v(!0),[C,w]=v(null);return h(e=>{e===`q`&&(c(),r(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getRetention(t);n||(u(r.cohorts),S(!1))}catch(e){n||(w(e.message),S(!1))}})(),()=>{n=!0}},[e,t]),p?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`retention · ${t}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Crunching cohorts…`)))):C?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`retention · ${t}`}),g.createElement(s,{reason:`error`,headline:`Failed to load`,hint:C})):!l||l.length===0?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`retention · ${t}`}),g.createElement(s,{reason:`no-data`,headline:`No retention data yet`,hint:`Retention needs at least 30 days of traffic`})):g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`retention · ${t}`}),g.createElement(i,{title:`Cohort retention (D1 / D7 / D30)`},g.createElement(d,{flexDirection:`row`},g.createElement(f,{bold:!0},`cohort`.padEnd(12)),g.createElement(f,{bold:!0},` D1 `),g.createElement(f,{bold:!0},` D7 `),g.createElement(f,{bold:!0},` D30 `)),l.map(e=>g.createElement(d,{key:e.date,flexDirection:`row`},g.createElement(f,null,e.date.padEnd(12).slice(0,12)),g.createElement(f,{color:b(e.day1)},x(e.day1)),g.createElement(f,{color:b(e.day7)},x(e.day7)),g.createElement(f,{color:b(e.day30)},x(e.day30))))),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{S as retentionCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import{spark as i}from"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as a}from"./analytical-screen-DI8ahq4z.js";import"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{Box as l,Text as u}from"ink";import d from"react";function f(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 p(p){let m=await e(),h=await t({strict:!1}),g=new c({config:m,cliVersion:p.cliVersion,token:h}),_;try{({siteId:_}=await s(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 v=r(p),y=p.range??`30d`;return a({cliVersion:p.cliVersion,title:`revenue · ${_} · ${y}`,commandName:`revenue`,authToken:h?.accessToken??null,refreshIntervalMs:p.watch?5*6e4:0,fetcher:e=>g.getRevenue(_,y,e),format: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
- `);return}process.stdout.write(n(e.series,[`bucket`,`amount`,`currency`,`transactions`],t))},panels:[{id:`totals`,title:`Top line`,render:e=>d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{color:`green`,bold:!0},f(e.totalAmount,e.currency)),` `,d.createElement(u,{color:`gray`},`total · `,e.totalTransactions,` transactions`)),typeof e.mrr==`number`?d.createElement(u,null,d.createElement(u,{bold:!0},`MRR `),d.createElement(u,{color:`magenta`},f(e.mrr,e.currency)),typeof e.arpu==`number`?d.createElement(u,{color:`gray`},` · ARPU `,f(e.arpu,e.currency)):null):null)},{id:`series`,title:`Daily (${y})`,render:e=>{let t=e.series.map(e=>e.amount);if(t.length===0)return d.createElement(o,{reason:`no-data`,headline:`No revenue events yet`,hint:"Send Stripe webhooks or `track('purchase', { amount })` events to populate this chart."});let n=Math.max(...t,1);return d.createElement(l,{flexDirection:`column`},d.createElement(u,{color:`magenta`},i(t,Math.min(60,t.length*2))),d.createElement(u,{color:`gray`},`peak: `,f(n,e.currency),` ·`,` `,`avg: `,f(e.totalAmount/Math.max(1,t.length),e.currency)))}},{id:`window`,title:`Window`,render:e=>d.createElement(u,{color:`gray`},new Date(e.windowStart).toISOString().slice(0,10),` →`,` `,new Date(e.windowEnd).toISOString().slice(0,10))}]})}export{p as revenueCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{DataTable as d}from"./data-table-CDTM2qS0.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";function x(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 S(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 C(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getSessions(d);return n({type:`sessions.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(w,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,u]=y(null),[m,C]=y(!0),[w,T]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getSessions(t);n||(u(r),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),m)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`sessions · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching sessions…`))));if(w)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`sessions · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:w}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`sessions · ${t}`}),_.createElement(s,{reason:`no-data`,headline:`No replays yet`,hint:`Enable session replay in your site settings`}));let E=[{key:`id`,label:`session id`,width:24},{key:`visitor`,label:`visitor`,width:18},{key:`duration`,label:`duration`,align:`right`,width:9,format:e=>x(e)},{key:`startedAt`,label:`when`,align:`right`,width:6,format:e=>S(String(e))},{key:`pageCount`,label:`events`,align:`right`,width:7},{key:`deviceType`,label:`device`,width:8,format:e=>String(e??`—`)}];return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`sessions · ${t}`}),_.createElement(i,{title:`Recent sessions (${l.length})`},_.createElement(d,{columns:E,data:l,zebra:!0})),_.createElement(f,{marginTop:1},_.createElement(p,{color:`gray`},`Open any session for replay at https://app.zenovay.com/replay`)),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{C as sessionsCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e,t){let n=Math.round(e/100*t);return`█`.repeat(n)+`░`.repeat(Math.max(0,t-n))}function p(e){return e==null?{glyph:`·`,color:`gray`}:e>.5?{glyph:`▲`,color:`green`}:e<-.5?{glyph:`▼`,color:`red`}:{glyph:`→`,color:`gray`}}async function m(m){let h=await e(),g=await t({strict:!1}),_=new c({config:h,cliVersion:m.cliVersion,token:g}),v;try{({siteId:v}=await s(_,{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 y=r(m),b=m.period??`30d`,x=[{key:`source`,header:`source`,width:22},{key:`channel`,header:`channel`,width:10,format:e=>String(e??`—`)},{key:`visitors`,header:`visitors`,width:8,align:`right`},{key:`delta`,header:`Δ`,width:6,align:`right`,format:e=>typeof e==`number`?`${e>0?`+`:``}${(e*100).toFixed(1)}%`:`—`}];return i({cliVersion:m.cliVersion,title:`sources · ${v} · ${b}`,commandName:`sources`,authToken:g?.accessToken??null,refreshIntervalMs:6e4,fetcher:e=>_.getSources(v,b,m.compare,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
- `);return}process.stdout.write(n(e.sources,[`source`,`channel`,`visitors`,`conversions`,`revenue`,`delta`],t))},panels:[{id:`summary`,title:`Total`,render:e=>d.createElement(u,null,d.createElement(u,{bold:!0},e.totalVisitors.toLocaleString()),` `,d.createElement(u,{color:`gray`},`visitors · `,e.sources.length,` sources`))},{id:`channels`,title:`By channel`,render:e=>{if(e.sources.length===0)return d.createElement(o,{reason:`no-data`,headline:`No traffic yet`,hint:`Sources appear once visitors arrive from search, social or referrals.`});let t=e.totalVisitors||1,n=[...e.sources].sort((e,t)=>t.visitors-e.visitors).slice(0,12);return d.createElement(l,{flexDirection:`column`},n.map((e,n)=>{let r=e.visitors/t*100,i=p(e.delta);return d.createElement(l,{key:`${e.source}-${n}`},d.createElement(u,null,d.createElement(u,{color:`cyan`},e.source.padEnd(20).slice(0,20)),` `,d.createElement(u,{color:`magenta`},f(r,30)),` `,d.createElement(u,null,e.visitors.toString().padStart(6),` `),d.createElement(u,{color:`gray`},`(`,r.toFixed(1),`%)`),` `,d.createElement(u,{color:i.color},i.glyph)))}))}},{id:`table`,title:`Detail`,render:e=>e.sources.length===0?d.createElement(o,{reason:`no-data`,headline:`No source detail`,hint:`Detail rows fill in once traffic is attributed.`}):d.createElement(a,{data:e.sources.slice(0,20),columns:x})}]})}export{m as sourcesCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e){return`${(e*100).toFixed(1)}%`}function p(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 m(m){let h=await e(),g=await t({strict:!1}),_=new c({config:h,cliVersion:m.cliVersion,token:g}),v;try{({siteId:v}=await s(_,{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 y=r(m),b=m.range??`24h`,x=[{key:`url`,header:`page`,width:40,format:e=>String(e??`—`)},{key:`views`,header:`views`,width:8,align:`right`}],S=[{key:`country`,header:`country`,width:8},{key:`visitors`,header:`visitors`,width:8,align:`right`}];return i({cliVersion:m.cliVersion,title:`stats · ${v} · ${b}`,commandName:`stats`,authToken:g?.accessToken??null,refreshIntervalMs:m.watch?6e4:0,fetcher:e=>_.getStats(v,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
- `);return}process.stdout.write(n([{range:b,visitors:e.visitors,pageviews:e.pageviews,sessions:e.sessions,bounceRate:f(e.bounceRate),avgSession:p(e.avgSessionSec)}],[`range`,`visitors`,`pageviews`,`sessions`,`bounceRate`,`avgSession`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},e.visitors.toLocaleString()),d.createElement(u,{color:`gray`},` visitors `),d.createElement(u,{bold:!0},e.pageviews.toLocaleString()),d.createElement(u,{color:`gray`},` pageviews `),d.createElement(u,{bold:!0},e.sessions.toLocaleString()),d.createElement(u,{color:`gray`},` sessions`)),d.createElement(u,{color:`gray`},`bounce `,f(e.bounceRate),` · avg session `,p(e.avgSessionSec)))},{id:`pages`,title:`Top pages`,render:e=>e.topPages.length===0?d.createElement(o,{reason:`no-data`,headline:`No pages tracked`,hint:`Pageviews appear once your tracker fires its first event.`}):d.createElement(a,{data:e.topPages.slice(0,10),columns:x})},{id:`countries`,title:`Top countries`,render:e=>e.topCountries.length===0?d.createElement(o,{reason:`no-data`,headline:`No country data`,hint:`Country breakdown unlocks once visitors reach the site.`}):d.createElement(a,{data:e.topCountries.slice(0,10),columns:S})}]})}export{m as statsCommand};
@@ -1,4 +0,0 @@
1
- import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import"./ui-BtZp4Eh8.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
- `),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
- `),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
- `),0;let{waitUntilExit:t}=l(u.createElement(m,{themes:d}));return await t(),0}export{h as themesCommand};
@@ -1 +0,0 @@
1
- import{useTheme as e}from"./panel-DZqvtaao.js";import{BrandGradient as t}from"./prompt-DEng-me1.js";import{Box as n,Text as r,useInput as i}from"ink";import a,{useMemo as o,useState as s}from"react";import"diff";function c(e,t){return e.length<=t?e:t<=1?e.slice(0,t):`${e.slice(0,t-1)}…`}function l(e,t,n){if(e.length>=t)return c(e,t);let r=t-e.length;if(n===`right`)return` `.repeat(r)+e;if(n===`center`){let t=Math.floor(r/2),n=r-t;return` `.repeat(t)+e+` `.repeat(n)}return e+` `.repeat(r)}function u(e,t){return e.map(e=>{if(typeof e.width==`number`&&e.width>0)return e.width;let n=e.header.length;for(let r of t){let t=r[e.key],i=e.format?e.format(t,r):String(t??``);i.length>n&&(n=i.length)}return Math.max(3,n)})}function d({columns:i,data:o,zebra:s=!1}){let{theme:c}=e(),d=u(i,o),f=d.reduce((e,t)=>e+t,0)+i.length*3+1,p=(e,t,n)=>{let r=e;return d.forEach((e,i)=>{r+=`─`.repeat(e+2),r+=i===d.length-1?n:t}),r},m=p(`╭`,`┬`,`╮`),h=p(`├`,`┼`,`┤`),g=p(`╰`,`┴`,`╯`),_=i.map((e,t)=>l(e.header,d[t]??e.header.length,e.align??`left`)).join(` │ `);return a.createElement(n,{flexDirection:`column`,width:f},a.createElement(r,{color:c.border},m),a.createElement(n,{flexDirection:`row`},a.createElement(r,{color:c.border},`│ `),a.createElement(t,null,_),a.createElement(r,{color:c.border},` │`)),a.createElement(r,{color:c.border},h),o.map((e,t)=>{let o=s&&t%2==1,u=o?c.muted:c.fg,f=i.map((t,n)=>{let r=e[t.key],i=t.format?t.format(r,e):String(r??``);return l(i,d[n]??i.length,t.align??`left`)}).join(` │ `);return a.createElement(n,{key:t,flexDirection:`row`},a.createElement(r,{color:c.border},`│ `),a.createElement(r,{color:u},f),a.createElement(r,{color:c.border},` │`))}),a.createElement(r,{color:c.border},g))}export{d as Table};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{DataTable as d}from"./data-table-CDTM2qS0.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";function x(e){return e===`up`?{glyph:`● up`,color:`green`}:e===`down`?{glyph:`● down`,color:`red`}:{glyph:`○ unknown`,color:`gray`}}function S(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 C(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getUptime(d);return n({type:`uptime.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(w,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,u]=y(null),[m,C]=y(!0),[w,T]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getUptime(t);n||(u(r.monitors),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),m)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`uptime · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching monitors…`))));if(w)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`uptime · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:w}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`uptime · ${t}`}),_.createElement(s,{reason:`no-data`,headline:`No monitors configured`,hint:`Add one at app.zenovay.com/uptime`}));let E=[{key:`url`,label:`monitor`,width:36},{key:`status`,label:`status`,width:12,format:e=>x(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=>S(e)}];return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`uptime · ${t}`}),_.createElement(i,{title:`Monitors (${l.length})`},_.createElement(d,{columns:E,data:l,zebra:!0})),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{C as uptimeCommand};