@zenovay/cli 0.1.46 → 0.1.48

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 (81) hide show
  1. package/dist/{ai-D213ShI-.js → ai-_rqf7f6S.js} +1 -1
  2. package/dist/analytical-screen-DU3-yg-L.js +1 -0
  3. package/dist/analytics-BqehhVev.js +2 -0
  4. package/dist/bin.js +3 -3
  5. package/dist/chat-panel-D0OCo26Y.js +7 -0
  6. package/dist/companies-C6UkwchG.js +2 -0
  7. package/dist/{csv-emit-BO_9WNzp.js → csv-emit-BBRylOi9.js} +1 -1
  8. package/dist/deploys-BJOVeG9A.js +2 -0
  9. package/dist/{devices-CH8M4iis.js → devices-D13XKto5.js} +1 -1
  10. package/dist/{doctor-D6-THYxW.js → doctor-wNp0p9Id.js} +1 -1
  11. package/dist/errors-CkfNgmQo.js +2 -0
  12. package/dist/{export-CG9wBqtQ.js → export-lJaRsY1I.js} +1 -1
  13. package/dist/funnel-BSn9sc9M.js +3 -0
  14. package/dist/{geo-CJaEB5KN.js → geo-D-GReM3X.js} +1 -1
  15. package/dist/globe-DZkvJ7qV.js +2 -0
  16. package/dist/{health-dMNJp2tb.js → health-D3jvm575.js} +1 -1
  17. package/dist/{init-DYSe6Vcn.js → init-CRxbEaBn.js} +1 -1
  18. package/dist/{init-CgxoXN7k.js → init-DsNUzokE.js} +1 -1
  19. package/dist/live-DhJ5TBHS.js +1 -0
  20. package/dist/projects-DZ5z6LmV.js +2 -0
  21. package/dist/{query-zdZ4ceI0.js → query-BjNzNpU5.js} +1 -1
  22. package/dist/revenue-DGq_Hvf0.js +2 -0
  23. package/dist/{self-test-DzE99nUT.js → self-test-h1-eHX5E.js} +1 -1
  24. package/dist/sources-2MTc_2mw.js +2 -0
  25. package/dist/stats-Ca8-skO3.js +2 -0
  26. package/dist/{themes-CFTtwV8K.js → themes-tu_XBt7d.js} +1 -1
  27. package/dist/visitors-DRUXEj-A.js +2 -0
  28. package/dist/vitals-G3OnRL03.js +2 -0
  29. package/dist/{watch-BgMImDP3.js → watch-CuDG_kT6.js} +1 -1
  30. package/dist/{webhooks-forward-DWf84udt.js → webhooks-forward-CB5ES9W9.js} +1 -1
  31. package/dist/wizard-bin.js +1 -1
  32. package/package.json +1 -1
  33. package/dist/analytical-screen-gN9MJR34.js +0 -1
  34. package/dist/analytics-DF2T44kl.js +0 -2
  35. package/dist/companies-tJNXmMks.js +0 -2
  36. package/dist/deploys-Gqz4EU7p.js +0 -2
  37. package/dist/errors-BXTHvRfC.js +0 -2
  38. package/dist/funnel-BVa_bnxD.js +0 -3
  39. package/dist/globe-CzrRQX2k.js +0 -2
  40. package/dist/live-Dr2uQxLP.js +0 -1
  41. package/dist/projects-CBWVFG4D.js +0 -2
  42. package/dist/revenue-DJaQu3OS.js +0 -2
  43. package/dist/sources-CkxSyvLT.js +0 -2
  44. package/dist/stats-CKX2x_-S.js +0 -2
  45. package/dist/visitors-CRdgYweh.js +0 -2
  46. package/dist/vitals-UZJtXgZy.js +0 -2
  47. /package/dist/{annotation-Cnwd3YY4.js → annotation-8lalJWJI.js} +0 -0
  48. /package/dist/{api-keys-D70Onl1P.js → api-keys-CTJpLgES.js} +0 -0
  49. /package/dist/{audit-CU9Mttuw.js → audit-BzT7VEpz.js} +0 -0
  50. /package/dist/{commands-C1jcv2pS.js → commands-C7_3SVK7.js} +0 -0
  51. /package/dist/{completions-BQ4StZaH.js → completions-BqPBn7NY.js} +0 -0
  52. /package/dist/{csv-emit-DW3zkmKh.js → csv-emit-DzDpXH0X.js} +0 -0
  53. /package/dist/{domains-BC7-CHRo.js → domains-CjoJTahy.js} +0 -0
  54. /package/dist/{events-tail-BqdQbbmc.js → events-tail-CG35fOcB.js} +0 -0
  55. /package/dist/{examples-Du9MQhvk.js → examples-DWs2xIIj.js} +0 -0
  56. /package/dist/{globe-Cc-yuiNd.js → globe-BlA0FQ2P.js} +0 -0
  57. /package/dist/{goals-Ce5-A1vs.js → goals-DAZXyjYt.js} +0 -0
  58. /package/dist/{health-CDaLBYEV.js → health-BO5xnrAo.js} +0 -0
  59. /package/dist/{heatmaps-DcAqig5H.js → heatmaps-DeYlyvNG.js} +0 -0
  60. /package/dist/{home-HxR4gTQn.js → home-D81GWHKp.js} +0 -0
  61. /package/dist/{insights-ByZzXZHY.js → insights-U-i-gSic.js} +0 -0
  62. /package/dist/{integrations-U4kC8H0B.js → integrations-7ZefcgdK.js} +0 -0
  63. /package/dist/{journeys-CHxCgdxr.js → journeys-C0PEIJc1.js} +0 -0
  64. /package/dist/{logout-C5ORyahe.js → logout-DW7DW4pV.js} +0 -0
  65. /package/dist/{notes-CcKBUVCU.js → notes-CuYg1wF3.js} +0 -0
  66. /package/dist/{pages-u6aLFIpb.js → pages-DFgy8C9d.js} +0 -0
  67. /package/dist/{plans-CpRRn2lU.js → plans-D8E1cvUI.js} +0 -0
  68. /package/dist/{profile-DFf1dDSh.js → profile-BcUyym1H.js} +0 -0
  69. /package/dist/{retention-slZLDbA1.js → retention-DILiV_MU.js} +0 -0
  70. /package/dist/{sessions-WiMWIQck.js → sessions-Dg_OAaDW.js} +0 -0
  71. /package/dist/{settings-TskIncN8.js → settings-CVaQ7QSn.js} +0 -0
  72. /package/dist/{share-DpJKbbsA.js → share-JH4hayKJ.js} +0 -0
  73. /package/dist/{team-D2PjjTOh.js → team-CIubxrIA.js} +0 -0
  74. /package/dist/{teams-DdBAKI2f.js → teams-Dk7bsVhI.js} +0 -0
  75. /package/dist/{tour-DiwY-B8U.js → tour-Bxz6PP3u.js} +0 -0
  76. /package/dist/{ui-CLpqz5_6.js → ui-Cho9XZk0.js} +0 -0
  77. /package/dist/{update-C4T7lQkc.js → update-Wsnp3zMr.js} +0 -0
  78. /package/dist/{uptime-Bwmb7jOZ.js → uptime-Ypv2hc6V.js} +0 -0
  79. /package/dist/{usage-CXHVT8_C.js → usage-HtPrqo5h.js} +0 -0
  80. /package/dist/{use-24v4ZHT1.js → use-DELCCiL5.js} +0 -0
  81. /package/dist/{webhooks-_1mTPi8-.js → webhooks-gDzhehMo.js} +0 -0
@@ -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-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(`
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-Cho9XZk0.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,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"./client-Ckr8RqMm.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"./chat-panel-D0OCo26Y.js";import{runAnalyticalScreen as l}from"./analytical-screen-DU3-yg-L.js";import"./ui-Cho9XZk0.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){let n=e/100,r=new Intl.NumberFormat(`en-US`,{minimumFractionDigits:0,maximumFractionDigits:0}).format(n),i=(t||`USD`).toUpperCase();return i===`USD`?`$${r}`:i===`EUR`?`€${r}`:i===`GBP`?`£${r}`:`${r} ${i}`}async function m(m){let h=await e(),g=await t({strict:!1}),_=new n({config:h,cliVersion:m.cliVersion,token:g}),v,y;try{({siteId:v,site:y}=await o(_,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let b=i(m),x=m.range??`30d`;return l({cliVersion:m.cliVersion,title:`revenue · ${v} · ${x}`,commandName:`revenue`,ai:{api:_,siteId:v,siteLabel:y?.url?y.url.replace(/^https?:\/\//,``).replace(/\/$/,``):y?.name??v},authToken:g?.accessToken??null,refreshIntervalMs:m.watch?5*6e4:0,fetcher:e=>_.getRevenue(v,x,e),format:b,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`revenue`,{siteId:v}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);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-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)+`
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-DWs2xIIj.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,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"./client-Ckr8RqMm.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"./chat-panel-D0OCo26Y.js";import{runAnalyticalScreen as l}from"./analytical-screen-DU3-yg-L.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){let n=Math.round(e/100*t);return`█`.repeat(n)+`░`.repeat(Math.max(0,t-n))}function m(e){return e==null?{glyph:`·`,color:`gray`}:e>.5?{glyph:`▲`,color:`green`}:e<-.5?{glyph:`▼`,color:`red`}:{glyph:`→`,color:`gray`}}async function h(h){let g=await e(),_=await t({strict:!1}),v=new n({config:g,cliVersion:h.cliVersion,token:_}),y,b;try{({siteId:y,site:b}=await a(v,{explicit:h.siteId,headless:!!(h.json||h.csv||h.tsv||h.ndjson),cliVersion:h.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let x=i(h),S=h.period??`30d`,C=[{key:`source`,label:`source`,width:22},{key:`channel`,label:`channel`,width:10,format:e=>String(e??`—`)},{key:`visitors`,label:`visitors`,width:8,align:`right`},{key:`delta`,label:`Δ`,width:6,align:`right`,format:e=>typeof e==`number`?`${e>0?`+`:``}${(e*100).toFixed(1)}%`:`—`}];return l({cliVersion:h.cliVersion,title:`sources · ${y} · ${S}`,commandName:`sources`,authToken:_?.accessToken??null,refreshIntervalMs:6e4,fetcher:e=>v.getSources(y,S,h.compare,e),format:x,ai:{api:v,siteId:y,siteLabel:b?.url?b.url.replace(/^https?:\/\//,``).replace(/\/$/,``):b?.name??y},keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`sources`,{siteId:y}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);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};
@@ -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"./client-Ckr8RqMm.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"./chat-panel-D0OCo26Y.js";import{runAnalyticalScreen as s}from"./analytical-screen-DU3-yg-L.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){return`${(e*100).toFixed(1)}%`}function f(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.floor(e/60)}m ${Math.round(e%60)}s`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(p),b=p.range??`24h`,x=[{key:`url`,label:`page`,width:40,format:e=>String(e??`—`)},{key:`views`,label:`views`,width:8,align:`right`}],S=[{key:`country`,label:`country`,width:8},{key:`visitors`,label:`visitors`,width:8,align:`right`}];return s({cliVersion:p.cliVersion,title:`stats · ${_} · ${b}`,commandName:`stats`,ai:{api:g,siteId:_,siteLabel:v?.url?v.url.replace(/^https?:\/\//,``).replace(/\/$/,``):v?.name??_},authToken:h?.accessToken??null,refreshIntervalMs:p.watch?6e4:0,fetcher:e=>g.getStats(_,b,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);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-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)+`
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-Cho9XZk0.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,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"./client-Ckr8RqMm.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"./chat-panel-D0OCo26Y.js";import{runAnalyticalScreen as d}from"./analytical-screen-DU3-yg-L.js";import{Box as f,Text as p}from"ink";import m from"react";function h(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function g(e){let t=e,n=t.events??t.timeseries;return Array.isArray(n)&&n.length>0?o(n,8):`▁▁▁▁▁▁▁▁`}function _(e){let t=e;if(typeof t.sessionDurationSec==`number`)return t.sessionDurationSec;if(typeof t.sessionDurationMs==`number`)return Math.floor(t.sessionDurationMs/1e3);if(typeof t.durationMs==`number`)return Math.floor(t.durationMs/1e3);if(typeof t.duration==`number`)return Math.floor(t.duration/1e3);let n=Date.parse(e.startedAt);return Number.isNaN(n)?0:Math.max(0,Math.floor((Date.now()-n)/1e3))}async function v(o){let v=await e(),y=await t({strict:!1}),b=new n({config:v,cliVersion:o.cliVersion,token:y}),x,S;try{({siteId:x,site:S}=await s(b,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let C=i(o),w=o.limit??50,T=typeof o.minDuration==`number`&&o.minDuration>0?o.minDuration:0,E=e=>T<=0?e:e.filter(e=>_(e)>=T),D=6e4,O=e=>{let t=Date.parse(e.startedAt);return Number.isFinite(t)&&Date.now()-t<D},k=[{key:`startedAt`,label:``,width:5,format:(e,t)=>O(t)?`● new`:``},{key:`startedAt`,label:`when`,width:6,format:e=>h(String(e))},{key:`country`,label:`country`,width:7,format:e=>String(e??`—`)},{key:`city`,label:`city`,width:14,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`page`,label:`page`,width:26,format:e=>String(e??`—`)},{key:`id`,label:`24h`,width:8,format:(e,t)=>g(t)}];return d({cliVersion:o.cliVersion,title:`visitors · ${x}`,commandName:`visitors`,ai:{api:b,siteId:x,siteLabel:S?.url?S.url.replace(/^https?:\/\//,``).replace(/\/$/,``):S?.name??x},authToken:y?.accessToken??null,refreshIntervalMs:1e4,fetcher:e=>b.getVisitors(x,{limit:w},e),format:C,keybindings:{o:{label:`open in browser`,handler:()=>{u(l(`visitors`,{siteId:x}))}}},headlessEmit:(e,t)=>{let n={...e,visitors:E(e.visitors)};if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(n,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);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"./client-Ckr8RqMm.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"./chat-panel-D0OCo26Y.js";import{runAnalyticalScreen as l}from"./analytical-screen-DU3-yg-L.js";import{Box as u,Text as d}from"ink";import f from"react";const p={lcp:{good:2500,poor:4e3},inp:{good:200,poor:500},cls:{good:.1,poor:.25},ttfb:{good:800,poor:1800},fcp:{good:1800,poor:3e3}};function m(e,t){let n=p[e];return t<=n.good?{label:`good`,color:`green`}:t<=n.poor?{label:`needs`,color:`yellow`}:{label:`poor`,color:`red`}}function h(e,t){return e===`cls`?t.toFixed(3):t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`}async function g(p){let g=await e(),_=await t({strict:!1}),v=new n({config:g,cliVersion:p.cliVersion,token:_}),y,b;try{({siteId:y,site:b}=await a(v,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let x=i(p),S=[{key:`url`,label:`url`,width:32},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,label:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`lcp`,e.p75):`—`},{key:`inp`,label:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`inp`,e.p75):`—`},{key:`cls`,label:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?h(`cls`,e.p75):`—`},{key:`samples`,label:`n`,width:6,align:`right`}];return l({cliVersion:p.cliVersion,title:`vitals · ${y}`,commandName:`vitals`,ai:{api:v,siteId:y,siteLabel:b?.url?b.url.replace(/^https?:\/\//,``).replace(/\/$/,``):b?.name??y},authToken:_?.accessToken??null,refreshIntervalMs:p.watch?5*6e4:0,fetcher:e=>v.getVitals(y,{url:p.url,device:p.device,window:p.window},e),format:x,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`vitals`,{siteId:y}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);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};
@@ -1 +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
+ 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-BlA0FQ2P.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-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.
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-Cho9XZk0.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-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)});
2
+ import(`./init-CRxbEaBn.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.46",
3
+ "version": "0.1.48",
4
4
  "description": "Zenovay CLI — AI install wizard + full terminal analytics dashboard",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- import{ApiError as e}from"./api-CJnD6Auw.js";import{formatEvent as t}from"./formatter-DDG2TSOz.js";import{Panel as n}from"./panel-CYsRlDSL.js";import{Banner as r}from"./banner-Cr0PV2pB.js";import{Keybar as i}from"./keybar-Bh-y__tC.js";import{Box as a,Text as o,render as s,useApp as c,useInput as l}from"ink";import u,{useEffect as d,useMemo as f,useReducer as p,useRef as m}from"react";import h from"ink-spinner";function g(e,t){switch(t.type){case`set`:return{...e,data:t.data,status:`ready`,error:null};case`merge`:{let n=e.data?{...e.data,...t.partial}:t.partial;return{...e,data:n,status:`ready`,error:null}}case`error`:return{...e,status:`error`,error:{message:t.message,status:t.status,upgradeUrl:t.upgradeUrl}};case`refresh`:return{...e,refreshTick:e.refreshTick+1};case`focus`:return{...e,focusIndex:t.index};case`help-toggle`:return{...e,showHelp:!e.showHelp};default:return e}}async function _(e,n){let r=new AbortController,i=()=>r.abort();process.on(`SIGINT`,i);try{let i=await e.fetcher(r.signal);if(e.headlessEmit?e.headlessEmit(i,n):process.stdout.write(t(i,n)),e.streamer)for await(let i of e.streamer(r.signal))process.stdout.write(t(i,n));return 0}catch(e){if(e.name===`AbortError`)return 0;let t=e.message;return process.stderr.write(`${t}\n`),1}finally{process.off(`SIGINT`,i)}}const v=({cliVersion:e})=>u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:e,subtitle:`login required`}),u.createElement(n,{title:`Not logged in`,state:`warn`},u.createElement(o,null,`You need to authenticate before running this command.`),u.createElement(o,null,` `),u.createElement(o,{color:`gray`},`Run `),u.createElement(o,{color:`cyan`},`zenovay login`),u.createElement(o,{color:`gray`},` to start the device-flow.`)));function y(t){let{exit:s}=c(),[_,v]=p(g,{data:null,status:`loading`,error:null,refreshTick:0,focusIndex:0,showHelp:!1}),y=m(v);y.current=v;let b=f(()=>({q:{label:`quit`,handler:()=>{s(),t.onExit(0)}},r:{label:`refresh`,handler:()=>y.current({type:`refresh`})},"?":{label:`help`,handler:()=>y.current({type:`help-toggle`})}}),[s,t]),x=f(()=>({...t.keybindings??{},...b}),[t.keybindings,b]);if(l((e,n)=>{if(n.tab&&n.shift){v({type:`focus`,index:(_.focusIndex-1+t.panels.length)%t.panels.length});return}if(n.tab){v({type:`focus`,index:(_.focusIndex+1)%t.panels.length});return}if(e>=`1`&&e<=`9`){let n=Number(e)-1;n<t.panels.length&&v({type:`focus`,index:n});return}let r=x[e];r&&r.handler()}),d(()=>{let n=new AbortController,r=!1,i=async()=>{try{let e=await t.fetcher(n.signal);r||y.current({type:`set`,data:e})}catch(t){if(r)return;if(t instanceof e){if(t.status===402){let e=t.body,n=typeof e==`object`&&e&&`upgradeUrl`in e?e.upgradeUrl:void 0;y.current({type:`error`,message:`This command requires a higher plan.`,status:402,upgradeUrl:n});return}y.current({type:`error`,message:t.message,status:t.status});return}if(t.name===`AbortError`)return;y.current({type:`error`,message:t.message})}};i();let a=null,o=t.refreshIntervalMs??15e3;return o>0&&!t.streamer&&(a=setInterval(i,o)),()=>{r=!0,n.abort(),a&&clearInterval(a)}},[t.fetcher,t.refreshIntervalMs,t.streamer,_.refreshTick]),d(()=>{if(!t.streamer)return;let e=new AbortController,n=!1;return(async()=>{try{for await(let r of t.streamer(e.signal)){if(n)return;y.current({type:`merge`,partial:r})}}catch(e){if(n||e.name===`AbortError`)return;y.current({type:`error`,message:e.message})}})(),()=>{n=!0,e.abort()}},[t.streamer]),_.status===`loading`&&_.data===null)return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(n,{title:`Loading`,state:`busy`},u.createElement(a,null,u.createElement(o,{color:`magenta`},u.createElement(h,{type:`dots`})),u.createElement(o,null,` Fetching `,t.commandName,`…`))),u.createElement(i,{items:[{key:`q`,label:`quit`}]}));if(_.status===`error`&&_.error){let e=_.error.status===402;return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(n,{title:e?`Upgrade required`:`Error`,state:e?`warn`:`err`},u.createElement(o,{color:e?`yellow`:`red`},_.error.message),e&&_.error.upgradeUrl?u.createElement(u.Fragment,null,u.createElement(o,null,` `),u.createElement(o,{color:`gray`},`Upgrade: `),u.createElement(o,{color:`cyan`},_.error.upgradeUrl)):null),u.createElement(i,{items:[{key:`r`,label:`retry`},{key:`q`,label:`quit`}]}))}let S=_.data,C=Object.entries(x).map(([e,t])=>({key:e,label:t.label})),w=Math.ceil(t.panels.length/2),T=t.panels.slice(0,w),E=t.panels.slice(w);return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(a,{flexDirection:`row`},T.map((e,t)=>{let r=_.focusIndex===t;return u.createElement(a,{key:e.id,flexDirection:`column`,marginRight:1,flexGrow:1},u.createElement(n,{title:e.title,state:r?`busy`:`idle`},e.render(S,r)))})),E.length>0?u.createElement(a,{flexDirection:`row`},E.map((e,t)=>{let r=t+w,i=_.focusIndex===r;return u.createElement(a,{key:e.id,flexDirection:`column`,marginRight:1,flexGrow:1},u.createElement(n,{title:e.title,state:i?`busy`:`idle`},e.render(S,i)))})):null,_.showHelp?u.createElement(n,{title:`Help`,state:`idle`},Object.entries(x).map(([e,t])=>u.createElement(o,{key:e},`[`,e,`] `,t.label)),u.createElement(o,{color:`gray`},`[tab/shift+tab] cycle focus [1-9] focus panel`)):null,u.createElement(i,{items:C}))}async function b(e){return e.authToken===null?e.format?(process.stderr.write("Not logged in — run `zenovay login` first.\n"),2):new Promise(t=>{let{unmount:n}=s(u.createElement(v,{cliVersion:e.cliVersion}));setTimeout(()=>{n(),t(2)},50)}):e.format?_(e,e.format):new Promise(t=>{let{unmount:n}=s(u.createElement(y,{...e,onExit:e=>{n(),t(e)}}))})}export{b as runAnalyticalScreen};
@@ -1,2 +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{deepLinkFor as h,openInBrowser as g}from"./keybar-deep-link-AZ29NpWE.js";import{Box as _,Text as v,render as y,useApp as b,useInput as x}from"ink";import S,{useEffect as C,useState as w}from"react";import T from"ink-spinner";function E(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 D(e,t){return e.catch(e=>{if(E(e))throw e;return t})}async function O(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 A(c,u,`24h`);if(t.csv||t.tsv){let{writeCsv:n}=await import(`./csv-emit-BO_9WNzp.js`);return n(e.topPages,[`path`,`views`,`uniqueVisitors`,`avgTime`,`bounceRate`],t.tsv?`tsv`:`csv`)}if(t.ndjson){for(let t of e.topPages)process.stdout.write(JSON.stringify(t)+`
2
- `);return 0}return i({type:`overview.snapshot`,data:e}),0}catch(e){let{emitErrorEnvelope:n}=await import(`./error-codes-De8Cx8OK.js`);return n(e,{command:`analytics`,cliVersion:t.cliVersion})}return new Promise(e=>{let{unmount:n}=y(S.createElement(j,{api:c,siteId:u,siteLabel:f,cliVersion:t.cliVersion,onExit:t=>{n(),e(t)}}))})}function k(e){return e===`24h`?`7d`:e}async function A(e,t,n){let[r,i,a,o,s]=await Promise.all([D(e.getStats(t,n),null),D(e.getPages(t),[]),D(e.getSources(t,k(n),`prev`),null),D(e.getGeo(t),null),D(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 j=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=b(),[l,y]=w(null),[E,D]=w(!0),[O,k]=w(null),[j,M]=w(`24h`),[N,ee]=w(t),[P,F]=w(n),[I,L]=w(!1),[R,z]=w([]);x(async t=>{if(t===`o`||t===`O`){g(h(`overview`,{siteId:N}));return}if(t===`q`){a(),i(0);return}if(t===`1`){M(`24h`);return}if(t===`2`){M(`7d`);return}if(t===`3`){M(`30d`);return}if(t===`4`){M(`90d`);return}if(t===`s`){if(R.length===0)try{let t=await e.getSites();z(t)}catch{}L(e=>!e);return}}),C(()=>{let t=!1;return D(!0),(async()=>{try{let n=await A(e,N,j);t||(y(n),D(!1))}catch(e){t||(k(e.message),D(!1))}})(),()=>{t=!0}},[e,N,j]);let B=()=>S.createElement(o,{title:`Switch site`,state:`idle`},R.length===0?S.createElement(v,{color:`gray`},`Loading your sites…`):R.map(e=>S.createElement(_,{key:e.id},S.createElement(v,{color:e.id===N?`cyan`:`gray`},e.id===N?`› `:` `),S.createElement(v,{bold:e.id===N},e.name),S.createElement(v,{color:`gray`},` (`,e.url.replace(/^https?:\/\//,``).replace(/\/$/,``),`)`))),S.createElement(_,{marginTop:1},S.createElement(v,{color:`gray`},`Press `),S.createElement(v,{color:`cyan`},`[number]`),S.createElement(v,{color:`gray`},` to pick, `),S.createElement(v,{color:`cyan`},`[s]`),S.createElement(v,{color:`gray`},` to close.`)));x(e=>{if(!I)return;let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=R.length){let e=R[t-1];ee(e.id),F(e.url.replace(/^https?:\/\//,``).replace(/\/$/,``)),L(!1)}},{isActive:I});let V=`overview · ${P} · ${j}`,H=[{key:`q`,label:`quit`},{key:`o`,label:`open in browser`},{key:`s`,label:`site`},{key:`1-4`,label:`range (24h/7d/30d/90d)`}];if(E)return S.createElement(_,{flexDirection:`column`},S.createElement(s,{version:r,subtitle:V}),S.createElement(o,{title:`Loading`,state:`busy`},S.createElement(_,null,S.createElement(v,{color:`cyan`},S.createElement(T,{type:`dots`})),S.createElement(v,null,` Fetching dashboard…`))),I?B():null);if(O)return S.createElement(_,{flexDirection:`column`},S.createElement(s,{version:r,subtitle:V}),S.createElement(f,{reason:`error`,headline:`Failed to load`,hint:O}),I?B():null,S.createElement(c,{items:H}));if(!l||l.visitors===0&&l.pageviews===0&&l.topPages.length===0)return S.createElement(_,{flexDirection:`column`},S.createElement(s,{version:r,subtitle:V}),S.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.`}),I?B():null,S.createElement(c,{items:H}));let U=process.stdout.columns??80,W=Math.max(18,Math.floor(U/4)-1),G=Math.max(28,Math.floor(U/2)-2),K=[{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)}%`:`—`}],q=l.prevVisitors>0?(l.visitors-l.prevVisitors)/l.prevVisitors:void 0,J=l.prevPageviews>0?(l.pageviews-l.prevPageviews)/l.prevPageviews:void 0,Y=Math.max(1,...l.channels.map(e=>e.visitors)),X=Math.max(1,...l.countries.map(e=>e.visitors)),Z=Math.max(1,...l.browsers.map(e=>e.visitors)),Q=Math.max(1,...l.devices.map(e=>e.visitors)),$=Math.max(8,Math.floor(G/3));return S.createElement(_,{flexDirection:`column`},S.createElement(s,{version:r,subtitle:V}),S.createElement(_,{flexDirection:`row`},S.createElement(p,{title:`Visitors`,value:l.visitors,format:`number`,width:W,series:l.series,...typeof q==`number`?{delta:q}:{}}),S.createElement(p,{title:`Pageviews`,value:l.pageviews,format:`number`,width:W,series:l.pageviewsSeries,...typeof J==`number`?{delta:J}:{}}),S.createElement(p,{title:`Bounce rate`,value:l.bounceRate??``,emptyHint:`—`,format:`percent`,width:W}),S.createElement(p,{title:`Avg session`,value:l.avgSession??``,emptyHint:`—`,format:`duration`,width:W})),S.createElement(_,{flexDirection:`row`,flexWrap:`wrap`},S.createElement(_,{width:G,flexDirection:`column`},S.createElement(o,{title:`Channels`},l.channels.length===0?S.createElement(v,{color:`gray`},`No channel data yet.`):l.channels.map(e=>S.createElement(_,{key:e.name,flexDirection:`row`},S.createElement(_,{width:12},S.createElement(v,null,e.name)),S.createElement(m,{value:e.visitors,max:Y,width:$,showPercent:!1,...typeof e.delta==`number`?{delta:e.delta}:{}}),S.createElement(v,{color:`gray`},` `,e.visitors))))),S.createElement(_,{width:G,flexDirection:`column`},S.createElement(o,{title:`Top countries`},l.countries.length===0?S.createElement(v,{color:`gray`},`No geo data yet.`):l.countries.map(e=>S.createElement(_,{key:e.country,flexDirection:`row`},S.createElement(_,{width:5},S.createElement(v,null,e.country)),S.createElement(m,{value:e.visitors,max:X,width:$,showPercent:!1}),S.createElement(v,{color:`gray`},` `,e.visitors)))))),S.createElement(_,{flexDirection:`row`,flexWrap:`wrap`},S.createElement(_,{width:G,flexDirection:`column`},S.createElement(o,{title:`Top browsers`},l.browsers.length===0?S.createElement(v,{color:`gray`},`No browser data yet.`):l.browsers.map(e=>S.createElement(_,{key:e.name,flexDirection:`row`},S.createElement(_,{width:12},S.createElement(v,null,e.name)),S.createElement(m,{value:e.visitors,max:Z,width:$,showPercent:!1}),S.createElement(v,{color:`gray`},` `,e.visitors))))),S.createElement(_,{width:G,flexDirection:`column`},S.createElement(o,{title:`Top devices`},l.devices.length===0?S.createElement(v,{color:`gray`},`No device data yet.`):l.devices.map(e=>S.createElement(_,{key:e.name,flexDirection:`row`},S.createElement(_,{width:12},S.createElement(v,null,e.name)),S.createElement(m,{value:e.visitors,max:Q,width:$,showPercent:!1}),S.createElement(v,{color:`gray`},` `,e.visitors)))))),S.createElement(o,{title:`Top pages (${j})`},l.topPages.length===0?S.createElement(v,{color:`gray`},`No pages with data in this window yet.`):S.createElement(d,{columns:K,data:l.topPages,zebra:!0})),I?B():null,S.createElement(c,{items:H}))};async function M(e){return O(e)}export{M 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{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){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function m(e){return e==null?`—`:e>=500?`Enterprise`:e>=50?`Growth`:`SMB`}async function h(h){let g=await e(),_=await t({strict:!1}),v=new 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.window??`24h`,C=h.limit??100,w=[{key:`lastSeenAt`,label:`when`,width:6,format:e=>p(String(e))},{key:`name`,label:`company`,width:24,format:e=>String(e).slice(0,24)},{key:`employeeCount`,label:`tier`,width:11,format:e=>m(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 l({cliVersion:h.cliVersion,title:`companies · ${y} · ${S}`,commandName:`companies`,authToken:_?.accessToken??null,refreshIntervalMs:h.watch?3e4:0,fetcher:e=>v.getCompaniesSnapshot(y,{window:S,limit:C},e),format:x,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`companies`,{siteId:y}))}}},headlessEmit:(e,t)=>{let n=h.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 f.createElement(u,{flexDirection:`column`},f.createElement(d,null,f.createElement(d,{bold:!0},e.total),f.createElement(d,{color:`gray`},` companies in `,S)),f.createElement(d,{color:`gray`},f.createElement(d,{color:`green`},`● `,t,` new`),` · `,n,` enterprise`))}},{id:`feed`,title:`Feed`,render:e=>{let t=h.newOnly?e.companies.filter(e=>e.isNew):e.companies;return t.length===0?f.createElement(d,{color:`gray`},`— no `,h.newOnly?`new `:``,`companies in window —`):f.createElement(o,{data:t.slice(0,30),columns:w,headerStyle:`accent`})}}]})}export{h as companiesCommand};
@@ -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-gN9MJR34.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`}async function f(f){if(f.connect){let t=await e(),n=t.apiBase.replace(`api.zenovay.com`,`app.zenovay.com`),r=`${n}/settings/integrations/github`;return process.stdout.write(`\n Connect GitHub to Zenovay:\n ${r}\n\n Open this URL in your browser. Zenovay re-uses the same GitHub\n OAuth app you already authorized for login (auth-zenovay), so\n no separate "Zenovay Deploys" app is needed. Pick the repos you\n want to track and deploys will appear here automatically.\n\n`),0}let p=await e(),m=await t({strict:!1}),h=new n({config:p,cliVersion:f.cliVersion,token:m}),g,_;try{({siteId:g,site:_}=await a(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.limit??50,b=[{key:`pushed_at`,label:`when`,width:6,format:e=>d(String(e))},{key:`branch`,label:`branch`,width:14,format:e=>String(e??`—`).slice(0,14)},{key:`commit_sha`,label:`commit`,width:9,format:e=>String(e).slice(0,8)},{key:`commit_author`,label:`author`,width:16,format:e=>String(e??`—`).slice(0,16)},{key:`commit_message`,label:`message`,width:40,format:e=>String(e??`—`).slice(0,40)},{key:`show_on_chart`,label:`chart`,width:5,format:e=>e?`●`:`○`}];return s({cliVersion:f.cliVersion,title:`deploys · ${g}`,commandName:`deploys`,authToken:m?.accessToken??null,refreshIntervalMs:0,fetcher:e=>h.getDeploys(g,{branch:f.branch,since:f.since,limit:y},e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.deploys)process.stdout.write(JSON.stringify(t)+`
2
- `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(r(e.deploys,[`pushed_at`,`branch`,`commit_sha`,`commit_author`,`commit_message`,`repository`,`commit_url`,`show_on_chart`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>{let t=e.deploys.filter(e=>e.show_on_chart).length,n=new Set(e.deploys.map(e=>e.repository).filter(e=>!!e));return u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.total),u.createElement(l,{color:`gray`},` commits`,f.branch?` · branch=${f.branch}`:``)),u.createElement(l,{color:`gray`},u.createElement(l,{color:`magenta`},`● `,t,` on chart`),u.createElement(l,null,` · `),u.createElement(l,null,n.size,` `,n.size===1?`repo`:`repos`)))}},{id:`list`,title:`Recent`,render:e=>e.deploys.length===0?u.createElement(c,{flexDirection:`column`},u.createElement(l,{color:`gray`},`— no commits yet —`),u.createElement(l,{color:`gray`},"Run `zenovay deploys --connect` to wire up the GitHub integration.")):u.createElement(o,{data:e.deploys.slice(0,30),columns:b,headerStyle:`accent`})}]})}export{f as deploysCommand};
@@ -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{deepLinkFor as c,openInBrowser as l}from"./keybar-deep-link-AZ29NpWE.js";import{runAnalyticalScreen as u}from"./analytical-screen-gN9MJR34.js";import"./ui-CLpqz5_6.js";import{Box as d,Text as f}from"ink";import p from"react";function m(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}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`}async function g(g){let _=await e(),v=await t({strict:!1}),y=new n({config:_,cliVersion:g.cliVersion,token:v}),b,x;try{({siteId:b,site:x}=await o(y,{explicit:g.siteId,headless:!!(g.json||g.csv||g.tsv||g.ndjson),cliVersion:g.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let S=i(g),C=g.window??`24h`,w=g.limit??100,T=[{key:`ts`,label:`when`,width:6,format:e=>h(String(e))},{key:`class`,label:`class`,width:18,format:e=>String(e)},{key:`message`,label:`message`,width:42,format:e=>m(String(e??``),42)},{key:`page`,label:`page`,width:24,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:8,format:e=>String(e??`—`)}];return u({cliVersion:g.cliVersion,title:`errors · ${b} · ${C}`,commandName:`errors`,authToken:v?.accessToken??null,refreshIntervalMs:g.watch?3e4:0,fetcher:e=>y.getErrors(b,{window:C,limit:w},e),format:S,keybindings:{o:{label:`open in browser`,handler:()=>{l(c(`errors`,{siteId:b}))}}},headlessEmit:(e,t)=>{let n=g.search?e.errors.filter(e=>e.class.toLowerCase().includes(g.search.toLowerCase())||e.message.toLowerCase().includes(g.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=g.search?e.errors.filter(e=>e.class.toLowerCase().includes(g.search.toLowerCase())||e.message.toLowerCase().includes(g.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 p.createElement(d,{flexDirection:`column`},p.createElement(f,null,p.createElement(f,{bold:!0},t.length),p.createElement(f,{color:`gray`},` errors in `,C)),o.length===0?null:p.createElement(d,{flexDirection:`column`,marginTop:1},o.map(([e,t])=>p.createElement(f,{key:e},p.createElement(f,{color:`red`},e.padEnd(20).slice(0,20)),` `,p.createElement(f,{color:`gray`},a(t,30))))))}},{id:`table`,title:`Detail`,render:e=>{let t=g.search?e.errors.filter(e=>e.class.toLowerCase().includes(g.search.toLowerCase())||e.message.toLowerCase().includes(g.search.toLowerCase())):e.errors;return t.length===0?p.createElement(f,{color:`gray`},`— no errors `,g.search?`matching "${g.search}"`:`in window`,` —`):p.createElement(s,{data:t.slice(0,30),columns:T,headerStyle:`accent`})}}]})}export{g as errorsCommand};
@@ -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{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*t);return`█`.repeat(Math.max(0,Math.min(t,n)))+`░`.repeat(Math.max(0,t-n))}async function m(m){let g=await e(),_=await t({strict:!1}),v=new n({config:g,cliVersion:m.cliVersion,token:_}),y,b;try{({siteId:y,site:b}=await a(v,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let x=i(m);if(!m.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 l({cliVersion:m.cliVersion,title:`funnels · ${y}`,commandName:`funnels`,authToken:_?.accessToken??null,refreshIntervalMs:0,fetcher:e=>v.listFunnels(y,e),format:x,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`funnel`,{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.funnels,[`id`,`name`,`stepCount`],t))},panels:[{id:`funnels`,title:`Funnels`,render:t=>t.funnels.length===0?f.createElement(d,{color:`gray`},`— no funnels defined —`):f.createElement(o,{data:t.funnels,columns:e,headerStyle:`accent`})},{id:`hint`,title:`Next`,render:()=>f.createElement(d,{color:`gray`},"Run `zenovay funnel <id>` for drop-off detail.")}]})}let S=m.window??`30d`;return l({cliVersion:m.cliVersion,title:`funnel · ${m.funnelId} · ${S}`,commandName:`funnel`,authToken:_?.accessToken??null,refreshIntervalMs:0,fetcher:e=>v.getFunnel(y,m.funnelId,S,e),format:x,keybindings:{o:{label:`open in browser`,handler:()=>{c(s(`funnel`,{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(`
3
- `);return}process.stdout.write(r(e.steps,[`id`,`name`,`visitors`,`conversions`],t))},panels:[{id:`overview`,title:h(`Overview`),render:e=>f.createElement(u,{flexDirection:`column`},f.createElement(d,{bold:!0},e.name),f.createElement(d,{color:`gray`},e.totalEntries.toLocaleString(),` entries · `,e.totalCompletions.toLocaleString(),` completed (`,(e.conversionRate*100).toFixed(1),`%)`))},{id:`flow`,title:`Flow`,render:e=>{let t=e.totalEntries||1;return f.createElement(u,{flexDirection:`column`},e.steps.map((n,r)=>{let i=n.visitors/t,a=e.steps[r-1],o=a?a.visitors-n.visitors:0,s=a?o/Math.max(1,a.visitors)*100:0;return f.createElement(u,{key:n.id,flexDirection:`column`},a?f.createElement(d,{color:`red`},` `,`↓ drop `,o.toLocaleString(),` (`,s.toFixed(1),`%)`):null,f.createElement(d,null,f.createElement(d,{bold:!0},`${r+1}. ${n.name}`.padEnd(22).slice(0,22)),` `,f.createElement(d,{color:`magenta`},p(i,30)),` `,f.createElement(d,null,(i*100).toFixed(1).padStart(5),`% `),f.createElement(d,{color:`gray`},n.visitors.toLocaleString())))}))}}]})}function h(e){return e}export{m as funnelCommand};
@@ -1,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"./formatter-DDG2TSOz.js";import{emit as r,isHeadless as i}from"./emit-NkY7PE3R.js";import{Panel as a,useTheme 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{Bar as d}from"./bar-Cjia2R58.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useMemo as y,useRef as b,useState as x}from"react";import ee from"ink-spinner";import S from"open";const C={DZ:{lat:28.0339,lng:1.6596,name:`Algeria`,spread:8},EG:{lat:26.8206,lng:30.8025,name:`Egypt`,spread:6},ET:{lat:9.145,lng:40.4897,name:`Ethiopia`,spread:6},GH:{lat:7.9465,lng:-1.0232,name:`Ghana`,spread:3},KE:{lat:-.0236,lng:37.9062,name:`Kenya`,spread:4},MA:{lat:31.7917,lng:-7.0926,name:`Morocco`,spread:5},NG:{lat:9.082,lng:8.6753,name:`Nigeria`,spread:5},ZA:{lat:-30.5595,lng:22.9375,name:`South Africa`,spread:7},TZ:{lat:-6.369,lng:34.8888,name:`Tanzania`,spread:5},UG:{lat:1.3733,lng:32.2903,name:`Uganda`,spread:3},TN:{lat:33.8869,lng:9.5375,name:`Tunisia`,spread:3},SN:{lat:14.4974,lng:-14.4524,name:`Senegal`,spread:3},CI:{lat:7.54,lng:-5.5471,name:`Côte d'Ivoire`,spread:3},CM:{lat:7.3697,lng:12.3547,name:`Cameroon`,spread:4},AO:{lat:-11.2027,lng:17.8739,name:`Angola`,spread:6},MZ:{lat:-18.6657,lng:35.5296,name:`Mozambique`,spread:6},ZW:{lat:-19.0154,lng:29.1549,name:`Zimbabwe`,spread:4},ZM:{lat:-13.1339,lng:27.8493,name:`Zambia`,spread:5},RW:{lat:-1.9403,lng:29.8739,name:`Rwanda`,spread:1.5},MG:{lat:-18.7669,lng:46.8691,name:`Madagascar`,spread:5},LY:{lat:26.3351,lng:17.2283,name:`Libya`,spread:8},SD:{lat:12.8628,lng:30.2176,name:`Sudan`,spread:7},US:{lat:39.0902,lng:-98.5795,name:`United States`,spread:18},CA:{lat:56.1304,lng:-106.3468,name:`Canada`,spread:22},MX:{lat:23.6345,lng:-102.5528,name:`Mexico`,spread:9},BR:{lat:-10.235,lng:-51.9253,name:`Brazil`,spread:18},AR:{lat:-38.4161,lng:-63.6167,name:`Argentina`,spread:11},CL:{lat:-35.6751,lng:-71.543,name:`Chile`,spread:11},CO:{lat:4.5709,lng:-74.2973,name:`Colombia`,spread:6},PE:{lat:-9.19,lng:-75.0152,name:`Peru`,spread:7},VE:{lat:6.4238,lng:-66.5897,name:`Venezuela`,spread:6},EC:{lat:-1.8312,lng:-78.1834,name:`Ecuador`,spread:3},BO:{lat:-16.2902,lng:-63.5887,name:`Bolivia`,spread:6},UY:{lat:-32.5228,lng:-55.7658,name:`Uruguay`,spread:2.5},PY:{lat:-23.4425,lng:-58.4438,name:`Paraguay`,spread:4},GT:{lat:15.7835,lng:-90.2308,name:`Guatemala`,spread:2},CU:{lat:21.5218,lng:-77.7812,name:`Cuba`,spread:3},DO:{lat:18.7357,lng:-70.1627,name:`Dominican Republic`,spread:1.5},CR:{lat:9.7489,lng:-83.7534,name:`Costa Rica`,spread:1.2},PA:{lat:8.538,lng:-80.7821,name:`Panama`,spread:1.5},HN:{lat:15.2,lng:-86.2419,name:`Honduras`,spread:2},PR:{lat:18.2208,lng:-66.5901,name:`Puerto Rico`,spread:.6},JM:{lat:18.1096,lng:-77.2975,name:`Jamaica`,spread:.7},TT:{lat:10.6918,lng:-61.2225,name:`Trinidad and Tobago`,spread:.6},GB:{lat:55.3781,lng:-3.436,name:`United Kingdom`,spread:3},IE:{lat:53.4129,lng:-8.2439,name:`Ireland`,spread:2},FR:{lat:46.6034,lng:1.8883,name:`France`,spread:4},DE:{lat:51.1657,lng:10.4515,name:`Germany`,spread:3.5},IT:{lat:41.8719,lng:12.5674,name:`Italy`,spread:3.5},ES:{lat:40.4637,lng:-3.7492,name:`Spain`,spread:4},PT:{lat:39.3999,lng:-8.2245,name:`Portugal`,spread:2},NL:{lat:52.1326,lng:5.2913,name:`Netherlands`,spread:1.2},BE:{lat:50.5039,lng:4.4699,name:`Belgium`,spread:1},CH:{lat:46.8182,lng:8.2275,name:`Switzerland`,spread:1.4},AT:{lat:47.5162,lng:14.5501,name:`Austria`,spread:2},PL:{lat:51.9194,lng:19.1451,name:`Poland`,spread:3.5},CZ:{lat:49.8175,lng:15.473,name:`Czechia`,spread:1.8},SE:{lat:60.1282,lng:18.6435,name:`Sweden`,spread:5},NO:{lat:60.472,lng:8.4689,name:`Norway`,spread:5},FI:{lat:61.9241,lng:25.7482,name:`Finland`,spread:4},DK:{lat:56.2639,lng:9.5018,name:`Denmark`,spread:1.5},IS:{lat:64.9631,lng:-19.0208,name:`Iceland`,spread:3},GR:{lat:39.0742,lng:21.8243,name:`Greece`,spread:3},TR:{lat:38.9637,lng:35.2433,name:`Turkey`,spread:6},RO:{lat:45.9432,lng:24.9668,name:`Romania`,spread:3},HU:{lat:47.1625,lng:19.5033,name:`Hungary`,spread:2},UA:{lat:48.3794,lng:31.1656,name:`Ukraine`,spread:5},RU:{lat:61.524,lng:80,name:`Russia`,spread:28},BG:{lat:42.7339,lng:25.4858,name:`Bulgaria`,spread:2},HR:{lat:45.1,lng:15.2,name:`Croatia`,spread:2},RS:{lat:44.0165,lng:21.0059,name:`Serbia`,spread:2},SK:{lat:48.669,lng:19.699,name:`Slovakia`,spread:1.8},SI:{lat:46.1512,lng:14.9955,name:`Slovenia`,spread:1.2},LT:{lat:55.1694,lng:23.8813,name:`Lithuania`,spread:1.5},LV:{lat:56.8796,lng:24.6032,name:`Latvia`,spread:1.5},EE:{lat:58.5953,lng:25.0136,name:`Estonia`,spread:1.5},BY:{lat:53.7098,lng:27.9534,name:`Belarus`,spread:3},MD:{lat:47.4116,lng:28.3699,name:`Moldova`,spread:1.2},AL:{lat:41.1533,lng:20.1683,name:`Albania`,spread:1},MK:{lat:41.6086,lng:21.7453,name:`North Macedonia`,spread:1},BA:{lat:43.9159,lng:17.6791,name:`Bosnia and Herzegovina`,spread:1.2},ME:{lat:42.7087,lng:19.3744,name:`Montenegro`,spread:.8},XK:{lat:42.6026,lng:20.903,name:`Kosovo`,spread:.7},LU:{lat:49.8153,lng:6.1296,name:`Luxembourg`,spread:.4},MT:{lat:35.9375,lng:14.3754,name:`Malta`,spread:.3},CY:{lat:35.1264,lng:33.4299,name:`Cyprus`,spread:.6},CN:{lat:35.8617,lng:104.1954,name:`China`,spread:18},JP:{lat:36.2048,lng:138.2529,name:`Japan`,spread:5},KR:{lat:35.9078,lng:127.7669,name:`South Korea`,spread:2},IN:{lat:20.5937,lng:78.9629,name:`India`,spread:12},ID:{lat:-2.7893,lng:113.9213,name:`Indonesia`,spread:12},PH:{lat:12.8797,lng:121.774,name:`Philippines`,spread:5},VN:{lat:14.0583,lng:108.2772,name:`Vietnam`,spread:5},TH:{lat:15.87,lng:100.9925,name:`Thailand`,spread:4},MY:{lat:4.2105,lng:101.9758,name:`Malaysia`,spread:4},SG:{lat:1.3521,lng:103.8198,name:`Singapore`,spread:.3},PK:{lat:30.3753,lng:69.3451,name:`Pakistan`,spread:6},BD:{lat:23.685,lng:90.3563,name:`Bangladesh`,spread:3},LK:{lat:7.8731,lng:80.7718,name:`Sri Lanka`,spread:2},MM:{lat:21.9162,lng:95.956,name:`Myanmar`,spread:6},KH:{lat:12.5657,lng:104.991,name:`Cambodia`,spread:3},LA:{lat:19.8563,lng:102.4955,name:`Laos`,spread:3},NP:{lat:28.3949,lng:84.124,name:`Nepal`,spread:3},IR:{lat:32.4279,lng:53.688,name:`Iran`,spread:7},IQ:{lat:33.2232,lng:43.6793,name:`Iraq`,spread:4},IL:{lat:31.0461,lng:34.8516,name:`Israel`,spread:1},SA:{lat:23.8859,lng:45.0792,name:`Saudi Arabia`,spread:8},AE:{lat:23.4241,lng:53.8478,name:`UAE`,spread:2},QA:{lat:25.3548,lng:51.1839,name:`Qatar`,spread:.6},KW:{lat:29.3117,lng:47.4818,name:`Kuwait`,spread:.8},OM:{lat:21.4735,lng:55.9754,name:`Oman`,spread:4},JO:{lat:30.5852,lng:36.2384,name:`Jordan`,spread:2},LB:{lat:33.8547,lng:35.8623,name:`Lebanon`,spread:.7},SY:{lat:34.8021,lng:38.9968,name:`Syria`,spread:3},YE:{lat:15.5527,lng:48.5164,name:`Yemen`,spread:4},AF:{lat:33.9391,lng:67.71,name:`Afghanistan`,spread:5},KZ:{lat:48.0196,lng:66.9237,name:`Kazakhstan`,spread:13},UZ:{lat:41.3775,lng:64.5853,name:`Uzbekistan`,spread:5},TM:{lat:38.9697,lng:59.5563,name:`Turkmenistan`,spread:5},KG:{lat:41.2044,lng:74.7661,name:`Kyrgyzstan`,spread:3},TJ:{lat:38.861,lng:71.2761,name:`Tajikistan`,spread:3},AZ:{lat:40.1431,lng:47.5769,name:`Azerbaijan`,spread:2},GE:{lat:42.3154,lng:43.3569,name:`Georgia`,spread:2},AM:{lat:40.0691,lng:45.0382,name:`Armenia`,spread:1.2},HK:{lat:22.3193,lng:114.1694,name:`Hong Kong`,spread:.3},TW:{lat:23.6978,lng:120.9605,name:`Taiwan`,spread:1.5},AU:{lat:-25.2744,lng:133.7751,name:`Australia`,spread:18},NZ:{lat:-40.9006,lng:174.886,name:`New Zealand`,spread:5},PG:{lat:-6.314,lng:143.9555,name:`Papua New Guinea`,spread:5},FJ:{lat:-16.578,lng:179.4144,name:`Fiji`,spread:1}},w=Object.fromEntries(Object.entries(C).map(([e,t])=>[e,{lat:t.lat,lng:t.lng}]));function T(e){return!e||e.length!==2?null:C[e.toUpperCase()]??null}function E(e,t){let n=T(e);if(!n||t<=0)return[];let r=[],i=0;for(let t=0;t<e.length;t++)i=i*31+e.charCodeAt(t)>>>0;for(let e=0;e<t;e++){i=i+1831565813>>>0;let e=i;e=Math.imul(e^e>>>15,e|1)>>>0,e=(e^e+(Math.imul(e^e>>>7,e|61)>>>0))>>>0;let t=((e^e>>>14)>>>0)/4294967296;i=i+2246822507>>>0;let a=i;a=Math.imul(a^a>>>15,a|1)>>>0,a=(a^a+(Math.imul(a^a>>>7,a|61)>>>0))>>>0;let o=((a^a>>>14)>>>0)/4294967296,s=n.spread*Math.sqrt(t),c=o*2*Math.PI;r.push({lat:n.lat+s*Math.sin(c)*.7,lng:n.lng+s*Math.cos(c)/Math.max(.3,Math.cos(n.lat*Math.PI/180))})}return r}const D=360,O=180,k=new Uint8Array(D*O),A=new Uint8Array(D*O),j=[`__OCEAN__`];function M(e){let t=(e%360+360)%360;return Math.floor(t)}function N(e){return Math.max(0,Math.min(O-1,Math.floor(90-e)))}function P(e,t,n){let r=N(e),i=M(t);k[r*D+i]=1,A[r*D+i]=n}for(let e of Object.keys(C)){let t=C[e];j.push(e);let n=j.length-1,r=Math.max(.5,t.spread*.85),i=Math.max(.25,Math.cos(t.lat*Math.PI/180)),a=Math.max(.5,t.spread/i),o=Math.floor(t.lat-r),s=Math.ceil(t.lat+r),c=Math.floor(t.lng-a),l=Math.ceil(t.lng+a);for(let e=o;e<=s;e++)for(let i=c;i<=l;i++){let o=(e-t.lat)/r,s=(i-t.lng)/a;s*s+o*o>1||P(e,i,n)}}const F=new Uint8Array(k);for(let e=1;e<O-1;e++)for(let t=0;t<D;t++){if(k[e*D+t])continue;let n=0,r=0;for(let i=-1;i<=1;i++)for(let a=-1;a<=1;a++){if(i===0&&a===0)continue;let o=(t+a+D)%D;k[(e+i)*D+o]&&(n++,r||=A[(e+i)*D+o]??0)}n>=4&&(F[e*D+t]=1,A[e*D+t]=r)}k.set(F);const I=new Uint8Array(D*O);for(let e=0;e<O;e++)for(let t=0;t<D;t++){let n=A[e*D+t];if(!n)continue;let r=e>0?A[(e-1)*D+t]:0,i=e<O-1?A[(e+1)*D+t]:0,a=A[e*D+(t-1+D)%D],o=A[e*D+(t+1)%D];(r!==n||i!==n||a!==n||o!==n)&&(I[e*D+t]=1)}function L(e,t){if(e<-90||e>90)return 0;let n=Math.max(0,Math.min(O-1,Math.floor(90-e))),r=(t%360+360)%360,i=Math.floor(r);return k[n*D+i]===1?1:0}function R(e,t){if(e<-90||e>90)return 0;let n=Math.max(0,Math.min(O-1,Math.floor(90-e))),r=(t%360+360)%360,i=Math.floor(r);return I[n*D+i]===1?1:0}function z(e){return e*Math.PI/180}function B(e,t){let n=z(e),r=z(t);return{x:Math.cos(n)*Math.sin(r),y:Math.sin(n),z:Math.cos(n)*Math.cos(r)}}function V(e,t){let n=Math.cos(t),r=Math.sin(t);return{x:n*e.x+r*e.z,y:e.y,z:-r*e.x+n*e.z}}function H(e,t){let n=Math.cos(t),r=Math.sin(t);return{x:e.x,y:n*e.y-r*e.z,z:r*e.y+n*e.z}}function U(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function W(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function G(e,t,n,r){let i=r*r;for(let a=-r;a<=r;a++)for(let o=-r;o<=r;o++)o*o+a*a<=i&&W(e,Math.round(t+o),Math.round(n+a))}const K=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function q(e,t,n){let r=0;for(let i=0;i<K.length;i++){let[a,o]=K[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function J(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`·`:r<=5?`○`:`●`}function Y(e){if(e)return!0;let t=process.env;if(t.NO_COLOR||t.ZENOVAY_GLOBE===`ascii`)return!0;let n=(t.LANG||t.LC_ALL||t.LC_CTYPE||``).toLowerCase();return!!(n&&!n.includes(`utf`))}function X(e,t,n){if(e.z<0)return null;let r=t/2,i=n/2,a=Math.min(t,n/2)*.95;return{x:r+e.x*a,y:i-e.y*a}}function Z(e){let t=e.dw/2,n=e.dh/2,r=Math.min(e.dw,e.dh/2)*.95,i=Math.round(2*Math.PI*r);for(let a=0;a<i;a++){let o=a/i*2*Math.PI,s=Math.round(t+r*Math.cos(o)),c=Math.round(n+r*Math.sin(o));W(e,s,c)}}function te(e,t,n){for(let r of[-60,-30,0,30,60])for(let i=-180;i<=180;i+=4){let a=H(V(B(r,i),t),n),o=X(a,e.dw,e.dh);o&&W(e,Math.round(o.x),Math.round(o.y))}for(let r=-180;r<180;r+=30)for(let i=-85;i<=85;i+=4){let a=H(V(B(i,r),t),n),o=X(a,e.dw,e.dh);o&&W(e,Math.round(o.x),Math.round(o.y))}}function ne({visitors:e,highlight:t,width:n=50,height:r=25,rotationDeg:i=0,tiltDeg:a=20,gridlines:s=!0,asciiOnly:c}){let{theme:l}=o(),u=Y(c),d=U(n,r),m=U(n,r),h=U(n,r),g=U(n,r),v=U(n,r),y=z(i),b=z(-a);Z(d),s&&te(d,y,b);{let e=m.dw/2,t=m.dh/2,n=Math.min(m.dw,m.dh/2)*.95,r=Math.cos(y),i=Math.sin(y),a=Math.cos(b),o=Math.sin(b);for(let s=0;s<m.dh;s++){let c=(t-s)/n;if(!(c<-1||c>1))for(let t=0;t<m.dw;t++){let l=(t-e)/n,u=l*l+c*c;if(u>1)continue;let d=Math.sqrt(1-u),f=l,p=c,g=a*p+o*d,_=-o*p+a*d,v=r*f-i*_,y=i*f+r*_,b=Math.asin(g)*(180/Math.PI),x=Math.atan2(v,y)*(180/Math.PI);L(b,x)&&(W(m,t,s),R(b,x)&&W(h,t,s))}}}for(let t of e){let e=H(V(B(t.lat,t.lng),y),b),n=X(e,g.dw,g.dh);if(!n)continue;let r=typeof t.freshness==`number`?t.freshness:.5;G(g,n.x,n.y,r>.7?2:1)}if(t&&t.length>0)for(let e of t){let t=H(V(B(e.lat,e.lng),y),b),n=X(t,v.dw,v.dh);if(!n)continue;G(v,n.x,n.y,2)}let x=[];for(let e=0;e<r;e++){let t=[],r=null,i=(e,n)=>{r&&r.color===e?r.text+=n:(r={color:e,text:n},t.push(r))};for(let r=0;r<n;r++){let n=u?J(v,r,e):q(v,r,e);if(n!==` `){i(l.warn,n);continue}let a=u?J(g,r,e):q(g,r,e);if(a!==` `){i(l.accent,a);continue}let o=u?J(h,r,e):q(h,r,e);if(o!==` `){i(l.fg,o);continue}let s=u?J(m,r,e):q(m,r,e);if(s!==` `){i(l.success,s);continue}let c=u?J(d,r,e):q(d,r,e);if(c!==` `){i(l.muted,c);continue}let f=t.length>0?t[t.length-1]:void 0;i(f?f.color:l.muted,` `)}x.push(_.createElement(f,{key:e},_.createElement(p,null,t.map((e,t)=>_.createElement(p,{key:t,color:e.color,bold:!0},e.text)))))}return _.createElement(f,{flexDirection:`column`},x)}async function Q(e,t,n){let r=await e.getGeo(t).catch(()=>({countries:[],cities:[]})),i=(r.countries??[]).map(e=>{let t=T(e.country),r=n.get(e.country)??0;return{code:e.country,visitors:e.visitors,lat:t?.lat,lng:t?.lng,freshness:e.visitors>r?1:.4}});return{countries:i,totalVisitors:i.reduce((e,t)=>e+t.visitors,0),unknownCount:i.filter(e=>typeof e.lat!=`number`).reduce((e,t)=>e+t.visitors,0),lastFetchedAt:Date.now()}}async function re(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await l(c,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(a.browser){let e=`https://app.zenovay.com/domains/${encodeURIComponent(u)}?tab=globe`;a.json?process.stdout.write(JSON.stringify({openedUrl:e})+`
2
- `):process.stdout.write(`\n Opening Mapbox globe in your default browser:\n ${e}\n\n`);try{await S(e)}catch{}return 0}if(i(a)){let e=await Q(c,u,new Map);return r({type:`globe.snapshot`,data:{countries:e.countries,total:e.totalVisitors,unknownCount:e.unknownCount}}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement($,{api:c,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const ie=5e3,ae=60,oe=1,se=80,$=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:l}=h(),{theme:m}=o(),[C,w]=x(null),[D,O]=x(!0),[k,A]=x(null),[j,M]=x(0),[N,P]=x(!1),[F,I]=x(20),[L,R]=x(1),[z,B]=x(0),V=b(new Map);g(n=>{if(n===`q`){l(),i(0);return}if(n===` `){P(e=>!e);return}if(n===`+`||n===`=`){R(e=>Math.min(1.6,e+.1));return}if(n===`-`||n===`_`){R(e=>Math.max(.7,e-.1));return}if(n===`t`){I(e=>(e+15)%60);return}if(n===`j`){B(e=>e+1);return}if(n===`k`){B(e=>Math.max(0,e-1));return}if(n===`w`){let e=`https://app.zenovay.com/domains/${encodeURIComponent(t)}?tab=globe`;S(e).catch(()=>{});return}if(n===`o`&&C){let e=C.countries[z];e?.lng!==void 0&&(M(-e.lng),P(!0));return}n===`r`&&(async()=>{try{let n=await Q(e,t,V.current);V.current=new Map(n.countries.map(e=>[e.code,e.visitors])),w(n)}catch(e){A(e.message)}})()}),v(()=>{let n=!1,r=null,i=async()=>{try{let r=await Q(e,t,V.current);if(n)return;V.current=new Map(r.countries.map(e=>[e.code,e.visitors])),w(r),O(!1)}catch(e){n||(A(e.message),O(!1))}n||(r=setTimeout(i,ie))};return i(),()=>{n=!0,r&&clearTimeout(r)}},[e,t]),v(()=>{if(N)return;let e=setInterval(()=>{M(e=>(e+oe)%360)},ae);return()=>clearInterval(e)},[N]);let H=y(()=>{if(!C)return[];let e=[];for(let t of C.countries){if(typeof t.lat!=`number`||typeof t.lng!=`number`)continue;let n=Math.min(se,Math.max(3,t.visitors*5));for(let r of E(t.code,n))e.push({lat:r.lat,lng:r.lng,freshness:t.freshness})}return e},[C]),U=y(()=>{if(!C)return[];let e=C.countries[Math.min(z,C.countries.length-1)];return!e||typeof e.lat!=`number`?[]:E(e.code,Math.min(80,Math.max(8,e.visitors*4)))},[C,z]),W=`globe · ${n} · live`,G=[{key:`q`,label:`quit`},{key:`j/k`,label:`select country`},{key:`o`,label:`orbit to selected`},{key:`space`,label:N?`resume`:`pause`},{key:`t`,label:`tilt ${F}°`},{key:`+/-`,label:`zoom`},{key:`w`,label:`open Mapbox view in browser`},{key:`r`,label:`refresh`}];if(D)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),_.createElement(a,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`cyan`},_.createElement(ee,{type:`dots`})),_.createElement(p,null,` Spinning up Earth…`))));if(k)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),_.createElement(u,{reason:`error`,headline:`Failed to load`,hint:k}),_.createElement(c,{items:G}));if(!C||C.countries.length===0&&C.unknownCount===0)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),_.createElement(u,{reason:`no-data`,headline:`No geolocated visitors yet`,hint:`Visit your site to populate the map.`}),_.createElement(c,{items:G}));let K=process.stdout.columns??100,q=36,J=Math.max(40,Math.min(90,K-q-4)),Y=Math.round(J*L),X=Math.round(Y*.5),Z=C.countries.slice(0,12),te=Math.max(1,...Z.map(e=>e.visitors)),re=Math.max(1,Math.floor((Date.now()-C.lastFetchedAt)/1e3)),$=C.countries[Math.min(z,C.countries.length-1)],ce=$?T($.code):null;return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),$?_.createElement(f,{flexDirection:`row`,marginBottom:1},_.createElement(f,{width:2}),_.createElement(f,{borderStyle:`round`,borderColor:m.warn,paddingX:1},_.createElement(p,{color:m.warn,bold:!0},ce?.name??$.code),_.createElement(p,{color:m.dim},` · `),_.createElement(p,{color:m.fg},$.visitors,` visitor`,$.visitors===1?``:`s`))):null,_.createElement(f,{flexDirection:`row`},_.createElement(f,{flexDirection:`column`,marginRight:2},_.createElement(ne,{visitors:H,highlight:U,width:Y,height:X,rotationDeg:j,tiltDeg:F}),_.createElement(f,{marginTop:1},_.createElement(p,{color:m.dim},C.totalVisitors,` visitors · `,C.countries.length,` countries`,C.unknownCount>0?` · ${C.unknownCount} unmapped`:``,` · `,N?`rotation paused`:`↻ ${oe}°/${ae}ms`,` · refreshed `,re,`s ago`))),_.createElement(f,{flexDirection:`column`,width:q},_.createElement(a,{title:`Live by country`},Z.map((e,t)=>{let n=t===Math.min(z,C.countries.length-1),r=e.freshness>.7,i=n?m.warn:r?m.success:m.fg;return _.createElement(f,{key:e.code,flexDirection:`row`},_.createElement(f,{width:2},_.createElement(p,{color:m.warn},n?`›`:` `)),_.createElement(f,{width:3},_.createElement(p,{color:i,bold:n},e.code)),_.createElement(d,{value:e.visitors,max:te,width:14,showPercent:!1}),_.createElement(f,{width:6},_.createElement(p,{color:m.muted},String(e.visitors).padStart(5))))})),C.countries.length>12?_.createElement(f,{marginTop:1},_.createElement(p,{color:m.muted},`+`,C.countries.length-12,` more (j/k to scroll)`)):null)),_.createElement(c,{items:G}))};export{re as globeCommand};
@@ -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{deepLinkFor as d,openInBrowser as f}from"./keybar-deep-link-AZ29NpWE.js";import{Globe as p}from"./globe-Cc-yuiNd.js";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";async function C(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getLive(u);return r({type:`live.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(w,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=_(),[g,C]=x(null),[w,T]=x(!0),[E,D]=x(null);if(v(e=>{if(e===`o`||e===`O`){f(d(`live`,{siteId:t}));return}e===`q`&&(c(),i(0))}),b(()=>{let n=!1,r=async()=>{try{let r=await e.getLive(t);n||(C(r),T(!1),D(null))}catch(e){n||(D(e.message),T(!1))}};r();let i=setInterval(r,2e3);return()=>{n=!0,clearInterval(i)}},[e,t]),w)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:`live · ${n}`}),y.createElement(a,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Connecting…`))));if(E&&!g)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:`live · ${n}`}),y.createElement(l,{reason:`error`,headline:`Failed to load`,hint:E}));let O=process.stdout.columns??80,k=Math.max(20,Math.min(40,Math.floor(O/3)));return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:`live · ${n}`}),y.createElement(m,{flexDirection:`row`},y.createElement(u,{title:`Active now`,value:g?.activeVisitors??0,format:`number`,width:k}),y.createElement(a,{title:`Globe`,width:Math.max(40,O-k-4)},y.createElement(p,{data:[],width:Math.max(36,O-k-10),height:10}))),y.createElement(a,{title:`Recent events`},!g||g.recentEvents.length===0?y.createElement(h,{color:`gray`},`— waiting for events —`):g.recentEvents.slice(0,15).map((e,t)=>y.createElement(m,{key:t},y.createElement(h,{color:`cyan`},(e.type??`pageview`).padEnd(10)),y.createElement(h,null,e.path.padEnd(36).slice(0,36)),y.createElement(h,{color:`gray`},e.country??`—`)))),y.createElement(s,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{C as liveCommand};
@@ -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-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
- `);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,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{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,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{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 +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-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
- `);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,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{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};
@@ -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{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};
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes