@zenovay/cli 0.1.45 → 0.1.46

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 (87) hide show
  1. package/dist/{ai-CWwCXhe0.js → ai-D213ShI-.js} +1 -1
  2. package/dist/analytics-DF2T44kl.js +2 -0
  3. package/dist/bin.js +3 -3
  4. package/dist/companies-tJNXmMks.js +2 -0
  5. package/dist/{completions-hnfe6foE.js → completions-BQ4StZaH.js} +36 -5
  6. package/dist/csv-emit-BO_9WNzp.js +1 -0
  7. package/dist/csv-emit-DW3zkmKh.js +1 -0
  8. package/dist/{deploys-Ccskm10z.js → deploys-Gqz4EU7p.js} +1 -1
  9. package/dist/devices-CH8M4iis.js +2 -0
  10. package/dist/{doctor-Cq52FX17.js → doctor-D6-THYxW.js} +1 -1
  11. package/dist/errors-BXTHvRfC.js +2 -0
  12. package/dist/export-CG9wBqtQ.js +4 -0
  13. package/dist/funnel-BVa_bnxD.js +3 -0
  14. package/dist/geo-CJaEB5KN.js +2 -0
  15. package/dist/{health-xzMCrRNU.js → health-dMNJp2tb.js} +1 -1
  16. package/dist/heatmaps-DcAqig5H.js +1 -0
  17. package/dist/{init-BxDnnHgf.js → init-CgxoXN7k.js} +1 -1
  18. package/dist/{init-B2-pLG0u.js → init-DYSe6Vcn.js} +1 -1
  19. package/dist/insights-ByZzXZHY.js +1 -0
  20. package/dist/journeys-CHxCgdxr.js +1 -0
  21. package/dist/keybar-deep-link-AZ29NpWE.js +1 -0
  22. package/dist/live-Dr2uQxLP.js +1 -0
  23. package/dist/pages-u6aLFIpb.js +1 -0
  24. package/dist/{projects-BS2nyR1j.js → projects-CBWVFG4D.js} +1 -1
  25. package/dist/{query-BE8QcVVv.js → query-zdZ4ceI0.js} +1 -1
  26. package/dist/retention-slZLDbA1.js +1 -0
  27. package/dist/revenue-DJaQu3OS.js +2 -0
  28. package/dist/{self-test-Cigy1lvx.js → self-test-DzE99nUT.js} +1 -1
  29. package/dist/sessions-WiMWIQck.js +1 -0
  30. package/dist/sources-CkxSyvLT.js +2 -0
  31. package/dist/{stats-C4batJ0w.js → stats-CKX2x_-S.js} +1 -1
  32. package/dist/{themes-DXUwTDTq.js → themes-CFTtwV8K.js} +1 -1
  33. package/dist/uptime-Bwmb7jOZ.js +1 -0
  34. package/dist/visitors-CRdgYweh.js +2 -0
  35. package/dist/vitals-UZJtXgZy.js +2 -0
  36. package/dist/watch-BgMImDP3.js +1 -0
  37. package/dist/{webhooks-forward-e7zEIN10.js → webhooks-forward-DWf84udt.js} +1 -1
  38. package/dist/wizard-bin.js +1 -1
  39. package/package.json +1 -1
  40. package/dist/analytics-B3SEdA7W.js +0 -1
  41. package/dist/companies-lp8odhxs.js +0 -2
  42. package/dist/devices-D0WJQvjR.js +0 -1
  43. package/dist/errors-DRkkUKAc.js +0 -2
  44. package/dist/export-ByT57x4F.js +0 -4
  45. package/dist/funnel-Cix0d1qb.js +0 -3
  46. package/dist/geo-D-mMV-37.js +0 -1
  47. package/dist/heatmaps-CMVJvHds.js +0 -1
  48. package/dist/insights-DJmhPEI4.js +0 -1
  49. package/dist/journeys-B1XQviZ7.js +0 -1
  50. package/dist/live-srten0wD.js +0 -1
  51. package/dist/pages-JyzSlLDx.js +0 -1
  52. package/dist/retention-DE7K_nO7.js +0 -1
  53. package/dist/revenue-BpoPFvXQ.js +0 -2
  54. package/dist/sessions-BUyLI8Vz.js +0 -1
  55. package/dist/sources-C2EqaN4v.js +0 -2
  56. package/dist/uptime-BlU9iceL.js +0 -1
  57. package/dist/visitors-DnD81bQQ.js +0 -2
  58. package/dist/vitals-DnsdMEzu.js +0 -2
  59. package/dist/watch-DYaGvHA3.js +0 -1
  60. /package/dist/{analytical-screen-CxdwI377.js → analytical-screen-gN9MJR34.js} +0 -0
  61. /package/dist/{annotation-wR2A1Hw1.js → annotation-Cnwd3YY4.js} +0 -0
  62. /package/dist/{api-keys-kIevMXkb.js → api-keys-D70Onl1P.js} +0 -0
  63. /package/dist/{audit-CQHzQ_Cz.js → audit-CU9Mttuw.js} +0 -0
  64. /package/dist/{commands-D-kcaRBC.js → commands-C1jcv2pS.js} +0 -0
  65. /package/dist/{domains-CcGfEZpu.js → domains-BC7-CHRo.js} +0 -0
  66. /package/dist/{events-tail-BPgkQp32.js → events-tail-BqdQbbmc.js} +0 -0
  67. /package/dist/{examples-BejDD0xG.js → examples-Du9MQhvk.js} +0 -0
  68. /package/dist/{globe-C-lbJoTS.js → globe-Cc-yuiNd.js} +0 -0
  69. /package/dist/{globe-zZX6wWCj.js → globe-CzrRQX2k.js} +0 -0
  70. /package/dist/{goals-CV923p74.js → goals-Ce5-A1vs.js} +0 -0
  71. /package/dist/{health-Cc59YZgf.js → health-CDaLBYEV.js} +0 -0
  72. /package/dist/{home-BE0fjNXg.js → home-HxR4gTQn.js} +0 -0
  73. /package/dist/{integrations-C4tTW2eS.js → integrations-U4kC8H0B.js} +0 -0
  74. /package/dist/{logout-DWyGARdO.js → logout-C5ORyahe.js} +0 -0
  75. /package/dist/{notes-DYgUBDqU.js → notes-CcKBUVCU.js} +0 -0
  76. /package/dist/{plans-BXLT2qP3.js → plans-CpRRn2lU.js} +0 -0
  77. /package/dist/{profile-CqTlpqoB.js → profile-DFf1dDSh.js} +0 -0
  78. /package/dist/{settings-B5QzMjDs.js → settings-TskIncN8.js} +0 -0
  79. /package/dist/{share-DUXroknt.js → share-DpJKbbsA.js} +0 -0
  80. /package/dist/{team-DAx6QIUq.js → team-D2PjjTOh.js} +0 -0
  81. /package/dist/{teams-Cldfq0do.js → teams-DdBAKI2f.js} +0 -0
  82. /package/dist/{tour-_QdbuG8q.js → tour-DiwY-B8U.js} +0 -0
  83. /package/dist/{ui-CTH6j-SR.js → ui-CLpqz5_6.js} +0 -0
  84. /package/dist/{update-secSZPDw.js → update-C4T7lQkc.js} +0 -0
  85. /package/dist/{usage-CpzJCJUW.js → usage-CXHVT8_C.js} +0 -0
  86. /package/dist/{use-BZ2hTiH_.js → use-24v4ZHT1.js} +0 -0
  87. /package/dist/{webhooks-DhXyYlaN.js → webhooks-_1mTPi8-.js} +0 -0
@@ -1,2 +1,2 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{resolveSiteId as a}from"./resolve-site-CoOL4KPZ.js";import{DataTable as o}from"./data-table-D-JVXhZ7.js";import{runAnalyticalScreen as s}from"./analytical-screen-CxdwI377.js";import{Text as c}from"ink";import l from"react";function u(){let e=process.stdout.columns??80,t=Math.max(40,e-4-18),n=1,r=t-n,i=Math.max(8,Math.floor(r*.3)),a=Math.max(8,Math.floor(r*.32)),o=Math.max(4,Math.floor(r*.1)),s=Math.max(6,Math.floor(r*.12)),c=Math.max(4,r-i-a-o-s);return{current:n,name:i,domain:a,tier:o,pageviews24h:s,id:c}}async function d(d){let f=await e(),p=await t({strict:!1}),m=new n({config:f,cliVersion:d.cliVersion,token:p}),h,g;try{({siteId:h,site:g}=await a(m,{explicit:d.siteId,headless:!!(d.json||d.csv||d.tsv||d.ndjson),cliVersion:d.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let _=i(d),v=u(),y=[{key:`isCurrent`,label:``,width:v.current,format:e=>e?`*`:` `},{key:`name`,label:`project`,width:v.name},{key:`domain`,label:`domain`,width:v.domain,format:e=>String(e??`—`)},{key:`tier`,label:`tier`,width:v.tier},{key:`pageviews24h`,label:`24h pv`,width:v.pageviews24h,align:`right`},{key:`id`,label:`id`,width:v.id}];return s({cliVersion:d.cliVersion,title:`projects · ${p?.teamId??`—`}`,commandName:`projects`,authToken:p?.accessToken??null,refreshIntervalMs:0,fetcher:e=>m.getProjects(h,e),format:_,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.projects)process.stdout.write(JSON.stringify(t)+`
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{resolveSiteId as a}from"./resolve-site-CoOL4KPZ.js";import{DataTable as o}from"./data-table-D-JVXhZ7.js";import{runAnalyticalScreen as s}from"./analytical-screen-gN9MJR34.js";import{Text as c}from"ink";import l from"react";function u(){let e=process.stdout.columns??80,t=Math.max(40,e-4-18),n=1,r=t-n,i=Math.max(8,Math.floor(r*.3)),a=Math.max(8,Math.floor(r*.32)),o=Math.max(4,Math.floor(r*.1)),s=Math.max(6,Math.floor(r*.12)),c=Math.max(4,r-i-a-o-s);return{current:n,name:i,domain:a,tier:o,pageviews24h:s,id:c}}async function d(d){let f=await e(),p=await t({strict:!1}),m=new n({config:f,cliVersion:d.cliVersion,token:p}),h,g;try{({siteId:h,site:g}=await a(m,{explicit:d.siteId,headless:!!(d.json||d.csv||d.tsv||d.ndjson),cliVersion:d.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let _=i(d),v=u(),y=[{key:`isCurrent`,label:``,width:v.current,format:e=>e?`*`:` `},{key:`name`,label:`project`,width:v.name},{key:`domain`,label:`domain`,width:v.domain,format:e=>String(e??`—`)},{key:`tier`,label:`tier`,width:v.tier},{key:`pageviews24h`,label:`24h pv`,width:v.pageviews24h,align:`right`},{key:`id`,label:`id`,width:v.id}];return s({cliVersion:d.cliVersion,title:`projects · ${p?.teamId??`—`}`,commandName:`projects`,authToken:p?.accessToken??null,refreshIntervalMs:0,fetcher:e=>m.getProjects(h,e),format:_,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.projects)process.stdout.write(JSON.stringify(t)+`
2
2
  `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(r(e.projects,[`id`,`name`,`domain`,`tier`,`pageviews24h`,`isCurrent`],t))},keybindings:{s:{label:`switch project (logout + login)`,handler:()=>{process.stderr.write("To switch project: run `zenovay logout` then `zenovay login`.\n")}}},panels:[{id:`projects`,title:`Projects`,render:e=>e.projects.length===0?l.createElement(c,{color:`gray`},`— no projects yet —`):l.createElement(o,{data:e.projects,columns:y,headerStyle:`accent`})}]})}export{d as projectsCommand};
@@ -1,4 +1,4 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{requireTier as r}from"./tier-ztFrvV9H.js";import{formatTabular as i,selectFormat as a}from"./formatter-DDG2TSOz.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./progress-row-5G_PO8xL.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import"./sparkline-DM2BGvjD.js";import{resolveSiteId as c}from"./resolve-site-CoOL4KPZ.js";import{DataTable as l}from"./data-table-D-JVXhZ7.js";import"./bar-Cjia2R58.js";import"./ui-CTH6j-SR.js";import{Box as u,Text as d,useApp as f,useInput as p}from"ink";import m,{useMemo as h,useState as g}from"react";import _ from"ink-text-input";function v({api:e,siteId:t,maxRows:n}){let{exit:r}=f(),[i,a]=g(``),[c,v]=g(null),[y,b]=g(null),[x,S]=g(!1),[C,w]=g([]);p((e,t)=>{t.escape&&r()});let T=async i=>{if(i.trim()){if(i.trim()===`\\q`||i.trim()===`exit`||i.trim()===`quit`){r();return}w(e=>[...e,i]),S(!0),b(null);try{let r=await e.runSqlQuery(t,i,{maxRows:n});v(r)}catch(e){b(e.message),v(null)}finally{S(!1),a(``)}}},E=h(()=>c?c.columns.map(e=>({key:e,label:e,width:18,format:e=>e==null?`∅`:String(e).slice(0,18)})):[],[c]);return m.createElement(u,{flexDirection:`column`},m.createElement(s,{version:`query`}),m.createElement(o,{title:`History`,state:`idle`},C.length===0?m.createElement(d,{color:`gray`},`— no queries yet — Esc or \\q to exit —`):C.slice(-5).map((e,t)=>m.createElement(d,{key:t,color:`gray`},`> ${e.slice(0,80)}${e.length>80?`…`:``}`))),m.createElement(u,null,m.createElement(d,{color:`magenta`},`sql`,`>`,` `),m.createElement(_,{value:i,onChange:a,onSubmit:T})),x?m.createElement(d,{color:`gray`},`running…`):null,y?m.createElement(o,{title:`Error`,state:`err`},m.createElement(d,{color:`red`},y)):null,c?m.createElement(o,{title:`${c.row_count} rows · ${c.duration_ms}ms${c.truncated?` · truncated`:``}`,state:`ok`},c.row_count===0?m.createElement(d,{color:`gray`},`— empty —`):m.createElement(l,{data:c.rows.slice(0,50),columns:E,headerStyle:`accent`})):null)}async function y(o){let s=await e(),l=await t({strict:!1}),u=new n({config:s,cliVersion:o.cliVersion,token:l});try{await r(u,`scale`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(u,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=o.maxRows??1e3,p=a(o);if(o.sql)try{let e=await u.runSqlQuery(d,o.sql,{maxRows:f});if(p===`json`)process.stdout.write(JSON.stringify(e,null,2)),process.stdout.write(`
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{requireTier as r}from"./tier-ztFrvV9H.js";import{formatTabular as i,selectFormat as a}from"./formatter-DDG2TSOz.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./progress-row-5G_PO8xL.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import"./sparkline-DM2BGvjD.js";import{resolveSiteId as c}from"./resolve-site-CoOL4KPZ.js";import{DataTable as l}from"./data-table-D-JVXhZ7.js";import"./bar-Cjia2R58.js";import"./ui-CLpqz5_6.js";import{Box as u,Text as d,useApp as f,useInput as p}from"ink";import m,{useMemo as h,useState as g}from"react";import _ from"ink-text-input";function v({api:e,siteId:t,maxRows:n}){let{exit:r}=f(),[i,a]=g(``),[c,v]=g(null),[y,b]=g(null),[x,S]=g(!1),[C,w]=g([]);p((e,t)=>{t.escape&&r()});let T=async i=>{if(i.trim()){if(i.trim()===`\\q`||i.trim()===`exit`||i.trim()===`quit`){r();return}w(e=>[...e,i]),S(!0),b(null);try{let r=await e.runSqlQuery(t,i,{maxRows:n});v(r)}catch(e){b(e.message),v(null)}finally{S(!1),a(``)}}},E=h(()=>c?c.columns.map(e=>({key:e,label:e,width:18,format:e=>e==null?`∅`:String(e).slice(0,18)})):[],[c]);return m.createElement(u,{flexDirection:`column`},m.createElement(s,{version:`query`}),m.createElement(o,{title:`History`,state:`idle`},C.length===0?m.createElement(d,{color:`gray`},`— no queries yet — Esc or \\q to exit —`):C.slice(-5).map((e,t)=>m.createElement(d,{key:t,color:`gray`},`> ${e.slice(0,80)}${e.length>80?`…`:``}`))),m.createElement(u,null,m.createElement(d,{color:`magenta`},`sql`,`>`,` `),m.createElement(_,{value:i,onChange:a,onSubmit:T})),x?m.createElement(d,{color:`gray`},`running…`):null,y?m.createElement(o,{title:`Error`,state:`err`},m.createElement(d,{color:`red`},y)):null,c?m.createElement(o,{title:`${c.row_count} rows · ${c.duration_ms}ms${c.truncated?` · truncated`:``}`,state:`ok`},c.row_count===0?m.createElement(d,{color:`gray`},`— empty —`):m.createElement(l,{data:c.rows.slice(0,50),columns:E,headerStyle:`accent`})):null)}async function y(o){let s=await e(),l=await t({strict:!1}),u=new n({config:s,cliVersion:o.cliVersion,token:l});try{await r(u,`scale`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(u,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=o.maxRows??1e3,p=a(o);if(o.sql)try{let e=await u.runSqlQuery(d,o.sql,{maxRows:f});if(p===`json`)process.stdout.write(JSON.stringify(e,null,2)),process.stdout.write(`
2
2
  `);else if(p===`ndjson`)for(let t of e.rows)process.stdout.write(JSON.stringify(t)+`
3
3
  `);else if(p===`csv`||p===`tsv`)process.stdout.write(i(e.rows,e.columns,p));else{let t=e.columns.map(t=>Math.max(t.length,...e.rows.map(e=>String(e[t]??``).length))),n=`+`+t.map(e=>`-`.repeat(e+2)).join(`+`)+`+`;process.stdout.write(n+`
4
4
  `),process.stdout.write(`|`+e.columns.map((e,n)=>` ${e.padEnd(t[n]??0)} `).join(`|`)+`|
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{requireTier as r}from"./tier-ztFrvV9H.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import{resolveSiteId as l}from"./resolve-site-CoOL4KPZ.js";import{EmptyState as u}from"./empty-state-BbUJUNcp.js";import{deepLinkFor as d,openInBrowser as f}from"./keybar-deep-link-AZ29NpWE.js";import{Box as p,Text as m,render as h,useApp as g,useInput as _}from"ink";import v,{useEffect as y,useState as b}from"react";import x from"ink-spinner";function S(e){return e>=.6?`magenta`:e>=.4?`cyan`:e>=.2?`blue`:`gray`}function C(e){return!Number.isFinite(e)||e===0?` — `:` ${(e*100).toFixed(0).padStart(3)}% `}async function w(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getRetention(d);return i({type:`retention.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=h(v.createElement(T,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const T=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=g(),[l,h]=b(null),[w,T]=b(!0),[E,D]=b(null);return _(e=>{if(e===`o`||e===`O`){f(d(`retention`,{siteId:t}));return}e===`q`&&(a(),i(0))}),y(()=>{let n=!1;return(async()=>{try{let r=await e.getRetention(t);n||(h(r.cohorts),T(!1))}catch(e){n||(D(e.message),T(!1))}})(),()=>{n=!0}},[e,t]),w?v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(o,{title:`Loading`,state:`busy`},v.createElement(p,null,v.createElement(m,{color:`magenta`},v.createElement(x,{type:`dots`})),v.createElement(m,null,` Crunching cohorts…`)))):E?v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(u,{reason:`error`,headline:`Failed to load`,hint:E})):!l||l.length===0?v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(u,{reason:`no-data`,headline:`No retention data yet`,hint:`Retention needs at least 30 days of traffic`})):v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:r,subtitle:`retention · ${n}`}),v.createElement(o,{title:`Cohort retention (D1 / D7 / D30)`},v.createElement(p,{flexDirection:`row`},v.createElement(m,{bold:!0},`cohort`.padEnd(12)),v.createElement(m,{bold:!0},` D1 `),v.createElement(m,{bold:!0},` D7 `),v.createElement(m,{bold:!0},` D30 `)),l.map(e=>v.createElement(p,{key:e.date,flexDirection:`row`},v.createElement(m,null,e.date.padEnd(12).slice(0,12)),v.createElement(m,{color:S(e.day1)},C(e.day1)),v.createElement(m,{color:S(e.day7)},C(e.day7)),v.createElement(m,{color:S(e.day30)},C(e.day30))))),v.createElement(c,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{w as retentionCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./progress-row-5G_PO8xL.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{spark as a}from"./sparkline-DM2BGvjD.js";import{resolveSiteId as o}from"./resolve-site-CoOL4KPZ.js";import"./data-table-D-JVXhZ7.js";import"./bar-Cjia2R58.js";import{deepLinkFor as s,openInBrowser as c}from"./keybar-deep-link-AZ29NpWE.js";import{runAnalyticalScreen as l}from"./analytical-screen-gN9MJR34.js";import"./ui-CLpqz5_6.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){let n=e/100,r=new Intl.NumberFormat(`en-US`,{minimumFractionDigits:0,maximumFractionDigits:0}).format(n),i=(t||`USD`).toUpperCase();return i===`USD`?`$${r}`:i===`EUR`?`€${r}`:i===`GBP`?`£${r}`:`${r} ${i}`}async function m(m){let h=await e(),g=await t({strict:!1}),_=new n({config:h,cliVersion:m.cliVersion,token:g}),v,y;try{({siteId:v,site:y}=await o(_,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let b=i(m),x=m.range??`30d`;return l({cliVersion:m.cliVersion,title:`revenue · ${v} · ${x}`,commandName:`revenue`,authToken:g?.accessToken??null,refreshIntervalMs:m.watch?5*6e4:0,fetcher:e=>_.getRevenue(v,x,e),format:b,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`revenue`,{siteId:v}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);return}process.stdout.write(r(e.series,[`bucket`,`amount`,`currency`,`transactions`],t))},panels:[{id:`totals`,title:`Top line`,render:e=>f.createElement(u,{flexDirection:`column`},f.createElement(d,null,f.createElement(d,{color:`green`,bold:!0},p(e.totalAmount,e.currency)),` `,f.createElement(d,{color:`gray`},`total · `,e.totalTransactions,` transactions`)),typeof e.mrr==`number`?f.createElement(d,null,f.createElement(d,{bold:!0},`MRR `),f.createElement(d,{color:`magenta`},p(e.mrr,e.currency)),typeof e.arpu==`number`?f.createElement(d,{color:`gray`},` · ARPU `,p(e.arpu,e.currency)):null):null)},{id:`series`,title:`Daily (${x})`,render:e=>{let t=e.series.map(e=>e.amount);if(t.length===0)return f.createElement(d,{color:`gray`},`— no transactions —`);let n=Math.max(...t,1);return f.createElement(u,{flexDirection:`column`},f.createElement(d,{color:`magenta`},a(t,Math.min(60,t.length*2))),f.createElement(d,{color:`gray`},`peak: `,p(n,e.currency),` ·`,` `,`avg: `,p(e.totalAmount/Math.max(1,t.length),e.currency)))}},{id:`window`,title:`Window`,render:e=>f.createElement(d,{color:`gray`},new Date(e.windowStart).toISOString().slice(0,10),` →`,` `,new Date(e.windowEnd).toISOString().slice(0,10))}]})}export{m as revenueCommand};
@@ -1,7 +1,7 @@
1
1
  import{spawn as e}from"node:child_process";import t from"chalk";const n=3e4,r=4,i=1e3;function a(e,t){let n=e.requires;if(!n)return null;if(n.auth!==!1&&!t.authenticated)return`not authenticated`;if(n.tier&&t.currentTier){let e={free:0,pro:1,scale:2,enterprise:3},r=e[t.currentTier]??0,i=e[n.tier]??99}return n.multipleTeams&&!t.hasMultipleTeams?`requires 2+ teams`:n.freeTeam&&!t.hasFreeTeam?`requires a Free-tier team`:null}function o(t,n,r,i){return new Promise(a=>{let o=e(`node`,[t,...n],{env:{...process.env,ZENOVAY_NO_UPDATE_CHECK:`1`,...i},stdio:[`ignore`,`pipe`,`pipe`]}),s=``,c=``,l=!1,u=setTimeout(()=>{l=!0;try{o.kill(`SIGKILL`)}catch{}},r);o.stdout?.on(`data`,e=>{s+=e.toString(`utf8`),s.length>1048576&&(s=s.slice(0,1048576))}),o.stderr?.on(`data`,e=>{c+=e.toString(`utf8`),c.length>1048576&&(c=c.slice(0,1048576))}),o.on(`error`,e=>{clearTimeout(u),a({stdout:s,stderr:c+`\n[spawn error: ${e.message}]`,exitCode:-1,timedOut:l})}),o.on(`close`,e=>{clearTimeout(u),a({stdout:s,stderr:c,exitCode:e??0,timedOut:l})})})}async function s(e,t){let r=Date.now(),s=a(e,t.env);if(s)return{name:e.name,category:e.category,status:`skip`,durationMs:0,reason:s};if(e.inProcess)try{let t=await e.inProcess(),n=Date.now()-r;return t.ok?{name:e.name,category:e.category,status:`pass`,durationMs:n,...t.detail?{detail:t.detail}:{}}:{name:e.name,category:e.category,status:`fail`,durationMs:n,reason:t.reason}}catch(t){return{name:e.name,category:e.category,status:`fail`,durationMs:Date.now()-r,reason:t.message}}let c=e.name===`stack-leak.bad-net`?{ZENOVAY_API_BASE:`http://127.0.0.1:1`}:void 0,l=t.timeoutMs??n,u=await o(t.binPath,e.command,l,c),d=Date.now()-r;if(u.timedOut)return{name:e.name,category:e.category,status:`fail`,durationMs:d,reason:`timeout (${Math.round(l/1e3)}s)`,...t.verbose?{rawStdout:u.stdout.slice(0,i),rawStderr:u.stderr.slice(0,i)}:{}};let f;try{f=e.assert(u.stdout,u.stderr,u.exitCode)}catch(n){return{name:e.name,category:e.category,status:`fail`,durationMs:d,reason:`assert threw: ${n.message}`,...t.verbose?{rawStdout:u.stdout.slice(0,i),rawStderr:u.stderr.slice(0,i)}:{}}}return f.ok?{name:e.name,category:e.category,status:`pass`,durationMs:d,...f.detail?{detail:f.detail}:{},...t.verbose?{rawStdout:u.stdout.slice(0,i),rawStderr:u.stderr.slice(0,i)}:{}}:{name:e.name,category:e.category,status:`fail`,durationMs:d,reason:f.reason,...t.verbose?{rawStdout:u.stdout.slice(0,i),rawStderr:u.stderr.slice(0,i)}:{}}}async function c(e,t){let n=Date.now(),i=Math.max(1,t.parallel??r),a=Array(e.length).fill(void 0),o=[];for(let n=0;n<e.length;n++){let r=e[n];r&&(t.quick&&!r.quick||o.push(n))}let c=0,l=[],u=async()=>{for(;;){let n=c;if(c+=1,n>=o.length)return;let r=o[n];if(r===void 0)return;let i=e[r];if(!i)continue;let l=await s(i,t);a[r]=l,t.onResult?.(l)}};for(let e=0;e<i;e++)l.push(u());await Promise.all(l);let d=[];for(let e of a)e&&d.push(e);let f=d.filter(e=>e.status===`pass`).length,p=d.filter(e=>e.status===`fail`).length,m=d.filter(e=>e.status===`skip`).length;return{results:d,total:d.length,pass:f,fail:p,skip:m,durationMs:Date.now()-n}}async function l(e){let t={currentTier:null,hasMultipleTeams:!1,hasFreeTeam:!1,authenticated:!1};try{let{readToken:n}=await import(`./token-store-DpyCOgNw.js`),{readConfig:r}=await import(`./config-CUWIr4Qh.js`),{ApiV2Client:i}=await import(`./api-v2-CKwqzSrF.js`),a=await n({strict:!1}).catch(()=>null);if(!a)return t;t.authenticated=!0;let o=await r(),s=new i({config:o,cliVersion:e,token:a}),c=await s.me();if(c.team?.plan){let e=c.team.plan.toLowerCase();(e===`free`||e===`pro`||e===`scale`||e===`enterprise`)&&(t.currentTier=e)}c.teams&&c.teams.length>=2&&(t.hasMultipleTeams=!0),(c.teams&&c.teams.some(e=>e.plan?.toLowerCase()===`free`)||t.currentTier===`free`)&&(t.hasFreeTeam=!0)}catch{}return t}function u(e){let t=e.trim();if(!t)return{ok:!1,reason:`empty stdout`};try{return{ok:!0,value:JSON.parse(t)}}catch{let e=t.split(`
2
2
  `).filter(e=>e.trim().startsWith(`{`)||e.trim().startsWith(`[`)).pop();if(e)try{return{ok:!0,value:JSON.parse(e)}}catch{}return{ok:!1,reason:`stdout not JSON (got ${t.length} bytes)`}}}function d(e,t,n){if(n!==0)return{ok:!1,reason:`exit ${n}`};let r=u(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}}function f(e,t,n){if(n!==0){let r=[e,t];for(let e of r)if(e.includes(`tier_insufficient`))return{ok:!0,detail:{gated:!0}};return{ok:!1,reason:`exit ${n} — ${(t||e).slice(0,80)}`}}let r=u(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}}function p(e){if(typeof e!=`object`||!e)return!1;let t=e;if(Array.isArray(t.items)||Array.isArray(t.rows)||Array.isArray(t.data))return!0;if(typeof t.data==`object`&&t.data!==null){let e=t.data;if(Array.isArray(e.items)||Array.isArray(e.rows))return!0}return!1}const m=[{name:`analytics`,category:`ANALYTICS`,command:[`analytics`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.visitors??a.data?.visitors,s=a.pageviews??a.data?.pageviews;return{ok:!0,detail:{visitors:o??null,pageviews:s??null}}},quick:!0},{name:`overview`,category:`ANALYTICS`,command:[`overview`,`--json`],assert:d},{name:`pages`,category:`ANALYTICS`,command:[`pages`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.items??a.data?.items;return{ok:!0,detail:{rows:o?.length??0}}},quick:!0},{name:`sources`,category:`ANALYTICS`,command:[`sources`,`--json`],assert:d,quick:!0},{name:`devices`,category:`ANALYTICS`,command:[`devices`,`--json`],assert:d},{name:`geo`,category:`ANALYTICS`,command:[`geo`,`--json`],assert:d},{name:`live`,category:`ANALYTICS`,command:[`live`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);if(i.ok&&typeof i.value==`object`&&i.value!==null){let e=i.value,t=e.bounceRate??e.data?.bounceRate;if(typeof t==`number`&&(t<0||t>1))return{ok:!1,reason:`bounceRate semantics violated (got ${t}, expected 0..1)`}}return{ok:!0}}},{name:`revenue`,category:`ANALYTICS`,command:[`revenue`,`--json`],assert:d},{name:`funnels`,category:`ANALYTICS`,command:[`funnels`,`--json`],assert:f,requires:{tier:`pro`}},{name:`home`,category:`ANALYTICS`,command:[`home`,`--json`],assert:d},{name:`usage`,category:`ANALYTICS`,command:[`usage`,`--json`],assert:d,quick:!0},{name:`stats`,category:`ANALYTICS`,command:[`stats`,`--json`],assert:d},{name:`retention`,category:`BEHAVIOR`,command:[`retention`,`--json`],assert:f,requires:{tier:`pro`}},{name:`uptime`,category:`BEHAVIOR`,command:[`uptime`,`--json`],assert:f,requires:{tier:`pro`}},{name:`sessions`,category:`BEHAVIOR`,command:[`sessions`,`--json`],assert:f,requires:{tier:`pro`}},{name:`heatmaps`,category:`BEHAVIOR`,command:[`heatmaps`,`--json`],assert:f,requires:{tier:`pro`}},{name:`journeys`,category:`BEHAVIOR`,command:[`journeys`,`--json`],assert:f,requires:{tier:`pro`}},{name:`insights`,category:`INTELLIGENCE`,command:[`insights`,`--json`],assert:f,requires:{tier:`pro`}},{name:`domains list`,category:`MANAGE`,command:[`domains`,`list`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);return!i.ok||!p(i.value)?{ok:!1,reason:`expected list shape ({items|rows|data})`}:{ok:!0}},quick:!0},{name:`api-keys list`,category:`MANAGE`,command:[`api-keys`,`list`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);return!i.ok||!p(i.value)?{ok:!1,reason:`expected list shape`}:{ok:!0}}},{name:`team list`,category:`MANAGE`,command:[`team`,`list`,`--json`],assert:f,requires:{tier:`pro`}},{name:`webhooks list`,category:`MANAGE`,command:[`webhooks`,`list`,`--json`],assert:d},{name:`profile show`,category:`ACCOUNT`,command:[`profile`,`show`,`--json`],assert:d,quick:!0},{name:`plans info`,category:`ACCOUNT`,command:[`plans`,`info`,`--json`],assert:d},{name:`settings get`,category:`ACCOUNT`,command:[`settings`,`get`,`--json`],assert:d},{name:`integrations list`,category:`ACCOUNT`,command:[`integrations`,`list`,`--json`],assert:d},{name:`goals list`,category:`ACCOUNT`,command:[`goals`,`list`,`--json`],assert:f,requires:{tier:`pro`}},{name:`notes list`,category:`ACCOUNT`,command:[`notes`,`list`,`--json`],assert:d},{name:`audit list`,category:`ACCOUNT`,command:[`audit`,`list`,`--json`],assert:f,requires:{tier:`pro`}},{name:`share url`,category:`ACCOUNT`,command:[`share`,`url`,`--json`],assert:(e,t,n)=>n!==0&&n!==1&&n!==2?{ok:!1,reason:`unexpected exit ${n}`}:{ok:!0}},{name:`teams list`,category:`ACCOUNT`,command:[`teams`,`list`,`--json`],assert:d},{name:`health`,category:`OPERATIONS`,command:[`health`,`--json`],assert:(e,t,n)=>{let r=u(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}},quick:!0},{name:`commands`,category:`OPERATIONS`,command:[`commands`,`--json`],assert:(e,t,n)=>{let r=d(e,t,n);if(!r.ok)return r;let i=u(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.commands;return!Array.isArray(o)||o.length===0?{ok:!1,reason:`commands tree empty`}:{ok:!0,detail:{commands:o.length}}}},{name:`themes`,category:`OPERATIONS`,command:[`themes`,`--json`],assert:d},{name:`projects`,category:`OPERATIONS`,command:[`projects`,`--json`],assert:d},{name:`idor.cross-team`,category:`SECURITY`,command:[`domains`,`list`,`--site-id`,`00000000-0000-0000-0000-000000000001`,`--json`],assert:(e,t,n)=>{let r=e+t;return/forbidden|not_found|tier_insufficient|auth_required|auth_invalid/.test(r)?{ok:!0,detail:{rejected:!0}}:r.includes(`"items"`)||r.includes(`"rows"`)?{ok:!1,reason:`expected forbidden/not_found, got data`}:{ok:!0,detail:{rejected:`empty`}}},requires:{multipleTeams:!0},dev:!0},{name:`idor.bad-uuid`,category:`SECURITY`,command:[`analytics`,`--site-id`,`00000000-0000-0000-0000-000000000000`,`--json`],assert:(e,t,n)=>{let r=e+t;return/not_found|forbidden|auth_/.test(r)?{ok:!0,detail:{rejected:!0}}:/error|invalid|"code":/i.test(r)?{ok:!0,detail:{rejected:`error-shaped`}}:{ok:!1,reason:`silent zeros — expected not_found`}},quick:!0,dev:!0},{name:`tier-gate.retention`,category:`SECURITY`,command:[`retention`,`--json`],assert:(e,t,n)=>{let r=e+t;return r.includes(`tier_insufficient`)?{ok:!0,detail:{gated:`tier_insufficient`}}:/upgrade_required|tier_required/.test(r)?{ok:!0,detail:{gated:`legacy-or-transitional`}}:/"code":\s*"forbidden"/.test(r)&&/tier|upgrade|plan/i.test(r)?{ok:!0,detail:{gated:`forbidden+tier-message`}}:n===0&&!/"type"\s*:\s*"error"/.test(r)?{ok:!0,detail:{gated:`pass-through (Pro+ access)`}}:{ok:!1,reason:`gate did not behave as expected (no tier envelope and no clean pass-through)`}},dev:!0},{name:`stack-leak.bad-net`,category:`SECURITY`,command:[`analytics`,`--json`],assert:(e,t,n)=>{let r=e+t;return/\/Users\//.test(r)||/node:internal\//.test(r)?{ok:!1,reason:`stack trace leaked filesystem path`}:{ok:!0}},quick:!0},{name:`token-perms`,category:`SECURITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{stat:e}=await import(`node:fs/promises`),t=await import(`node:path`),n=process.env.HOME??process.env.USERPROFILE??``,r=process.env.XDG_CONFIG_HOME??t.join(n,`.config`),i=process.platform===`win32`?t.join(process.env.APPDATA??t.join(n,`AppData`,`Roaming`),`zenovay`,`auth.json`):t.join(r,`zenovay`,`auth.json`);try{let t=await e(i);if(process.platform===`win32`)return{ok:!0,detail:{mode:`win32-skip`}};let n=t.mode&511;return n===384?{ok:!0,detail:{mode:`0600`}}:{ok:!1,reason:`auth.json mode ${n.toString(8)} != 0600`}}catch(e){let t=e.code;return t===`ENOENT`?{ok:!0,detail:{mode:`no-auth-file`}}:{ok:!1,reason:e.message}}},quick:!0},{name:`secret-scrub`,category:`SECURITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{SECRET_PATTERNS:e,scrubSecrets:t}=await import(`./secrets-M60NENIa.js`),n=[{name:`openai-proj`,sample:`sk-proj-abcdefghijklmnopqrstuvwxyz0123456789`},{name:`anthropic`,sample:`sk-ant-abcdefghijklmnopqrstuvwxyz0123456789`},{name:`openai-sk`,sample:`sk-abcdefghijklmnopqrstuvwxyz0123`},{name:`github-pat-new`,sample:`github_pat_`+`a`.repeat(82)},{name:`github-pat`,sample:`ghp_`+`a`.repeat(36)},{name:`github-oauth`,sample:`gho_`+`a`.repeat(36)},{name:`aws-access-key`,sample:`AKIAABCDEFGHIJKLMNOP`},{name:`stripe-live`,sample:`sk_live_`+`a`.repeat(28)},{name:`stripe-test`,sample:`pk_test_`+`a`.repeat(28)},{name:`stripe-restricted`,sample:`rk_live_`+`a`.repeat(28)},{name:`stripe-webhook`,sample:`whsec_`+`a`.repeat(28)},{name:`slack-bot`,sample:`xoxb-1234567890-abcdef`},{name:`google-api`,sample:`AIza`+`a`.repeat(35)},{name:`jwt`,sample:`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTYifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`},{name:`private-key-rsa`,sample:`-----BEGIN RSA PRIVATE KEY-----`},{name:`private-key-pkcs8`,sample:`-----BEGIN PRIVATE KEY-----`},{name:`supabase-jwt`,sample:`eyJhbGciOi`+`a`.repeat(40)},{name:`resend-api`,sample:`re_`+`a`.repeat(20)},{name:`gitlab-pat`,sample:`glpat-`+`a`.repeat(20)},{name:`shopify`,sample:`shpat_`+`a`.repeat(32)},{name:`service-role-key`,sample:`service_role: "`+`a`.repeat(40)+`"`}],r=n.map(e=>`${e.name}=${e.sample}`).join(`
3
3
  `),i=t(r),a=n.filter(e=>i.includes(`[REDACTED:${e.name}]`)).length,o=e.length,s=Math.max(18,o-4);return a>=s?{ok:!0,detail:{matched:a,total:o}}:{ok:!1,reason:`${a}/${o} patterns redacted (need >= ${s})`}},quick:!0},{name:`help-line-count`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=e.split(`
4
- `).length;return r<90?{ok:!0,detail:{lines:r}}:{ok:!1,reason:`${r} lines (target < 90)`}},dev:!0},{name:`help-no-wave-markers`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=/\b(?:Wave\s*\d|W\d|V2\.1)\b/i,i=e.match(r);return i?{ok:!1,reason:`found marker: ${i[0]}`}:{ok:!0}},dev:!0},{name:`help-has-groups`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=[`ANALYTICS`,`BEHAVIOR`,`MANAGE`,`ACCOUNT`,`OPERATIONS`],i=r.filter(t=>!e.includes(t));return i.length===0?{ok:!0,detail:{found:r}}:{ok:!1,reason:`missing groups: ${i.join(`, `)}`}},dev:!0},{name:`examples-coverage`,category:`DISCOVERABILITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{EXAMPLES:e}=await import(`./examples-BejDD0xG.js`),t=Object.keys(e).length;return t>=25?{ok:!0,detail:{commands:t}}:{ok:!1,reason:`${t} commands have examples (need >= 25)`}},dev:!0},{name:`envelope-shape`,category:`DISCOVERABILITY`,command:[`commands`,`--json`],assert:(e,t,n)=>{if(n!==0)return{ok:!1,reason:`exit ${n}`};let r=u(e);if(!r.ok)return{ok:!1,reason:r.reason};let i=r.value,a=typeof i.version==`string`&&Array.isArray(i.commands);return a?{ok:!0,detail:{commands:i.commands.length}}:{ok:!1,reason:`commands payload missing version+commands`}},dev:!0}],h=m.length;async function g(e){let t=process.argv[1]??process.execPath,n=!!e.full||process.env.ZENOVAY_SELF_TEST_FULL===`1`,r=m.filter(e=>n||!e.dev);e.quick&&(r=r.filter(e=>e.quick));let i=await l(e.cliVersion);return e.json?_({...e,binPath:t,env:i,catalog:r}):b({...e,binPath:t,env:i,catalog:r})}async function _(e){let t=await c(e.catalog,{binPath:e.binPath,quick:e.quick??!1,verbose:e.verbose??!1,parallel:e.parallel,env:e.env,onResult:e=>{let t={type:`self-test.result`,name:e.name,category:e.category,status:e.status,durationMs:e.durationMs,...e.detail?{detail:e.detail}:{},...e.reason?{reason:e.reason}:{},...e.rawStdout?{rawStdout:e.rawStdout}:{},...e.rawStderr?{rawStderr:e.rawStderr}:{}};process.stdout.write(`${JSON.stringify(t)}\n`)}});return process.stdout.write(`${JSON.stringify({type:`self-test.summary`,total:t.total,pass:t.pass,fail:t.fail,skip:t.skip,durationMs:t.durationMs,cliVersion:e.cliVersion,env:e.env})}\n`),t.fail>0?1:0}const v=26,y=8;async function b(e){S(e.cliVersion,e.quick??!1,e.catalog.length);let t=new Map,n=0,r=null,i=new Map;for(let t of e.catalog)i.set(t.category,(i.get(t.category)??0)+1);let a=await c(e.catalog,{binPath:e.binPath,quick:e.quick??!1,verbose:e.verbose??!1,parallel:e.parallel,env:e.env,onResult:a=>{for(t.set(a.name,a);n<e.catalog.length;){let a=e.catalog[n];if(!a)break;let o=t.get(a.name);if(!o)break;r!==a.category&&(C(a.category,i.get(a.category)??0),r=a.category),w(a,o),t.delete(a.name),n+=1}}});return T(a),a.fail>0?1:0}function x(){return Math.max(60,process.stdout.columns??80)}function S(e,n,r){let i=Math.min(120,x()),a=i-2,o=`ZENOVAY · v${e}`,s=`self-test · ${n?`quick`:`full`} · ${r} test${r===1?``:`s`}`,c=`╭─ `+o+` `+`─`.repeat(Math.max(0,a-o.length-4))+`╮`,l=`│ `+s+` `.repeat(Math.max(0,a-s.length-2))+`│`,u=`╰`+`─`.repeat(a)+`╯`;process.stdout.write(t.cyan(c)+`
4
+ `).length;return r<90?{ok:!0,detail:{lines:r}}:{ok:!1,reason:`${r} lines (target < 90)`}},dev:!0},{name:`help-no-wave-markers`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=/\b(?:Wave\s*\d|W\d|V2\.1)\b/i,i=e.match(r);return i?{ok:!1,reason:`found marker: ${i[0]}`}:{ok:!0}},dev:!0},{name:`help-has-groups`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=[`ANALYTICS`,`BEHAVIOR`,`MANAGE`,`ACCOUNT`,`OPERATIONS`],i=r.filter(t=>!e.includes(t));return i.length===0?{ok:!0,detail:{found:r}}:{ok:!1,reason:`missing groups: ${i.join(`, `)}`}},dev:!0},{name:`examples-coverage`,category:`DISCOVERABILITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{EXAMPLES:e}=await import(`./examples-Du9MQhvk.js`),t=Object.keys(e).length;return t>=25?{ok:!0,detail:{commands:t}}:{ok:!1,reason:`${t} commands have examples (need >= 25)`}},dev:!0},{name:`envelope-shape`,category:`DISCOVERABILITY`,command:[`commands`,`--json`],assert:(e,t,n)=>{if(n!==0)return{ok:!1,reason:`exit ${n}`};let r=u(e);if(!r.ok)return{ok:!1,reason:r.reason};let i=r.value,a=typeof i.version==`string`&&Array.isArray(i.commands);return a?{ok:!0,detail:{commands:i.commands.length}}:{ok:!1,reason:`commands payload missing version+commands`}},dev:!0}],h=m.length;async function g(e){let t=process.argv[1]??process.execPath,n=!!e.full||process.env.ZENOVAY_SELF_TEST_FULL===`1`,r=m.filter(e=>n||!e.dev);e.quick&&(r=r.filter(e=>e.quick));let i=await l(e.cliVersion);return e.json?_({...e,binPath:t,env:i,catalog:r}):b({...e,binPath:t,env:i,catalog:r})}async function _(e){let t=await c(e.catalog,{binPath:e.binPath,quick:e.quick??!1,verbose:e.verbose??!1,parallel:e.parallel,env:e.env,onResult:e=>{let t={type:`self-test.result`,name:e.name,category:e.category,status:e.status,durationMs:e.durationMs,...e.detail?{detail:e.detail}:{},...e.reason?{reason:e.reason}:{},...e.rawStdout?{rawStdout:e.rawStdout}:{},...e.rawStderr?{rawStderr:e.rawStderr}:{}};process.stdout.write(`${JSON.stringify(t)}\n`)}});return process.stdout.write(`${JSON.stringify({type:`self-test.summary`,total:t.total,pass:t.pass,fail:t.fail,skip:t.skip,durationMs:t.durationMs,cliVersion:e.cliVersion,env:e.env})}\n`),t.fail>0?1:0}const v=26,y=8;async function b(e){S(e.cliVersion,e.quick??!1,e.catalog.length);let t=new Map,n=0,r=null,i=new Map;for(let t of e.catalog)i.set(t.category,(i.get(t.category)??0)+1);let a=await c(e.catalog,{binPath:e.binPath,quick:e.quick??!1,verbose:e.verbose??!1,parallel:e.parallel,env:e.env,onResult:a=>{for(t.set(a.name,a);n<e.catalog.length;){let a=e.catalog[n];if(!a)break;let o=t.get(a.name);if(!o)break;r!==a.category&&(C(a.category,i.get(a.category)??0),r=a.category),w(a,o),t.delete(a.name),n+=1}}});return T(a),a.fail>0?1:0}function x(){return Math.max(60,process.stdout.columns??80)}function S(e,n,r){let i=Math.min(120,x()),a=i-2,o=`ZENOVAY · v${e}`,s=`self-test · ${n?`quick`:`full`} · ${r} test${r===1?``:`s`}`,c=`╭─ `+o+` `+`─`.repeat(Math.max(0,a-o.length-4))+`╮`,l=`│ `+s+` `.repeat(Math.max(0,a-s.length-2))+`│`,u=`╰`+`─`.repeat(a)+`╯`;process.stdout.write(t.cyan(c)+`
5
5
  `),process.stdout.write(t.cyan(l)+`
6
6
  `),process.stdout.write(t.cyan(u)+`
7
7
 
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{requireTier as r}from"./tier-ztFrvV9H.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import{resolveSiteId as l}from"./resolve-site-CoOL4KPZ.js";import{DataTable as u}from"./data-table-D-JVXhZ7.js";import{EmptyState as d}from"./empty-state-BbUJUNcp.js";import{deepLinkFor as f,openInBrowser as p}from"./keybar-deep-link-AZ29NpWE.js";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";function C(e){if(!e||e<=0)return`—`;let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return`${n}m ${(t%60).toString().padStart(2,`0`)}s`}function w(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.max(0,Math.floor((Date.now()-t)/1e3));return n<60?`${n}s`:n<3600?`${Math.floor(n/60)}m`:n<86400?`${Math.floor(n/3600)}h`:`${Math.floor(n/86400)}d`}async function T(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getSessions(d);return i({type:`sessions.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const E=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=_(),[l,g]=x(null),[T,E]=x(!0),[D,O]=x(null);if(v(e=>{if(e===`o`||e===`O`){p(f(`sessions`,{siteId:t}));return}e===`q`&&(a(),i(0))}),b(()=>{let n=!1;return(async()=>{try{let r=await e.getSessions(t);n||(g(r),E(!1))}catch(e){n||(O(e.message),E(!1))}})(),()=>{n=!0}},[e,t]),T)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(o,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching sessions…`))));if(D)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(d,{reason:`error`,headline:`Failed to load`,hint:D}));if(!l||l.length===0)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(d,{reason:`no-data`,headline:`No replays yet`,hint:`Enable session replay in your site settings`}));let k=[{key:`id`,label:`session id`,width:24},{key:`visitor`,label:`visitor`,width:18},{key:`duration`,label:`duration`,align:`right`,width:9,format:e=>C(e)},{key:`startedAt`,label:`when`,align:`right`,width:6,format:e=>w(String(e))},{key:`pageCount`,label:`events`,align:`right`,width:7},{key:`deviceType`,label:`device`,width:8,format:e=>String(e??`—`)}];return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`sessions · ${n}`}),y.createElement(o,{title:`Recent sessions (${l.length})`},y.createElement(u,{columns:k,data:l,zebra:!0})),y.createElement(m,{marginTop:1},y.createElement(h,{color:`gray`},`Open any session for replay at https://app.zenovay.com/replay`)),y.createElement(c,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{T as sessionsCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{resolveSiteId as a}from"./resolve-site-CoOL4KPZ.js";import{DataTable as o}from"./data-table-D-JVXhZ7.js";import{deepLinkFor as s,openInBrowser as c}from"./keybar-deep-link-AZ29NpWE.js";import{runAnalyticalScreen as l}from"./analytical-screen-gN9MJR34.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){let n=Math.round(e/100*t);return`█`.repeat(n)+`░`.repeat(Math.max(0,t-n))}function m(e){return e==null?{glyph:`·`,color:`gray`}:e>.5?{glyph:`▲`,color:`green`}:e<-.5?{glyph:`▼`,color:`red`}:{glyph:`→`,color:`gray`}}async function h(h){let g=await e(),_=await t({strict:!1}),v=new n({config:g,cliVersion:h.cliVersion,token:_}),y,b;try{({siteId:y,site:b}=await a(v,{explicit:h.siteId,headless:!!(h.json||h.csv||h.tsv||h.ndjson),cliVersion:h.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let x=i(h),S=h.period??`30d`,C=[{key:`source`,label:`source`,width:22},{key:`channel`,label:`channel`,width:10,format:e=>String(e??`—`)},{key:`visitors`,label:`visitors`,width:8,align:`right`},{key:`delta`,label:`Δ`,width:6,align:`right`,format:e=>typeof e==`number`?`${e>0?`+`:``}${(e*100).toFixed(1)}%`:`—`}];return l({cliVersion:h.cliVersion,title:`sources · ${y} · ${S}`,commandName:`sources`,authToken:_?.accessToken??null,refreshIntervalMs:6e4,fetcher:e=>v.getSources(y,S,h.compare,e),format:x,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`sources`,{siteId:y}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);return}process.stdout.write(r(e.sources,[`source`,`channel`,`visitors`,`conversions`,`revenue`,`delta`],t))},panels:[{id:`summary`,title:`Total`,render:e=>f.createElement(d,null,f.createElement(d,{bold:!0},e.totalVisitors.toLocaleString()),` `,f.createElement(d,{color:`gray`},`visitors · `,e.sources.length,` sources`))},{id:`channels`,title:`By channel`,render:e=>{if(e.sources.length===0)return f.createElement(d,{color:`gray`},`— no source data —`);let t=e.totalVisitors||1,n=[...e.sources].sort((e,t)=>t.visitors-e.visitors).slice(0,12);return f.createElement(u,{flexDirection:`column`},n.map((e,n)=>{let r=e.visitors/t*100,i=m(e.delta);return f.createElement(u,{key:`${e.source}-${n}`},f.createElement(d,null,f.createElement(d,{color:`cyan`},e.source.padEnd(20).slice(0,20)),` `,f.createElement(d,{color:`magenta`},p(r,30)),` `,f.createElement(d,null,e.visitors.toString().padStart(6),` `),f.createElement(d,{color:`gray`},`(`,r.toFixed(1),`%)`),` `,f.createElement(d,{color:i.color},i.glyph)))}))}},{id:`table`,title:`Detail`,render:e=>e.sources.length===0?f.createElement(d,{color:`gray`},`— —`):f.createElement(o,{data:e.sources.slice(0,20),columns:C,headerStyle:`accent`})}]})}export{h as sourcesCommand};
@@ -1,2 +1,2 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{resolveSiteId as a}from"./resolve-site-CoOL4KPZ.js";import{DataTable as o}from"./data-table-D-JVXhZ7.js";import{runAnalyticalScreen as s}from"./analytical-screen-CxdwI377.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){return`${(e*100).toFixed(1)}%`}function f(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.floor(e/60)}m ${Math.round(e%60)}s`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(p),b=p.range??`24h`,x=[{key:`url`,label:`page`,width:40,format:e=>String(e??`—`)},{key:`views`,label:`views`,width:8,align:`right`}],S=[{key:`country`,label:`country`,width:8},{key:`visitors`,label:`visitors`,width:8,align:`right`}];return s({cliVersion:p.cliVersion,title:`stats · ${_} · ${b}`,commandName:`stats`,authToken:h?.accessToken??null,refreshIntervalMs:p.watch?6e4:0,fetcher:e=>g.getStats(_,b,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{resolveSiteId as a}from"./resolve-site-CoOL4KPZ.js";import{DataTable as o}from"./data-table-D-JVXhZ7.js";import{runAnalyticalScreen as s}from"./analytical-screen-gN9MJR34.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){return`${(e*100).toFixed(1)}%`}function f(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.floor(e/60)}m ${Math.round(e%60)}s`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(p),b=p.range??`24h`,x=[{key:`url`,label:`page`,width:40,format:e=>String(e??`—`)},{key:`views`,label:`views`,width:8,align:`right`}],S=[{key:`country`,label:`country`,width:8},{key:`visitors`,label:`visitors`,width:8,align:`right`}];return s({cliVersion:p.cliVersion,title:`stats · ${_} · ${b}`,commandName:`stats`,authToken:h?.accessToken??null,refreshIntervalMs:p.watch?6e4:0,fetcher:e=>g.getStats(_,b,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
2
  `);return}process.stdout.write(r([{range:b,visitors:e.visitors,pageviews:e.pageviews,sessions:e.sessions,bounceRate:d(e.bounceRate),avgSession:f(e.avgSessionSec)}],[`range`,`visitors`,`pageviews`,`sessions`,`bounceRate`,`avgSession`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.visitors.toLocaleString()),u.createElement(l,{color:`gray`},` visitors `),u.createElement(l,{bold:!0},e.pageviews.toLocaleString()),u.createElement(l,{color:`gray`},` pageviews `),u.createElement(l,{bold:!0},e.sessions.toLocaleString()),u.createElement(l,{color:`gray`},` sessions`)),u.createElement(l,{color:`gray`},`bounce `,d(e.bounceRate),` · avg session `,f(e.avgSessionSec)))},{id:`pages`,title:`Top pages`,render:e=>e.topPages.length===0?u.createElement(l,{color:`gray`},`— no pages —`):u.createElement(o,{data:e.topPages.slice(0,10),columns:x,headerStyle:`accent`})},{id:`countries`,title:`Top countries`,render:e=>e.topCountries.length===0?u.createElement(l,{color:`gray`},`— no country data —`):u.createElement(o,{data:e.topCountries.slice(0,10),columns:S,headerStyle:`accent`})}]})}export{p as statsCommand};
@@ -1,4 +1,4 @@
1
- import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./panel-CYsRlDSL.js";import{Banner as a}from"./banner-Cr0PV2pB.js";import"./progress-row-5G_PO8xL.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import"./sparkline-DM2BGvjD.js";import"./data-table-D-JVXhZ7.js";import"./bar-Cjia2R58.js";import"./ui-CTH6j-SR.js";import{promises as o}from"node:fs";import{Box as s,Text as c,render as l}from"ink";import u from"react";const d=[{name:`mocha`,theme:n,mode:`dark`},{name:`latte`,theme:t,mode:`light`},{name:`dracula`,theme:e,mode:`dark`},{name:`tokyoNight`,theme:i,mode:`dark`},{name:`nord`,theme:r,mode:`dark`}],f=[`name`,`bg`,`fg`,`muted`,`accent`,`accent2`,`success`,`warn`,`error`,`border`,`dim`];function p({name:e,theme:t,mode:n}){let r=[t.accent,t.accent2,t.success,t.warn,t.error];return u.createElement(s,{flexDirection:`row`},u.createElement(c,{bold:!0},e.padEnd(14)),u.createElement(c,{color:`gray`},n.padEnd(7)),r.map((e,t)=>u.createElement(c,{key:t,color:e},`████`,` `)),u.createElement(c,{color:`gray`},t.bg))}function m({themes:e}){return u.createElement(s,{flexDirection:`column`},u.createElement(a,{version:`themes`}),u.createElement(s,{marginTop:1,marginBottom:1},u.createElement(c,{color:`gray`},e.length,` themes — pass --theme <name> to any command, or set in your config.`)),u.createElement(s,{flexDirection:`column`},u.createElement(s,null,u.createElement(c,{bold:!0},`name`.padEnd(14)),u.createElement(c,{bold:!0},`mode`.padEnd(7)),u.createElement(c,{bold:!0},`swatch`.padEnd(28)),u.createElement(c,{bold:!0},`bg`)),e.map(({name:e,theme:t,mode:n})=>u.createElement(p,{key:e,name:e,theme:t,mode:n}))))}async function h(e){if(e.validate){let t;try{let n=await o.readFile(e.validate,`utf8`);t=JSON.parse(n)}catch(t){return process.stderr.write(`✗ Failed to read ${e.validate}: ${t.message}\n`),1}let n=f.filter(e=>t[e]==null);return n.length>0?(process.stderr.write(`✗ Missing required tokens: ${n.join(`, `)}\n`),e.json&&process.stdout.write(JSON.stringify({ok:!1,missing:n},null,2)+`
1
+ import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./panel-CYsRlDSL.js";import{Banner as a}from"./banner-Cr0PV2pB.js";import"./progress-row-5G_PO8xL.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import"./sparkline-DM2BGvjD.js";import"./data-table-D-JVXhZ7.js";import"./bar-Cjia2R58.js";import"./ui-CLpqz5_6.js";import{promises as o}from"node:fs";import{Box as s,Text as c,render as l}from"ink";import u from"react";const d=[{name:`mocha`,theme:n,mode:`dark`},{name:`latte`,theme:t,mode:`light`},{name:`dracula`,theme:e,mode:`dark`},{name:`tokyoNight`,theme:i,mode:`dark`},{name:`nord`,theme:r,mode:`dark`}],f=[`name`,`bg`,`fg`,`muted`,`accent`,`accent2`,`success`,`warn`,`error`,`border`,`dim`];function p({name:e,theme:t,mode:n}){let r=[t.accent,t.accent2,t.success,t.warn,t.error];return u.createElement(s,{flexDirection:`row`},u.createElement(c,{bold:!0},e.padEnd(14)),u.createElement(c,{color:`gray`},n.padEnd(7)),r.map((e,t)=>u.createElement(c,{key:t,color:e},`████`,` `)),u.createElement(c,{color:`gray`},t.bg))}function m({themes:e}){return u.createElement(s,{flexDirection:`column`},u.createElement(a,{version:`themes`}),u.createElement(s,{marginTop:1,marginBottom:1},u.createElement(c,{color:`gray`},e.length,` themes — pass --theme <name> to any command, or set in your config.`)),u.createElement(s,{flexDirection:`column`},u.createElement(s,null,u.createElement(c,{bold:!0},`name`.padEnd(14)),u.createElement(c,{bold:!0},`mode`.padEnd(7)),u.createElement(c,{bold:!0},`swatch`.padEnd(28)),u.createElement(c,{bold:!0},`bg`)),e.map(({name:e,theme:t,mode:n})=>u.createElement(p,{key:e,name:e,theme:t,mode:n}))))}async function h(e){if(e.validate){let t;try{let n=await o.readFile(e.validate,`utf8`);t=JSON.parse(n)}catch(t){return process.stderr.write(`✗ Failed to read ${e.validate}: ${t.message}\n`),1}let n=f.filter(e=>t[e]==null);return n.length>0?(process.stderr.write(`✗ Missing required tokens: ${n.join(`, `)}\n`),e.json&&process.stdout.write(JSON.stringify({ok:!1,missing:n},null,2)+`
2
2
  `),1):(process.stdout.write(`✔ Valid theme (${f.length} tokens present).\n`),e.json&&process.stdout.write(JSON.stringify({ok:!0,theme:t},null,2)+`
3
3
  `),0)}if(e.json)return process.stdout.write(JSON.stringify({themes:d.map(({name:e,theme:t,mode:n})=>({name:e,mode:n,background:t.bg,foreground:t.fg,accent:t.accent}))},null,2)+`
4
4
  `),0;let{waitUntilExit:t}=l(u.createElement(m,{themes:d}));return await t(),0}export{h as themesCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{requireTier as r}from"./tier-ztFrvV9H.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import{resolveSiteId as l}from"./resolve-site-CoOL4KPZ.js";import{DataTable as u}from"./data-table-D-JVXhZ7.js";import{EmptyState as d}from"./empty-state-BbUJUNcp.js";import{deepLinkFor as f,openInBrowser as p}from"./keybar-deep-link-AZ29NpWE.js";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";function C(e){return e===`up`?{glyph:`● up`,color:`green`}:e===`down`?{glyph:`● down`,color:`red`}:{glyph:`○ unknown`,color:`gray`}}function w(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.round((t-Date.now())/(1e3*60*60*24));return`${n}d`}async function T(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getUptime(d);return i({type:`uptime.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const E=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=_(),[l,g]=x(null),[T,E]=x(!0),[D,O]=x(null);if(v(e=>{if(e===`o`||e===`O`){p(f(`uptime`,{siteId:t}));return}e===`q`&&(a(),i(0))}),b(()=>{let n=!1;return(async()=>{try{let r=await e.getUptime(t);n||(g(r.monitors),E(!1))}catch(e){n||(O(e.message),E(!1))}})(),()=>{n=!0}},[e,t]),T)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(o,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching monitors…`))));if(D)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(d,{reason:`error`,headline:`Failed to load`,hint:D}));if(!l||l.length===0)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(d,{reason:`no-data`,headline:`No monitors configured`,hint:`Add one at app.zenovay.com/uptime`}));let k=[{key:`url`,label:`monitor`,width:36},{key:`status`,label:`status`,width:12,format:e=>C(String(e)).glyph},{key:`p95ms`,label:`p95 ms`,align:`right`,width:8,format:e=>typeof e==`number`?String(e):`—`},{key:`sslExpiry`,label:`ssl exp`,align:`right`,width:7,format:e=>w(e)}];return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:r,subtitle:`uptime · ${n}`}),y.createElement(o,{title:`Monitors (${l.length})`},y.createElement(u,{columns:k,data:l,zebra:!0})),y.createElement(c,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{T as uptimeCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{brailleSpark as a,spark as o}from"./sparkline-DM2BGvjD.js";import{resolveSiteId as s}from"./resolve-site-CoOL4KPZ.js";import{DataTable as c}from"./data-table-D-JVXhZ7.js";import{deepLinkFor as l,openInBrowser as u}from"./keybar-deep-link-AZ29NpWE.js";import{runAnalyticalScreen as d}from"./analytical-screen-gN9MJR34.js";import{Box as f,Text as p}from"ink";import m from"react";function h(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function g(e){let t=e,n=t.events??t.timeseries;return Array.isArray(n)&&n.length>0?o(n,8):`▁▁▁▁▁▁▁▁`}function _(e){let t=e;if(typeof t.sessionDurationSec==`number`)return t.sessionDurationSec;if(typeof t.sessionDurationMs==`number`)return Math.floor(t.sessionDurationMs/1e3);if(typeof t.durationMs==`number`)return Math.floor(t.durationMs/1e3);if(typeof t.duration==`number`)return Math.floor(t.duration/1e3);let n=Date.parse(e.startedAt);return Number.isNaN(n)?0:Math.max(0,Math.floor((Date.now()-n)/1e3))}async function v(o){let v=await e(),y=await t({strict:!1}),b=new n({config:v,cliVersion:o.cliVersion,token:y}),x,S;try{({siteId:x,site:S}=await s(b,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let C=i(o),w=o.limit??50,T=typeof o.minDuration==`number`&&o.minDuration>0?o.minDuration:0,E=e=>T<=0?e:e.filter(e=>_(e)>=T),D=6e4,O=e=>{let t=Date.parse(e.startedAt);return Number.isFinite(t)&&Date.now()-t<D},k=[{key:`startedAt`,label:``,width:5,format:(e,t)=>O(t)?`● new`:``},{key:`startedAt`,label:`when`,width:6,format:e=>h(String(e))},{key:`country`,label:`country`,width:7,format:e=>String(e??`—`)},{key:`city`,label:`city`,width:14,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`page`,label:`page`,width:26,format:e=>String(e??`—`)},{key:`id`,label:`24h`,width:8,format:(e,t)=>g(t)}];return d({cliVersion:o.cliVersion,title:`visitors · ${x}`,commandName:`visitors`,authToken:y?.accessToken??null,refreshIntervalMs:1e4,fetcher:e=>b.getVisitors(x,{limit:w},e),format:C,keybindings:{o:{label:`open in browser`,handler:()=>{u(l(`visitors`,{siteId:x}))}}},headlessEmit:(e,t)=>{let n={...e,visitors:E(e.visitors)};if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(n,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);return}let i=[`startedAt`,`country`,`city`,`device`,`page`];process.stdout.write(r(n.visitors,i,t))},panels:[{id:`live`,title:`Now`,render:e=>{let t=E(e.visitors),n=[...t].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)),r=n[0],i=Array(24*6).fill(0),o=Date.now();for(let e of t){let t=o-new Date(e.startedAt).getTime(),n=Math.floor(t/(10*60*1e3));n>=0&&n<i.length&&(i[i.length-1-n]+=1)}return m.createElement(f,{flexDirection:`column`},m.createElement(p,{bold:!0},t.length,` live`),m.createElement(p,{color:`gray`},a(i,40)),r?m.createElement(p,{color:`gray`},`top: `,r.city??r.country??`—`,` · `,r.page??`—`):null)}},{id:`visitors`,title:`Active sessions`,render:e=>{let t=E(e.visitors),n=[...t].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)).slice(0,w);return n.length===0?m.createElement(p,{color:`gray`},`— no visitors yet —`):m.createElement(c,{columns:k,data:n,headerStyle:`accent`})}}]})}export{v as visitorsCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{resolveSiteId as a}from"./resolve-site-CoOL4KPZ.js";import{DataTable as o}from"./data-table-D-JVXhZ7.js";import{deepLinkFor as s,openInBrowser as c}from"./keybar-deep-link-AZ29NpWE.js";import{runAnalyticalScreen as l}from"./analytical-screen-gN9MJR34.js";import{Box as u,Text as d}from"ink";import f from"react";const p={lcp:{good:2500,poor:4e3},inp:{good:200,poor:500},cls:{good:.1,poor:.25},ttfb:{good:800,poor:1800},fcp:{good:1800,poor:3e3}};function m(e,t){let n=p[e];return t<=n.good?{label:`good`,color:`green`}:t<=n.poor?{label:`needs`,color:`yellow`}:{label:`poor`,color:`red`}}function h(e,t){return e===`cls`?t.toFixed(3):t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`}async function g(p){let g=await e(),_=await t({strict:!1}),v=new n({config:g,cliVersion:p.cliVersion,token:_}),y,b;try{({siteId:y,site:b}=await a(v,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let x=i(p),S=[{key:`url`,label:`url`,width:32},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,label:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`lcp`,e.p75):`—`},{key:`inp`,label:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`inp`,e.p75):`—`},{key:`cls`,label:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`cls`,e.p75):`—`},{key:`samples`,label:`n`,width:6,align:`right`}];return l({cliVersion:p.cliVersion,title:`vitals · ${y}`,commandName:`vitals`,authToken:_?.accessToken??null,refreshIntervalMs:p.watch?5*6e4:0,fetcher:e=>v.getVitals(y,{url:p.url,device:p.device,window:p.window},e),format:x,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`vitals`,{siteId:y}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);return}process.stdout.write(r(e.vitals,[`url`,`device`,`samples`],t))},panels:[{id:`summary`,title:`Site-wide p75`,render:e=>{let t=t=>{let n=0,r=0;for(let i of e.vitals){let e=i[t]?.p75;typeof e==`number`&&(n+=e*i.samples,r+=i.samples)}return r>0?n/r:0},n=[`lcp`,`inp`,`cls`,`ttfb`,`fcp`];return f.createElement(u,{flexDirection:`column`},n.map(e=>{let n=t(e),r=m(e,n);return f.createElement(d,{key:e},f.createElement(d,{color:r.color},`● `),f.createElement(d,{bold:!0},e.toUpperCase().padEnd(5)),` `,f.createElement(d,null,h(e,n).padStart(8)),` `,f.createElement(d,{color:r.color},r.label))}))}},{id:`pages`,title:`Per-page`,render:e=>e.vitals.length===0?f.createElement(d,{color:`gray`},`— no vitals data yet —`):f.createElement(o,{data:e.vitals.slice(0,15),columns:S,headerStyle:`accent`})}]})}export{g as vitalsCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{parseSseStream as r}from"./client-Ckr8RqMm.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import{spark as l}from"./sparkline-DM2BGvjD.js";import{resolveSiteId as u}from"./resolve-site-CoOL4KPZ.js";import{EmptyState as d}from"./empty-state-BbUJUNcp.js";import{deepLinkFor as f,openInBrowser as p}from"./keybar-deep-link-AZ29NpWE.js";import{Globe as m}from"./globe-Cc-yuiNd.js";import{z as h}from"zod";import{Box as g,Text as _,render as v,useApp as y,useInput as b}from"ink";import x,{useEffect as S,useState as C}from"react";import w from"ink-spinner";import T from"ink-text-input";const E=h.object({siteId:h.string().optional(),window:h.string().optional(),totalVisitors:h.number().optional(),visitors:h.object({count:h.number().optional(),series:h.array(h.number()).optional()}).optional(),topPages:h.array(h.object({path:h.string(),views:h.number().optional(),count:h.number().optional()})).optional(),sources:h.array(h.object({source:h.string(),visitors:h.number()})).optional()}).passthrough();async function D(r){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:r.cliVersion,token:s}),l;try{({siteId:l}=await u(c,{explicit:r.siteId,headless:!!r.json,cliVersion:r.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(a(r)){let e=await c.getDashboardSnapshot(l);return i({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=v(x.createElement(O,{api:c,siteId:l,intervalMs:r.intervalMs??15e3,cliVersion:r.cliVersion,onExit:n=>{t(),e(n)}}))})}const O=({api:e,siteId:t,intervalMs:n,cliVersion:i,onExit:a})=>{let{exit:l}=y(),[u,h]=C(null),[v,T]=C(null),[D,O]=C(null),[I,L]=C([]),[R,z]=C(!0),[B,V]=C(null),[H,U]=C(1),[W,G]=C(!1),[K,q]=C(!1);b((e,n)=>{if(e===`o`||e===`O`){p(f(`watch`,{siteId:t}));return}if(e===`q`){l(),a(0);return}if(e===`?`||e===`/`){q(e=>!e);return}if(e===`g`){G(e=>!e);return}if(n.tab){U(e=>{let t=n.shift?(e+4)%6+1:e%6+1;return t});return}(e===`1`||e===`2`||e===`3`||e===`4`||e===`5`||e===`6`)&&U(Number(e))});let[J,Y]=C(!1);if(S(()=>{let r=!1,i=async()=>{try{let n=await e.getDashboardSnapshot(t);if(r)return;let i=E.safeParse(n);if(!i.success){Y(!0),z(!1);return}Y(!1);let a=i.data,o={visitors:a.visitors??(typeof a.totalVisitors==`number`?{count:a.totalVisitors}:void 0),topPages:a.topPages?.map(e=>({path:e.path,views:e.views??e.count??0})),sources:a.sources};h(o),e.getVitals(t).then(e=>{r||T(e)},()=>{}),e.getGoals(t).then(e=>{r||O(e)},()=>{}),z(!1),V(null)}catch(e){r||V(e.message)}};i();let a=setInterval(i,n);return()=>{r=!0,clearInterval(a)}},[e,t,n]),S(()=>{let n=new AbortController;return(async()=>{try{let i=await e.openEventsStream(t,n.signal);for await(let e of r(i))e.type===`error`&&L(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>n.abort()},[e,t]),R)return x.createElement(g,{flexDirection:`column`},x.createElement(s,{version:i,subtitle:`watch · ${t}`}),x.createElement(o,{title:`Loading`,state:`busy`},x.createElement(g,null,x.createElement(_,{color:`magenta`},x.createElement(w,{type:`dots`})),x.createElement(_,null,` Fetching snapshot…`))));if(B&&!u)return x.createElement(g,{flexDirection:`column`},x.createElement(s,{version:i,subtitle:`watch · ${t}`}),x.createElement(o,{title:`Error`,state:`err`},x.createElement(_,{color:`red`},B)));if(J&&!u)return x.createElement(g,{flexDirection:`column`},x.createElement(s,{version:i,subtitle:`watch · ${t}`}),x.createElement(d,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let X=process.stdout.columns??80,Z=Math.max(20,Math.floor(X/3)-1),Q=[];return x.createElement(g,{flexDirection:`column`},x.createElement(s,{version:i,subtitle:`watch · ${t}${W?` · globe`:``}`}),x.createElement(g,{flexDirection:`row`},x.createElement(g,{flexDirection:`column`},W?x.createElement(o,{title:`Live globe`,focused:H===1,width:Z},x.createElement(m,{data:Q,width:Math.max(40,Z-4),height:12})):x.createElement(A,{snapshot:u,focused:H===1,width:Z}),x.createElement(N,{events:I,focused:H===4,width:Z})),x.createElement(g,{flexDirection:`column`},x.createElement(j,{snapshot:u,focused:H===2,width:Z}),x.createElement(P,{vitals:v,focused:H===5,width:Z})),x.createElement(g,{flexDirection:`column`},x.createElement(M,{snapshot:u,focused:H===3,width:Z}),x.createElement(F,{goals:D,focused:H===6,width:Z}))),K?x.createElement(k,{api:e,siteId:t,width:X-2}):null,x.createElement(c,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:W?`panels`:`globe`},{key:`?/`,label:K?`close chat`:`ai chat`},{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))},k=({api:e,siteId:t,width:n})=>{let[i,a]=C(``),[s,c]=C([]),[l,u]=C(!1),[d,f]=C(``),[p,m]=C(null),h=async n=>{let i=n.trim();if(!i||l)return;m(null),a(``);let o=[...s,{role:`user`,content:i}];c(o),u(!0),f(``);try{let n=o.map(e=>({role:e.role,content:e.content})),i=await e.openAiStream(`chat`,{messages:n,siteId:t},void 0),a=``;for await(let e of r(i))if(e.type===`delta`)a+=e.content,f(a);else if(e.type===`error`)m(`${e.code}: ${e.message}`);else if(e.type===`done`)break;c([...o,{role:`assistant`,content:a}]),f(``)}catch(e){m(e instanceof Error?e.message:`chat failed`)}finally{u(!1)}};return x.createElement(g,{marginTop:1},x.createElement(o,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:n},x.createElement(g,{flexDirection:`column`},s.slice(-6).map((e,t)=>x.createElement(g,{key:t,flexDirection:`column`,marginBottom:1},x.createElement(_,{color:e.role===`user`?`cyan`:`magenta`,bold:!0},e.role===`user`?`you`:`zenovay`),x.createElement(_,null,e.content))),l&&d?x.createElement(g,{flexDirection:`column`,marginBottom:1},x.createElement(_,{color:`magenta`,bold:!0},`zenovay`),x.createElement(_,null,d)):null,p?x.createElement(_,{color:`red`},`✗ `,p):null,x.createElement(g,null,x.createElement(_,{color:`cyan`},l?`⠋ `:`▸ `),x.createElement(T,{value:i,onChange:a,onSubmit:h,placeholder:l?`streaming…`:`ask anything about your analytics`})))))},A=({snapshot:e,focused:t,width:n})=>{let r=e?.visitors?.count??0,i=e?.visitors?.series??[];return x.createElement(o,{title:`Visitors`,focused:t,width:n},x.createElement(_,{bold:!0},r.toString()),x.createElement(_,{color:`gray`},i.length>0?l(i,Math.max(8,n-6)):`— no data —`))},j=({snapshot:e,focused:t,width:n})=>{let r=e?.topPages?.slice(0,5)??[];return x.createElement(o,{title:`Top pages`,focused:t,width:n},r.length===0?x.createElement(_,{color:`gray`},`— no data —`):r.map(e=>x.createElement(g,{key:e.path},x.createElement(_,null,e.path.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:`gray`},` `,e.views))))},M=({snapshot:e,focused:t,width:n})=>{let r=e?.sources?.slice(0,5)??[];return x.createElement(o,{title:`Sources`,focused:t,width:n},r.length===0?x.createElement(_,{color:`gray`},`— no data —`):r.map(e=>x.createElement(g,{key:e.source},x.createElement(_,null,e.source.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:`gray`},` `,e.visitors))))},N=({events:e,focused:t,width:n})=>x.createElement(o,{title:`Events`,focused:t,width:n},e.length===0?x.createElement(_,{color:`gray`},`— waiting —`):e.slice(-10).map((e,t)=>x.createElement(_,{key:t},e.slice(0,n-4)))),P=({vitals:e,focused:t,width:n})=>{let r=(e,t,n)=>x.createElement(g,{key:e},x.createElement(_,{bold:!0},e.padEnd(6)),x.createElement(_,{color:`gray`},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return x.createElement(o,{title:`Vitals`,focused:t,width:n},r(`LCP`,e?.lcpP75,`ms`),r(`INP`,e?.inpP75,`ms`),r(`CLS`,e?.clsP75?e.clsP75*1e3:void 0,`/1k`),r(`TTFB`,e?.ttfbP75,`ms`),r(`FCP`,e?.fcpP75,`ms`))},F=({goals:e,focused:t,width:n})=>{let r=e?.goals?.slice(0,5)??[];return x.createElement(o,{title:`Goals`,focused:t,width:n},r.length===0?x.createElement(_,{color:`gray`},`— no data —`):r.map(e=>x.createElement(g,{key:e.name},x.createElement(_,null,e.name.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:`gray`},` `,e.completions))))};export{D as watchCommand};
@@ -1,3 +1,3 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{Panel as r}from"./panel-CYsRlDSL.js";import{Banner as i}from"./banner-Cr0PV2pB.js";import"./progress-row-5G_PO8xL.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import"./sparkline-DM2BGvjD.js";import"./data-table-D-JVXhZ7.js";import"./bar-Cjia2R58.js";import"./ui-CTH6j-SR.js";import{Box as a,Text as o,render as s,useApp as c,useInput as l}from"ink";import u,{useEffect as d,useState as f}from"react";async function p(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]),i=await crypto.subtle.sign(`HMAC`,r,n.encode(t));return Array.from(new Uint8Array(i),e=>e.toString(16).padStart(2,`0`)).join(``)}function m({stats:e}){return u.createElement(r,{title:`webhooks forward`,state:e.connected?`ok`:`busy`},u.createElement(a,{flexDirection:`column`},u.createElement(o,null,u.createElement(o,{color:`gray`},`public URL `),u.createElement(o,{color:`cyan`},e.publicUrl)),u.createElement(o,null,u.createElement(o,{color:`gray`},`→ forwarding to `),u.createElement(o,{color:`magenta`},e.wsUrl)),u.createElement(o,null,e.connected?u.createElement(o,{color:`green`},`● connected`):u.createElement(o,{color:`yellow`},`○ connecting…`),u.createElement(o,{color:`gray`},` · `,e.total,` requests · `,e.ok,` ok · `),u.createElement(o,{color:e.err>0?`red`:`gray`},e.err,` err`),e.lastStatus===null?null:u.createElement(o,{color:`gray`},` · last: HTTP `,e.lastStatus)),e.lastError?u.createElement(o,{color:`red`},`last error: `,e.lastError.slice(0,80)):null))}async function h(r){let h=await e(),g=await t({strict:!1});if(!g?.accessToken)return process.stderr.write("Not authenticated. Run `zenovay login` first.\n"),2;let _=r.siteId??g.teamId??``;if(!_)return process.stderr.write(`No site selected — pass --site-id or set ZENOVAY_SITE.
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{Panel as r}from"./panel-CYsRlDSL.js";import{Banner as i}from"./banner-Cr0PV2pB.js";import"./progress-row-5G_PO8xL.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import"./sparkline-DM2BGvjD.js";import"./data-table-D-JVXhZ7.js";import"./bar-Cjia2R58.js";import"./ui-CLpqz5_6.js";import{Box as a,Text as o,render as s,useApp as c,useInput as l}from"ink";import u,{useEffect as d,useState as f}from"react";async function p(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]),i=await crypto.subtle.sign(`HMAC`,r,n.encode(t));return Array.from(new Uint8Array(i),e=>e.toString(16).padStart(2,`0`)).join(``)}function m({stats:e}){return u.createElement(r,{title:`webhooks forward`,state:e.connected?`ok`:`busy`},u.createElement(a,{flexDirection:`column`},u.createElement(o,null,u.createElement(o,{color:`gray`},`public URL `),u.createElement(o,{color:`cyan`},e.publicUrl)),u.createElement(o,null,u.createElement(o,{color:`gray`},`→ forwarding to `),u.createElement(o,{color:`magenta`},e.wsUrl)),u.createElement(o,null,e.connected?u.createElement(o,{color:`green`},`● connected`):u.createElement(o,{color:`yellow`},`○ connecting…`),u.createElement(o,{color:`gray`},` · `,e.total,` requests · `,e.ok,` ok · `),u.createElement(o,{color:e.err>0?`red`:`gray`},e.err,` err`),e.lastStatus===null?null:u.createElement(o,{color:`gray`},` · last: HTTP `,e.lastStatus)),e.lastError?u.createElement(o,{color:`red`},`last error: `,e.lastError.slice(0,80)):null))}async function h(r){let h=await e(),g=await t({strict:!1});if(!g?.accessToken)return process.stderr.write("Not authenticated. Run `zenovay login` first.\n"),2;let _=r.siteId??g.teamId??``;if(!_)return process.stderr.write(`No site selected — pass --site-id or set ZENOVAY_SITE.
2
2
  `),2;if(!r.to)return process.stderr.write(`Missing --to <url> (e.g. --to localhost:3000/webhook).
3
3
  `),2;let v=r.to.match(/^https?:\/\//)?r.to:`http://${r.to}`,y=new n({config:h,cliVersion:r.cliVersion,token:g}),b;try{b=await y.createTunnel(_,r.to)}catch(e){return process.stderr.write(`Failed to register tunnel: ${e.message}\n`),1}let x=r.sign?r.secret??b.tunnelKey:null,S=()=>{let{exit:e}=c(),[t,n]=f({total:0,ok:0,err:0,lastStatus:null,lastError:null,publicUrl:b.publicUrl,wsUrl:b.wsUrl,connected:!1});return l((t,n)=>{(t===`q`||n.escape)&&e()}),d(()=>{let e=new AbortController,t=async e=>{try{let t={...e.headers};delete t.host,delete t[`content-length`],x&&(t[`X-Zenovay-Signature`]=`sha256=${await p(x,e.body)}`);let r=await fetch(v,{method:e.method,headers:t,body:e.method===`GET`||e.method===`HEAD`?void 0:e.body}),i=await r.text(),a={};return r.headers.forEach((e,t)=>{a[t]=e}),n(e=>({...e,total:e.total+1,ok:e.ok+(r.ok?1:0),err:e.err+(r.ok?0:1),lastStatus:r.status,lastError:r.ok?null:`HTTP ${r.status}`})),{status:r.status,headers:a,body:i}}catch(e){let t=e instanceof Error?e.message:String(e);return n(e=>({...e,total:e.total+1,err:e.err+1,lastError:t})),{status:502,body:JSON.stringify({error:`cli_local_failed`,detail:t})}}};return(async()=>{let r=y.tunnelClient(b.wsUrl);n(e=>({...e,connected:!0}));try{await r.start(t,e.signal)}catch(e){n(t=>({...t,connected:!1,lastError:e.message}))}})(),()=>{e.abort()}},[]),u.createElement(a,{flexDirection:`column`},u.createElement(i,{version:`webhooks forward`}),u.createElement(m,{stats:t}),u.createElement(o,{color:`gray`},`target: `,v,` `,r.sign?`· HMAC-signed`:``),u.createElement(o,{color:`gray`},`[q | Esc] quit`))},{waitUntilExit:C}=s(u.createElement(S,null));return await C(),0}export{h as webhooksForwardCommand};
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import(`./init-B2-pLG0u.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-DYSe6Vcn.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.45",
3
+ "version": "0.1.46",
4
4
  "description": "Zenovay CLI — AI install wizard + full terminal analytics dashboard",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import{ApiError as t}from"./api-CJnD6Auw.js";import{readToken as n}from"./token-store-C1AqhmDP.js";import{ApiV2Client as r}from"./api-v2-Byx59f4j.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import"./sparkline-DM2BGvjD.js";import{resolveSiteId as l}from"./resolve-site-CoOL4KPZ.js";import{stripUrlPrefix as u}from"./fmt-BQF1s-Qd.js";import{DataTable as d}from"./data-table-D-JVXhZ7.js";import{EmptyState as f}from"./empty-state-BbUJUNcp.js";import{MetricCard as p}from"./metric-card-qze7DsPv.js";import{Bar as m}from"./bar-Cjia2R58.js";import{Box as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useState as S}from"react";import C from"ink-spinner";function w(e){if(!(e instanceof t))return!1;let n=e.status;if(n===401||n===403||n===404)return!0;let r=e.body,i=r?.code;return i===`forbidden`||i===`not_found`||i===`auth_required`||i===`auth_invalid`||i===`tier_insufficient`}function T(e,t){return e.catch(e=>{if(w(e))throw e;return t})}async function E(t){let o=await e(),s=await n({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new r({config:o,cliVersion:t.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await l(c,{explicit:t.siteId,headless:!!t.json,cliVersion:t.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(a(t))try{let e=await O(c,u,`24h`);return i({type:`overview.snapshot`,data:e}),0}catch(e){let{emitErrorEnvelope:n}=await import(`./error-codes-De8Cx8OK.js`);return n(e,{command:`analytics`,cliVersion:t.cliVersion})}return new Promise(e=>{let{unmount:n}=_(b.createElement(k,{api:c,siteId:u,siteLabel:f,cliVersion:t.cliVersion,onExit:t=>{n(),e(t)}}))})}function D(e){return e===`24h`?`7d`:e}async function O(e,t,n){let[r,i,a,o,s]=await Promise.all([T(e.getStats(t,n),null),T(e.getPages(t),[]),T(e.getSources(t,D(n),`prev`),null),T(e.getGeo(t),null),T(e.getDevices(t),null)]),c=i.reduce((e,t)=>e+t.views,0),l=(r?.daily??[]).map(e=>e.visitors),u=(r?.daily??[]).map(e=>e.pageviews),d=Math.floor(l.length/2),f=l.slice(0,d).reduce((e,t)=>e+t,0),p=u.slice(0,d).reduce((e,t)=>e+t,0),m=(a?.sources??[]).filter(e=>e.channel!==`other`||!e.source.includes(`/`)).slice(0,6).map(e=>({name:e.source,visitors:e.visitors,delta:e.delta??null}));return{visitors:r?.visitors??0,pageviews:r?.pageviews??c,bounceRate:r?.bounceRate??null,avgSession:r?.avgSessionSec??null,series:l,pageviewsSeries:u,prevVisitors:f,prevPageviews:p,topPages:i.slice(0,10),channels:m,countries:(o?.countries??[]).slice(0,8),browsers:(s?.browsers??[]).slice(0,5),devices:(s?.devices??[]).slice(0,5)}}const k=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=v(),[l,_]=S(null),[w,T]=S(!0),[E,D]=S(null),[k,A]=S(`24h`),[j,M]=S(t),[N,P]=S(n),[F,I]=S(!1),[L,R]=S([]);y(async t=>{if(t===`q`){a(),i(0);return}if(t===`1`){A(`24h`);return}if(t===`2`){A(`7d`);return}if(t===`3`){A(`30d`);return}if(t===`4`){A(`90d`);return}if(t===`s`){if(L.length===0)try{let t=await e.getSites();R(t)}catch{}I(e=>!e);return}}),x(()=>{let t=!1;return T(!0),(async()=>{try{let n=await O(e,j,k);t||(_(n),T(!1))}catch(e){t||(D(e.message),T(!1))}})(),()=>{t=!0}},[e,j,k]);let z=()=>b.createElement(o,{title:`Switch site`,state:`idle`},L.length===0?b.createElement(g,{color:`gray`},`Loading your sites…`):L.map(e=>b.createElement(h,{key:e.id},b.createElement(g,{color:e.id===j?`cyan`:`gray`},e.id===j?`› `:` `),b.createElement(g,{bold:e.id===j},e.name),b.createElement(g,{color:`gray`},` (`,e.url.replace(/^https?:\/\//,``).replace(/\/$/,``),`)`))),b.createElement(h,{marginTop:1},b.createElement(g,{color:`gray`},`Press `),b.createElement(g,{color:`cyan`},`[number]`),b.createElement(g,{color:`gray`},` to pick, `),b.createElement(g,{color:`cyan`},`[s]`),b.createElement(g,{color:`gray`},` to close.`)));y(e=>{if(!F)return;let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=L.length){let e=L[t-1];M(e.id),P(e.url.replace(/^https?:\/\//,``).replace(/\/$/,``)),I(!1)}},{isActive:F});let B=`overview · ${N} · ${k}`,V=[{key:`q`,label:`quit`},{key:`s`,label:`site`},{key:`1-4`,label:`range (24h/7d/30d/90d)`}];if(w)return b.createElement(h,{flexDirection:`column`},b.createElement(s,{version:r,subtitle:B}),b.createElement(o,{title:`Loading`,state:`busy`},b.createElement(h,null,b.createElement(g,{color:`cyan`},b.createElement(C,{type:`dots`})),b.createElement(g,null,` Fetching dashboard…`))),F?z():null);if(E)return b.createElement(h,{flexDirection:`column`},b.createElement(s,{version:r,subtitle:B}),b.createElement(f,{reason:`error`,headline:`Failed to load`,hint:E}),F?z():null,b.createElement(c,{items:V}));if(!l||l.visitors===0&&l.pageviews===0&&l.topPages.length===0)return b.createElement(h,{flexDirection:`column`},b.createElement(s,{version:r,subtitle:B}),b.createElement(f,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event — or press [s] to switch to a different site, or [1-4] to widen the time range.`}),F?z():null,b.createElement(c,{items:V}));let H=process.stdout.columns??80,U=Math.max(18,Math.floor(H/4)-1),W=Math.max(28,Math.floor(H/2)-2),G=[{key:`path`,label:`path`,width:32,format:e=>u(String(e??``))},{key:`views`,label:`views`,align:`right`,width:8},{key:`uniqueVisitors`,label:`visitors`,align:`right`,width:8},{key:`avgTime`,label:`avg time`,align:`right`,width:9,format:e=>typeof e==`number`?`${Math.round(e/1e3)}s`:`—`},{key:`bounceRate`,label:`bounce`,align:`right`,width:7,format:e=>typeof e==`number`?`${(e*100).toFixed(0)}%`:`—`}],K=l.prevVisitors>0?(l.visitors-l.prevVisitors)/l.prevVisitors:void 0,q=l.prevPageviews>0?(l.pageviews-l.prevPageviews)/l.prevPageviews:void 0,J=Math.max(1,...l.channels.map(e=>e.visitors)),Y=Math.max(1,...l.countries.map(e=>e.visitors)),X=Math.max(1,...l.browsers.map(e=>e.visitors)),Z=Math.max(1,...l.devices.map(e=>e.visitors)),Q=Math.max(8,Math.floor(W/3));return b.createElement(h,{flexDirection:`column`},b.createElement(s,{version:r,subtitle:B}),b.createElement(h,{flexDirection:`row`},b.createElement(p,{title:`Visitors`,value:l.visitors,format:`number`,width:U,series:l.series,...typeof K==`number`?{delta:K}:{}}),b.createElement(p,{title:`Pageviews`,value:l.pageviews,format:`number`,width:U,series:l.pageviewsSeries,...typeof q==`number`?{delta:q}:{}}),b.createElement(p,{title:`Bounce rate`,value:l.bounceRate??``,emptyHint:`—`,format:`percent`,width:U}),b.createElement(p,{title:`Avg session`,value:l.avgSession??``,emptyHint:`—`,format:`duration`,width:U})),b.createElement(h,{flexDirection:`row`,flexWrap:`wrap`},b.createElement(h,{width:W,flexDirection:`column`},b.createElement(o,{title:`Channels`},l.channels.length===0?b.createElement(g,{color:`gray`},`No channel data yet.`):l.channels.map(e=>b.createElement(h,{key:e.name,flexDirection:`row`},b.createElement(h,{width:12},b.createElement(g,null,e.name)),b.createElement(m,{value:e.visitors,max:J,width:Q,showPercent:!1,...typeof e.delta==`number`?{delta:e.delta}:{}}),b.createElement(g,{color:`gray`},` `,e.visitors))))),b.createElement(h,{width:W,flexDirection:`column`},b.createElement(o,{title:`Top countries`},l.countries.length===0?b.createElement(g,{color:`gray`},`No geo data yet.`):l.countries.map(e=>b.createElement(h,{key:e.country,flexDirection:`row`},b.createElement(h,{width:5},b.createElement(g,null,e.country)),b.createElement(m,{value:e.visitors,max:Y,width:Q,showPercent:!1}),b.createElement(g,{color:`gray`},` `,e.visitors)))))),b.createElement(h,{flexDirection:`row`,flexWrap:`wrap`},b.createElement(h,{width:W,flexDirection:`column`},b.createElement(o,{title:`Top browsers`},l.browsers.length===0?b.createElement(g,{color:`gray`},`No browser data yet.`):l.browsers.map(e=>b.createElement(h,{key:e.name,flexDirection:`row`},b.createElement(h,{width:12},b.createElement(g,null,e.name)),b.createElement(m,{value:e.visitors,max:X,width:Q,showPercent:!1}),b.createElement(g,{color:`gray`},` `,e.visitors))))),b.createElement(h,{width:W,flexDirection:`column`},b.createElement(o,{title:`Top devices`},l.devices.length===0?b.createElement(g,{color:`gray`},`No device data yet.`):l.devices.map(e=>b.createElement(h,{key:e.name,flexDirection:`row`},b.createElement(h,{width:12},b.createElement(g,null,e.name)),b.createElement(m,{value:e.visitors,max:Z,width:Q,showPercent:!1}),b.createElement(g,{color:`gray`},` `,e.visitors)))))),b.createElement(o,{title:`Top pages (${k})`},l.topPages.length===0?b.createElement(g,{color:`gray`},`No pages with data in this window yet.`):b.createElement(d,{columns:G,data:l.topPages,zebra:!0})),F?z():null,b.createElement(c,{items:V}))};async function A(e){return E(e)}export{A as analyticsCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{resolveSiteId as a}from"./resolve-site-CoOL4KPZ.js";import{DataTable as o}from"./data-table-D-JVXhZ7.js";import{runAnalyticalScreen as s}from"./analytical-screen-CxdwI377.js";import{Box as c,Text as l}from"ink";import u from"react";function d(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 f(e){return e==null?`—`:e>=500?`Enterprise`:e>=50?`Growth`:`SMB`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(p),b=p.window??`24h`,x=p.limit??100,S=[{key:`lastSeenAt`,label:`when`,width:6,format:e=>d(String(e))},{key:`name`,label:`company`,width:24,format:e=>String(e).slice(0,24)},{key:`employeeCount`,label:`tier`,width:11,format:e=>f(typeof e==`number`?e:null)},{key:`industry`,label:`industry`,width:18,format:e=>String(e??`—`).slice(0,18)},{key:`visitCount`,label:`visits`,width:6,align:`right`},{key:`isNew`,label:``,width:5,format:e=>e?`NEW`:``}];return s({cliVersion:p.cliVersion,title:`companies · ${_} · ${b}`,commandName:`companies`,authToken:h?.accessToken??null,refreshIntervalMs:p.watch?3e4:0,fetcher:e=>g.getCompaniesSnapshot(_,{window:b,limit:x},e),format:y,headlessEmit:(e,t)=>{let n=p.newOnly?e.companies.filter(e=>e.isNew):e.companies;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of n)process.stdout.write(JSON.stringify(e)+`
2
- `);else process.stdout.write(JSON.stringify({companies:n,total:n.length},null,2));return}process.stdout.write(r(n,[`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 u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.total),u.createElement(l,{color:`gray`},` companies in `,b)),u.createElement(l,{color:`gray`},u.createElement(l,{color:`green`},`● `,t,` new`),` · `,n,` enterprise`))}},{id:`feed`,title:`Feed`,render:e=>{let t=p.newOnly?e.companies.filter(e=>e.isNew):e.companies;return t.length===0?u.createElement(l,{color:`gray`},`— no `,p.newOnly?`new `:``,`companies in window —`):u.createElement(o,{data:t.slice(0,30),columns:S,headerStyle:`accent`})}}]})}export{p as companiesCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import"./formatter-DDG2TSOz.js";import{emit as r,isHeadless as i}from"./emit-NkY7PE3R.js";import{Panel as a}from"./panel-CYsRlDSL.js";import{Banner as o}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as s}from"./keybar-Bh-y__tC.js";import{resolveSiteId as c}from"./resolve-site-CoOL4KPZ.js";import{DataTable as l}from"./data-table-D-JVXhZ7.js";import{EmptyState as u}from"./empty-state-BbUJUNcp.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(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getDevices(u);return r({type:`devices.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=m(),[p,b]=v(null),[x,S]=v(!0),[C,w]=v(null);if(h(e=>{e===`q`&&(c(),i(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getDevices(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(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(a,{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(C)return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(u,{reason:`error`,headline:`Failed to load`,hint:C}));let T=!p||p.devices.length===0&&p.browsers.length===0&&p.os.length===0;if(T)return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(u,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let E=[{key:`name`,label:`name`,width:16},{key:`visitors`,label:`visitors`,align:`right`,width:8}];return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(d,{flexDirection:`row`},g.createElement(a,{title:`Devices`},p.devices.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(l,{columns:E,data:p.devices,zebra:!0})),g.createElement(a,{title:`Browsers`},p.browsers.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(l,{columns:E,data:p.browsers,zebra:!0})),g.createElement(a,{title:`OS`},p.os.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(l,{columns:E,data:p.os,zebra:!0}))),g.createElement(s,{items:[{key:`q`,label:`quit`}]}))};export{b as devicesCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./progress-row-5G_PO8xL.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{spark as a}from"./sparkline-DM2BGvjD.js";import{resolveSiteId as o}from"./resolve-site-CoOL4KPZ.js";import{DataTable as s}from"./data-table-D-JVXhZ7.js";import"./bar-Cjia2R58.js";import{runAnalyticalScreen as c}from"./analytical-screen-CxdwI377.js";import"./ui-CTH6j-SR.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}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`}async function m(m){let h=await e(),g=await t({strict:!1}),_=new n({config:h,cliVersion:m.cliVersion,token:g}),v,y;try{({siteId:v,site:y}=await o(_,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let b=i(m),x=m.window??`24h`,S=m.limit??100,C=[{key:`ts`,label:`when`,width:6,format:e=>p(String(e))},{key:`class`,label:`class`,width:18,format:e=>String(e)},{key:`message`,label:`message`,width:42,format:e=>f(String(e??``),42)},{key:`page`,label:`page`,width:24,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:8,format:e=>String(e??`—`)}];return c({cliVersion:m.cliVersion,title:`errors · ${v} · ${x}`,commandName:`errors`,authToken:g?.accessToken??null,refreshIntervalMs:m.watch?3e4:0,fetcher:e=>_.getErrors(v,{window:x,limit:S},e),format:b,headlessEmit:(e,t)=>{let n=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of n)process.stdout.write(JSON.stringify(e)+`
2
- `);else process.stdout.write(JSON.stringify({errors:n,total:n.length},null,2));return}process.stdout.write(r(n,[`ts`,`class`,`message`,`page`,`device`,`fingerprint`],t))},panels:[{id:`summary`,title:`Recent errors`,render:e=>{let t=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors,n=new Map,r=Date.now(),i=60;for(let e of t){let t=new Date(e.ts).getTime(),a=Math.floor((r-t)/(60*1e3));if(a<0||a>=i)continue;let o=n.get(e.class)??Array(i).fill(0),s=i-1-a;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 d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},t.length),d.createElement(u,{color:`gray`},` errors in `,x)),o.length===0?null:d.createElement(l,{flexDirection:`column`,marginTop:1},o.map(([e,t])=>d.createElement(u,{key:e},d.createElement(u,{color:`red`},e.padEnd(20).slice(0,20)),` `,d.createElement(u,{color:`gray`},a(t,30))))))}},{id:`table`,title:`Detail`,render:e=>{let t=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors;return t.length===0?d.createElement(u,{color:`gray`},`— no errors `,m.search?`matching "${m.search}"`:`in window`,` —`):d.createElement(s,{data:t.slice(0,30),columns:C,headerStyle:`accent`})}}]})}export{m as errorsCommand};
@@ -1,4 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{emitErrorEnvelope as n}from"./error-codes-DiyTHi_I.js";import{ApiV2Client as r}from"./api-v2-Byx59f4j.js";import{requireTier as i}from"./tier-ztFrvV9H.js";import{formatTabular as a}from"./formatter-DDG2TSOz.js";import{emitEnvelope as o,wrapItem as s}from"./emit-NkY7PE3R.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{resolveSiteId as c}from"./resolve-site-CoOL4KPZ.js";import{resolve as l}from"node:path";import{writeFile as u}from"node:fs/promises";function d(e,t,n){return a(e,t,n)}function f(e){let t=(e??`30d`).toLowerCase();return t===`7d`||t===`30d`||t===`90d`?t:`30d`}function p(e,t){t||process.stderr.isTTY&&process.stderr.write(`${e}\n`)}async function m(a){let d=await e(),m=await t({strict:!1}),_=new r({config:d,cliVersion:a.cliVersion,token:m});if(a.type!==`analytics`&&a.type!==`sessions`&&a.type!==`heatmaps`){let e=`Unknown export type '${a.type}'. Use one of: analytics, sessions, heatmaps.`;return a.json?n(Error(e),{command:`export`,cliVersion:a.cliVersion}):(process.stderr.write(`Error: ${e}\n`),2)}let v=a.format===`json`?`json`:`csv`,y=f(a.range),b=!!a.json;if(a.type===`sessions`||a.type===`heatmaps`)try{await i(_,`pro`)}catch(e){return a.json?n(e,{command:`export ${a.type}`,cliVersion:a.cliVersion}):(process.stderr.write(`${e.message}\n`),2)}let x;try{({siteId:x}=await c(_,{explicit:a.siteId,headless:b,cliVersion:a.cliVersion}))}catch(e){return a.json?n(e,{command:`export ${a.type}`,cliVersion:a.cliVersion}):(process.stderr.write(`${e.message}\n`),2)}try{p(`→ Fetching ${a.type} ${y}...`,b);let{rows:e,columns:t}=await h(_,a.type,x,y),n=g(e,t,v),r=a.out?l(process.cwd(),a.out):null;return r?(await u(r,n,`utf8`),a.json?(o(s({rowsWritten:e.length,file:r,format:v,range:y,type:a.type},`export.completed`,{siteId:x,command:`export ${a.type}`,cliVersion:a.cliVersion})),0):(process.stdout.write(`✓ Exported ${e.length} rows to ${r}\n`),0)):(process.stdout.write(n),n.endsWith(`
2
- `)||process.stdout.write(`
3
- `),a.json&&o(s({rowsWritten:e.length,file:null,format:v,range:y,type:a.type},`export.completed`,{siteId:x,command:`export ${a.type}`,cliVersion:a.cliVersion})),0)}catch(e){return a.json?n(e,{command:`export ${a.type}`,cliVersion:a.cliVersion}):(process.stderr.write(`✗ ${e.message}\n`),1)}}async function h(e,t,n,r){if(t===`analytics`){let t=await e.getStats(n,r);if(t.daily&&t.daily.length>0){let e=t.daily.map(e=>({date:e.date,visitors:e.visitors,pageviews:e.pageviews}));return{rows:e,columns:[`date`,`visitors`,`pageviews`]}}let i=[{range:r,visitors:t.visitors,pageviews:t.pageviews,sessions:t.sessions,bounceRate:t.bounceRate,avgSessionSec:t.avgSessionSec,windowStart:t.windowStart,windowEnd:t.windowEnd}];return{rows:i,columns:[`range`,`visitors`,`pageviews`,`sessions`,`bounceRate`,`avgSessionSec`,`windowStart`,`windowEnd`]}}if(t===`sessions`){let t=await e.getSessions(n),r=t.map(e=>({id:e.id,visitor:e.visitor,durationMs:e.duration,startedAt:e.startedAt,pageCount:e.pageCount,deviceType:e.deviceType??``}));return{rows:r,columns:[`id`,`visitor`,`durationMs`,`startedAt`,`pageCount`,`deviceType`]}}let i=await e.getHeatmaps(n),a=i.map(e=>({id:e.id,url:e.url,type:e.type,captureCount:e.captureCount,createdAt:e.createdAt}));return{rows:a,columns:[`id`,`url`,`type`,`captureCount`,`createdAt`]}}function g(e,t,n){if(n===`json`){let n=e.map(e=>{let n={};for(let r of t)n[String(r)]=e[r];return n});return JSON.stringify(n,null,2)+`
4
- `}return d(e,t,`csv`)}export{m as exportCommand};
@@ -1,3 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{resolveSiteId as a}from"./resolve-site-CoOL4KPZ.js";import{DataTable as o}from"./data-table-D-JVXhZ7.js";import{runAnalyticalScreen as s}from"./analytical-screen-CxdwI377.js";import{Box as c,Text as l}from"ink";import u from"react";function d(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 f(f){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:f.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{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 y=i(f);if(!f.funnelId){let e=[{key:`name`,label:`name`,width:30},{key:`stepCount`,label:`steps`,width:6,align:`right`},{key:`id`,label:`id`,width:36,format:e=>String(e).slice(0,36)}];return s({cliVersion:f.cliVersion,title:`funnels · ${_}`,commandName:`funnels`,authToken:h?.accessToken??null,refreshIntervalMs:0,fetcher:e=>g.listFunnels(_,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(r(e.funnels,[`id`,`name`,`stepCount`],t))},panels:[{id:`funnels`,title:`Funnels`,render:t=>t.funnels.length===0?u.createElement(l,{color:`gray`},`— no funnels defined —`):u.createElement(o,{data:t.funnels,columns:e,headerStyle:`accent`})},{id:`hint`,title:`Next`,render:()=>u.createElement(l,{color:`gray`},"Run `zenovay funnel <id>` for drop-off detail.")}]})}let b=f.window??`30d`;return s({cliVersion:f.cliVersion,title:`funnel · ${f.funnelId} · ${b}`,commandName:`funnel`,authToken:h?.accessToken??null,refreshIntervalMs:0,fetcher:e=>g.getFunnel(_,f.funnelId,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(`
3
- `);return}process.stdout.write(r(e.steps,[`id`,`name`,`visitors`,`conversions`],t))},panels:[{id:`overview`,title:p(`Overview`),render:e=>u.createElement(c,{flexDirection:`column`},u.createElement(l,{bold:!0},e.name),u.createElement(l,{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 u.createElement(c,{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 u.createElement(c,{key:n.id,flexDirection:`column`},a?u.createElement(l,{color:`red`},` `,`↓ drop `,o.toLocaleString(),` (`,s.toFixed(1),`%)`):null,u.createElement(l,null,u.createElement(l,{bold:!0},`${r+1}. ${n.name}`.padEnd(22).slice(0,22)),` `,u.createElement(l,{color:`magenta`},d(i,30)),` `,u.createElement(l,null,(i*100).toFixed(1).padStart(5),`% `),u.createElement(l,{color:`gray`},n.visitors.toLocaleString())))}))}}]})}function p(e){return e}export{f as funnelCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import"./formatter-DDG2TSOz.js";import{emit as r,isHeadless as i}from"./emit-NkY7PE3R.js";import{Panel as a}from"./panel-CYsRlDSL.js";import{Banner as o}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as s}from"./keybar-Bh-y__tC.js";import{resolveSiteId as c}from"./resolve-site-CoOL4KPZ.js";import{DataTable as l}from"./data-table-D-JVXhZ7.js";import{EmptyState as u}from"./empty-state-BbUJUNcp.js";import{Globe as d}from"./globe-C-lbJoTS.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(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getGeo(u);return r({type:`geo.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=h(),[m,x]=y(null),[S,C]=y(!0),[w,T]=y(null);if(g(e=>{e===`q`&&(c(),i(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getGeo(t);n||(x(r),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),S)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(a,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching geo…`))));if(w)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(u,{reason:`error`,headline:`Failed to load`,hint:w}));let E=!m||m.countries.length===0&&m.cities.length===0;if(E)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(u,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let D=[{key:`country`,label:`country`,width:18},{key:`visitors`,label:`visitors`,align:`right`,width:8}],O=[{key:`city`,label:`city`,width:20},{key:`country`,label:`country`,width:12},{key:`visitors`,label:`visitors`,align:`right`,width:8}],k=process.stdout.columns??80;return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(f,{flexDirection:`row`},_.createElement(a,{title:`Countries`},m.countries.length===0?_.createElement(p,{color:`gray`},`— —`):_.createElement(l,{columns:D,data:m.countries.slice(0,15),zebra:!0})),_.createElement(a,{title:`Globe`},_.createElement(d,{data:[],width:Math.max(36,k-60),height:12}))),_.createElement(a,{title:`Cities`},m.cities.length===0?_.createElement(p,{color:`gray`},`— —`):_.createElement(l,{columns:O,data:m.cities.slice(0,20),zebra:!0})),_.createElement(s,{items:[{key:`q`,label:`quit`}]}))};export{x as geoCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{requireTier as r}from"./tier-ztFrvV9H.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import{resolveSiteId as l}from"./resolve-site-CoOL4KPZ.js";import{DataTable as u}from"./data-table-D-JVXhZ7.js";import{EmptyState as d}from"./empty-state-BbUJUNcp.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(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getHeatmaps(d);return i({type:`heatmaps.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=h(),[l,m]=y(null),[x,S]=y(!0),[C,w]=y(null);if(g(e=>{e===`q`&&(a(),i(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getHeatmaps(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(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(o,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching heatmaps…`))));if(C)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(d,{reason:`error`,headline:`Failed to load`,hint:C}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(d,{reason:`no-data`,headline:`No heatmaps yet`,hint:`Enable heatmaps in your site settings`}));let T=[{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(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(o,{title:`Heatmaps (${l.length})`},_.createElement(u,{columns:T,data:l,zebra:!0})),_.createElement(f,{marginTop:1},_.createElement(p,{color:`gray`},`Open any heatmap at https://app.zenovay.com/heatmaps`)),_.createElement(c,{items:[{key:`q`,label:`quit`}]}))};export{x as heatmapsCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{requireTier as r}from"./tier-ztFrvV9H.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import{resolveSiteId as l}from"./resolve-site-CoOL4KPZ.js";import{EmptyState as u}from"./empty-state-BbUJUNcp.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(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let m=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getInsights(d);return i({type:`insights.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(C,{api:u,siteId:d,siteLabel:m,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=m(),[l,p]=v(null),[S,C]=v(!0),[w,T]=v(null);return h(e=>{e===`q`&&(a(),i(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getInsights(t);n||(p(r),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),S?g.createElement(d,{flexDirection:`column`},g.createElement(s,{version:r,subtitle:`insights · ${n}`}),g.createElement(o,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Fetching insights…`)))):w?g.createElement(d,{flexDirection:`column`},g.createElement(s,{version:r,subtitle:`insights · ${n}`}),g.createElement(u,{reason:`error`,headline:`Failed to load`,hint:w})):!l||l.length===0?g.createElement(d,{flexDirection:`column`},g.createElement(s,{version:r,subtitle:`insights · ${n}`}),g.createElement(u,{reason:`no-data`,headline:`No insights yet`,hint:`Insights are generated nightly — check back tomorrow`})):g.createElement(d,{flexDirection:`column`},g.createElement(s,{version:r,subtitle:`insights · ${n}`}),l.map((e,t)=>g.createElement(o,{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(c,{items:[{key:`q`,label:`quit`}]}))};export{S as insightsCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{requireTier as r}from"./tier-ztFrvV9H.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import{resolveSiteId as l}from"./resolve-site-CoOL4KPZ.js";import{EmptyState as u}from"./empty-state-BbUJUNcp.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(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let m=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getJourneys(d);return i({type:`journeys.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:u,siteId:d,siteLabel:m,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=m(),[l,p]=v(null),[b,x]=v(!0),[S,C]=v(null);if(h(e=>{e===`q`&&(a(),i(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(s,{version:r,subtitle:`journeys · ${n}`}),g.createElement(o,{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(s,{version:r,subtitle:`journeys · ${n}`}),g.createElement(u,{reason:`error`,headline:`Failed to load`,hint:S}));if(!l||l.length===0)return g.createElement(d,{flexDirection:`column`},g.createElement(s,{version:r,subtitle:`journeys · ${n}`}),g.createElement(u,{reason:`no-data`,headline:`No journeys yet`,hint:`Need at least 2 page-views per session to compute flows`}));let w=Math.max(...l.map(e=>e.count),1),T=12;return g.createElement(d,{flexDirection:`column`},g.createElement(s,{version:r,subtitle:`journeys · ${n}`}),g.createElement(o,{title:`Top page transitions (${l.length})`},l.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(c,{items:[{key:`q`,label:`quit`}]}))};export{b as journeysCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import"./formatter-DDG2TSOz.js";import{emit as r,isHeadless as i}from"./emit-NkY7PE3R.js";import{Panel as a}from"./panel-CYsRlDSL.js";import{Banner as o}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as s}from"./keybar-Bh-y__tC.js";import"./sparkline-DM2BGvjD.js";import{resolveSiteId as c}from"./resolve-site-CoOL4KPZ.js";import{EmptyState as l}from"./empty-state-BbUJUNcp.js";import{MetricCard as u}from"./metric-card-qze7DsPv.js";import{Globe as d}from"./globe-C-lbJoTS.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(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getLive(u);return r({type:`live.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=h(),[m,x]=y(null),[S,C]=y(!0),[w,T]=y(null);if(g(e=>{e===`q`&&(c(),i(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(o,{version:r,subtitle:`live · ${n}`}),_.createElement(a,{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(o,{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(o,{version:r,subtitle:`live · ${n}`}),_.createElement(f,{flexDirection:`row`},_.createElement(u,{title:`Active now`,value:m?.activeVisitors??0,format:`number`,width:D}),_.createElement(a,{title:`Globe`,width:Math.max(40,E-D-4)},_.createElement(d,{data:[],width:Math.max(36,E-D-10),height:10}))),_.createElement(a,{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(s,{items:[{key:`q`,label:`quit`}]}))};export{x as liveCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import"./formatter-DDG2TSOz.js";import{emit as r,isHeadless as i}from"./emit-NkY7PE3R.js";import{Panel as a}from"./panel-CYsRlDSL.js";import{Banner as o}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as s}from"./keybar-Bh-y__tC.js";import{resolveSiteId as c}from"./resolve-site-CoOL4KPZ.js";import{DataTable as l}from"./data-table-D-JVXhZ7.js";import{EmptyState as u}from"./empty-state-BbUJUNcp.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(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getPages(u);return r({type:`pages.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=m(),[p,b]=v(null),[x,S]=v(!0),[C,w]=v(null);if(h(e=>{e===`q`&&(c(),i(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(o,{version:r,subtitle:`pages · ${n}`}),g.createElement(a,{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(o,{version:r,subtitle:`pages · ${n}`}),g.createElement(u,{reason:`error`,headline:`Failed to load`,hint:C}));if(!p||p.length===0)return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`pages · ${n}`}),g.createElement(u,{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(o,{version:r,subtitle:`pages · ${n}`}),g.createElement(a,{title:`Top pages (${p.length})`},g.createElement(l,{columns:T,data:p,zebra:!0})),g.createElement(s,{items:[{key:`q`,label:`quit`}]}))};export{b as pagesCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{requireTier as r}from"./tier-ztFrvV9H.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import{resolveSiteId as l}from"./resolve-site-CoOL4KPZ.js";import{EmptyState as u}from"./empty-state-BbUJUNcp.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(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let m=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getRetention(d);return i({type:`retention.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(C,{api:u,siteId:d,siteLabel:m,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=m(),[l,p]=v(null),[S,C]=v(!0),[w,T]=v(null);return h(e=>{e===`q`&&(a(),i(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(s,{version:r,subtitle:`retention · ${n}`}),g.createElement(o,{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(s,{version:r,subtitle:`retention · ${n}`}),g.createElement(u,{reason:`error`,headline:`Failed to load`,hint:w})):!l||l.length===0?g.createElement(d,{flexDirection:`column`},g.createElement(s,{version:r,subtitle:`retention · ${n}`}),g.createElement(u,{reason:`no-data`,headline:`No retention data yet`,hint:`Retention needs at least 30 days of traffic`})):g.createElement(d,{flexDirection:`column`},g.createElement(s,{version:r,subtitle:`retention · ${n}`}),g.createElement(o,{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(c,{items:[{key:`q`,label:`quit`}]}))};export{S as retentionCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./progress-row-5G_PO8xL.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{spark as a}from"./sparkline-DM2BGvjD.js";import{resolveSiteId as o}from"./resolve-site-CoOL4KPZ.js";import"./data-table-D-JVXhZ7.js";import"./bar-Cjia2R58.js";import{runAnalyticalScreen as s}from"./analytical-screen-CxdwI377.js";import"./ui-CTH6j-SR.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 n({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=i(f),y=f.range??`30d`;return s({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(r(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`},a(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};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{requireTier as r}from"./tier-ztFrvV9H.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import{resolveSiteId as l}from"./resolve-site-CoOL4KPZ.js";import{DataTable as u}from"./data-table-D-JVXhZ7.js";import{EmptyState as d}from"./empty-state-BbUJUNcp.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(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getSessions(d);return i({type:`sessions.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(w,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=h(),[l,m]=y(null),[C,w]=y(!0),[T,E]=y(null);if(g(e=>{e===`q`&&(a(),i(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(s,{version:r,subtitle:`sessions · ${n}`}),_.createElement(o,{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(s,{version:r,subtitle:`sessions · ${n}`}),_.createElement(d,{reason:`error`,headline:`Failed to load`,hint:T}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`sessions · ${n}`}),_.createElement(d,{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(s,{version:r,subtitle:`sessions · ${n}`}),_.createElement(o,{title:`Recent sessions (${l.length})`},_.createElement(u,{columns:D,data:l,zebra:!0})),_.createElement(f,{marginTop:1},_.createElement(p,{color:`gray`},`Open any session for replay at https://app.zenovay.com/replay`)),_.createElement(c,{items:[{key:`q`,label:`quit`}]}))};export{C as sessionsCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{resolveSiteId as a}from"./resolve-site-CoOL4KPZ.js";import{DataTable as o}from"./data-table-D-JVXhZ7.js";import{runAnalyticalScreen as s}from"./analytical-screen-CxdwI377.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 n({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(p),b=p.period??`30d`,x=[{key:`source`,label:`source`,width:22},{key:`channel`,label:`channel`,width:10,format:e=>String(e??`—`)},{key:`visitors`,label:`visitors`,width:8,align:`right`},{key:`delta`,label:`Δ`,width:6,align:`right`,format:e=>typeof e==`number`?`${e>0?`+`:``}${(e*100).toFixed(1)}%`:`—`}];return s({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(r(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(o,{data:e.sources.slice(0,20),columns:x,headerStyle:`accent`})}]})}export{p as sourcesCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{requireTier as r}from"./tier-ztFrvV9H.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import{resolveSiteId as l}from"./resolve-site-CoOL4KPZ.js";import{DataTable as u}from"./data-table-D-JVXhZ7.js";import{EmptyState as d}from"./empty-state-BbUJUNcp.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(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getUptime(d);return i({type:`uptime.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(w,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=h(),[l,m]=y(null),[C,w]=y(!0),[T,E]=y(null);if(g(e=>{e===`q`&&(a(),i(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(s,{version:r,subtitle:`uptime · ${n}`}),_.createElement(o,{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(s,{version:r,subtitle:`uptime · ${n}`}),_.createElement(d,{reason:`error`,headline:`Failed to load`,hint:T}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`uptime · ${n}`}),_.createElement(d,{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(s,{version:r,subtitle:`uptime · ${n}`}),_.createElement(o,{title:`Monitors (${l.length})`},_.createElement(u,{columns:D,data:l,zebra:!0})),_.createElement(c,{items:[{key:`q`,label:`quit`}]}))};export{C as uptimeCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{brailleSpark as a,spark as o}from"./sparkline-DM2BGvjD.js";import{resolveSiteId as s}from"./resolve-site-CoOL4KPZ.js";import{DataTable as c}from"./data-table-D-JVXhZ7.js";import{runAnalyticalScreen as l}from"./analytical-screen-CxdwI377.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){let t=e,n=t.events??t.timeseries;return Array.isArray(n)&&n.length>0?o(n,8):`▁▁▁▁▁▁▁▁`}function h(e){let t=e;if(typeof t.sessionDurationSec==`number`)return t.sessionDurationSec;if(typeof t.sessionDurationMs==`number`)return Math.floor(t.sessionDurationMs/1e3);if(typeof t.durationMs==`number`)return Math.floor(t.durationMs/1e3);if(typeof t.duration==`number`)return Math.floor(t.duration/1e3);let n=Date.parse(e.startedAt);return Number.isNaN(n)?0:Math.max(0,Math.floor((Date.now()-n)/1e3))}async function g(o){let g=await e(),_=await t({strict:!1}),v=new n({config:g,cliVersion:o.cliVersion,token:_}),y,b;try{({siteId:y,site:b}=await s(v,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let x=i(o),S=o.limit??50,C=typeof o.minDuration==`number`&&o.minDuration>0?o.minDuration:0,w=e=>C<=0?e:e.filter(e=>h(e)>=C),T=[{key:`startedAt`,label:`when`,width:6,format:e=>p(String(e))},{key:`country`,label:`country`,width:7,format:e=>String(e??`—`)},{key:`city`,label:`city`,width:14,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`page`,label:`page`,width:26,format:e=>String(e??`—`)},{key:`id`,label:`24h`,width:8,format:(e,t)=>m(t)}];return l({cliVersion:o.cliVersion,title:`visitors · ${y}`,commandName:`visitors`,authToken:_?.accessToken??null,refreshIntervalMs:1e4,fetcher:e=>v.getVisitors(y,{limit:S},e),format:x,headlessEmit:(e,t)=>{let n={...e,visitors:w(e.visitors)};if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(n,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
- `);return}let i=[`startedAt`,`country`,`city`,`device`,`page`];process.stdout.write(r(n.visitors,i,t))},panels:[{id:`live`,title:`Now`,render:e=>{let t=w(e.visitors),n=[...t].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)),r=n[0],i=Array(24*6).fill(0),o=Date.now();for(let e of t){let t=o-new Date(e.startedAt).getTime(),n=Math.floor(t/(10*60*1e3));n>=0&&n<i.length&&(i[i.length-1-n]+=1)}return f.createElement(u,{flexDirection:`column`},f.createElement(d,{bold:!0},t.length,` live`),f.createElement(d,{color:`gray`},a(i,40)),r?f.createElement(d,{color:`gray`},`top: `,r.city??r.country??`—`,` · `,r.page??`—`):null)}},{id:`visitors`,title:`Active sessions`,render:e=>{let t=w(e.visitors),n=[...t].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)).slice(0,S);return n.length===0?f.createElement(d,{color:`gray`},`— no visitors yet —`):f.createElement(c,{columns:T,data:n,headerStyle:`accent`})}}]})}export{g as visitorsCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./panel-CYsRlDSL.js";import"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import"./keybar-Bh-y__tC.js";import{resolveSiteId as a}from"./resolve-site-CoOL4KPZ.js";import{DataTable as o}from"./data-table-D-JVXhZ7.js";import{runAnalyticalScreen as s}from"./analytical-screen-CxdwI377.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 n({config:m,cliVersion:d.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(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=i(d),b=[{key:`url`,label:`url`,width:32},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,label:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`lcp`,e.p75):`—`},{key:`inp`,label:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`inp`,e.p75):`—`},{key:`cls`,label:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`cls`,e.p75):`—`},{key:`samples`,label:`n`,width:6,align:`right`}];return s({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(r(e.vitals,[`url`,`device`,`samples`],t))},panels:[{id:`summary`,title:`Site-wide p75`,render:e=>{let t=t=>{let n=0,r=0;for(let i of e.vitals){let e=i[t]?.p75;typeof e==`number`&&(n+=e*i.samples,r+=i.samples)}return r>0?n/r:0},n=[`lcp`,`inp`,`cls`,`ttfb`,`fcp`];return 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(o,{data:e.vitals.slice(0,15),columns:b,headerStyle:`accent`})}]})}export{m as vitalsCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-Byx59f4j.js";import{parseSseStream as r}from"./client-Ckr8RqMm.js";import"./formatter-DDG2TSOz.js";import{emit as i,isHeadless as a}from"./emit-NkY7PE3R.js";import{Panel as o}from"./panel-CYsRlDSL.js";import{Banner as s}from"./banner-Cr0PV2pB.js";import"./prompt-BS9qJvdR.js";import{Keybar as c}from"./keybar-Bh-y__tC.js";import{spark as l}from"./sparkline-DM2BGvjD.js";import{resolveSiteId as u}from"./resolve-site-CoOL4KPZ.js";import{EmptyState as d}from"./empty-state-BbUJUNcp.js";import{Globe as f}from"./globe-C-lbJoTS.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(r){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:r.cliVersion,token:s}),l;try{({siteId:l}=await u(c,{explicit:r.siteId,headless:!!r.json,cliVersion:r.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(a(r)){let e=await c.getDashboardSnapshot(l);return i({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:c,siteId:l,intervalMs:r.intervalMs??15e3,cliVersion:r.cliVersion,onExit:n=>{t(),e(n)}}))})}const E=({api:e,siteId:t,intervalMs:n,cliVersion:i,onExit:a})=>{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(),a(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 r=!1,i=async()=>{try{let n=await e.getDashboardSnapshot(t);if(r)return;let i=w.safeParse(n);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=>{r||C(e)},()=>{}),e.getGoals(t).then(e=>{r||E(e)},()=>{}),L(!1),z(null)}catch(e){r||z(e.message)}};i();let a=setInterval(i,n);return()=>{r=!0,clearInterval(a)}},[e,t,n]),b(()=>{let n=new AbortController;return(async()=>{try{let i=await e.openEventsStream(t,n.signal);for await(let e of r(i))e.type===`error`&&F(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>n.abort()},[e,t]),I)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:i,subtitle:`watch · ${t}`}),y.createElement(o,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching snapshot…`))));if(R&&!u)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:i,subtitle:`watch · ${t}`}),y.createElement(o,{title:`Error`,state:`err`},y.createElement(h,{color:`red`},R)));if(K&&!u)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{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(s,{version:i,subtitle:`watch · ${t}${H?` · globe`:``}`}),y.createElement(m,{flexDirection:`row`},y.createElement(m,{flexDirection:`column`},H?y.createElement(o,{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(c,{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:n})=>{let[i,a]=x(``),[s,c]=x([]),[l,u]=x(!1),[d,f]=x(``),[p,g]=x(null),_=async n=>{let i=n.trim();if(!i||l)return;g(null),a(``);let o=[...s,{role:`user`,content:i}];c(o),u(!0),f(``);try{let n=o.map(e=>({role:e.role,content:e.content})),i=await e.openAiStream(`chat`,{messages:n,siteId:t},void 0),a=``;for await(let e of r(i))if(e.type===`delta`)a+=e.content,f(a);else if(e.type===`error`)g(`${e.code}: ${e.message}`);else if(e.type===`done`)break;c([...o,{role:`assistant`,content:a}]),f(``)}catch(e){g(e instanceof Error?e.message:`chat failed`)}finally{u(!1)}};return y.createElement(m,{marginTop:1},y.createElement(o,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:n},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:a,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(o,{title:`Visitors`,focused:t,width:n},y.createElement(h,{bold:!0},r.toString()),y.createElement(h,{color:`gray`},i.length>0?l(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(o,{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(o,{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(o,{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(o,{title:`Vitals`,focused:t,width:n},r(`LCP`,e?.lcpP75,`ms`),r(`INP`,e?.inpP75,`ms`),r(`CLS`,e?.clsP75?e.clsP75*1e3:void 0,`/1k`),r(`TTFB`,e?.ttfbP75,`ms`),r(`FCP`,e?.fcpP75,`ms`))},N=({goals:e,focused:t,width:n})=>{let r=e?.goals?.slice(0,5)??[];return y.createElement(o,{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};
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes