@zenovay/cli 0.1.64 → 0.1.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agency-C69JHza5.js → agency-BxYMejNb.js} +1 -1
- package/dist/ai-Vpr5B5_M.js +1 -0
- package/dist/alerts-DKQa_K77.js +3 -0
- package/dist/analytical-screen-B_wWUnT4.js +2 -0
- package/dist/analytics-BO22Zeas.js +2 -0
- package/dist/{annotation-BuwTxCIH.js → annotation-CL1q8mjr.js} +1 -1
- package/dist/{api-keys-CHRLCfrl.js → api-keys-lfjOVUIe.js} +1 -1
- package/dist/{api-v2-CI5hxW-O.js → api-v2-CPUUcP1i.js} +1 -1
- package/dist/{api-v2-CTc_U2Gw.js → api-v2-D9N_2hdW.js} +1 -1
- package/dist/{audit-Demn5lBp.js → audit-DfKQdrug.js} +3 -4
- package/dist/banner-DdgwXGzt.js +1 -0
- package/dist/{bar-DWT-1xOE.js → bar-C1Zrfe9H.js} +1 -1
- package/dist/bin.js +6 -5
- package/dist/chat-panel-ZlKZ0W6J.js +7 -0
- package/dist/{commands-BX5I2UyT.js → commands-NsH5CS-H.js} +1 -1
- package/dist/companies-CtZ2vGQs.js +2 -0
- package/dist/{completions-CaYLmArp.js → completions-Bem7-lcb.js} +1 -1
- package/dist/csv-emit-BWWv60mT.js +1 -0
- package/dist/csv-emit-CVO5kebZ.js +1 -0
- package/dist/{data-table-BpbyyNSA.js → data-table-DJzT7bAr.js} +1 -1
- package/dist/deploys-CUbSa8S5.js +2 -0
- package/dist/devices-CrkIxfde.js +2 -0
- package/dist/{doctor-C1O4DlbQ.js → doctor-D5HWdhgv.js} +5 -5
- package/dist/{domains-BCDiOFYb.js → domains-V4sD09io.js} +1 -1
- package/dist/{emit-DBYk96TD.js → emit-C9vAopcy.js} +1 -1
- package/dist/{empty-state-CJxa1jUN.js → empty-state-DbToIL5T.js} +1 -1
- package/dist/errors-D3fS1kYu.js +2 -0
- package/dist/events-tail-DGRZewwc.js +5 -0
- package/dist/export-FjEyji8r.js +4 -0
- package/dist/funnel-C7DmrdUC.js +3 -0
- package/dist/geo-C9OcRStg.js +2 -0
- package/dist/{globe-C_m7zGZM.js → globe-PiPL3Bei.js} +2 -2
- package/dist/{goals-OQ1s7Vhq.js → goals-CVRryIri.js} +1 -1
- package/dist/health-DMiTjQ9Z.js +2 -0
- package/dist/health-vxoiMF8G.js +1 -0
- package/dist/heatmaps-G3Nf95tV.js +1 -0
- package/dist/home-CXwRtMge.js +2 -0
- package/dist/init-CNwLaGfm.js +1 -0
- package/dist/init-C_I6rfNw.js +79 -0
- package/dist/insights-J99-8Rcu.js +1 -0
- package/dist/integrations-CWPrMJfZ.js +10 -0
- package/dist/journeys-BLxqoeFu.js +1 -0
- package/dist/{keybar-DsYTkKZX.js → keybar-QgnmSion.js} +1 -1
- package/dist/keybar-deep-link-DbmPjAEz.js +1 -0
- package/dist/live-CWSLgkC2.js +1 -0
- package/dist/login-DPaqczTC.js +1 -0
- package/dist/login-DuKqHRot.js +2 -0
- package/dist/{logout-eXZJMigi.js → logout-BkeT6Hke.js} +1 -1
- package/dist/{metric-card-COEIZmbN.js → metric-card-bQ-j_G6l.js} +1 -1
- package/dist/{notes-DUqpXghJ.js → notes-C8cba6QA.js} +1 -1
- package/dist/open-url-BxXbZzWS.js +1 -0
- package/dist/pages-CKs5X38q.js +2 -0
- package/dist/panel-B-XxdP-N.js +1 -0
- package/dist/{plans-CNWFx-qt.js → plans-oxxMSOdB.js} +5 -5
- package/dist/{profile-CZm-_uy-.js → profile-CD9QVZ2I.js} +1 -1
- package/dist/progress-row-5ns2IsFh.js +3 -0
- package/dist/projects-hIQqeDYq.js +2 -0
- package/dist/{prompt-D-Uzz_GF.js → prompt-B4s3o9G7.js} +1 -1
- package/dist/query-BLHvu1IF.js +8 -0
- package/dist/resolve-site-DQVcWhjG.js +2 -0
- package/dist/retention-B8bgiVux.js +1 -0
- package/dist/revenue-BiViSloE.js +2 -0
- package/dist/secrets-M60NENIa.js +1 -0
- package/dist/self-test-CSST_zHj.js +16 -0
- package/dist/sessions-lUUiiNYc.js +1 -0
- package/dist/{settings-CTbX2BXa.js → settings-CFFiWmGO.js} +1 -1
- package/dist/{share-BG5ipcQi.js → share-Cx62AEP-.js} +1 -1
- package/dist/sources-D-KqX0Sg.js +2 -0
- package/dist/stats-BzTqFpJL.js +2 -0
- package/dist/{status-agent-Dej6dGvX.js → status-agent-TIyEIKOj.js} +2 -2
- package/dist/{team-B1qfFxKA.js → team-BRebgNMO.js} +1 -1
- package/dist/{teams-BzLZoKsj.js → teams-DhrkUkt8.js} +1 -1
- package/dist/theme-BuGrQHax.js +1 -0
- package/dist/themes-gluHmb6E.js +4 -0
- package/dist/{tour-Bwbv_E4Q.js → tour-STZ66G7K.js} +1 -1
- package/dist/ui-whccLLRv.js +1 -0
- package/dist/{update-BDMLrzzb.js → update-BCgHj5O4.js} +1 -1
- package/dist/uptime-CwG6bqir.js +1 -0
- package/dist/{usage-kXVWbunU.js → usage-BFCTeA8E.js} +1 -1
- package/dist/{use-B8cSIrZL.js → use-baQFldqI.js} +1 -1
- package/dist/visitors-BtriXh9k.js +2 -0
- package/dist/vitals-BgAwONID.js +2 -0
- package/dist/watch-Cv4FtwSJ.js +1 -0
- package/dist/{webhooks-BhZkT0SX.js → webhooks-PRWhMVgS.js} +1 -1
- package/dist/webhooks-forward-BDxi2TcF.js +3 -0
- package/dist/wizard-bin.js +1 -1
- package/dist/ws-client-BZMMGeRe.js +1 -0
- package/package.json +20 -20
- package/dist/ai-CPogCNEQ.js +0 -7
- package/dist/alerts-DWVCFKlS.js +0 -3
- package/dist/analytical-screen-BasvNR-9.js +0 -1
- package/dist/analytics-C7mAE3gV.js +0 -2
- package/dist/banner-3iSWTDFy.js +0 -1
- package/dist/chat-panel-CqJaCIg3.js +0 -7
- package/dist/companies-DEdYd-bV.js +0 -2
- package/dist/csv-emit-BuRZNWYM.js +0 -1
- package/dist/csv-emit-Dn3c0RCG.js +0 -1
- package/dist/deploys-DTIU1Kqt.js +0 -2
- package/dist/devices-DK_o0JcI.js +0 -2
- package/dist/errors-Dig3nVCV.js +0 -2
- package/dist/events-tail-u_lwZas2.js +0 -5
- package/dist/export-DkAIRS9F.js +0 -4
- package/dist/funnel-Brtq8avo.js +0 -3
- package/dist/geo-c9hA42_9.js +0 -2
- package/dist/health-B5DBRP3C.js +0 -1
- package/dist/health-BttlLZWZ.js +0 -2
- package/dist/heatmaps-BPxqgMmV.js +0 -1
- package/dist/home-DGrXLbbO.js +0 -2
- package/dist/init-BIJkCrgc.js +0 -79
- package/dist/init-BhfcLbDE.js +0 -1
- package/dist/insights-CrUKfMD5.js +0 -1
- package/dist/integrations-S-9EITZH.js +0 -10
- package/dist/journeys-BbySeXM2.js +0 -1
- package/dist/keybar-deep-link-DC31T3CP.js +0 -1
- package/dist/live-dcM0RwGp.js +0 -1
- package/dist/login-DgU__egg.js +0 -1
- package/dist/login-yhuXiFqh.js +0 -2
- package/dist/pages-Bk5gbJ2v.js +0 -1
- package/dist/panel-B_yDcIcn.js +0 -1
- package/dist/progress-row-BpAXjJPL.js +0 -3
- package/dist/projects-BOU9sd2x.js +0 -2
- package/dist/query-CFNNsz6m.js +0 -8
- package/dist/resolve-site-mj0esTrm.js +0 -2
- package/dist/retention-CYDhYbyf.js +0 -1
- package/dist/revenue-D8uN4mjW.js +0 -2
- package/dist/secrets-c-NB_plk.js +0 -1
- package/dist/self-test-Cc5PWB08.js +0 -16
- package/dist/sessions-DqTjJFcP.js +0 -1
- package/dist/sources-D0FxjzeB.js +0 -2
- package/dist/stats-DmkvUylD.js +0 -2
- package/dist/themes-Dqt--qhd.js +0 -4
- package/dist/ui-Cey-h6wI.js +0 -1
- package/dist/uptime-CNGVODGc.js +0 -1
- package/dist/visitors-D7Q6chjq.js +0 -2
- package/dist/vitals-DmMAuIdP.js +0 -2
- package/dist/watch-D5WeMSz2.js +0 -1
- package/dist/webhooks-forward-D9PZDQ77.js +0 -3
- package/dist/wrapper-Dl9i0Nh7.js +0 -6
- package/dist/ws-client-MoEdfqAO.js +0 -1
- /package/dist/{client-DTXWADkX.js → client-Dm8uGVCy.js} +0 -0
- /package/dist/{confirm-DS5wux0g.js → confirm-CIdxMt7N.js} +0 -0
- /package/dist/{examples-BtWVpY-G.js → examples-CFatZcPz.js} +0 -0
- /package/dist/{fmt-gMsty5jy.js → fmt-xxIPQJX-.js} +0 -0
- /package/dist/{formatter-DutfcQAc.js → formatter-DDG2TSOz.js} +0 -0
- /package/dist/{secrets-ApB7yh2A.js → secrets-DPf_7SkN.js} +0 -0
- /package/dist/{sparkline-BZ0eMB-w.js → sparkline-CpoBjjlc.js} +0 -0
- /package/dist/{telemetry--Yk0J5zc.js → telemetry-DC0Jw3JD.js} +0 -0
- /package/dist/{tier-BneaO4vD.js → tier-C4q8fJ8m.js} +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./client-Dm8uGVCy.js";import{openInBrowser as a}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{useTheme as o}from"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import"./chat-panel-ZlKZ0W6J.js";import{resolveSiteId as s}from"./resolve-site-DQVcWhjG.js";import{DataTable as c}from"./data-table-DJzT7bAr.js";import{deepLinkFor as l}from"./keybar-deep-link-DbmPjAEz.js";import{runAnalyticalScreen as u}from"./analytical-screen-B_wWUnT4.js";import{Box as d,Text as f}from"ink";import p from"react";function m(e,t){let n=Math.round(e/100*t);return`█`.repeat(n)+`░`.repeat(Math.max(0,t-n))}function h(e){return e==null?{glyph:`·`,tone:`neutral`}:e>.5?{glyph:`▲`,tone:`up`}:e<-.5?{glyph:`▼`,tone:`down`}:{glyph:`→`,tone:`neutral`}}function g({data:e}){let{theme:t}=o();return p.createElement(f,null,p.createElement(f,{bold:!0},e.totalVisitors.toLocaleString()),` `,p.createElement(f,{color:t.muted},`visitors · `,e.sources.length,` sources`))}function _({data:e}){let{theme:t}=o();if(e.sources.length===0)return p.createElement(f,{color:t.muted},`— no source data —`);let n={up:t.success,down:t.accent2,neutral:t.muted},r=e.totalVisitors||1,i=[...e.sources].sort((e,t)=>t.visitors-e.visitors).slice(0,12);return p.createElement(d,{flexDirection:`column`},i.map((e,i)=>{let a=e.visitors/r*100,o=h(e.delta);return p.createElement(d,{key:`${e.source}-${i}`},p.createElement(f,null,p.createElement(f,{color:t.accent},e.source.padEnd(20).slice(0,20)),` `,p.createElement(f,{color:t.accent},m(a,30)),` `,p.createElement(f,null,e.visitors.toString().padStart(6),` `),p.createElement(f,{color:t.muted},`(`,a.toFixed(1),`%)`),` `,p.createElement(f,{color:n[o.tone]},o.glyph)))}))}function v({data:e,columns:t}){let{theme:n}=o();return e.sources.length===0?p.createElement(f,{color:n.muted},`— —`):p.createElement(c,{data:e.sources.slice(0,20),columns:t,headerStyle:`accent`})}async function y(o){let c=await e(),d=await t({strict:!1}),f=new n({config:c,cliVersion:o.cliVersion,token:d}),m,h;try{({siteId:m,site:h}=await s(f,{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 y=i(o),b=o.period??`30d`,x=[{key:`source`,label:`source`,width:22},{key:`channel`,label:`channel`,width:10,format:e=>String(e??`—`)},{key:`visitors`,label:`visitors`,width:8,align:`right`},{key:`delta`,label:`Δ`,width:6,align:`right`,format:e=>typeof e==`number`?`${e>0?`+`:``}${(e*100).toFixed(1)}%`:`—`}];return u({cliVersion:o.cliVersion,title:`sources · ${m} · ${b}`,commandName:`sources`,authToken:d?.accessToken??null,refreshIntervalMs:6e4,fetcher:e=>f.getSources(m,b,o.compare,e),format:y,ai:{api:f,siteId:m,siteLabel:h?.url?h.url.replace(/^https?:\/\//,``).replace(/\/$/,``):h?.name??m},keybindings:{o:{label:`open in browser`,handler:()=>{a(l(`sources`,{siteId:m}))}}},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=>p.createElement(g,{data:e})},{id:`channels`,title:`By channel`,render:e=>p.createElement(_,{data:e})},{id:`table`,title:`Detail`,render:e=>p.createElement(v,{data:e,columns:x})}]})}export{y as sourcesCommand};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./client-Dm8uGVCy.js";import"./theme-BuGrQHax.js";import{useTheme as a}from"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import"./chat-panel-ZlKZ0W6J.js";import{resolveSiteId as o}from"./resolve-site-DQVcWhjG.js";import{DataTable as s}from"./data-table-DJzT7bAr.js";import{runAnalyticalScreen as c}from"./analytical-screen-B_wWUnT4.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e){return`${(e*100).toFixed(1)}%`}function p(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.floor(e/60)}m ${Math.round(e%60)}s`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}const m=({data:e})=>{let{theme:t}=a();return d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},e.visitors.toLocaleString()),d.createElement(u,{color:t.muted},` visitors `),d.createElement(u,{bold:!0},e.pageviews.toLocaleString()),d.createElement(u,{color:t.muted},` pageviews `),d.createElement(u,{bold:!0},e.sessions.toLocaleString()),d.createElement(u,{color:t.muted},` sessions`)),d.createElement(u,{color:t.muted},`bounce `,f(e.bounceRate),` · avg session `,p(e.avgSessionSec)))},h=({label:e})=>{let{theme:t}=a();return d.createElement(u,{color:t.dim},e)};async function g(a){let l=await e(),u=await t({strict:!1}),g=new n({config:l,cliVersion:a.cliVersion,token:u}),_,v;try{({siteId:_,site:v}=await o(g,{explicit:a.siteId,headless:!!(a.json||a.csv||a.tsv||a.ndjson),cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(a),b=a.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 c({cliVersion:a.cliVersion,title:`stats · ${_} · ${b}`,commandName:`stats`,ai:{api:g,siteId:_,siteLabel:v?.url?v.url.replace(/^https?:\/\//,``).replace(/\/$/,``):v?.name??_},authToken:u?.accessToken??null,refreshIntervalMs:a.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:f(e.bounceRate),avgSession:p(e.avgSessionSec)}],[`range`,`visitors`,`pageviews`,`sessions`,`bounceRate`,`avgSession`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>d.createElement(m,{data:e})},{id:`pages`,title:`Top pages`,render:e=>e.topPages.length===0?d.createElement(h,{label:`— no pages —`}):d.createElement(s,{data:e.topPages.slice(0,10),columns:x,headerStyle:`accent`})},{id:`countries`,title:`Top countries`,render:e=>e.topCountries.length===0?d.createElement(h,{label:`— no country data —`}):d.createElement(s,{data:e.topCountries.slice(0,10),columns:S,headerStyle:`accent`})}]})}export{g as statsCommand};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{configPath as e,readConfig as t,writeConfig as n}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as r}from"./token-store-BQuGH0z2.js";import{emit as i}from"./telemetry-DRh10SvO.js";import{ApiV2Client as a}from"./api-v2-
|
|
2
|
-
`),2;let s=new a({config:n,cliVersion:e.cliVersion,token:o}),c=e.siteId??n.defaultSiteId??``;if(!c)return process.stderr.write("status-agent: no site selected — pass --site-id or run `zenovay use <site>`\n"),2;y();let l=n.statusAgent?.notifyOn,u=n.statusAgent?.refreshIntervalMs,d=S(e.notifyOn??l),m=e.intervalMs??u??h,g=Date.now(),b=0;i(`status_agent.start`,{properties:{rule_count:d.length,interval_ms:m}});let x=null,T=!1,E=0,A=null,j=()=>{T=!0,A&&A()};for(process.on(`SIGTERM`,j),process.on(`SIGINT`,j);!T;){try{let[e,t,n]=await Promise.all([s.getLive(c).catch(()=>({activeVisitors:0,recentEvents:[]})),s.getErrors(c,{window:`24h`}).catch(()=>({errors:[],total:0})),s.getRevenue(c,`24h`).catch(()=>null)]),r=e.activeVisitors,a=n?.mrr??n?.totalAmount??0,o=t.total/86400,l=x&&x>0?(x-a)/x*100:0,u=k(d,{error_rate:o,revenue_drop:l}),f=!1;for(let e of u){if(!D(e.rule.key,e.actual))continue;f=!0,i(`status_agent.alert_fired`,{properties:{rule_key:e.rule.key,op:e.rule.op
|
|
1
|
+
import{configPath as e,readConfig as t,writeConfig as n}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as r}from"./token-store-BQuGH0z2.js";import{emit as i}from"./telemetry-DRh10SvO.js";import{ApiV2Client as a}from"./api-v2-CPUUcP1i.js";import{spawn as o}from"node:child_process";import s from"node:path";import{existsSync as c,mkdirSync as l,readFileSync as u,renameSync as d,unlinkSync as f,writeFileSync as p}from"node:fs";import{homedir as m}from"node:os";const h=6e4;function g(){return s.join(m(),`.zenovay`)}function _(){return s.join(g(),`status-agent.pid`)}function v(){return s.join(g(),`tmux-status`)}function y(){l(g(),{recursive:!0,mode:448})}function b(e){let t=_(),n=`${t}.tmp.${process.pid}`;p(n,String(e),{mode:384}),d(n,t)}function x(e){try{return process.kill(e,0),!0}catch{return!1}}function S(e){if(!e)return[];let t=[];for(let n of e.split(`,`).map(e=>e.trim()).filter(Boolean)){let e=n.match(/^([a-z_]+)\s*(>|<)\s*(-?\d+(?:\.\d+)?)$/i);if(!e)continue;t.push({key:(e[1]??``).toLowerCase(),op:e[2]??`>`,value:Number(e[3]??0)})}return t}function C(e,t,n,r=!1){let i=(t/1e5).toFixed(1),a=[`#[fg=colour141]● ${e} live`,`#[fg=colour114]▲ MRR $${i}k`,`#[fg=colour203]✗ ${n.toFixed(0)} err/s`].join(` `);return r?`#[reverse]${a}#[noreverse]`:a}const w=3e4,T=5*60*1e3,E=new Map;function D(e,t){let n=Math.floor(t/10),r=`${e}:${n}`,i=Date.now(),a=E.get(r);return a&&i-a<T?!1:(E.set(r,i),!0)}async function O(e,t){let n=process.platform;try{if(n===`darwin`){await new Promise((n,r)=>{let i=o(`terminal-notifier`,[`-title`,e,`-message`,t,`-group`,`zenovay`],{stdio:`ignore`});i.on(`error`,r),i.on(`exit`,()=>n())});return}if(n===`linux`){await new Promise((n,r)=>{let i=o(`notify-send`,[e,t],{stdio:`ignore`});i.on(`error`,r),i.on(`exit`,()=>n())});return}}catch{}process.stdout.write(`\x1b]9;${e} — ${t}\x07`)}function k(e,t){let n=[];for(let r of e){let e=t[r.key];if(typeof e!=`number`)continue;r.op===`>`&&e>r.value&&n.push({rule:r,actual:e}),r.op===`<`&&e<r.value&&n.push({rule:r,actual:e})}return n}async function A(e){let n=await t(),o=await r({strict:!1});if(!o)return process.stderr.write(`status-agent: not logged in
|
|
2
|
+
`),2;let s=new a({config:n,cliVersion:e.cliVersion,token:o}),c=e.siteId??n.defaultSiteId??``;if(!c)return process.stderr.write("status-agent: no site selected — pass --site-id or run `zenovay use <site>`\n"),2;y();let l=n.statusAgent?.notifyOn,u=n.statusAgent?.refreshIntervalMs,d=S(e.notifyOn??l),m=e.intervalMs??u??h,g=Date.now(),b=0;i(`status_agent.start`,{properties:{rule_count:d.length,interval_ms:m}});let x=null,T=!1,E=0,A=null,j=()=>{T=!0,A&&A()};for(process.on(`SIGTERM`,j),process.on(`SIGINT`,j);!T;){try{let[e,t,n]=await Promise.all([s.getLive(c).catch(()=>({activeVisitors:0,recentEvents:[]})),s.getErrors(c,{window:`24h`}).catch(()=>({errors:[],total:0})),s.getRevenue(c,`24h`).catch(()=>null)]),r=e.activeVisitors,a=n?.mrr??n?.totalAmount??0,o=t.total/86400,l=x&&x>0?(x-a)/x*100:0,u=k(d,{error_rate:o,revenue_drop:l}),f=!1;for(let e of u){if(!D(e.rule.key,e.actual))continue;f=!0,i(`status_agent.alert_fired`,{properties:{rule_key:e.rule.key,op:e.rule.op}}),await O(`Zenovay alert`,`${e.rule.key} ${e.rule.op} ${e.rule.value} (got ${e.actual.toFixed(2)})`)}f&&(E=Date.now());let m=E>0&&Date.now()-E<w;p(v(),C(r,a,o,m),{mode:420}),b+=1,b%10==0&&i(`status_agent.tick`,{properties:{tick:b,has_revenue:a>0,has_visitors:r>0,had_errors:o>0}}),x=a}catch(e){process.stderr.write(`status-agent tick failed: ${e.message}\n`)}await new Promise(e=>{let t=setTimeout(e,m);A=()=>{clearTimeout(t),e()}}),A=null}i(`status_agent.stop`,{duration_ms:Date.now()-g,properties:{ticks:b}});try{f(_())}catch{}return 0}function j(){return[`# Add to ~/.tmux.conf:`,`set -g status-right "#(cat ~/.zenovay/tmux-status) %H:%M"`,``,`# Then reload:`,`# $ tmux source ~/.tmux.conf`].join(`
|
|
3
3
|
`)}function M(){let e=process.argv[0]??`zenovay`;return[`[Unit]`,`Description=Zenovay status agent`,`After=network.target`,``,`[Service]`,`Type=simple`,`ExecStart=${e} status-agent --child`,`Restart=on-failure`,`RestartSec=10`,``,`[Install]`,`WantedBy=default.target`,``,`# Save as ~/.config/systemd/user/zenovay-status.service`,`# systemctl --user enable --now zenovay-status`].join(`
|
|
4
4
|
`)}function N(){let e=process.argv[0]??`zenovay`;return[`<?xml version="1.0" encoding="UTF-8"?>`,`<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">`,`<plist version="1.0">`,`<dict>`,` <key>Label</key><string>com.zenovay.status-agent</string>`,` <key>ProgramArguments</key>`,` <array>`,` <string>${e}</string>`,` <string>status-agent</string>`,` <string>--child</string>`,` </array>`,` <key>RunAtLoad</key><true/>`,` <key>KeepAlive</key><true/>`,`</dict>`,`</plist>`,``,`<!-- Save as ~/Library/LaunchAgents/com.zenovay.status-agent.plist -->`,`<!-- launchctl load ~/Library/LaunchAgents/com.zenovay.status-agent.plist -->`].join(`
|
|
5
5
|
`)}async function P(r){if(r.installTmux)return process.stdout.write(j()+`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{requireTier as r}from"./tier-C4q8fJ8m.js";import{confirmDestructive as i}from"./confirm-CIdxMt7N.js";import{fmtDate as a,formatTable as o,shortId as s}from"./fmt-xxIPQJX-.js";async function c(c){let l=await e(),u=await t({strict:!1}),d=new n({config:l,cliVersion:c.cliVersion,token:u});try{await r(d,`pro`)}catch(e){return process.stderr.write(`✗ ${e.message}\n`),2}try{switch(c.action){case`list`:{let e=await d.listTeam();if(c.json)return process.stdout.write(JSON.stringify(e,null,2)+`
|
|
2
2
|
`),0;let t=[{key:`userId`,header:`user id`,width:14,format:e=>s(String(e))},{key:`email`,header:`email`,width:32,format:e=>String(e??`—`)},{key:`role`,header:`role`,width:8},{key:`joinedAt`,header:`joined`,width:10,format:e=>a(e)}],n=[{key:`id`,header:`invite id`,width:14,format:e=>s(String(e))},{key:`email`,header:`email`,width:32},{key:`role`,header:`role`,width:8},{key:`expiresAt`,header:`expires`,width:10,format:e=>a(e)}];return process.stdout.write(`\nMEMBERS (${e.members.length})\n`),e.members.length===0?process.stdout.write(` — none —
|
|
3
3
|
`):process.stdout.write(o({rows:e.members,cols:t})),process.stdout.write(`\nPENDING INVITES (${e.invites.length})\n`),e.invites.length===0?process.stdout.write(` — none —
|
|
4
4
|
`):process.stdout.write(o({rows:e.invites,cols:n})),process.stdout.write(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as n}from"./token-store-BQuGH0z2.js";import{ApiV2Client as r}from"./api-v2-
|
|
1
|
+
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as n}from"./token-store-BQuGH0z2.js";import{ApiV2Client as r}from"./api-v2-CPUUcP1i.js";function i(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}async function a(a){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:a.cliVersion,token:s});try{switch(a.action){case`reset`:{let e=await t({currentTeamId:void 0,currentTeamName:void 0});return a.json?(process.stdout.write(JSON.stringify({reset:!0,currentTeamId:e.currentTeamId??null})+`
|
|
2
2
|
`),0):(process.stdout.write(`✔ Team override cleared. Future commands use the API key's default team.
|
|
3
3
|
`),0)}case`current`:{let e=await c.me(),t=e.teams?.find(e=>e.isCurrent)??(e.team?{id:e.team.id,name:e.team.name,plan:e.team.plan,role:`?`,siteCount:0,isCurrent:!0}:null);return a.json?(process.stdout.write(JSON.stringify({current:t,override:o.currentTeamId??null},null,2)+`
|
|
4
4
|
`),0):t?(process.stdout.write(`\n current team: ${t.name} (${i(t.id)})\n plan: ${t.plan}\n override? ${o.currentTeamId?"yes — set via `teams switch`":`no — using API key default`}\n\n`),0):(process.stdout.write(`No team currently bound.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={xs:1,sm:2,md:3,lg:5,xl:8},t=e=>({headline:{color:e.fg,bold:!0},title:{color:e.fg,bold:!0},body:{color:e.fg},label:{color:e.dim,dim:!0,uppercase:!0},mono:{color:e.fg},caption:{color:e.muted}}),n={name:`mocha`,bg:`#1F1D1A`,fg:`#F4F1EC`,muted:`#A8A39B`,accent:`#6E9CE8`,accent2:`#FDA4AF`,success:`#54C896`,warn:`#E4AE3A`,error:`#DC2626`,info:`#6BB1D4`,border:`#2E2C29`,dim:`#7C7770`,spacing:e,radius:`round`,typography:t({fg:`#F4F1EC`,muted:`#A8A39B`,accent:`#6E9CE8`,dim:`#7C7770`})},r={name:`latte`,bg:`#FAF8F5`,fg:`#1F1D1A`,muted:`#6F6B66`,accent:`#3B6FD4`,accent2:`#D9648A`,success:`#2E9E6B`,warn:`#C9920E`,error:`#DC2626`,info:`#3F8FB8`,border:`#E8E4DE`,dim:`#9A968F`,spacing:e,radius:`round`,typography:t({fg:`#1F1D1A`,muted:`#6F6B66`,accent:`#3B6FD4`,dim:`#9A968F`})},i={name:`dracula`,bg:`#282A36`,fg:`#F8F8F2`,muted:`#6272A4`,accent:`#BD93F9`,accent2:`#FF79C6`,success:`#50FA7B`,warn:`#F1FA8C`,error:`#FF5555`,info:`#8BE9FD`,border:`#44475A`,dim:`#6272A4`,spacing:e,radius:`round`,typography:t({fg:`#F8F8F2`,muted:`#6272A4`,accent:`#BD93F9`,dim:`#6272A4`})},a={name:`tokyoNight`,bg:`#1A1B26`,fg:`#C0CAF5`,muted:`#565F89`,accent:`#7AA2F7`,accent2:`#BB9AF7`,success:`#9ECE6A`,warn:`#E0AF68`,error:`#F7768E`,info:`#7DCFFF`,border:`#3B4261`,dim:`#414868`,spacing:e,radius:`round`,typography:t({fg:`#C0CAF5`,muted:`#565F89`,accent:`#7AA2F7`,dim:`#414868`})},o={name:`nord`,bg:`#2E3440`,fg:`#D8DEE9`,muted:`#4C566A`,accent:`#88C0D0`,accent2:`#81A1C1`,success:`#A3BE8C`,warn:`#EBCB8B`,error:`#BF616A`,info:`#81A1C1`,border:`#3B4252`,dim:`#434C5E`,spacing:e,radius:`round`,typography:t({fg:`#D8DEE9`,muted:`#4C566A`,accent:`#88C0D0`,dim:`#434C5E`})};export{i as dracula,r as latte,n as mocha,o as nord,a as tokyoNight};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./theme-BuGrQHax.js";import{useTheme as a}from"./panel-B-XxdP-N.js";import{Banner as o}from"./banner-DdgwXGzt.js";import"./progress-row-5ns2IsFh.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import"./sparkline-CpoBjjlc.js";import"./data-table-DJzT7bAr.js";import"./bar-C1Zrfe9H.js";import"./ui-whccLLRv.js";import{promises as s}from"node:fs";import{Box as c,Text as l,render as u}from"ink";import d from"react";const f=[{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`}],p=[`name`,`bg`,`fg`,`muted`,`accent`,`accent2`,`success`,`warn`,`error`,`border`,`dim`];function m({name:e,theme:t,mode:n}){let{theme:r}=a(),i=[t.accent,t.accent2,t.success,t.warn,t.error];return d.createElement(c,{flexDirection:`row`},d.createElement(l,{bold:!0},e.padEnd(14)),d.createElement(l,{color:r.muted},n.padEnd(7)),i.map((e,t)=>d.createElement(l,{key:t,color:e},`████`,` `)),d.createElement(l,{color:r.muted},t.bg))}function h({themes:e}){let{theme:t}=a();return d.createElement(c,{flexDirection:`column`},d.createElement(o,{version:`themes`}),d.createElement(c,{marginTop:1,marginBottom:1},d.createElement(l,{color:t.muted},e.length,` themes — pass --theme <name> to any command, or set in your config.`)),d.createElement(c,{flexDirection:`column`},d.createElement(c,null,d.createElement(l,{bold:!0},`name`.padEnd(14)),d.createElement(l,{bold:!0},`mode`.padEnd(7)),d.createElement(l,{bold:!0},`swatch`.padEnd(28)),d.createElement(l,{bold:!0},`bg`)),e.map(({name:e,theme:t,mode:n})=>d.createElement(m,{key:e,name:e,theme:t,mode:n}))))}async function g(e){if(e.validate){let t;try{let n=await s.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=p.filter(e=>t[e]==null);return n.length>0?(process.stderr.write(`✗ Missing required tokens: ${n.join(`, `)}\n`),e.json&&process.stdout.write(JSON.stringify({ok:!1,missing:n},null,2)+`
|
|
2
|
+
`),1):(process.stdout.write(`✔ Valid theme (${p.length} tokens present).\n`),e.json&&process.stdout.write(JSON.stringify({ok:!0,theme:t},null,2)+`
|
|
3
|
+
`),0)}if(e.json)return process.stdout.write(JSON.stringify({themes:f.map(({name:e,theme:t,mode:n})=>({name:e,mode:n,background:t.bg,foreground:t.fg,accent:t.accent}))},null,2)+`
|
|
4
|
+
`),0;let{waitUntilExit:t}=u(d.createElement(h,{themes:f}));return await t(),0}export{g as themesCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Panel as e,useTheme as t}from"./panel-
|
|
1
|
+
import"./theme-BuGrQHax.js";import{Panel as e,useTheme as t}from"./panel-B-XxdP-N.js";import{Banner as n}from"./banner-DdgwXGzt.js";import{spawn as r}from"node:child_process";import{Box as i,Text as a,render as o,useApp as s,useInput as c}from"ink";import l,{useEffect as u,useState as d}from"react";import f from"ink-spinner";const p=[{title:`Identify`,explainer:"Who you are and which team you’re acting on. CLI uses your saved bearer token from `zenovay login`.",command:`profile show`},{title:`Tracked sites`,explainer:`The websites your account can read.`,command:`domains list`},{title:`Today's analytics`,explainer:`What visitors did on your sites in the last 24 hours.`,command:`analytics`},{title:`Traffic sources`,explainer:`Where visitors come from — direct, organic, referrals.`,command:`sources --period 7d`},{title:`Recent sessions`,explainer:`Replay-style listing of recorded sessions (Pro+).`,command:`sessions`,tierGated:!0},{title:`Alert configs`,explainer:`Threshold-based alerts you’ve set up.`,command:`alerts list`,tierGated:!0},{title:`Export today`,explainer:`Bulk-export analytics data to CSV.`,command:`export analytics --range 7d --format csv`,csvPreview:!0},{title:`Self-test`,explainer:`One-command verification that everything works.`,command:`self-test --quick`,maxLines:24}],m=p.length;async function h(e){let t=process.argv[1]??process.execPath;return e.nonInteractive?g(t,e.cliVersion):new Promise(n=>{let{unmount:r}=o(l.createElement(y,{cliVersion:e.cliVersion,binPath:t,onDone:e=>{r(),n(e)}}))})}async function g(e,t){process.stdout.write(`Zenovay CLI v${t} — tour (non-interactive)\n`),process.stdout.write(`────────────────────────────────────────────────────
|
|
2
2
|
|
|
3
3
|
`);for(let t=0;t<p.length;t++){let n=p[t];process.stdout.write(`[${t+1}/${m}] ${n.title}\n`),process.stdout.write(` ${n.explainer}\n`),process.stdout.write(` $ zenovay ${n.command}\n\n`);let r=await v(e,n);if(r.tierSkipped){process.stdout.write(` → Skipping (requires Pro plan)
|
|
4
4
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Text as e}from"ink";import t from"react";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import{classifyBump as t,fetchManifest as n}from"./check-D9G0N7NB.js";import{applyUpdate as r}from"./apply-B19bFTz0.js";import"./formatter-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import{classifyBump as t,fetchManifest as n}from"./check-D9G0N7NB.js";import{applyUpdate as r}from"./apply-B19bFTz0.js";import"./formatter-DDG2TSOz.js";import{emit$1 as i,isHeadless as a}from"./emit-C9vAopcy.js";async function o(o){let s=await e(),c=await n({cliBase:s.cliBase}),l=t(o.cliVersion,c.latest);if(o.check)return a({json:o.json})?i({type:`info`,message:`latest=${c.latest} current=${o.cliVersion} bump=${l}`}):process.stdout.write(`Current: ${o.cliVersion}\nLatest: ${c.latest}\nBump: ${l}\n`),{updated:!1,from:o.cliVersion,to:c.latest};if(l===`none`)return a({json:o.json})||process.stdout.write(`Already on latest (${o.cliVersion}).\n`),{updated:!1,from:o.cliVersion,to:c.latest};if(l===`downgrade`&&!o.forceDowngrade)throw Error(`Refused to downgrade ${o.cliVersion} → ${c.latest}. Pass --force-downgrade if you really want this.`);let u=await r({currentVersion:o.cliVersion,cliBase:s.cliBase,binaryPath:o.binaryPath,forceDowngrade:o.forceDowngrade});return a({json:o.json})?u.updated&&i({type:`update.applied`,from:u.from,to:u.to}):u.updated?process.stdout.write(`Updated ${u.from} → ${u.to}\n`):process.stdout.write(`Not updated (${u.reason??`unknown`}).\n`),u}export{o as updateCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{requireTier as r}from"./tier-C4q8fJ8m.js";import"./formatter-DDG2TSOz.js";import{emit$1 as i,isHeadless as a}from"./emit-C9vAopcy.js";import{openInBrowser as o}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{Panel as s,useTheme as c}from"./panel-B-XxdP-N.js";import{Banner as l}from"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import{Keybar as u}from"./keybar-QgnmSion.js";import{resolveSiteId as d}from"./resolve-site-DQVcWhjG.js";import{DataTable as f}from"./data-table-DJzT7bAr.js";import{EmptyState as p}from"./empty-state-DbToIL5T.js";import{deepLinkFor as m}from"./keybar-deep-link-DbmPjAEz.js";import{Box as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useState as S}from"react";import C from"ink-spinner";function w(e){return e===`up`?{glyph:`● up`,color:`green`}:e===`down`?{glyph:`● down`,color:`red`}:{glyph:`○ unknown`,color:`gray`}}function T(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.round((t-Date.now())/(1e3*60*60*24));return`${n}d`}async function E(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(l,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let u,f;try{({siteId:u,site:f}=await d(l,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??u;if(a(o)){let e=await l.getUptime(u);return i({type:`uptime.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=_(b.createElement(D,{api:l,siteId:u,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const D=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=v(),{theme:d}=c(),[_,E]=S(null),[D,O]=S(!0),[k,A]=S(null);if(y(e=>{if(e===`o`||e===`O`){o(m(`uptime`,{siteId:t}));return}e===`q`&&(a(),i(0))}),x(()=>{let n=!1;return(async()=>{try{let r=await e.getUptime(t);n||(E(r.monitors),O(!1))}catch(e){n||(A(e.message),O(!1))}})(),()=>{n=!0}},[e,t]),D)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(s,{title:`Loading`,state:`busy`},b.createElement(h,null,b.createElement(g,{color:d.accent},b.createElement(C,{type:`dots`})),b.createElement(g,null,` Fetching monitors…`))));if(k)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(p,{reason:`error`,headline:`Failed to load`,hint:k}));if(!_||_.length===0)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(p,{reason:`no-data`,headline:`No monitors configured`,hint:`Add one at app.zenovay.com/uptime`}));let j=[{key:`url`,label:`monitor`,width:36},{key:`status`,label:`status`,width:12,format:e=>w(String(e)).glyph},{key:`p95ms`,label:`p95 ms`,align:`right`,width:8,format:e=>typeof e==`number`?String(e):`—`},{key:`sslExpiry`,label:`ssl exp`,align:`right`,width:7,format:e=>T(e)}];return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(s,{title:`Monitors (${_.length})`},b.createElement(f,{columns:j,data:_,zebra:!0})),b.createElement(u,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{E as uptimeCommand};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{fmtDate as r,fmtNumber as i}from"./fmt-xxIPQJX-.js";const a=1e8,o=e=>e<=0||e>=a;function s(e,t,n=24){if(o(t))return`─`.repeat(n);let r=Math.min(1,e/t),i=Math.round(r*n);return`█`.repeat(i)+`░`.repeat(Math.max(0,n-i))}function c(e,t){if(o(t))return`—`;let n=e/t*100;return`${n.toFixed(0)}%`}function l(e,t){if(o(t))return``;let n=e/t;return n>=1?`⚠ over limit`:n>=.8?`⚠ near limit`:``}function u(e,t){return o(e)?`∞`:t(e)}async function d(a){let o=await e(),d=await t({strict:!1});if(!d)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let f=new n({config:o,cliVersion:a.cliVersion,token:d}),p;try{p=await f.getUsage()}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}if(a.json)return process.stdout.write(JSON.stringify(p,null,2)+`
|
|
2
2
|
`),0;let m=[{label:`events this month`,used:p.events.thisMonth,limit:p.events.monthlyLimit,format:i},{label:`events today`,used:p.events.today,limit:p.events.dailyLimit,format:i},{label:`websites`,used:p.websites.used,limit:p.websites.limit},{label:`team members`,used:p.teamMembers.used,limit:p.teamMembers.limit}],h=18,g=8,_=9,v=[];v.push(``),v.push(` plan: ${p.plan}`),v.push(``);for(let e of m){let t=e.format??i,n=t(e.used).padStart(g),r=u(e.limit,t).padStart(_),a=s(e.used,e.limit),o=c(e.used,e.limit).padStart(5),d=l(e.used,e.limit);v.push(` ${e.label.padEnd(h)} ${n} / ${r} ${a} ${o} ${d}`.trimEnd())}return v.push(` ${`api keys`.padEnd(h)} ${i(p.apiKeys.used).padStart(g)} / ${`—`.padStart(_)} ${`─`.repeat(24)} ${`—`.padStart(5)}`),v.push(``),v.push(` data retention: ${p.dataRetentionDays} days`),v.push(` last event: ${r(p.events.lastEventAt,`datetime`)}`),v.push(``),process.stdout.write(v.join(`
|
|
3
3
|
`)),0}export{d as usageCommand};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import{ApiClient as n}from"./api-FCanTxsb.js";import{readToken as r}from"./token-store-BQuGH0z2.js";import"./formatter-
|
|
1
|
+
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import{ApiClient as n}from"./api-FCanTxsb.js";import{readToken as r}from"./token-store-BQuGH0z2.js";import"./formatter-DDG2TSOz.js";import{emitEnvelope as i,wrapSnapshot as a}from"./emit-C9vAopcy.js";async function o(o){if(o.reset)return await t({defaultSiteId:void 0,defaultSiteName:void 0}),o.json?(i(a({reset:!0,defaultSiteId:null},`use.reset`)),0):(process.stdout.write(`Default site cleared.
|
|
2
2
|
`),0);if(!o.match||!o.match.trim()){let t=await e();if(t.defaultSiteId){let e={siteId:t.defaultSiteId,name:t.defaultSiteName??null,domain:t.defaultSiteName??null};return o.json?(i(a(e,`use.current`,{siteId:t.defaultSiteId})),0):(process.stdout.write(`Default site: ${e.name??e.siteId} (${t.defaultSiteId})\n`),0)}return o.json?(i(a(null,`use.current`,{})),0):(process.stdout.write("No default site set. Run `zenovay use <domain>` to set one.\n"),0)}let c=await e(),l=await r({strict:!1});if(!l&&!process.env.ZENOVAY_API_TOKEN)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:c,cliVersion:o.cliVersion,token:l}),d=o.match.trim().toLowerCase(),f=await u.getSites(),p=f.find(e=>e.id===o.match||e.trackingCode===o.match||e.url===o.match),m=p??f.find(e=>s(e.url).includes(d)||e.name.toLowerCase().includes(d));return m?(await t({defaultSiteId:m.id,defaultSiteName:m.name}),o.json?(i(a({siteId:m.id,name:m.name,domain:s(m.url)},`use.set`,{siteId:m.id})),0):(process.stdout.write(`Default site → ${m.name} (${m.url})\n`),0)):(process.stderr.write(`No site matched "${o.match}". Your sites:\n${f.map(e=>` ${e.name} — ${e.url} — ${e.id}`).join(`
|
|
3
3
|
`)}\n`),2)}function s(e){return e.toLowerCase().replace(/^https?:\/\//,``).replace(/\/.*$/,``)}export{o as useCommand};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./client-Dm8uGVCy.js";import{openInBrowser as a}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{useTheme as o}from"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import{brailleSpark as s,spark as c}from"./sparkline-CpoBjjlc.js";import"./chat-panel-ZlKZ0W6J.js";import{resolveSiteId as l}from"./resolve-site-DQVcWhjG.js";import{DataTable as u}from"./data-table-DJzT7bAr.js";import{deepLinkFor as d}from"./keybar-deep-link-DbmPjAEz.js";import{runAnalyticalScreen as f}from"./analytical-screen-B_wWUnT4.js";import{Box as p,Text as m}from"ink";import h from"react";function g(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 _(e){let t=e,n=t.events??t.timeseries;return Array.isArray(n)&&n.length>0?c(n,8):`▁▁▁▁▁▁▁▁`}function v(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 y(o){let s=await e(),c=await t({strict:!1}),u=new n({config:s,cliVersion:o.cliVersion,token:c}),p,m;try{({siteId:p,site:m}=await l(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 y=i(o),S=o.limit??50,C=typeof o.minDuration==`number`&&o.minDuration>0?o.minDuration:0,w=e=>C<=0?e:e.filter(e=>v(e)>=C),T=6e4,E=e=>{let t=Date.parse(e.startedAt);return Number.isFinite(t)&&Date.now()-t<T},D=[{key:`startedAt`,label:``,width:5,format:(e,t)=>E(t)?`● new`:``},{key:`startedAt`,label:`when`,width:6,format:e=>g(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)=>_(t)}];return f({cliVersion:o.cliVersion,title:`visitors · ${p}`,commandName:`visitors`,ai:{api:u,siteId:p,siteLabel:m?.url?m.url.replace(/^https?:\/\//,``).replace(/\/$/,``):m?.name??p},authToken:c?.accessToken??null,refreshIntervalMs:1e4,fetcher:e=>u.getVisitors(p,{limit:S},e),format:y,keybindings:{o:{label:`open in browser`,handler:()=>{a(d(`visitors`,{siteId:p}))}}},headlessEmit:(e,t)=>{let n={...e,visitors:w(e.visitors)};if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(n,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
|
|
2
|
+
`);return}let i=[`startedAt`,`country`,`city`,`device`,`page`];process.stdout.write(r(n.visitors,i,t))},panels:[{id:`live`,title:`Now`,render:e=>h.createElement(b,{visitors:w(e.visitors)})},{id:`visitors`,title:`Active sessions`,render:e=>h.createElement(x,{visitors:w(e.visitors),limit:S,columns:D})}]})}const b=({visitors:e})=>{let{theme:t}=o(),n=[...e].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)),r=n[0],i=Array(24*6).fill(0),a=Date.now();for(let t of e){let e=a-new Date(t.startedAt).getTime(),n=Math.floor(e/(10*60*1e3));n>=0&&n<i.length&&(i[i.length-1-n]+=1)}return h.createElement(p,{flexDirection:`column`},h.createElement(m,{bold:!0},e.length,` live`),h.createElement(m,{color:t.muted},s(i,40)),r?h.createElement(m,{color:t.muted},`top: `,r.city??r.country??`—`,` · `,r.page??`—`):null)},x=({visitors:e,limit:t,columns:n})=>{let{theme:r}=o(),i=[...e].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)).slice(0,t);return i.length===0?h.createElement(m,{color:r.dim},`— no visitors yet —`):h.createElement(u,{columns:n,data:i,headerStyle:`accent`})};export{y as visitorsCommand};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./client-Dm8uGVCy.js";import{openInBrowser as a}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{useTheme as o}from"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import"./chat-panel-ZlKZ0W6J.js";import{resolveSiteId as s}from"./resolve-site-DQVcWhjG.js";import{DataTable as c}from"./data-table-DJzT7bAr.js";import{deepLinkFor as l}from"./keybar-deep-link-DbmPjAEz.js";import{runAnalyticalScreen as u}from"./analytical-screen-B_wWUnT4.js";import{Box as d,Text as f}from"ink";import p from"react";const m={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 h(e,t){let n=m[e];return t<=n.good?{label:`good`,tone:`good`}:t<=n.poor?{label:`needs`,tone:`needs`}:{label:`poor`,tone:`poor`}}function g(e,t){return e===`cls`?t.toFixed(3):t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`}function _({data:e}){let{theme:t}=o(),n={good:t.success,needs:t.warn,poor:t.error},r=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},i=[`lcp`,`inp`,`cls`,`ttfb`,`fcp`];return p.createElement(d,{flexDirection:`column`},i.map(e=>{let t=r(e),i=h(e,t);return p.createElement(f,{key:e},p.createElement(f,{color:n[i.tone]},`● `),p.createElement(f,{bold:!0},e.toUpperCase().padEnd(5)),` `,p.createElement(f,null,g(e,t).padStart(8)),` `,p.createElement(f,{color:n[i.tone]},i.label))}))}function v({data:e,columns:t}){let{theme:n}=o();return e.vitals.length===0?p.createElement(f,{color:n.muted},`— no vitals data yet —`):p.createElement(c,{data:e.vitals.slice(0,15),columns:t,headerStyle:`accent`})}async function y(o){let c=await e(),d=await t({strict:!1}),f=new n({config:c,cliVersion:o.cliVersion,token:d}),m,h;try{({siteId:m,site:h}=await s(f,{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 y=i(o),b=[{key:`url`,label:`url`,width:32},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,label:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?g(`lcp`,e.p75):`—`},{key:`inp`,label:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?g(`inp`,e.p75):`—`},{key:`cls`,label:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?g(`cls`,e.p75):`—`},{key:`samples`,label:`n`,width:6,align:`right`}];return u({cliVersion:o.cliVersion,title:`vitals · ${m}`,commandName:`vitals`,ai:{api:f,siteId:m,siteLabel:h?.url?h.url.replace(/^https?:\/\//,``).replace(/\/$/,``):h?.name??m},authToken:d?.accessToken??null,refreshIntervalMs:o.watch?5*6e4:0,fetcher:e=>f.getVitals(m,{url:o.url,device:o.device,window:o.window},e),format:y,keybindings:{o:{label:`open in browser`,handler:()=>{a(l(`vitals`,{siteId:m}))}}},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=>p.createElement(_,{data:e})},{id:`pages`,title:`Per-page`,render:e=>p.createElement(v,{data:e,columns:b})}]})}export{y as vitalsCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import"./formatter-DDG2TSOz.js";import{emit$1 as r,isHeadless as i}from"./emit-C9vAopcy.js";import{parseSseStream as a}from"./client-Dm8uGVCy.js";import{openInBrowser as o}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{Panel as s,useTheme as c}from"./panel-B-XxdP-N.js";import{Banner as l}from"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import{Keybar as u}from"./keybar-QgnmSion.js";import{spark as d}from"./sparkline-CpoBjjlc.js";import{resolveSiteId as f}from"./resolve-site-DQVcWhjG.js";import{EmptyState as p}from"./empty-state-DbToIL5T.js";import{deepLinkFor as m}from"./keybar-deep-link-DbmPjAEz.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=Math.PI*2;function D(e){let t=e,n=Math.PI*Math.sin(e);for(let e=0;e<6;e++){let e=2*t+Math.sin(2*t)-n,r=2+2*Math.cos(2*t);if(r===0)break;t-=e/r}return t}function O(e,t){if(e<-90||e>90||t<-180||t>180)return null;let n=e*Math.PI/180,r=t*Math.PI/180,i=D(n),a=r*Math.cos(i)/Math.PI,o=Math.sin(i);return{x:a,y:o}}function k(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 A(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function j(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function M(e){let t=e.dw/2,n=e.dh/2,r=e.dw/2-1,i=e.dh/2-1,a=Math.max(e.dw,e.dh)*2;for(let o=0;o<a;o++){let s=o/a*E,c=Math.round(t+r*Math.cos(s)),l=Math.round(n+i*Math.sin(s));j(e,c,l)}}function N(e){let t=Math.floor(e.dh/2);for(let n=0;n<e.dw;n+=4)j(e,n,t)}function P(e,t){let n=e.dw/2,r=e.dh/2,i=e.dw/2-1,a=e.dh/2-1;for(let o of t){let t=O(o.lat,o.lng);if(!t)continue;let s=Math.round(n+t.x*i),c=Math.round(r-t.y*a);j(e,s,c),j(e,s+1,c),j(e,s,c+1),j(e,s+1,c+1)}}const F=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function I(e,t,n){let r=0;for(let i=0;i<F.length;i++){let[a,o]=F[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function L(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`.`:r<=4?`:`:r<=6?`*`:`#`}function R({data:e,width:t=80,height:n=20,asciiOnly:r}){let{theme:i}=c(),a=k(r),o=A(t,n);M(o),N(o),P(o,e);let s=[];for(let e=0;e<n;e++){let n=``;for(let r=0;r<t;r++)n+=a?L(o,r,e):I(o,r,e);s.push(n)}return x.createElement(g,{flexDirection:`column`},s.map((e,t)=>x.createElement(_,{key:t,color:i.accent},e)),x.createElement(_,{color:i.muted},e.length,` live · `,a?`ascii mode`:`braille mode`))}const z=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 B(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:a.cliVersion,token:s}),l;try{({siteId:l}=await f(c,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(i(a)){let e=await c.getDashboardSnapshot(l);return r({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=v(x.createElement(V,{api:c,siteId:l,intervalMs:a.intervalMs??15e3,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const V=({api:e,siteId:t,intervalMs:n,cliVersion:r,onExit:i})=>{let{theme:d}=c(),{exit:f}=y(),[h,v]=C(null),[T,E]=C(null),[D,O]=C(null),[k,A]=C([]),[j,M]=C(!0),[N,P]=C(null),[F,I]=C(1),[L,B]=C(!1),[V,Y]=C(!1);b((e,n)=>{if(e===`o`||e===`O`){o(m(`watch`,{siteId:t}));return}if(e===`q`){f(),i(0);return}if(e===`?`||e===`/`){Y(e=>!e);return}if(e===`g`){B(e=>!e);return}if(n.tab){I(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`)&&I(Number(e))});let[X,Z]=C(!1);if(S(()=>{let r=!1,i=async()=>{try{let n=await e.getDashboardSnapshot(t);if(r)return;let i=z.safeParse(n);if(!i.success){Z(!0),M(!1);return}Z(!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};v(o),e.getVitals(t).then(e=>{r||E(e)},()=>{}),e.getGoals(t).then(e=>{r||O(e)},()=>{}),M(!1),P(null)}catch(e){r||P(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 r=await e.openEventsStream(t,n.signal);for await(let e of a(r))e.type===`error`&&A(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>n.abort()},[e,t]),j)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(s,{title:`Loading`,state:`busy`},x.createElement(g,null,x.createElement(_,{color:d.accent},x.createElement(w,{type:`dots`})),x.createElement(_,null,` Fetching snapshot…`))));if(N&&!h)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(s,{title:`Error`,state:`err`},x.createElement(_,{color:d.error},N)));if(X&&!h)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(p,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let Q=process.stdout.columns??80,$=Math.max(20,Math.floor(Q/3)-1),ee=[];return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}${L?` · globe`:``}`}),x.createElement(g,{flexDirection:`row`},x.createElement(g,{flexDirection:`column`},L?x.createElement(s,{title:`Live globe`,focused:F===1,width:$},x.createElement(R,{data:ee,width:Math.max(40,$-4),height:12})):x.createElement(U,{snapshot:h,focused:F===1,width:$}),x.createElement(K,{events:k,focused:F===4,width:$})),x.createElement(g,{flexDirection:`column`},x.createElement(W,{snapshot:h,focused:F===2,width:$}),x.createElement(q,{vitals:T,focused:F===5,width:$})),x.createElement(g,{flexDirection:`column`},x.createElement(G,{snapshot:h,focused:F===3,width:$}),x.createElement(J,{goals:D,focused:F===6,width:$}))),V?x.createElement(H,{api:e,siteId:t,width:Q-2}):null,x.createElement(u,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:L?`panels`:`globe`},{key:`?/`,label:V?`close chat`:`ai chat`},{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))},H=({api:e,siteId:t,width:n})=>{let{theme:r}=c(),[i,o]=C(``),[l,u]=C([]),[d,f]=C(!1),[p,m]=C(``),[h,v]=C(null),y=async n=>{let r=n.trim();if(!r||d)return;v(null),o(``);let i=[...l,{role:`user`,content:r}];u(i),f(!0),m(``);try{let n=i.map(e=>({role:e.role,content:e.content})),r=await e.openAiStream(`chat`,{messages:n,siteId:t},void 0),o=``;for await(let e of a(r))if(e.type===`delta`)o+=e.content,m(o);else if(e.type===`error`)v(`${e.code}: ${e.message}`);else if(e.type===`done`)break;u([...i,{role:`assistant`,content:o}]),m(``)}catch(e){v(e instanceof Error?e.message:`chat failed`)}finally{f(!1)}};return x.createElement(g,{marginTop:1},x.createElement(s,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:n},x.createElement(g,{flexDirection:`column`},l.slice(-6).map((e,t)=>x.createElement(g,{key:t,flexDirection:`column`,marginBottom:1},x.createElement(_,{color:e.role===`user`?r.accent:r.info,bold:!0},e.role===`user`?`you`:`zenovay`),x.createElement(_,null,e.content))),d&&p?x.createElement(g,{flexDirection:`column`,marginBottom:1},x.createElement(_,{color:r.info,bold:!0},`zenovay`),x.createElement(_,null,p)):null,h?x.createElement(_,{color:r.error},`✗ `,h):null,x.createElement(g,null,x.createElement(_,{color:r.accent},d?`⠋ `:`▸ `),x.createElement(T,{value:i,onChange:o,onSubmit:y,placeholder:d?`streaming…`:`ask anything about your analytics`})))))},U=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.visitors?.count??0,a=e?.visitors?.series??[];return x.createElement(s,{title:`Visitors`,focused:t,width:n},x.createElement(_,{bold:!0},i.toString()),x.createElement(_,{color:r.muted},a.length>0?d(a,Math.max(8,n-6)):`— no data —`))},W=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.topPages?.slice(0,5)??[];return x.createElement(s,{title:`Top pages`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.path},x.createElement(_,null,e.path.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.views))))},G=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.sources?.slice(0,5)??[];return x.createElement(s,{title:`Sources`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.source},x.createElement(_,null,e.source.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.visitors))))},K=({events:e,focused:t,width:n})=>{let{theme:r}=c();return x.createElement(s,{title:`Events`,focused:t,width:n},e.length===0?x.createElement(_,{color:r.muted},`— waiting —`):e.slice(-10).map((e,t)=>x.createElement(_,{key:t},e.slice(0,n-4))))},q=({vitals:e,focused:t,width:n})=>{let{theme:r}=c(),i=(e,t,n)=>x.createElement(g,{key:e},x.createElement(_,{bold:!0},e.padEnd(6)),x.createElement(_,{color:r.muted},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return x.createElement(s,{title:`Vitals`,focused:t,width:n},i(`LCP`,e?.lcpP75,`ms`),i(`INP`,e?.inpP75,`ms`),i(`CLS`,e?.clsP75?e.clsP75*1e3:void 0,`/1k`),i(`TTFB`,e?.ttfbP75,`ms`),i(`FCP`,e?.fcpP75,`ms`))},J=({goals:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.goals?.slice(0,5)??[];return x.createElement(s,{title:`Goals`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.name},x.createElement(_,null,e.name.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.completions))))};export{B as watchCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{emitErrorEnvelope as n}from"./error-codes-C5caZH9p.js";import{ApiV2Client as r}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{emitErrorEnvelope as n}from"./error-codes-C5caZH9p.js";import{ApiV2Client as r}from"./api-v2-CPUUcP1i.js";import{confirmDestructive as i}from"./confirm-CIdxMt7N.js";import"./formatter-DDG2TSOz.js";import{emitEnvelope as a,wrapItem as o,wrapList as s}from"./emit-C9vAopcy.js";function c(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}function l(e){return e?new Date(e).toISOString().slice(0,10):`—`}async function u(u){let d=await e(),f=await t({strict:!1}),p=new r({config:d,cliVersion:u.cliVersion,token:f});try{switch(u.action){case`list`:{let{webhooks:e}=await p.listWebhooks();if(u.json)return a(s(e,`webhooks.list`),{legacyKey:`webhooks`,legacyValue:e}),0;if(e.length===0)return process.stdout.write("No webhooks yet. Add one with `zenovay webhooks add <https-url> --events <e1,e2>`.\n"),0;let t=[``,`id`,`url`,`events`,`created`],n=[1,14,40,28,10],r=e=>e.map((e,t)=>(e??``).padEnd(n[t])).join(` `);process.stdout.write(r(t)+`
|
|
2
2
|
`),process.stdout.write(r(n.map(e=>`─`.repeat(e)))+`
|
|
3
3
|
`);for(let t of e){let e=t.status===`disabled`?`○`:`●`,i=t.url.length>n[2]?`${t.url.slice(0,n[2]-1)}…`:t.url,a=t.events.join(`,`),o=a.length>n[3]?`${a.slice(0,n[3]-1)}…`:a;process.stdout.write(r([e,c(t.id),i,o,l(t.createdAt)])+`
|
|
4
4
|
`)}return process.stdout.write(`
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import"./theme-BuGrQHax.js";import{Panel as r,useTheme as i}from"./panel-B-XxdP-N.js";import{Banner as a}from"./banner-DdgwXGzt.js";import"./progress-row-5ns2IsFh.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import"./sparkline-CpoBjjlc.js";import"./data-table-DJzT7bAr.js";import"./bar-C1Zrfe9H.js";import"./ui-whccLLRv.js";import{Box as o,Text as s,render as c,useApp as l,useInput as u}from"ink";import d,{useEffect as f,useState as p}from"react";async function m(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 h({stats:e}){let{theme:t}=i();return d.createElement(r,{title:`webhooks forward`,state:e.connected?`ok`:`busy`},d.createElement(o,{flexDirection:`column`},d.createElement(s,null,d.createElement(s,{color:t.muted},`public URL `),d.createElement(s,{color:t.accent},e.publicUrl)),d.createElement(s,null,d.createElement(s,{color:t.muted},`→ forwarding to `),d.createElement(s,{color:t.accent},e.wsUrl)),d.createElement(s,null,e.connected?d.createElement(s,{color:t.success},`● connected`):d.createElement(s,{color:t.warn},`○ connecting…`),d.createElement(s,{color:t.muted},` · `,e.total,` requests · `,e.ok,` ok · `),d.createElement(s,{color:e.err>0?t.error:t.muted},e.err,` err`),e.lastStatus===null?null:d.createElement(s,{color:t.muted},` · last: HTTP `,e.lastStatus)),e.lastError?d.createElement(s,{color:t.error},`last error: `,e.lastError.slice(0,80)):null))}async function g(r){let g=await e(),_=await t({strict:!1});if(!_?.accessToken)return process.stderr.write("Not authenticated. Run `zenovay login` first.\n"),2;let v=r.siteId??_.teamId??``;if(!v)return process.stderr.write(`No site selected — pass --site-id or set ZENOVAY_SITE.
|
|
2
|
+
`),2;if(!r.to)return process.stderr.write(`Missing --to <url> (e.g. --to localhost:3000/webhook).
|
|
3
|
+
`),2;let y=r.to.match(/^https?:\/\//)?r.to:`http://${r.to}`,b=new n({config:g,cliVersion:r.cliVersion,token:_}),x;try{x=await b.createTunnel(v,r.to)}catch(e){return process.stderr.write(`Failed to register tunnel: ${e.message}\n`),1}let S=r.sign?r.secret??x.tunnelKey:null,C=()=>{let{theme:e}=i(),{exit:t}=l(),[n,c]=p({total:0,ok:0,err:0,lastStatus:null,lastError:null,publicUrl:x.publicUrl,wsUrl:x.wsUrl,connected:!1});return u((e,n)=>{(e===`q`||n.escape)&&t()}),f(()=>{let e=new AbortController,t=async e=>{try{let t={...e.headers};delete t.host,delete t[`content-length`],S&&(t[`X-Zenovay-Signature`]=`sha256=${await m(S,e.body)}`);let n=await fetch(y,{method:e.method,headers:t,body:e.method===`GET`||e.method===`HEAD`?void 0:e.body}),r=await n.text(),i={};return n.headers.forEach((e,t)=>{i[t]=e}),c(e=>({...e,total:e.total+1,ok:e.ok+(n.ok?1:0),err:e.err+(n.ok?0:1),lastStatus:n.status,lastError:n.ok?null:`HTTP ${n.status}`})),{status:n.status,headers:i,body:r}}catch(e){let t=e instanceof Error?e.message:String(e);return c(e=>({...e,total:e.total+1,err:e.err+1,lastError:t})),{status:502,body:JSON.stringify({error:`cli_local_failed`,detail:t})}}};return(async()=>{let n=b.tunnelClient(x.wsUrl);c(e=>({...e,connected:!0}));try{await n.start(t,e.signal)}catch(e){c(t=>({...t,connected:!1,lastError:e.message}))}})(),()=>{e.abort()}},[]),d.createElement(o,{flexDirection:`column`},d.createElement(a,{version:`webhooks forward`}),d.createElement(h,{stats:n}),d.createElement(s,{color:e.muted},`target: `,y,` `,r.sign?`· HMAC-signed`:``),d.createElement(s,{color:e.muted},`[q | Esc] quit`))},{waitUntilExit:w}=c(d.createElement(C,null));return await w(),0}export{g as webhooksForwardCommand};
|
package/dist/wizard-bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import(`./init-
|
|
2
|
+
import(`./init-CNwLaGfm.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)});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=[500,1e3,2e3,4e3,8e3,16e3,32e3,6e4];let t=null;async function n(){if(t)return t;let e=globalThis.WebSocket;if(typeof e==`function`)return t=e,e;try{let e=await import(`ws`),n=e.default??e.WebSocket;if(!n)throw Error(`ws package missing default export`);return t=n,n}catch(e){throw Error(`WebSocket unavailable: install Node 22+ or add the 'ws' dependency (${e.message})`)}}function r(e,t){return new Promise((n,r)=>{if(t?.aborted){r(t.reason??Error(`aborted`));return}let i=setTimeout(()=>{t?.removeEventListener(`abort`,a),n()},e),a=()=>{clearTimeout(i),r(t?.reason??Error(`aborted`))};t?.addEventListener(`abort`,a,{once:!0})})}function i(t){return e[Math.min(t-1,e.length-1)]??6e4}function a(e,t){if(!t)return e;let n=e.includes(`?`)?`&`:`?`;return`${e}${n}access_token=${encodeURIComponent(t)}`}async function o(e,t,n,r){let i=a(e,n),o;try{o=n?new t(i,{headers:{Authorization:`Bearer ${n}`}}):new t(i)}catch(e){throw Error(`ws connect failed: ${e.message}`)}return await new Promise((e,t)=>{let n=!1,i=()=>{n||(n=!0,c(),e({socket:o,open:!0}))},a=e=>{if(n)return;n=!0,c();let r=e?.message??(typeof e==`string`?e:`ws connection error`);t(Error(r))},s=()=>{if(!n){n=!0,c();try{o.close()}catch{}t(r?.reason??Error(`aborted`))}},c=()=>{o.onopen=null,o.onerror=null,r?.removeEventListener(`abort`,s)};o.onopen=i,o.onerror=a,r?.addEventListener(`abort`,s,{once:!0})})}async function*s(e){let t=e.webSocketImpl??await n(),a=e.pingIntervalMs??3e4,s=e.maxReconnectAttempts??10,c=0;for(;;){if(e.signal?.aborted)return;let n;try{n=await o(e.url,t,e.bearer,e.signal)}catch(t){if(e.signal?.aborted)return;if(c++,c>s)throw t;let n=i(c);e.onReconnect?.(c,n);try{await r(n,e.signal)}catch{return}continue}yield{type:`open`};let l=[],u=[],d=!1,f=Date.now(),p=!1,m=e=>{f=Date.now();let t=u.shift();t?t(e):l.push(e)},h=()=>{if(!d)for(d=!0;u.length;)u.shift()(null)};n.socket.onmessage=e=>{m({type:`message`,data:e.data})},n.socket.onclose=()=>{m({type:`close`}),h()},n.socket.onerror=e=>{let t=e?.message??`ws error`;m({type:`error`,data:t})};let g=()=>{try{n.socket.close()}catch{}h()};e.signal?.addEventListener(`abort`,g,{once:!0});let _=null;a>0&&(_=setInterval(()=>{if(Date.now()-f>a*1.5){try{n.socket.close()}catch{}h()}},Math.max(1e3,Math.floor(a/2))));try{for(;;){if(e.signal?.aborted)return;let t;if(t=l.length>0?l.shift():d?null:await new Promise(e=>u.push(e)),t===null||(t.type===`message`&&(p=!0),yield t,t.type===`close`))break}}finally{_&&clearInterval(_),e.signal?.removeEventListener(`abort`,g);try{n.socket.close()}catch{}}if(e.signal?.aborted)return;if(p&&(c=0),c++,c>s)throw Error(`ws connection exceeded reconnect cap`);let v=i(c);e.onReconnect?.(c,v);try{await r(v,e.signal)}catch{return}}}var c=class{opts;ac=null;socket=null;running=!1;constructor(e){this.opts=e}async start(e){this.running=!0,this.ac=new AbortController;let t=l(this.ac.signal,this.opts.signal),a=this.opts.webSocketImpl??await n(),s=this.opts.maxReconnectAttempts??10,c=0;for(;this.running;){if(t.aborted)return;let n;try{n=await o(this.opts.url,a,this.opts.bearer,t)}catch(e){if(t.aborted)return;if(c++,c>s)throw e;let n=i(c);this.opts.onReconnect?.(c,n);try{await r(n,t)}catch{return}continue}this.socket=n.socket;let l=!1;if(await new Promise(r=>{n.socket.onmessage=t=>{l=!0;let r=typeof t.data==`string`?t.data:String(t.data),i=null;try{i=JSON.parse(r)}catch{return}!i||typeof i.correlationId!=`string`||e(i).then(e=>{let t={correlationId:i.correlationId,status:e.status,headers:e.headers,body:e.body};try{n.socket.send(JSON.stringify(t))}catch{}}).catch(e=>{let t={correlationId:i.correlationId,status:502,body:JSON.stringify({error:e.message})};try{n.socket.send(JSON.stringify(t))}catch{}})},n.socket.onclose=()=>r(),n.socket.onerror=()=>r(),t.addEventListener(`abort`,()=>{try{n.socket.close()}catch{}r()},{once:!0})}),this.socket=null,t.aborted||!this.running)return;if(l&&(c=0),c++,c>s)throw Error(`ws tunnel exceeded reconnect cap`);let u=i(c);this.opts.onReconnect?.(c,u);try{await r(u,t)}catch{return}}}async stop(){this.running=!1,this.ac?.abort();try{this.socket?.close()}catch{}this.socket=null}};function l(e,t){if(!t)return e;let n=new AbortController,r=()=>n.abort(e.reason),i=()=>n.abort(t.reason);return e.aborted?n.abort(e.reason):e.addEventListener(`abort`,r,{once:!0}),t.aborted?n.abort(t.reason):t.addEventListener(`abort`,i,{once:!0}),n.signal}export{c as WsTunnelClient,s as connectWs};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenovay/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.66",
|
|
4
4
|
"description": "Zenovay CLI — AI install wizard + full terminal analytics dashboard",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,22 +15,6 @@
|
|
|
15
15
|
"README.md",
|
|
16
16
|
"LICENSE"
|
|
17
17
|
],
|
|
18
|
-
"scripts": {
|
|
19
|
-
"dev": "tsx src/bin.ts",
|
|
20
|
-
"build": "tsdown",
|
|
21
|
-
"build:binaries": "tsx scripts/build-binaries.ts",
|
|
22
|
-
"typecheck": "tsc --noEmit",
|
|
23
|
-
"lint": "node -e \"console.log('lint: TypeScript ESLint v9 setup pending — see eslint.config.mjs');\"",
|
|
24
|
-
"test": "vitest run",
|
|
25
|
-
"test:watch": "vitest",
|
|
26
|
-
"test:all": "vitest run tests/unit tests/integration tests/security",
|
|
27
|
-
"test:release": "vitest run tests/e2e tests/update --testTimeout=600000",
|
|
28
|
-
"test:smoke": "vitest run tests/smoke --testTimeout=60000",
|
|
29
|
-
"test:update-golden": "UPDATE_GOLDEN=1 vitest run tests/e2e",
|
|
30
|
-
"render:globe": "tsx scripts/render-globe.ts",
|
|
31
|
-
"smoke": "bash scripts/smoke-test.sh",
|
|
32
|
-
"prepare": "husky install"
|
|
33
|
-
},
|
|
34
18
|
"dependencies": {
|
|
35
19
|
"@hono/node-server": "^1.14.0",
|
|
36
20
|
"cac": "^6.7.14",
|
|
@@ -54,11 +38,13 @@
|
|
|
54
38
|
"@types/node": "^22.10.0",
|
|
55
39
|
"@types/react": "^18.3.12",
|
|
56
40
|
"@types/semver": "^7.5.8",
|
|
41
|
+
"@typescript-eslint/parser": "^8.61.0",
|
|
57
42
|
"@vitest/coverage-v8": "^2.1.8",
|
|
58
43
|
"csv-parse": "^6.2.1",
|
|
59
44
|
"eslint": "^9.16.0",
|
|
60
45
|
"husky": "^9.1.7",
|
|
61
46
|
"ink-testing-library": "^4.0.0",
|
|
47
|
+
"react-devtools-core": "^4.19.1",
|
|
62
48
|
"tsdown": "^0.9.0",
|
|
63
49
|
"tsx": "^4.19.2",
|
|
64
50
|
"typescript": "^5.7.2",
|
|
@@ -67,7 +53,6 @@
|
|
|
67
53
|
"engines": {
|
|
68
54
|
"node": ">=20.0.0"
|
|
69
55
|
},
|
|
70
|
-
"packageManager": "pnpm@9.15.9",
|
|
71
56
|
"author": "Zenovay <cli@zenovay.com>",
|
|
72
57
|
"license": "SEE LICENSE IN LICENSE",
|
|
73
58
|
"homepage": "https://cli.zenovay.com",
|
|
@@ -85,5 +70,20 @@
|
|
|
85
70
|
"tui",
|
|
86
71
|
"ai-agent",
|
|
87
72
|
"install-wizard"
|
|
88
|
-
]
|
|
89
|
-
|
|
73
|
+
],
|
|
74
|
+
"scripts": {
|
|
75
|
+
"dev": "tsx src/bin.ts",
|
|
76
|
+
"build": "tsdown",
|
|
77
|
+
"build:binaries": "tsx scripts/build-binaries.ts",
|
|
78
|
+
"typecheck": "tsc --noEmit",
|
|
79
|
+
"lint": "eslint 'src/**/*.{ts,tsx}'",
|
|
80
|
+
"test": "vitest run",
|
|
81
|
+
"test:watch": "vitest",
|
|
82
|
+
"test:all": "vitest run tests/unit tests/integration tests/security",
|
|
83
|
+
"test:release": "vitest run tests/e2e tests/update --testTimeout=600000",
|
|
84
|
+
"test:smoke": "vitest run tests/smoke --testTimeout=60000",
|
|
85
|
+
"test:update-golden": "UPDATE_GOLDEN=1 vitest run tests/e2e",
|
|
86
|
+
"render:globe": "tsx scripts/render-globe.ts",
|
|
87
|
+
"smoke": "bash scripts/smoke-test.sh"
|
|
88
|
+
}
|
|
89
|
+
}
|
package/dist/ai-CPogCNEQ.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import{ApiClient as t}from"./api-FCanTxsb.js";import{readToken as n}from"./token-store-BQuGH0z2.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as r}from"./api-v2-CI5hxW-O.js";import{detectInstalled as i,initCommand as a}from"./init-BIJkCrgc.js";import{parseSseStream as o}from"./client-DTXWADkX.js";import"./formatter-DutfcQAc.js";import{emit$1 as s,isHeadless as c}from"./emit-DBYk96TD.js";import"./secrets-ApB7yh2A.js";import"./login-yhuXiFqh.js";import{Panel as l}from"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./progress-row-BpAXjJPL.js";import{Select as u}from"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./sparkline-BZ0eMB-w.js";import{ChatPanel as d}from"./chat-panel-CqJaCIg3.js";import{Box as f,Text as p,render as m}from"ink";import h from"react";async function g(e){let t=await i(e.cwd),n;if(e.mode)n=e.mode;else if(!t.installed)n=`install`;else if(c(e))return s({type:`error`,code:`no_mode`,message:`Headless mode requires --mode chat|mcp|install`}),2;else n=await _(t);return n===`install`?a({cliVersion:e.cliVersion,cwd:e.cwd,json:e.json}):n===`chat`?v(e):y(e)}async function _(e){return new Promise(t=>{let n=[{label:`Chat with your analytics`,value:`chat`,description:`Ask natural-language questions about your data`},{label:`Manage via MCP`,value:`mcp`,description:`Create goals, funnels, sites, etc. in plain English`},{label:`Re-run install / repair`,value:`install`,description:`Run the install wizard again`}],{unmount:r}=m(h.createElement(f,{flexDirection:`column`},h.createElement(l,{title:`Zenovay detected${e.packageMarker?` (${e.packageMarker})`:``}`,state:`idle`},h.createElement(p,null,`What do you want to do?`)),h.createElement(u,{items:n,onSelect:e=>{r(),t(e)}})))})}async function v(t){let i=await e(),a=await n({strict:!1});if(!a)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let o=i.defaultSiteId,s=i.defaultSiteName,c=new r({config:i,cliVersion:t.cliVersion,token:a});return new Promise(e=>{let{unmount:n}=m(h.createElement(d,{cliVersion:t.cliVersion,api:c,dashboardContext:{commandName:`ai chat`,siteId:o,siteLabel:s,metricsSnapshot:null},onClose:()=>{n(),e(0)}}))})}async function y(r){let i=await e(),a=await n({strict:!1});if(!a)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new t({config:i,cliVersion:r.cliVersion,token:a});process.stdout.write(`
|
|
2
|
-
Zenovay · MCP mode — describe what you want to create or change. Ctrl-C to exit.
|
|
3
|
-
|
|
4
|
-
> `);let c=await b();if(!c)return 0;let l=await s.openAiStream(`mcp`,{messages:[{role:`user`,content:c}]});for await(let e of o(l)){if(e.type===`delta`&&process.stdout.write(e.content),e.type===`tool_start`&&process.stdout.write(`\n[tool: ${e.name}] `),e.type===`tool_result`&&process.stdout.write(`
|
|
5
|
-
[result]`),e.type===`done`){process.stdout.write(`
|
|
6
|
-
`);break}if(e.type===`error`)return process.stderr.write(`\n[${e.code}] ${e.message}\n`),1}return 0}function b(){return new Promise(e=>{let t=``,n=r=>{let i=r.toString(`utf8`);i.includes(`
|
|
7
|
-
`)||i.includes(`\r`)?(t+=i.replace(/[\r\n]/g,``),process.stdin.off(`data`,n),process.stdin.pause(),e(t)):t+=i};process.stdin.resume(),process.stdin.on(`data`,n)})}export{g as aiCommand};
|
package/dist/alerts-DWVCFKlS.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{emitErrorEnvelope as n}from"./error-codes-C5caZH9p.js";import{ApiV2Client as r}from"./api-v2-CI5hxW-O.js";import{confirmDestructive as i}from"./confirm-DS5wux0g.js";import"./formatter-DutfcQAc.js";import{emitEnvelope as a,wrapItem as o,wrapList as s}from"./emit-DBYk96TD.js";import{Panel as c}from"./panel-B_yDcIcn.js";import{Banner as l}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{resolveSiteId as u}from"./resolve-site-mj0esTrm.js";import{fmtDate as d,shortId as f}from"./fmt-gMsty5jy.js";import{DataTable as p}from"./data-table-BpbyyNSA.js";import{Box as m,Text as h,render as g}from"ink";import _ from"react";const v=new Set([`visitors`,`pageviews`,`bounce_rate`,`avg_session_duration`,`errors`,`lcp`,`inp`,`cls`,`uptime`,`revenue`]),y=/^\d+(m|h|d)$/;function b(e){let t=e.metric;if(!t)return{errorMessage:"--metric is required for `alerts create`."};if(!v.has(t))return{errorMessage:`--metric must be one of: ${[...v].join(`, `)}. Got: ${t}.`};let n=e.op;if(n!==`gt`&&n!==`lt`)return{errorMessage:"--op must be `gt` or `lt`."};let r=e.threshold,i=typeof r==`number`?r:Number(r);if(!Number.isFinite(i))return{errorMessage:`--threshold must be a number.`};let a=e.window;if(!a||!y.test(a))return{errorMessage:"--window must match `<n>m|h|d` (e.g. 5m, 1h, 7d)."};let o=e.channel,s=`email`;if(o!==void 0){if(o!==`email`&&o!==`webhook`)return{errorMessage:`--channel must be 'email' or 'webhook'. Got: ${o}.`};s=o}return s===`email`&&!e.email?{errorMessage:`--email <addr> is required when --channel email (the default).`}:{body:{metric:t,op:n,threshold:i,window:a,...e.name?{name:e.name}:{},channel:s,...e.email?{email:e.email}:{}}}}async function x(c){let l=await e(),d=await t({strict:!1}),p=new r({config:l,cliVersion:c.cliVersion,token:d}),m;try{({siteId:m}=await u(p,{explicit:c.siteId,headless:!!c.json,cliVersion:c.cliVersion}))}catch(e){return c.json?n(e,{command:`alerts`,cliVersion:c.cliVersion}):(process.stderr.write(`${e.message}\n`),2)}try{switch(c.action){case`list`:{let e=await p.listAlerts(m);return c.json?(a(s(e,`alerts.list`,{siteId:m,cliVersion:c.cliVersion,command:`alerts list`})),0):e.length===0?(process.stdout.write("No alerts yet. Create one with `zenovay alerts create --metric <m> --op <gt|lt> --threshold <n> --window <1h>`.\n"),0):w(e,m,c.cliVersion)}case`create`:{let e=b(c);if(`errorMessage`in e)return c.json?n(new S(e.errorMessage),{command:`alerts create`,cliVersion:c.cliVersion}):(process.stderr.write(`Error: ${e.errorMessage}\n`),2);let t=await p.createAlert(m,e.body);return c.json?(a(o(t,`alerts.created`,{siteId:m,cliVersion:c.cliVersion,command:`alerts create`})),0):(process.stdout.write(`\n ✓ Alert created: ${t.metric} ${t.op} ${t.threshold} over ${t.window}\n id: ${t.id}\n\n`),0)}case`delete`:{if(!c.id){let e="alert id is required for `alerts delete`.";return c.json?n(new S(e),{command:`alerts delete`,cliVersion:c.cliVersion}):(process.stderr.write(`Error: ${e}\n`),2)}let e;try{let t=await p.listAlerts(m);e=t.find(e=>e.id===c.id)}catch{}let t=e?`${e.metric} ${e.op} ${e.threshold} (${f(c.id)})`:f(c.id),r=await i({resource:`alert`,name:t,yes:c.yes,destructive:!0});return r?(await p.deleteAlert(m,c.id),c.json?(a(o({deleted:!0,id:c.id},`alerts.deleted`,{siteId:m,cliVersion:c.cliVersion,command:`alerts delete`})),0):(process.stdout.write(`✓ Alert deleted (${f(c.id)}). Notifications stopped immediately.\n`),0)):c.json?(process.stdout.write(JSON.stringify({cancelled:!0})+`
|
|
2
|
-
`),1):(process.stdout.write(`Cancelled.
|
|
3
|
-
`),1)}}}catch(e){return c.json?n(e,{command:`alerts ${c.action}`,cliVersion:c.cliVersion}):(process.stderr.write(`✗ ${e.message}\n`),1)}}var S=class extends Error{constructor(e){super(e),this.name=`ValidationError`}};const C=({items:e,siteId:t,cliVersion:n})=>{let r=[{key:`id`,label:`id`,width:14,format:e=>f(String(e))},{key:`metric`,label:`metric`,width:18},{key:`op`,label:`op`,width:3},{key:`threshold`,label:`threshold`,width:10,align:`right`,format:e=>String(e??``)},{key:`window`,label:`window`,width:7},{key:`createdAt`,label:`created`,width:10,format:e=>d(e)}];return _.createElement(m,{flexDirection:`column`},_.createElement(l,{version:n,subtitle:`alerts · ${t}`}),_.createElement(c,{title:`${e.length} alert${e.length===1?``:`s`}`,state:`idle`},_.createElement(p,{columns:r,data:e,headerStyle:`accent`}),_.createElement(m,{marginTop:1},_.createElement(h,{color:`gray`},`Create: zenovay alerts create --metric <m> --op <gt|lt> --threshold <n> --window <1h>`))))};function w(e,t,n){return new Promise(r=>{let i=g(_.createElement(C,{items:e,siteId:t,cliVersion:n}));setTimeout(()=>{i.unmount(),r(0)},50)})}export{x as alertsCommand};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ApiError as e}from"./api-FCanTxsb.js";import{formatEvent as t}from"./formatter-DutfcQAc.js";import{Panel as n}from"./panel-B_yDcIcn.js";import{Banner as r}from"./banner-3iSWTDFy.js";import{Keybar as i}from"./keybar-DsYTkKZX.js";import{ChatPanel as a}from"./chat-panel-CqJaCIg3.js";import{Box as o,Text as s,render as c,useApp as l,useInput as u}from"ink";import d,{useEffect as f,useMemo as p,useReducer as m,useRef as h,useState as g}from"react";import _ from"ink-spinner";function v(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 y(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 b=({cliVersion:e})=>d.createElement(o,{flexDirection:`column`},d.createElement(r,{version:e,subtitle:`login required`}),d.createElement(n,{title:`Not logged in`,state:`warn`},d.createElement(s,null,`You need to authenticate before running this command.`),d.createElement(s,null,` `),d.createElement(s,{color:`gray`},`Run `),d.createElement(s,{color:`cyan`},`zenovay login`),d.createElement(s,{color:`gray`},` to start the device-flow.`)));function x(t){let{exit:c}=l(),[y,b]=m(v,{data:null,status:`loading`,error:null,refreshTick:0,focusIndex:0,showHelp:!1}),[x,S]=g(!1),C=h(b);C.current=b;let w=p(()=>{let e={q:{label:`quit`,handler:()=>{c(),t.onExit(0)}},r:{label:`refresh`,handler:()=>C.current({type:`refresh`})},"?":{label:`help`,handler:()=>C.current({type:`help-toggle`})}};return t.ai&&(e[`/`]={label:`ask AI`,handler:()=>S(!0)}),e},[c,t]),T=p(()=>({...t.keybindings??{},...w}),[t.keybindings,w]);if(u((e,n)=>{if(x)return;if(n.tab&&n.shift){b({type:`focus`,index:(y.focusIndex-1+t.panels.length)%t.panels.length});return}if(n.tab){b({type:`focus`,index:(y.focusIndex+1)%t.panels.length});return}if(e>=`1`&&e<=`9`){let n=Number(e)-1;n<t.panels.length&&b({type:`focus`,index:n});return}let r=T[e];r&&r.handler()}),f(()=>{let n=new AbortController,r=!1,i=async()=>{try{let e=await t.fetcher(n.signal);r||C.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;C.current({type:`error`,message:`This command requires a higher plan.`,status:402,upgradeUrl:n});return}C.current({type:`error`,message:t.message,status:t.status});return}if(t.name===`AbortError`)return;C.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,y.refreshTick]),f(()=>{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;C.current({type:`merge`,partial:r})}}catch(e){if(n||e.name===`AbortError`)return;C.current({type:`error`,message:e.message})}})(),()=>{n=!0,e.abort()}},[t.streamer]),x&&t.ai)return d.createElement(a,{cliVersion:t.cliVersion,api:t.ai.api,dashboardContext:{commandName:t.commandName,siteId:t.ai.siteId,siteLabel:t.ai.siteLabel,metricsSnapshot:y.data},onClose:()=>S(!1)});if(y.status===`loading`&&y.data===null)return d.createElement(o,{flexDirection:`column`},d.createElement(r,{version:t.cliVersion,subtitle:t.title}),d.createElement(n,{title:`Loading`,state:`busy`},d.createElement(o,null,d.createElement(s,{color:`magenta`},d.createElement(_,{type:`dots`})),d.createElement(s,null,` Fetching `,t.commandName,`…`))),d.createElement(i,{items:[{key:`q`,label:`quit`}]}));if(y.status===`error`&&y.error){let e=y.error.status===402;return d.createElement(o,{flexDirection:`column`},d.createElement(r,{version:t.cliVersion,subtitle:t.title}),d.createElement(n,{title:e?`Upgrade required`:`Error`,state:e?`warn`:`err`},d.createElement(s,{color:e?`yellow`:`red`},y.error.message),e&&y.error.upgradeUrl?d.createElement(d.Fragment,null,d.createElement(s,null,` `),d.createElement(s,{color:`gray`},`Upgrade: `),d.createElement(s,{color:`cyan`},y.error.upgradeUrl)):null),d.createElement(i,{items:[{key:`r`,label:`retry`},{key:`q`,label:`quit`}]}))}let E=y.data,D=Object.entries(T).map(([e,t])=>({key:e,label:t.label})),O=Math.ceil(t.panels.length/2),k=t.panels.slice(0,O),A=t.panels.slice(O);return d.createElement(o,{flexDirection:`column`},d.createElement(r,{version:t.cliVersion,subtitle:t.title}),d.createElement(o,{flexDirection:`row`},k.map((e,t)=>{let r=y.focusIndex===t;return d.createElement(o,{key:e.id,flexDirection:`column`,marginRight:1,flexGrow:1},d.createElement(n,{title:e.title,state:r?`busy`:`idle`},e.render(E,r)))})),A.length>0?d.createElement(o,{flexDirection:`row`},A.map((e,t)=>{let r=t+O,i=y.focusIndex===r;return d.createElement(o,{key:e.id,flexDirection:`column`,marginRight:1,flexGrow:1},d.createElement(n,{title:e.title,state:i?`busy`:`idle`},e.render(E,i)))})):null,y.showHelp?d.createElement(n,{title:`Help`,state:`idle`},Object.entries(T).map(([e,t])=>d.createElement(s,{key:e},`[`,e,`] `,t.label)),d.createElement(s,{color:`gray`},`[tab/shift+tab] cycle focus [1-9] focus panel`)):null,d.createElement(i,{items:D}))}async function S(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}=c(d.createElement(b,{cliVersion:e.cliVersion}));setTimeout(()=>{n(),t(2)},50)}):e.format?y(e,e.format):new Promise(t=>{let{unmount:n}=c(d.createElement(x,{...e,onExit:e=>{n(),t(e)}}))})}export{S as runAnalyticalScreen};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import{ApiError as t}from"./api-FCanTxsb.js";import{readToken as n}from"./token-store-BQuGH0z2.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as r}from"./api-v2-CI5hxW-O.js";import"./client-DTXWADkX.js";import"./formatter-DutfcQAc.js";import{emit$1 as i,isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as c}from"./keybar-DsYTkKZX.js";import"./sparkline-BZ0eMB-w.js";import{ChatPanel as l}from"./chat-panel-CqJaCIg3.js";import{resolveSiteId as u}from"./resolve-site-mj0esTrm.js";import{stripUrlPrefix as d}from"./fmt-gMsty5jy.js";import{DataTable as f}from"./data-table-BpbyyNSA.js";import{EmptyState as p}from"./empty-state-CJxa1jUN.js";import{MetricCard as m}from"./metric-card-COEIZmbN.js";import{Bar as h}from"./bar-DWT-1xOE.js";import{deepLinkFor as g,openInBrowser as _}from"./keybar-deep-link-DC31T3CP.js";import{Box as v,Text as y,render as b,useApp as x,useInput as S}from"ink";import C,{useEffect as w,useState as T}from"react";import E from"ink-spinner";function D(e){if(!(e instanceof t))return!1;let n=e.status;if(n===401||n===403||n===404)return!0;let r=e.body,i=r?.code;return i===`forbidden`||i===`not_found`||i===`auth_required`||i===`auth_invalid`||i===`tier_insufficient`}function O(e,t){return e.catch(e=>{if(D(e))throw e;return t})}async function k(t){let o=await e(),s=await n({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new r({config:o,cliVersion:t.cliVersion,token:s}),l,d;try{({siteId:l,site:d}=await u(c,{explicit:t.siteId,headless:!!t.json,cliVersion:t.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??l;if(a(t))try{let e=await j(c,l,`24h`);if(t.csv||t.tsv){let{writeCsv:n}=await import(`./csv-emit-BuRZNWYM.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-fnm-9MRL.js`);return n(e,{command:`analytics`,cliVersion:t.cliVersion})}return new Promise(e=>{let{unmount:n}=b(C.createElement(M,{api:c,siteId:l,siteLabel:f,cliVersion:t.cliVersion,onExit:t=>{n(),e(t)}}))})}function A(e){return e===`24h`?`7d`:e}async function j(e,t,n){let[r,i,a,o,s]=await Promise.all([O(e.getStats(t,n),null),O(e.getPages(t),[]),O(e.getSources(t,A(n),`prev`),null),O(e.getGeo(t),null),O(e.getDevices(t),null)]),c=i.reduce((e,t)=>e+t.views,0),l=(r?.daily??[]).map(e=>e.visitors),u=(r?.daily??[]).map(e=>e.pageviews),d=Math.floor(l.length/2),f=l.slice(0,d).reduce((e,t)=>e+t,0),p=u.slice(0,d).reduce((e,t)=>e+t,0),m=(a?.sources??[]).filter(e=>e.channel!==`other`||!e.source.includes(`/`)).slice(0,6).map(e=>({name:e.source,visitors:e.visitors,delta:e.delta??null}));return{visitors:r?.visitors??0,pageviews:r?.pageviews??c,bounceRate:r?.bounceRate??null,avgSession:r?.avgSessionSec??null,series:l,pageviewsSeries:u,prevVisitors:f,prevPageviews:p,topPages:i.slice(0,10),channels:m,countries:(o?.countries??[]).slice(0,8),browsers:(s?.browsers??[]).slice(0,5),devices:(s?.devices??[]).slice(0,5)}}const M=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=x(),[u,b]=T(null),[D,O]=T(!0),[k,A]=T(null),[M,N]=T(`24h`),[P,F]=T(t),[I,L]=T(n),[R,z]=T(!1),[B,V]=T([]),[H,U]=T(!1);S(async t=>{if(!H){if(t===`/`){U(!0);return}if(t===`o`||t===`O`){_(g(`overview`,{siteId:P}));return}if(t===`q`){a(),i(0);return}if(t===`1`){N(`24h`);return}if(t===`2`){N(`7d`);return}if(t===`3`){N(`30d`);return}if(t===`4`){N(`90d`);return}if(t===`s`){if(B.length===0)try{let t=await e.getSites();V(t)}catch{}z(e=>!e);return}}}),w(()=>{let t=!1;return O(!0),(async()=>{try{let n=await j(e,P,M);t||(b(n),O(!1))}catch(e){t||(A(e.message),O(!1))}})(),()=>{t=!0}},[e,P,M]);let W=()=>C.createElement(o,{title:`Switch site`,state:`idle`},B.length===0?C.createElement(y,{color:`gray`},`Loading your sites…`):B.map(e=>C.createElement(v,{key:e.id},C.createElement(y,{color:e.id===P?`cyan`:`gray`},e.id===P?`› `:` `),C.createElement(y,{bold:e.id===P},e.name),C.createElement(y,{color:`gray`},` (`,e.url.replace(/^https?:\/\//,``).replace(/\/$/,``),`)`))),C.createElement(v,{marginTop:1},C.createElement(y,{color:`gray`},`Press `),C.createElement(y,{color:`cyan`},`[number]`),C.createElement(y,{color:`gray`},` to pick, `),C.createElement(y,{color:`cyan`},`[s]`),C.createElement(y,{color:`gray`},` to close.`)));S(e=>{if(H||!R)return;let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=B.length){let e=B[t-1];F(e.id),L(e.url.replace(/^https?:\/\//,``).replace(/\/$/,``)),z(!1)}});let G=`overview · ${I} · ${M}`,K=[{key:`q`,label:`quit`},{key:`/`,label:`ask AI`},{key:`o`,label:`open in browser`},{key:`s`,label:`site`},{key:`1-4`,label:`range (24h/7d/30d/90d)`}];if(H)return C.createElement(l,{cliVersion:r,api:e,dashboardContext:{commandName:`overview`,siteId:P,siteLabel:I,metricsSnapshot:u},onClose:()=>U(!1)});if(D)return C.createElement(v,{flexDirection:`column`},C.createElement(s,{version:r,subtitle:G}),C.createElement(o,{title:`Loading`,state:`busy`},C.createElement(v,null,C.createElement(y,{color:`cyan`},C.createElement(E,{type:`dots`})),C.createElement(y,null,` Fetching dashboard…`))),R?W():null);if(k)return C.createElement(v,{flexDirection:`column`},C.createElement(s,{version:r,subtitle:G}),C.createElement(p,{reason:`error`,headline:`Failed to load`,hint:k}),R?W():null,C.createElement(c,{items:K}));if(!u||u.visitors===0&&u.pageviews===0&&u.topPages.length===0)return C.createElement(v,{flexDirection:`column`},C.createElement(s,{version:r,subtitle:G}),C.createElement(p,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event — or press [s] to switch to a different site, or [1-4] to widen the time range.`}),R?W():null,C.createElement(c,{items:K}));let q=process.stdout.columns??80,J=Math.max(18,Math.floor(q/4)-1),Y=Math.max(28,Math.floor(q/2)-2),X=[{key:`path`,label:`path`,width:32,format:e=>d(String(e??``))},{key:`views`,label:`views`,align:`right`,width:8},{key:`uniqueVisitors`,label:`visitors`,align:`right`,width:8},{key:`avgTime`,label:`avg time`,align:`right`,width:9,format:e=>typeof e==`number`?`${Math.round(e/1e3)}s`:`—`},{key:`bounceRate`,label:`bounce`,align:`right`,width:7,format:e=>typeof e==`number`?`${(e*100).toFixed(0)}%`:`—`}],Z=u.prevVisitors>0?(u.visitors-u.prevVisitors)/u.prevVisitors:void 0,Q=u.prevPageviews>0?(u.pageviews-u.prevPageviews)/u.prevPageviews:void 0,ee=Math.max(1,...u.channels.map(e=>e.visitors)),te=Math.max(1,...u.countries.map(e=>e.visitors)),ne=Math.max(1,...u.browsers.map(e=>e.visitors)),re=Math.max(1,...u.devices.map(e=>e.visitors)),$=Math.max(8,Math.floor(Y/3));return C.createElement(v,{flexDirection:`column`},C.createElement(s,{version:r,subtitle:G}),C.createElement(v,{flexDirection:`row`},C.createElement(m,{title:`Visitors`,value:u.visitors,format:`number`,width:J,series:u.series,...typeof Z==`number`?{delta:Z}:{}}),C.createElement(m,{title:`Pageviews`,value:u.pageviews,format:`number`,width:J,series:u.pageviewsSeries,...typeof Q==`number`?{delta:Q}:{}}),C.createElement(m,{title:`Bounce rate`,value:u.bounceRate??``,emptyHint:`—`,format:`percent`,width:J}),C.createElement(m,{title:`Avg session`,value:u.avgSession??``,emptyHint:`—`,format:`duration`,width:J})),C.createElement(v,{flexDirection:`row`,flexWrap:`wrap`},C.createElement(v,{width:Y,flexDirection:`column`},C.createElement(o,{title:`Channels`},u.channels.length===0?C.createElement(y,{color:`gray`},`No channel data yet.`):u.channels.map(e=>C.createElement(v,{key:e.name,flexDirection:`row`},C.createElement(v,{width:12},C.createElement(y,null,e.name)),C.createElement(h,{value:e.visitors,max:ee,width:$,showPercent:!1,...typeof e.delta==`number`?{delta:e.delta}:{}}),C.createElement(y,{color:`gray`},` `,e.visitors))))),C.createElement(v,{width:Y,flexDirection:`column`},C.createElement(o,{title:`Top countries`},u.countries.length===0?C.createElement(y,{color:`gray`},`No geo data yet.`):u.countries.map(e=>C.createElement(v,{key:e.country,flexDirection:`row`},C.createElement(v,{width:5},C.createElement(y,null,e.country)),C.createElement(h,{value:e.visitors,max:te,width:$,showPercent:!1}),C.createElement(y,{color:`gray`},` `,e.visitors)))))),C.createElement(v,{flexDirection:`row`,flexWrap:`wrap`},C.createElement(v,{width:Y,flexDirection:`column`},C.createElement(o,{title:`Top browsers`},u.browsers.length===0?C.createElement(y,{color:`gray`},`No browser data yet.`):u.browsers.map(e=>C.createElement(v,{key:e.name,flexDirection:`row`},C.createElement(v,{width:12},C.createElement(y,null,e.name)),C.createElement(h,{value:e.visitors,max:ne,width:$,showPercent:!1}),C.createElement(y,{color:`gray`},` `,e.visitors))))),C.createElement(v,{width:Y,flexDirection:`column`},C.createElement(o,{title:`Top devices`},u.devices.length===0?C.createElement(y,{color:`gray`},`No device data yet.`):u.devices.map(e=>C.createElement(v,{key:e.name,flexDirection:`row`},C.createElement(v,{width:12},C.createElement(y,null,e.name)),C.createElement(h,{value:e.visitors,max:re,width:$,showPercent:!1}),C.createElement(y,{color:`gray`},` `,e.visitors)))))),C.createElement(o,{title:`Top pages (${M})`},u.topPages.length===0?C.createElement(y,{color:`gray`},`No pages with data in this window yet.`):C.createElement(f,{columns:X,data:u.topPages,zebra:!0})),R?W():null,C.createElement(c,{items:K}))};async function N(e){return k(e)}export{N as analyticsCommand};
|
package/dist/banner-3iSWTDFy.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{useTheme as e}from"./panel-B_yDcIcn.js";import{Box as t,Text as n}from"ink";import r from"react";function i(){let e=process.stdout.columns;return typeof e==`number`&&e>0?e:80}function a({version:a,subtitle:o}){let{theme:s}=e(),c=i(),l=`ZENOVAY`,u=`v${a}`,d=`╭─ `,f=` · `,p=` `,m=`─╮`,h=d.length+l.length+f.length+u.length+p.length+m.length,g=Math.max(2,c-h),_=`─`.repeat(g),v=`─`.repeat(Math.max(2,c-2)),y=o??``,b=y.slice(0,Math.max(0,c-4)),x=` `.repeat(Math.max(1,c-2-1-b.length-1));return r.createElement(t,{flexDirection:`column`},r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:s.border},d),r.createElement(n,{color:s.accent,bold:!0},l),r.createElement(n,{color:s.dim},f,u),r.createElement(n,{color:s.border},p,_,m)),o?r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:s.border},`│ `),r.createElement(n,{color:s.fg},b),r.createElement(n,{color:s.border},x,`│`)):null,r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:s.border},`╰`,v,`╯`)))}export{a as Banner};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{emit as e}from"./telemetry-DRh10SvO.js";import{parseSseStream as t}from"./client-DTXWADkX.js";import{useTheme as n}from"./panel-B_yDcIcn.js";import{Banner as r}from"./banner-3iSWTDFy.js";import{Box as i,Static as a,Text as o,useApp as s,useInput as c}from"ink";import l,{useEffect as u,useRef as d,useState as f}from"react";import p from"ink-spinner";import m from"ink-text-input";const h=2048;async function*g(e){let n=[{role:`system`,content:_(e.context)},...e.transcript,{role:`user`,content:e.newUserMessage}],r;try{r=await e.api.openAiStream(`chat`,{messages:n,siteId:e.context.siteId},e.signal)}catch(e){yield{type:`error`,message:e.message??`request failed`};return}if(!r.ok){yield{type:`error`,message:`chat request failed (${r.status})`,code:String(r.status)};return}let i=``;try{for await(let e of t(r))if(e.type===`delta`)i+=e.content,yield{type:`delta`,text:e.content};else if(e.type===`tool_start`)yield{type:`tool_start`,id:e.id,name:e.name};else if(e.type===`tool_result`)yield{type:`tool_result`,id:e.id,name:e.name,summary:e.summary,error:e.error};else if(e.type===`done`){yield{type:`done`,fullText:i};return}else if(e.type===`error`){yield{type:`error`,message:e.message,code:e.code};return}yield{type:`done`,fullText:i}}catch(e){if(e.name===`AbortError`){yield{type:`error`,message:`cancelled`,code:`aborted`};return}yield{type:`error`,message:e.message??`stream parse failed`}}}function _(e){let t=new Date().toISOString(),n=e.metricsSnapshot?v(e.metricsSnapshot,h):`(no live data yet)`,r=e.siteLabel?`${e.siteLabel}${e.siteId?` (id: ${e.siteId})`:``}`:e.siteId??`(no site)`;return[`You are the Zenovay AI assistant, embedded in the Zenovay terminal CLI.`,``,`The user is currently looking at the \`${e.commandName}\` view for their site ${r}.`,`They can ask questions about their analytics in plain English. Be concise`,`(≤200 words unless they ask for more). Cite specific numbers from the snapshot`,`below. Use plain text only — the terminal does not render markdown.`,``,`Current dashboard snapshot (live as of ${t}):`,n,``,`When you do not have enough data to answer, say so explicitly and tell`,`the user which command would surface that data (e.g. "run zenovay sources`,`--period 30d to get monthly trends"). Do NOT fabricate numbers.`].join(`
|
|
2
|
-
`)}function v(e,t){let n=JSON.stringify(e);if(n.length<=t)return JSON.stringify(e,null,2);let r=JSON.parse(n);for(let e=0;e<5;e+=1){r=y(r,10-e*2);let n=JSON.stringify(r);if(n.length<=t)return JSON.stringify(r,null,2)}let i=JSON.stringify(r).slice(0,t-16);return i+`… [truncated]`}function y(e,t){if(Array.isArray(e))return e.length>t?[...e.slice(0,t),`… ${e.length-t} more elided`]:e.map(e=>y(e,t));if(e&&typeof e==`object`){let n={};for(let[r,i]of Object.entries(e))n[r]=y(i,t);return n}return e}const b=30,x=6e4,S=({cliVersion:t,api:h,dashboardContext:_,onClose:v})=>{let{theme:y}=n(),{exit:S}=s(),[C,w]=f([]),[T,E]=f(``),[D,O]=f(!1),[k,A]=f(``),[j,M]=f(null),[N,P]=f([]),F=d(``),I=d(null);u(()=>{if(!D)return;let e=setInterval(()=>{F.current!==k&&A(F.current)},Math.floor(1e3/b));return()=>clearInterval(e)},[D,k]);let L=d(Date.now()),R=d(0),z=d(0);u(()=>(e(`chat.open`,{properties:{from:_.commandName,has_site:!!_.siteId}}),()=>{e(`chat.close`,{duration_ms:Date.now()-L.current,properties:{turns:R.current,tools_called:z.current}})}),[_.commandName,_.siteId]),c((e,t)=>{if(t.escape){I.current?.abort(),v();return}if(t.ctrl&&e===`c`){I.current?.abort(),v();return}});let B=async t=>{let n=t.trim();if(!n)return;if(n.startsWith(`/`)){V(n),E(``);return}if(D)return;E(``),M(null);let r={role:`user`,content:n};w(e=>[...e,r]),F.current=``,A(``),P([]),O(!0),I.current=new AbortController;let i=setTimeout(()=>{I.current?.abort(),M(`AI request timed out after ${x/1e3}s`)},x);try{let t=g({api:h,transcript:C,newUserMessage:n,context:_,signal:I.current.signal});R.current+=1;for await(let n of t)if(n.type===`delta`)F.current+=n.text;else if(n.type===`tool_start`)z.current+=1,e(`chat.tool_call`,{properties:{tool_name:n.name}}),P(e=>[...e,{id:n.id,name:n.name,status:`running`}]);else if(n.type===`tool_result`)n.error&&e(`chat.tool_error`,{properties:{tool_name:n.name??`unknown`,error:n.error.slice(0,128)}}),P(e=>e.map(e=>e.id===n.id?{...e,status:n.error?`error`:`done`,summary:n.summary,error:n.error,name:n.name??e.name}:e));else if(n.type===`done`){let e=n.fullText.length>0?n.fullText:F.current;w(t=>[...t,{role:`assistant`,content:e}]);break}else if(n.type===`error`){M(n.message),F.current.length>0&&w(e=>[...e,{role:`assistant`,content:F.current}]);break}}catch(e){M(e.message??`unknown error`)}finally{clearTimeout(i),F.current=``,A(``),P([]),O(!1),I.current=null}},V=e=>{let t=e.toLowerCase();if(t===`/clear`){w([]),M(null);return}if(t===`/exit`||t===`/quit`){I.current?.abort(),v();return}if(t===`/help`){w(e=>[...e,{role:`assistant`,content:`Slash commands:
|
|
3
|
-
/clear — wipe the transcript
|
|
4
|
-
/exit — close the chat (or press Esc)
|
|
5
|
-
/help — show this list
|
|
6
|
-
|
|
7
|
-
Ask anything about your current dashboard data.`}]);return}M(`Unknown slash command: ${e}. Try /help.`)},H=[`chat`,_.commandName,_.siteLabel].filter(e=>!!e);return l.createElement(i,{flexDirection:`column`},l.createElement(r,{version:t,subtitle:H.join(` · `)}),C.length===0&&!D?l.createElement(i,{marginTop:1,marginLeft:2},l.createElement(o,{color:y.dim},`Ask anything about your data. Try: "what's my top page today?"`)):null,l.createElement(a,{items:C},(e,t)=>l.createElement(i,{key:t,flexDirection:`column`,marginTop:1,marginLeft:2},l.createElement(o,{color:e.role===`user`?y.accent:y.dim,bold:!0},e.role===`user`?`you`:`ai`),l.createElement(o,{color:y.fg},e.content))),D?l.createElement(i,{flexDirection:`column`,marginTop:1,marginLeft:2},l.createElement(i,{flexDirection:`row`},l.createElement(o,{color:y.dim,bold:!0},`ai `),l.createElement(o,{color:`cyan`},l.createElement(p,{type:`dots`}))),N.length>0?l.createElement(i,{flexDirection:`column`,marginTop:0},N.map(e=>l.createElement(o,{key:e.id,color:e.status===`error`?y.error??`red`:y.dim},e.status===`running`?`… fetching `:e.status===`done`?`✓ `:`✗ `,e.name,e.status===`done`&&e.summary?` → ${e.summary}`:``,e.status===`error`&&e.error?`: ${e.error}`:``))):null,k.length>0?l.createElement(o,{color:y.fg},k):null):null,j?l.createElement(i,{marginTop:1,marginLeft:2},l.createElement(o,{color:y.error??`red`},`✗ `,j)):null,l.createElement(i,{marginTop:1,marginLeft:2,flexDirection:`column`},l.createElement(i,{flexDirection:`row`},l.createElement(o,{color:y.accent},D?`⋯ `:`> `),l.createElement(m,{value:T,onChange:E,onSubmit:e=>void B(e),placeholder:D?`streaming…`:`ask the AI`})),l.createElement(i,{marginTop:1},l.createElement(o,{color:y.dim},`[Enter] send · [/clear] reset · [/help] · [Esc] back to dashboard`))))};export{S as ChatPanel};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CI5hxW-O.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./chat-panel-CqJaCIg3.js";import{resolveSiteId as a}from"./resolve-site-mj0esTrm.js";import{DataTable as o}from"./data-table-BpbyyNSA.js";import{deepLinkFor as s,openInBrowser as c}from"./keybar-deep-link-DC31T3CP.js";import{runAnalyticalScreen as l}from"./analytical-screen-BasvNR-9.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`,ai:{api:v,siteId:y,siteLabel:b?.url?b.url.replace(/^https?:\/\//,``).replace(/\/$/,``):b?.name??y},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 +0,0 @@
|
|
|
1
|
-
import"./formatter-DutfcQAc.js";import{toCsv as e,writeCsv as t}from"./csv-emit-Dn3c0RCG.js";export{t as writeCsv};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{formatTabular as e}from"./formatter-DutfcQAc.js";function t(t,n,r){return e(t,n,r)}function n(e,n,r){return process.stdout.write(t(e,n,r)),0}export{t as toCsv,n as writeCsv};
|
package/dist/deploys-DTIU1Kqt.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CI5hxW-O.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./chat-panel-CqJaCIg3.js";import{resolveSiteId as a}from"./resolve-site-mj0esTrm.js";import{DataTable as o}from"./data-table-BpbyyNSA.js";import{runAnalyticalScreen as s}from"./analytical-screen-BasvNR-9.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`,ai:{api:h,siteId:g,siteLabel:_?.url?_.url.replace(/^https?:\/\//,``).replace(/\/$/,``):_?.name??g},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};
|
package/dist/devices-DK_o0JcI.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CI5hxW-O.js";import"./formatter-DutfcQAc.js";import{emit$1 as r,isHeadless as i}from"./emit-DBYk96TD.js";import{Panel as a}from"./panel-B_yDcIcn.js";import{Banner as o}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as s}from"./keybar-DsYTkKZX.js";import{resolveSiteId as c}from"./resolve-site-mj0esTrm.js";import{DataTable as l}from"./data-table-BpbyyNSA.js";import{EmptyState as u}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as d,openInBrowser as f}from"./keybar-deep-link-DC31T3CP.js";import{Box as p,Text as m,render as h,useApp as g,useInput as _}from"ink";import v,{useEffect as y,useState as b}from"react";import x from"ink-spinner";async function S(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getDevices(u);if(a.csv||a.tsv){let{writeCsv:t}=await import(`./csv-emit-BuRZNWYM.js`);return t(e.devices,[`name`,`visitors`],a.tsv?`tsv`:`csv`)}if(a.ndjson){for(let t of e.devices)process.stdout.write(JSON.stringify(t)+`
|
|
2
|
-
`);return 0}return r({type:`devices.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=h(v.createElement(C,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=g(),[h,S]=b(null),[C,w]=b(!0),[T,E]=b(null);if(_(e=>{if(e===`o`||e===`O`){f(d(`devices`,{siteId:t}));return}e===`q`&&(c(),i(0))}),y(()=>{let n=!1;return(async()=>{try{let r=await e.getDevices(t);n||(S(r),w(!1))}catch(e){n||(E(e.message),w(!1))}})(),()=>{n=!0}},[e,t]),C)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`devices · ${n}`}),v.createElement(a,{title:`Loading`,state:`busy`},v.createElement(p,null,v.createElement(m,{color:`magenta`},v.createElement(x,{type:`dots`})),v.createElement(m,null,` Fetching breakdown…`))));if(T)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`devices · ${n}`}),v.createElement(u,{reason:`error`,headline:`Failed to load`,hint:T}));let D=!h||h.devices.length===0&&h.browsers.length===0&&h.os.length===0;if(D)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`devices · ${n}`}),v.createElement(u,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let O=[{key:`name`,label:`name`,width:16},{key:`visitors`,label:`visitors`,align:`right`,width:8}];return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`devices · ${n}`}),v.createElement(p,{flexDirection:`row`},v.createElement(a,{title:`Devices`},h.devices.length===0?v.createElement(m,{color:`gray`},`— —`):v.createElement(l,{columns:O,data:h.devices,zebra:!0})),v.createElement(a,{title:`Browsers`},h.browsers.length===0?v.createElement(m,{color:`gray`},`— —`):v.createElement(l,{columns:O,data:h.browsers,zebra:!0})),v.createElement(a,{title:`OS`},h.os.length===0?v.createElement(m,{color:`gray`},`— —`):v.createElement(l,{columns:O,data:h.os,zebra:!0}))),v.createElement(s,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{S as devicesCommand};
|
package/dist/errors-Dig3nVCV.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CI5hxW-O.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./progress-row-BpAXjJPL.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import{spark as a}from"./sparkline-BZ0eMB-w.js";import"./chat-panel-CqJaCIg3.js";import{resolveSiteId as o}from"./resolve-site-mj0esTrm.js";import{DataTable as s}from"./data-table-BpbyyNSA.js";import"./bar-DWT-1xOE.js";import{deepLinkFor as c,openInBrowser as l}from"./keybar-deep-link-DC31T3CP.js";import{runAnalyticalScreen as u}from"./analytical-screen-BasvNR-9.js";import"./ui-Cey-h6wI.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`,ai:{api:y,siteId:b,siteLabel:x?.url?x.url.replace(/^https?:\/\//,``).replace(/\/$/,``):x?.name??b},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,5 +0,0 @@
|
|
|
1
|
-
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import{ApiClient as n}from"./api-FCanTxsb.js";import{readToken as r}from"./token-store-BQuGH0z2.js";import{parseSseStream as i}from"./client-DTXWADkX.js";import"./formatter-DutfcQAc.js";import{isHeadless as a}from"./emit-DBYk96TD.js";import{Panel as o}from"./panel-B_yDcIcn.js";import{Banner as s}from"./banner-3iSWTDFy.js";import{TextInput as c}from"./prompt-D-Uzz_GF.js";import{Keybar as l}from"./keybar-DsYTkKZX.js";import u from"node:path";import{promises as d}from"node:fs";import f from"node:os";import p from"node:crypto";import{Box as m,Static as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useRef as S,useState as C}from"react";const w=new Set([`type`,`page`,`country`,`device`,`user_id`,`sessionId`,`referrer`,`ts`,`url`,`method`,`status`]);function T(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(/\s/.test(r)){n+=1;continue}if(r===`(`){t.push({kind:`lparen`}),n+=1;continue}if(r===`)`){t.push({kind:`rparen`}),n+=1;continue}if(r===`"`||r===`'`){let i=r,a=n+1,o=``;for(;a<e.length&&e[a]!==i;)e[a]===`\\`&&a+1<e.length?(o+=e[a+1],a+=2):(o+=e[a],a+=1);if(a>=e.length)throw Error(`filter: unterminated string starting at column ${n+1}`);t.push({kind:`string`,value:o}),n=a+1;continue}if(r===`!`&&e[n+1]===`=`){t.push({kind:`op`,value:`!=`}),n+=2;continue}if(r===`!`&&e[n+1]===`~`){t.push({kind:`op`,value:`!~`}),n+=2;continue}if(r===`=`){t.push({kind:`op`,value:`=`}),n+=1;continue}if(r===`~`){t.push({kind:`op`,value:`~`}),n+=1;continue}let i=n;for(;n<e.length&&!/[\s()=!~]/.test(e[n])&&e[n]!==`"`&&e[n]!==`'`;)n+=1;let a=e.slice(i,n);if(a.length===0)throw Error(`filter: unexpected character at column ${i+1}`);let o=a.toUpperCase();o===`AND`?t.push({kind:`and`}):o===`OR`?t.push({kind:`or`}):t.push({kind:`ident`,value:a})}return t}function E(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function D(e,t,n){let r=e==null?``:String(e);switch(t){case`=`:return r===n;case`!=`:return r!==n;case`~`:{let e=new RegExp(E(n),`i`);return e.test(r)}case`!~`:{let e=new RegExp(E(n),`i`);return!e.test(r)}}}function O(e){return e.tokens[e.pos]}function k(e){let t=e.tokens[e.pos];return e.pos+=1,t}function A(e){let t=O(e);if(!t)throw Error(`filter: unexpected end of expression`);if(t.kind===`lparen`){k(e);let t=j(e),n=k(e);if(!n||n.kind!==`rparen`)throw Error(`filter: missing closing ")"`);return t}if(t.kind!==`ident`)throw Error(`filter: expected key, got ${t.kind}`);k(e);let n=t.value;if(!w.has(n))throw Error(`filter: unknown key "${n}". Allowed: ${[...w].join(`, `)}`);let r=k(e);if(!r||r.kind!==`op`)throw Error(`filter: expected operator after "${n}"`);let i=k(e);if(!i||i.kind!==`ident`&&i.kind!==`string`)throw Error(`filter: expected value after operator "${r.value}"`);let a=r.value,o=i.value;return e=>D(e[n],a,o)}function j(e){let t=A(e);for(;;){let n=O(e);if(!n)break;if(n.kind===`and`){k(e);let n=A(e),r=t;t=e=>r(e)&&n(e);continue}if(n.kind===`or`){k(e);let n=A(e),r=t;t=e=>r(e)||n(e);continue}break}return t}function M(e){if(typeof e!=`string`||e.trim().length===0)throw Error(`filter: expression is empty`);let t=T(e);if(t.length===0)throw Error(`filter: expression is empty`);let n={tokens:t,pos:0},r=j(n);if(n.pos!==t.length){let e=n.tokens[n.pos];throw Error(`filter: unexpected trailing token "${N(e)}"`)}return r}function N(e){return e.kind===`ident`||e.kind===`string`||e.kind===`op`?e.value:e.kind}const P=10*1024*1024;var F=class{currentBytes=0;initialized=!1;writeQueue=Promise.resolve();constructor(e,t=P){this.filePath=e,this.maxBytes=t}async init(){if(!this.initialized){this.initialized=!0;try{await d.mkdir(u.dirname(this.filePath),{recursive:!0,mode:448})}catch{}try{let e=await d.stat(this.filePath);this.currentBytes=e.size}catch{this.currentBytes=0}}}append(e){let t=(async()=>{await this.init();let t=e.endsWith(`
|
|
2
|
-
`)?e:`${e}\n`,n=Buffer.byteLength(t,`utf8`);this.currentBytes+n>this.maxBytes&&await this.rotate();try{await d.appendFile(this.filePath,t,{mode:384}),this.currentBytes+=n}catch(e){process.stderr.write(`[scrollback] append failed: ${e.message}\n`)}})();return this.writeQueue=this.writeQueue.then(()=>t,()=>t),t}async rotate(){let e=e=>{if(e===0)return this.filePath;let t=u.parse(this.filePath);return u.join(t.dir,`${t.name}.${e}${t.ext}`)};try{await d.unlink(e(3))}catch{}for(let t=2;t>=0;--t)try{await d.rename(e(t),e(t+1))}catch(n){n.code!==`ENOENT`&&process.stderr.write(`[scrollback] rotate ${e(t)} failed: ${n.message}\n`)}this.currentBytes=0}async close(){await this.writeQueue}};const I=5e3,L=33,R=`─── replay end, live below ───`;async function z(i){if(i.setForwardSecret)return await t({forwardSecret:i.setForwardSecret}),process.stdout.write(`Forward secret saved.
|
|
3
|
-
`),0;let o=await e(),s=await r({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:i.cliVersion,token:s}),l=null;if(i.filter)try{l=M(i.filter)}catch(e){return process.stderr.write(`Invalid --filter expression: ${e.message}\n`),2}if(a(i))return H(c,i,l,o.forwardSecret);let d=i.scrollbackPath??u.join(f.homedir(),`.zenovay`,`events-scrollback.log`);return new Promise(e=>{let{unmount:t}=_(b.createElement(U,{api:c,opts:i,predicate:l,forwardSecret:o.forwardSecret,scrollbackPath:d,onExit:n=>{t(),e(n)}}))})}function B(e){return{raw:JSON.stringify(e),parsed:e}}async function V(e,t,n){let r=JSON.stringify(n),i=p.createHmac(`sha256`,t).update(r).digest(`hex`);try{await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Zenovay-Signature":`sha256=${i}`},body:r})}catch{}}async function H(e,t,n,r){let a=new AbortController;process.on(`SIGINT`,()=>a.abort());let o=()=>new Date().toISOString();try{let s=await e.openEventsStream(t.siteId,a.signal);for await(let e of i(s)){if(e.type===`error`)return process.stdout.write(`${JSON.stringify({ts:o(),type:`error`,code:e.code,message:e.message})}\n`),1;if(e.type===`done`)return 0;let i=e;if(n&&!n(i))continue;process.stdout.write(`${JSON.stringify({ts:o(),...i})}\n`),t.forwardTo&&r&&await V(t.forwardTo,r,{event:e,ts:o(),site_id:t.siteId})}return 0}catch(e){return process.stdout.write(`${JSON.stringify({ts:o(),type:`error`,code:`stream_failed`,message:e.message})}\n`),1}}const U=({api:e,opts:t,predicate:n,forwardSecret:r,scrollbackPath:a,onExit:u})=>{let{exit:f}=v(),p=S([]),_=S(null),[w,T]=C([]),[E,D]=C(null),[O,k]=C(!1),[A,j]=C(null);_.current||=new F(a),y(n=>{if(!O){if(E){D(null);return}if(n===`q`){f(),u(0);return}if(n===`f`){let e=p.current[p.current.length-1];e&&D(e);return}if(n===`w`){k(!0);return}if(n===`r`){G(e,t.siteId,p,j);return}}}),x(()=>{let e=setInterval(()=>{let e=p.current.slice(-100);T(e)},L);return()=>clearInterval(e)},[]),x(()=>{let a=new AbortController,o=!1;return(async()=>{t.replay24h&&await G(e,t.siteId,p,j);try{let s=await e.openEventsStream(t.siteId,a.signal);for await(let e of i(s)){if(o)break;if(e.type===`error`){let t={raw:`[ERR ${e.code}] ${e.message}`};W(p,t),_.current?.append(t.raw);continue}if(e.type===`done`)break;let i=e;if(n&&!n(i))continue;let a=B(e);W(p,a),_.current?.append(a.raw),t.forwardTo&&r&&V(t.forwardTo,r,{event:e,ts:new Date().toISOString(),site_id:t.siteId})}}catch(e){let t={raw:`[DISCONNECT] ${e.message}`};W(p,t)}})(),()=>{o=!0,a.abort(),_.current?.close()}},[e,t.siteId,t.replay24h,t.forwardTo,n,r]);let M=async e=>{let t=e.trim()||`events.ndjson`;try{let e=p.current.map(e=>e.raw).join(`
|
|
4
|
-
`)+`
|
|
5
|
-
`;await d.writeFile(t,e,{mode:384}),j(`Wrote ${p.current.length} events → ${t}`)}catch(e){j(`Write failed: ${e.message}`)}k(!1)};return b.createElement(m,{flexDirection:`column`},b.createElement(s,{version:t.cliVersion,subtitle:`events tail · ${t.siteId}`}),b.createElement(h,{items:w},(e,t)=>b.createElement(g,{key:`v-${t}`,color:e.marker?`cyan`:void 0},e.raw)),E?b.createElement(o,{title:`Frozen event (press any key to resume)`,state:`warn`},b.createElement(g,null,E.parsed?JSON.stringify(E.parsed,null,2):E.raw)):null,O?b.createElement(o,{title:`Write buffer to NDJSON`,state:`busy`},b.createElement(c,{question:`filename:`,placeholder:`events.ndjson`,onSubmit:M})):null,A?b.createElement(g,{color:`green`},A):null,b.createElement(l,{items:[{key:`f`,label:`freeze`},{key:`w`,label:`write`},{key:`r`,label:`replay 24h`},{key:`q`,label:`quit`}]}))};function W(e,t){e.current.push(t),e.current.length>I&&e.current.splice(0,e.current.length-I)}async function G(e,t,n,r){let i=e.getEventsHistory;if(typeof i==`function`)try{let a=await i.call(e,t,`24h`);if(Array.isArray(a))for(let e of a)W(n,{raw:JSON.stringify(e),parsed:e});W(n,{raw:R,marker:!0}),r(`Replayed ${Array.isArray(a)?a.length:0} events`);return}catch(e){r(`Replay failed: ${e.message}`);return}r(`Replay endpoint coming Wave 1`)}export{z as eventsTailCommand};
|
package/dist/export-DkAIRS9F.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{emitErrorEnvelope as n}from"./error-codes-C5caZH9p.js";import{ApiV2Client as r}from"./api-v2-CI5hxW-O.js";import{requireTier as i}from"./tier-BneaO4vD.js";import"./formatter-DutfcQAc.js";import{emitEnvelope as a,wrapItem as o}from"./emit-DBYk96TD.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{resolveSiteId as s}from"./resolve-site-mj0esTrm.js";import{toCsv as c}from"./csv-emit-Dn3c0RCG.js";import{resolve as l}from"node:path";import{writeFile as u}from"node:fs/promises";function d(e){let t=(e??`30d`).toLowerCase();return t===`7d`||t===`30d`||t===`90d`?t:`30d`}function f(e,t){t||process.stderr.isTTY&&process.stderr.write(`${e}\n`)}async function p(c){let p=await e(),g=await t({strict:!1}),_=new r({config:p,cliVersion:c.cliVersion,token:g});if(c.type!==`analytics`&&c.type!==`sessions`&&c.type!==`heatmaps`){let e=`Unknown export type '${c.type}'. Use one of: analytics, sessions, heatmaps.`;return c.json?n(Error(e),{command:`export`,cliVersion:c.cliVersion}):(process.stderr.write(`Error: ${e}\n`),2)}let v=c.format===`json`?`json`:`csv`,y=d(c.range),b=!!c.json;if(c.type===`sessions`||c.type===`heatmaps`)try{await i(_,`pro`)}catch(e){return c.json?n(e,{command:`export ${c.type}`,cliVersion:c.cliVersion}):(process.stderr.write(`${e.message}\n`),2)}let x;try{({siteId:x}=await s(_,{explicit:c.siteId,headless:b,cliVersion:c.cliVersion}))}catch(e){return c.json?n(e,{command:`export ${c.type}`,cliVersion:c.cliVersion}):(process.stderr.write(`${e.message}\n`),2)}try{f(`→ Fetching ${c.type} ${y}...`,b);let{rows:e,columns:t}=await m(_,c.type,x,y),n=h(e,t,v),r=c.out?l(process.cwd(),c.out):null;return r?(await u(r,n,`utf8`),c.json?(a(o({rowsWritten:e.length,file:r,format:v,range:y,type:c.type},`export.completed`,{siteId:x,command:`export ${c.type}`,cliVersion:c.cliVersion})),0):(process.stdout.write(`✓ Exported ${e.length} rows to ${r}\n`),0)):(process.stdout.write(n),n.endsWith(`
|
|
2
|
-
`)||process.stdout.write(`
|
|
3
|
-
`),c.json&&a(o({rowsWritten:e.length,file:null,format:v,range:y,type:c.type},`export.completed`,{siteId:x,command:`export ${c.type}`,cliVersion:c.cliVersion})),0)}catch(e){return c.json?n(e,{command:`export ${c.type}`,cliVersion:c.cliVersion}):(process.stderr.write(`✗ ${e.message}\n`),1)}}async function m(e,t,n,r){if(t===`analytics`){let t=await e.getStats(n,r);if(t.daily&&t.daily.length>0){let e=t.daily.map(e=>({date:e.date,visitors:e.visitors,pageviews:e.pageviews}));return{rows:e,columns:[`date`,`visitors`,`pageviews`]}}let i=[{range:r,visitors:t.visitors,pageviews:t.pageviews,sessions:t.sessions,bounceRate:t.bounceRate,avgSessionSec:t.avgSessionSec,windowStart:t.windowStart,windowEnd:t.windowEnd}];return{rows:i,columns:[`range`,`visitors`,`pageviews`,`sessions`,`bounceRate`,`avgSessionSec`,`windowStart`,`windowEnd`]}}if(t===`sessions`){let t=await e.getSessions(n),r=t.map(e=>({id:e.id,visitor:e.visitor,durationMs:e.duration,startedAt:e.startedAt,pageCount:e.pageCount,deviceType:e.deviceType??``}));return{rows:r,columns:[`id`,`visitor`,`durationMs`,`startedAt`,`pageCount`,`deviceType`]}}let i=await e.getHeatmaps(n),a=i.map(e=>({id:e.id,url:e.url,type:e.type,captureCount:e.captureCount,createdAt:e.createdAt}));return{rows:a,columns:[`id`,`url`,`type`,`captureCount`,`createdAt`]}}function h(e,t,n){if(n===`json`){let n=e.map(e=>{let n={};for(let r of t)n[String(r)]=e[r];return n});return JSON.stringify(n,null,2)+`
|
|
4
|
-
`}return c(e,t,`csv`)}export{p as exportCommand};
|
package/dist/funnel-Brtq8avo.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CI5hxW-O.js";import"./client-DTXWADkX.js";import{formatTabular as r,selectFormat as i}from"./formatter-DutfcQAc.js";import"./panel-B_yDcIcn.js";import"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import"./keybar-DsYTkKZX.js";import"./chat-panel-CqJaCIg3.js";import{resolveSiteId as a}from"./resolve-site-mj0esTrm.js";import{DataTable as o}from"./data-table-BpbyyNSA.js";import{deepLinkFor as s,openInBrowser as c}from"./keybar-deep-link-DC31T3CP.js";import{runAnalyticalScreen as l}from"./analytical-screen-BasvNR-9.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`,ai:{api:v,siteId:y,siteLabel:b?.url?b.url.replace(/^https?:\/\//,``).replace(/\/$/,``):b?.name??y},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`,ai:{api:v,siteId:y,siteLabel:b?.url?b.url.replace(/^https?:\/\//,``).replace(/\/$/,``):b?.name??y},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};
|
package/dist/geo-c9hA42_9.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CI5hxW-O.js";import"./formatter-DutfcQAc.js";import{emit$1 as r,isHeadless as i}from"./emit-DBYk96TD.js";import{Panel as a}from"./panel-B_yDcIcn.js";import{Banner as o}from"./banner-3iSWTDFy.js";import"./prompt-D-Uzz_GF.js";import{Keybar as s}from"./keybar-DsYTkKZX.js";import{resolveSiteId as c}from"./resolve-site-mj0esTrm.js";import{DataTable as l}from"./data-table-BpbyyNSA.js";import{EmptyState as u}from"./empty-state-CJxa1jUN.js";import{deepLinkFor as d,openInBrowser as f}from"./keybar-deep-link-DC31T3CP.js";import{Box as p,Text as m,render as h,useApp as g,useInput as _}from"ink";import v,{useEffect as y,useState as b}from"react";import x from"ink-spinner";async function S(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getGeo(u);if(a.csv||a.tsv){let{writeCsv:t}=await import(`./csv-emit-BuRZNWYM.js`);return t(e.countries,[`country`,`visitors`],a.tsv?`tsv`:`csv`)}if(a.ndjson){for(let t of e.countries)process.stdout.write(JSON.stringify(t)+`
|
|
2
|
-
`);return 0}return r({type:`geo.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=h(v.createElement(C,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=g(),[h,S]=b(null),[C,w]=b(!0),[T,E]=b(null);if(_(e=>{if(e===`o`||e===`O`){f(d(`geo`,{siteId:t}));return}e===`q`&&(c(),i(0))}),y(()=>{let n=!1;return(async()=>{try{let r=await e.getGeo(t);n||(S(r),w(!1))}catch(e){n||(E(e.message),w(!1))}})(),()=>{n=!0}},[e,t]),C)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`geo · ${n}`}),v.createElement(a,{title:`Loading`,state:`busy`},v.createElement(p,null,v.createElement(m,{color:`magenta`},v.createElement(x,{type:`dots`})),v.createElement(m,null,` Fetching geo…`))));if(T)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`geo · ${n}`}),v.createElement(u,{reason:`error`,headline:`Failed to load`,hint:T}));let D=!h||h.countries.length===0&&h.cities.length===0;if(D)return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`geo · ${n}`}),v.createElement(u,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let O=[{key:`country`,label:`country`,width:18},{key:`visitors`,label:`visitors`,align:`right`,width:8}],k=[{key:`city`,label:`city`,width:20},{key:`country`,label:`country`,width:12},{key:`visitors`,label:`visitors`,align:`right`,width:8}],A=process.stdout.columns??80;return v.createElement(p,{flexDirection:`column`},v.createElement(o,{version:r,subtitle:`geo · ${n}`}),v.createElement(a,{title:`Countries`},h.countries.length===0?v.createElement(m,{color:`gray`},`— —`):v.createElement(l,{columns:O,data:h.countries.slice(0,15),zebra:!0})),v.createElement(a,{title:`Cities`},h.cities.length===0?v.createElement(m,{color:`gray`},`— —`):v.createElement(l,{columns:k,data:h.cities.slice(0,20),zebra:!0})),v.createElement(s,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{S as geoCommand};
|
package/dist/health-B5DBRP3C.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./config--JRu_jFq.js";import"./check-D9G0N7NB.js";import"./api-FCanTxsb.js";import"./token-store-BQuGH0z2.js";import"./formatter-DutfcQAc.js";import"./emit-DBYk96TD.js";import"./panel-B_yDcIcn.js";import{HealthReport as e,exitCodeFor as t,healthCommand as n,runHealthChecks as r}from"./health-BttlLZWZ.js";export{n as healthCommand};
|