@zenovay/cli 0.1.17 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/{ai-gVD3a1tJ.js → ai-4Yo74A1a.js} +1 -1
  2. package/dist/{api-v2-BwYWSe9Y.js → api-v2-CRj-zoG9.js} +1 -1
  3. package/dist/bin.js +5 -2
  4. package/dist/companies-f2shersJ.js +2 -0
  5. package/dist/data-table-CDTM2qS0.js +1 -0
  6. package/dist/deploys-CudLAqUS.js +2 -0
  7. package/dist/devices-B4_ouB05.js +1 -0
  8. package/dist/{doctor-o833kcpO.js → doctor-CjpTOujh.js} +1 -1
  9. package/dist/empty-state-CNtcEPJ9.js +1 -0
  10. package/dist/errors-CEJ43Vd4.js +2 -0
  11. package/dist/funnel-CK0vfgfb.js +3 -0
  12. package/dist/geo-CInOewrI.js +1 -0
  13. package/dist/globe-1bi4DjwJ.js +1 -0
  14. package/dist/{health-DEbOYNUm.js → health-DBiKIoYL.js} +1 -1
  15. package/dist/heatmaps-DfVR48Km.js +1 -0
  16. package/dist/{init-BTJHpHNW.js → init-BMNuKlUT.js} +1 -1
  17. package/dist/{init-D3kngcY4.js → init-HBcPrM1L.js} +1 -1
  18. package/dist/insights-Dd0HWA_M.js +1 -0
  19. package/dist/journeys-CCrSFXhO.js +1 -0
  20. package/dist/live-CUExJ1O5.js +1 -0
  21. package/dist/metric-card-W4GayhPO.js +1 -0
  22. package/dist/overview-CNuR2Mx9.js +1 -0
  23. package/dist/pages-CdoPyNQH.js +1 -0
  24. package/dist/projects-Cb8Jk1rh.js +2 -0
  25. package/dist/query-BDppYLwt.js +8 -0
  26. package/dist/retention-B-fiW8Un.js +1 -0
  27. package/dist/revenue-D0DkXtgI.js +2 -0
  28. package/dist/sessions-DYb8v1LG.js +1 -0
  29. package/dist/sources-2Zhm5ihV.js +2 -0
  30. package/dist/stats-Bf3LR7aS.js +2 -0
  31. package/dist/tier-Ceoo7ndQ.js +1 -0
  32. package/dist/uptime-I4CzdPZv.js +1 -0
  33. package/dist/{use-jeUUaX-X.js → use-DOxo6QgS.js} +1 -1
  34. package/dist/vitals-XBfK3I8H.js +2 -0
  35. package/dist/watch-CawlqYPo.js +1 -0
  36. package/dist/{webhooks-forward-DyNjdEfi.js → webhooks-forward-DcnCiBcP.js} +1 -1
  37. package/dist/wizard-bin.js +1 -1
  38. package/package.json +1 -1
  39. package/dist/companies-BGeGKsvN.js +0 -2
  40. package/dist/deploys-BdgjS9s8.js +0 -2
  41. package/dist/errors-CfBR-vTW.js +0 -2
  42. package/dist/funnel-2-RBc6Z6.js +0 -3
  43. package/dist/projects-CGvLylMB.js +0 -2
  44. package/dist/query-CIAAVHLq.js +0 -8
  45. package/dist/revenue-EPxBowpX.js +0 -2
  46. package/dist/sources-CG52LwT7.js +0 -2
  47. package/dist/stats-C1D7-kOD.js +0 -2
  48. package/dist/vitals-Cdbqkwdt.js +0 -2
  49. package/dist/watch-eGS9kl-m.js +0 -1
  50. /package/dist/{completions-DHOrzR_j.js → completions-hFMu39uk.js} +0 -0
  51. /package/dist/{events-tail-BOLPhm8f.js → events-tail-CtoMkdkb.js} +0 -0
  52. /package/dist/{health-DEmXOsf7.js → health-Bn_Bw6c_.js} +0 -0
  53. /package/dist/{logout-lHm-0I43.js → logout-B_-6rZdK.js} +0 -0
  54. /package/dist/{resolve-site-D4W9yMVw.js → resolve-site-B54mr0Bh.js} +0 -0
  55. /package/dist/{themes-Dmj61mS1.js → themes-Ty85UcjT.js} +0 -0
  56. /package/dist/{update-BQ026Ltb.js → update-5mypMXp6.js} +0 -0
@@ -1,4 +1,4 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{ApiClient as t,readToken as n}from"./api-DXmhz2DM.js";import{detectInstalled as r,initCommand as i}from"./init-D3kngcY4.js";import{parseSseStream as a}from"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import{emit as o,isHeadless as s}from"./emit-BmfLGjqr.js";import"./login-DvMRHd3J.js";import{Panel as c}from"./panel-DZqvtaao.js";import{Select as l}from"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{Box as u,Text as d,render as f}from"ink";import p from"react";async function m(e){let t=await r(e.cwd),n;if(e.mode)n=e.mode;else if(!t.installed)n=`install`;else if(s(e))return o({type:`error`,code:`no_mode`,message:`Headless mode requires --mode chat|mcp|install`}),2;else n=await h(t);return n===`install`?i({cliVersion:e.cliVersion,cwd:e.cwd,json:e.json}):n===`chat`?g(e):_(e)}async function h(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}=f(p.createElement(u,{flexDirection:`column`},p.createElement(c,{title:`Zenovay detected${e.packageMarker?` (${e.packageMarker})`:``}`,state:`idle`},p.createElement(d,null,`What do you want to do?`)),p.createElement(l,{items:n,onSelect:e=>{r(),t(e)}})))})}async function g(r){let i=await e(),o=await n({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new t({config:i,cliVersion:r.cliVersion,token:o});process.stdout.write(`
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{ApiClient as t,readToken as n}from"./api-DXmhz2DM.js";import{detectInstalled as r,initCommand as i}from"./init-HBcPrM1L.js";import{parseSseStream as a}from"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import{emit as o,isHeadless as s}from"./emit-BmfLGjqr.js";import"./login-DvMRHd3J.js";import{Panel as c}from"./panel-DZqvtaao.js";import{Select as l}from"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{Box as u,Text as d,render as f}from"ink";import p from"react";async function m(e){let t=await r(e.cwd),n;if(e.mode)n=e.mode;else if(!t.installed)n=`install`;else if(s(e))return o({type:`error`,code:`no_mode`,message:`Headless mode requires --mode chat|mcp|install`}),2;else n=await h(t);return n===`install`?i({cliVersion:e.cliVersion,cwd:e.cwd,json:e.json}):n===`chat`?g(e):_(e)}async function h(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}=f(p.createElement(u,{flexDirection:`column`},p.createElement(c,{title:`Zenovay detected${e.packageMarker?` (${e.packageMarker})`:``}`,state:`idle`},p.createElement(d,null,`What do you want to do?`)),p.createElement(l,{items:n,onSelect:e=>{r(),t(e)}})))})}async function g(r){let i=await e(),o=await n({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new t({config:i,cliVersion:r.cliVersion,token:o});process.stdout.write(`
2
2
  Zenovay · chat mode — type your question then press Enter. Ctrl-C to exit.
3
3
 
4
4
  > `);let c=await v();if(!c)return 0;let l=await s.openAiStream(`chat`,{messages:[{role:`user`,content:c}]});for await(let e of a(l)){if(e.type===`delta`&&process.stdout.write(e.content),e.type===`done`){process.stdout.write(`
@@ -1 +1 @@
1
- import{ApiClient as e,ApiError as t,ensureFreshToken as n}from"./api-DXmhz2DM.js";import{z as r}from"zod";const i=r.object({id:r.string(),startedAt:r.string(),country:r.string().nullable().optional(),city:r.string().nullable().optional(),device:r.enum([`mobile`,`desktop`,`tablet`,`unknown`]).optional(),os:r.string().nullable().optional(),browser:r.string().nullable().optional(),page:r.string().optional(),referrer:r.string().nullable().optional(),utmSource:r.string().nullable().optional(),utmMedium:r.string().nullable().optional(),utmCampaign:r.string().nullable().optional(),aiScore:r.number().min(0).max(100).nullable().optional()}),a=r.object({visitors:r.array(i),total:r.number().int(),windowStart:r.string(),windowEnd:r.string()}),o=r.object({type:r.enum([`visitor.started`,`visitor.ended`,`visitor.heartbeat`]),visitor:i}),s=r.object({source:r.string(),channel:r.enum([`direct`,`organic`,`paid`,`social`,`referral`,`email`,`other`]).optional(),visitors:r.number().int(),conversions:r.number().int().optional(),revenue:r.number().int().optional(),delta:r.number().nullable().optional()}),c=r.object({sources:r.array(s),totalVisitors:r.number().int(),windowStart:r.string(),windowEnd:r.string()}),l=r.object({bucket:r.string(),amount:r.number().int(),currency:r.string(),transactions:r.number().int()}),u=r.object({series:r.array(l),totalAmount:r.number().int(),currency:r.string(),totalTransactions:r.number().int(),mrr:r.number().int().optional(),arpu:r.number().int().optional(),windowStart:r.string(),windowEnd:r.string()}),d=r.object({url:r.string(),device:r.enum([`mobile`,`desktop`]).optional(),lcp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),inp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),cls:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),ttfb:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),fcp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),samples:r.number().int()}),f=r.object({vitals:r.array(d),windowStart:r.string(),windowEnd:r.string()}),p=r.object({id:r.string(),name:r.string(),visitors:r.number().int(),conversions:r.number().int(),dropOff:r.number().min(0).max(1).optional()}),m=r.object({funnelId:r.string(),name:r.string(),steps:r.array(p),totalEntries:r.number().int(),totalCompletions:r.number().int(),conversionRate:r.number().min(0).max(1),windowStart:r.string(),windowEnd:r.string()}),h=r.object({id:r.string(),name:r.string(),stepCount:r.number().int(),lastEvaluatedAt:r.string().nullable().optional()}),g=r.object({funnels:r.array(h)}),_=r.object({visitors:r.number().int(),pageviews:r.number().int(),sessions:r.number().int(),bounceRate:r.number().min(0).max(1),avgSessionSec:r.number(),topPages:r.array(r.object({url:r.string(),views:r.number().int()})),topCountries:r.array(r.object({country:r.string(),visitors:r.number().int()})),windowStart:r.string(),windowEnd:r.string()}),v=r.object({id:r.string(),name:r.string(),type:r.enum([`event`,`pageview`,`revenue`]),conversions24h:r.number().int(),conversions7d:r.number().int()}),y=r.object({goals:r.array(v)}),b=r.object({id:r.string(),name:r.string(),domain:r.string().nullable().optional(),industry:r.string().nullable().optional(),employeeCount:r.number().int().nullable().optional(),visitorCount:r.number().int(),firstSeenAt:r.string(),lastSeenAt:r.string()}),x=r.object({type:r.enum([`company.identified`,`company.returning`]),company:b}),S=r.object({companies:r.array(b),total:r.number().int()}),C=r.object({type:r.literal(`error.captured`),id:r.string(),message:r.string(),stack:r.string().optional(),url:r.string().optional(),occurredAt:r.string(),count:r.number().int().optional(),spike:r.number().optional()}),w=r.object({id:r.string(),ts:r.string(),class:r.string(),message:r.string(),page:r.string().nullable(),device:r.string().nullable(),fingerprint:r.string().nullable()}),T=r.object({errors:r.array(w),total:r.number().int()}),E=r.object({id:r.string(),name:r.string(),domain:r.string().nullable(),industry:r.string().nullable(),employeeCount:r.number().int().nullable(),visitCount:r.number().int(),firstSeenAt:r.string(),lastSeenAt:r.string(),isNew:r.boolean()}),D=r.object({companies:r.array(E),total:r.number().int()}),O=r.object({columns:r.array(r.string()),rows:r.array(r.record(r.unknown())),row_count:r.number(),duration_ms:r.number(),truncated:r.boolean()}),k=r.object({id:r.string(),provider:r.literal(`github`),commit_sha:r.string(),commit_message:r.string().nullable(),commit_author:r.string().nullable(),branch:r.string().nullable(),repository:r.string().nullable(),commit_url:r.string().nullable(),pushed_at:r.string(),show_on_chart:r.boolean()}),A=r.object({deploys:r.array(k),total:r.number().int()}),j=r.object({id:r.string(),name:r.string(),domain:r.string().nullable(),tier:r.string(),pageviews24h:r.number().int(),isCurrent:r.boolean()}),M=r.object({projects:r.array(j)}),N=r.object({type:r.string(),bucket:r.string(),count:r.number().int()}),P=r.object({events:r.array(N),windowStart:r.string(),windowEnd:r.string()}),F=r.object({id:r.string(),receivedAt:r.string(),url:r.string(),method:r.string(),headers:r.record(r.string(),r.string()),body:r.string()}),I=r.object({columns:r.array(r.string()),rows:r.array(r.array(r.unknown())),rowCount:r.number().int(),durationMs:r.number(),truncated:r.boolean().optional()}),L=r.object({resource:r.string(),values:r.array(r.string()),cachedAt:r.string().optional()});function R(e,t){throw Error(`api-v2: ${e} not yet implemented; awaiting backend Wave ${t}`)}async function*z(e,t){R(e,t)}function B(e){switch(e){case`24h`:return 1;case`7d`:return 7;case`30d`:return 30;case`90d`:return 90;case`1y`:return 365;default:return 7}}var V=class extends e{v2Opts;v2Fetch;v2Token;constructor(e){super(e),this.v2Opts=e,this.v2Fetch=e.fetchImpl??fetch,this.v2Token=e.token??null}get v2ApiBase(){return this.v2Opts.config.apiBase}async v2Headers(e={}){let t=process.env.ZENOVAY_API_TOKEN;if(t&&t.trim())return{Accept:`application/json`,"User-Agent":`zenovay-cli/${this.v2Opts.cliVersion}`,"X-Zenovay-CLI-Version":this.v2Opts.cliVersion,Authorization:`Bearer ${t.trim()}`,...e};this.v2Token||=await n({apiBase:this.v2ApiBase});let r={Accept:`application/json`,"User-Agent":`zenovay-cli/${this.v2Opts.cliVersion}`,"X-Zenovay-CLI-Version":this.v2Opts.cliVersion,...e};return this.v2Token&&(r.Authorization=`${this.v2Token.tokenType} ${this.v2Token.accessToken}`),r}async v2Request(e,n,r={},i){let a=`${this.v2ApiBase}${e}`,o=await this.v2Headers(r.headers??{}),s=await this.v2Fetch(a,{...r,headers:o,signal:i});if(s.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers(r.headers??{});s=await this.v2Fetch(a,{...r,headers:e,signal:i})}if(!s.ok){let n=await s.text().catch(()=>``),i=n;try{i=JSON.parse(n)}catch{}throw new t(s.status,i,`${r.method??`GET`} ${e} → ${s.status}`)}let c=await s.json();return n.parse(c)}async v2RequestRaw(e,n={},r){let i=`${this.v2ApiBase}${e}`,a=await this.v2Headers(n.headers??{}),o=await this.v2Fetch(i,{...n,headers:a,signal:r});if(o.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers(n.headers??{});o=await this.v2Fetch(i,{...n,headers:e,signal:r})}if(!o.ok){let r=await o.text().catch(()=>``),i=r;try{i=JSON.parse(r)}catch{}throw new t(o.status,i,`${n.method??`GET`} ${e} → ${o.status}`)}let s=await o.json();return s?.data??s}async getVisitors(e,t,n){let r=new URLSearchParams({site_id:e});t?.since&&r.set(`since`,t.since),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/visitors?${r.toString()}`,{},n),o=new Date,s=new Date(Date.now()-24*3600*1e3),c=e=>{if(!e)return`unknown`;let t=e.toLowerCase();return t.includes(`mobile`)?`mobile`:t.includes(`tablet`)?`tablet`:t.includes(`desktop`)?`desktop`:`unknown`};return a.parse({total:i.liveCount??i.visitors?.length??0,visitors:(i.visitors??[]).map(e=>({id:e.sessionId,startedAt:e.lastSeen,country:e.country,city:null,device:c(e.device??null),page:e.currentPath??void 0,aiScore:typeof e.valueScore==`number`?Math.max(0,Math.min(100,e.valueScore)):null})),windowStart:s.toISOString(),windowEnd:o.toISOString()})}streamVisitors(e,t){return this.streamChannel(e,`visitors`,t)}async getSources(e,t=`30d`,n,r){let i=new URLSearchParams({site_id:e,period:t});n&&i.set(`compare`,n);let a=await this.v2RequestRaw(`/v1/cli/sources?${i.toString()}`,{},r),o=a.channels??[],s=a.top_utm_sources??[],l=o.reduce((e,t)=>e+t.visitors,0),u=new Set([`direct`,`organic`,`paid`,`social`,`referral`,`email`]),d=[...o.map(e=>({source:e.name,channel:u.has(e.name)?e.name:`other`,visitors:e.visitors,delta:typeof e.delta==`number`?e.delta/100:null})),...s.map(e=>({source:e.medium?`${e.source}/${e.medium}`:e.source,channel:`other`,visitors:e.visitors}))],f=new Date,p=new Date(Date.now()-B(t)*24*3600*1e3);return c.parse({sources:d,totalVisitors:l,windowStart:p.toISOString(),windowEnd:f.toISOString()})}async getRevenue(e,t=`30d`,n){let r=new URLSearchParams({site_id:e,window:t}),i=await this.v2RequestRaw(`/v1/cli/revenue?${r.toString()}`,{},n),a=(i.daily??[]).map(e=>({bucket:e.date,amount:e.cents,currency:i.currency??`USD`,transactions:e.transactions})),o=a.reduce((e,t)=>e+t.amount,0),s=a.reduce((e,t)=>e+t.transactions,0),c=new Date,l=new Date(Date.now()-B(t)*24*3600*1e3),d={series:a,totalAmount:o,currency:i.currency??`USD`,totalTransactions:s,windowStart:l.toISOString(),windowEnd:c.toISOString()};return typeof i.mrr_cents==`number`&&(d.mrr=i.mrr_cents),u.parse(d)}async getVitals(e,t,n){let r=new URLSearchParams({site_id:e});t?.url&&r.set(`url`,t.url),t?.device&&r.set(`device`,t.device),t?.window&&r.set(`window`,t.window);let i=await this.v2RequestRaw(`/v1/cli/vitals?${r.toString()}`,{},n),a=[];if(i.p75&&(i.sample_count??0)>0){let e=i.p75,n={url:`— site-wide aggregate —`,device:t?.device??void 0,samples:i.sample_count??0,...typeof e.lcp==`number`?{lcp:{p50:e.lcp,p75:e.lcp,p90:e.lcp}}:{},...typeof e.inp==`number`?{inp:{p50:e.inp,p75:e.inp,p90:e.inp}}:{},...typeof e.cls==`number`?{cls:{p50:e.cls,p75:e.cls,p90:e.cls}}:{},...typeof e.fcp==`number`?{fcp:{p50:e.fcp,p75:e.fcp,p90:e.fcp}}:{},...typeof e.ttfb==`number`?{ttfb:{p50:e.ttfb,p75:e.ttfb,p90:e.ttfb}}:{}};a.push(n)}for(let e of i.worst_pages??[])a.push({url:e.path,device:t?.device??void 0,samples:e.sample_count,lcp:{p50:e.lcp_p75,p75:e.lcp_p75,p90:e.lcp_p75}});let o=new Date,s=new Date(Date.now()-B(t?.window??`7d`)*24*3600*1e3);return f.parse({vitals:a,windowStart:s.toISOString(),windowEnd:o.toISOString()})}async getFunnel(e,t,n=`30d`,r){let i=new URLSearchParams({site_id:e,window:n}),a=await this.v2RequestRaw(`/v1/cli/funnels/${encodeURIComponent(t)}?${i.toString()}`,{},r),o=a.total_entries??0,s=(a.steps??[]).map(e=>({id:`step-${e.order}`,name:e.name,visitors:e.visitors,conversions:e.visitors,dropOff:Math.max(0,Math.min(1,e.dropoffPct/100))})),c=s[s.length-1],l=c?.visitors??0,u=o>0?Math.min(1,l/o):0,d=new Date,f=new Date(Date.now()-B(n)*24*3600*1e3);return m.parse({funnelId:a.id??t,name:a.name??t,steps:s,totalEntries:o,totalCompletions:l,conversionRate:u,windowStart:f.toISOString(),windowEnd:d.toISOString()})}async listFunnels(e,t){let n=new URLSearchParams({site_id:e}),r=await this.v2RequestRaw(`/v1/cli/funnels?${n.toString()}`,{},t);return g.parse({funnels:(r.funnels??[]).map(e=>({id:e.id,name:e.name,stepCount:e.step_count}))})}async getStats(e,t=`24h`,n){let r=new URLSearchParams({site_id:e,range:t}),i=await this.v2RequestRaw(`/v1/cli/stats?${r.toString()}`,{},n),a=i.visitors??0,o=i.pageviews??0,s=a,c=s>0?o/s:0,l=c>0?Math.max(0,Math.min(1,1/Math.max(1,c))):0,u=0,d=new Date,f=new Date(Date.now()-B(t)*24*3600*1e3);return _.parse({visitors:a,pageviews:o,sessions:s,bounceRate:l,avgSessionSec:u,topPages:i.topPage?[{url:i.topPage.path,views:i.topPage.views}]:[],topCountries:i.topSource?[{country:i.topSource.channel,visitors:i.topSource.visitors}]:[],windowStart:f.toISOString(),windowEnd:d.toISOString()})}async getGoals(e,t){let n=new URLSearchParams({site_id:e});return this.v2Request(`/v1/cli/goals?${n.toString()}`,y,{},t)}streamCompaniesV2(e,t){return this.streamChannel(e,`companies`,t)}streamCompanies(e,t){return z(`streamCompanies`,2)}async getCompanies(e){R(`getCompanies`,2)}async getCompaniesSnapshot(e,t,n){let r=new URLSearchParams({site_id:e});t?.window&&r.set(`window`,t.window),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/companies?${r.toString()}`,{},n);return D.parse(i)}async runSqlQuery(e,n,r,i){let a=`${this.v2ApiBase}/v1/cli/query`,o=await this.v2Headers({"Content-Type":`application/json`}),s=await this.v2Fetch(a,{method:`POST`,headers:o,signal:i,body:JSON.stringify({site_id:e,sql:n,...r?.maxRows?{max_rows:r.maxRows}:{}})});if(!s.ok){let e=await s.text().catch(()=>``),n=e;try{n=JSON.parse(e)}catch{}throw new t(s.status,n,`POST /v1/cli/query → ${s.status}`)}let c=await s.json();return O.parse(c.data??c)}async getDeploys(e,t,n){let r=new URLSearchParams({site_id:e});t?.since&&r.set(`since`,t.since),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit)),t?.branch&&r.set(`branch`,t.branch),t?.onChartOnly&&r.set(`on_chart_only`,`true`);let i=await this.v2RequestRaw(`/v1/cli/deploys?${r.toString()}`,{},n);return A.parse(i)}async getProjects(e,t){let n=new URLSearchParams({site_id:e}),r=await this.v2RequestRaw(`/v1/cli/projects?${n.toString()}`,{},t);return M.parse(r)}async getErrors(e,t,n){let r=new URLSearchParams({site_id:e});t?.window&&r.set(`window`,t.window),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/errors?${r.toString()}`,{},n);return T.parse(i)}streamErrorsV2(e,t){return this.streamChannel(e,`errors`,t)}streamErrors(e,t){return z(`streamErrors`,2)}async getEventsHistory(e,t){R(`getEventsHistory`,2)}forwardWebhook(e,t){return z(`forwardWebhook`,2)}async registerTunnel(e,t){R(`registerTunnel`,2)}async queryRaw(e,t,n){R(`queryRaw`,3)}async getCompletions(e,t){R(`getCompletions`,3)}async*streamChannel(e,t,n){let{connectWs:r}=await import(`./ws-client-3QuvHd5K.js`),i=this.v2ApiBase.replace(/^https:\/\//,`wss://`).replace(/^http:\/\//,`ws://`),a=`${i}/v1/cli/stream/${encodeURIComponent(e)}?channels=${t}`,o=this.v2Token?.accessToken;for await(let e of r({url:a,bearer:o,signal:n})){if(e.type!==`message`)continue;let t=e.data;if(t&&typeof t==`object`){let e=t;yield e.event??t}}}async createTunnel(e,n,r){let i=`${this.v2ApiBase}/v1/cli/tunnels`,a=await this.v2Headers({"Content-Type":`application/json`}),o=await this.v2Fetch(i,{method:`POST`,headers:a,signal:r,body:JSON.stringify({site_id:e,target_pattern:n})});if(!o.ok){let e=await o.text().catch(()=>``);throw new t(o.status,e,`POST /v1/cli/tunnels → ${o.status}`)}let s=await o.json(),c=s.data??{};if(!c.tunnel_key||!c.public_url||!c.ws_url)throw new t(500,s,`createTunnel: malformed response`);return{tunnelKey:c.tunnel_key,publicUrl:c.public_url,wsUrl:c.ws_url,siteId:c.site_id??e}}tunnelClient(e){let t=this.v2Token?.accessToken;return{start:async(n,r)=>{let{WsTunnelClient:i}=await import(`./ws-client-3QuvHd5K.js`),a=new i({url:e,bearer:t,signal:r});await a.start(n)}}}};export{V as ApiV2Client};
1
+ import{ApiClient as e,ApiError as t,ensureFreshToken as n}from"./api-DXmhz2DM.js";import{z as r}from"zod";const i=r.object({id:r.string(),startedAt:r.string(),country:r.string().nullable().optional(),city:r.string().nullable().optional(),device:r.enum([`mobile`,`desktop`,`tablet`,`unknown`]).optional(),os:r.string().nullable().optional(),browser:r.string().nullable().optional(),page:r.string().optional(),referrer:r.string().nullable().optional(),utmSource:r.string().nullable().optional(),utmMedium:r.string().nullable().optional(),utmCampaign:r.string().nullable().optional(),aiScore:r.number().min(0).max(100).nullable().optional()}),a=r.object({visitors:r.array(i),total:r.number().int(),windowStart:r.string(),windowEnd:r.string()}),o=r.object({type:r.enum([`visitor.started`,`visitor.ended`,`visitor.heartbeat`]),visitor:i}),s=r.object({source:r.string(),channel:r.enum([`direct`,`organic`,`paid`,`social`,`referral`,`email`,`other`]).optional(),visitors:r.number().int(),conversions:r.number().int().optional(),revenue:r.number().int().optional(),delta:r.number().nullable().optional()}),c=r.object({sources:r.array(s),totalVisitors:r.number().int(),windowStart:r.string(),windowEnd:r.string()}),l=r.object({bucket:r.string(),amount:r.number().int(),currency:r.string(),transactions:r.number().int()}),u=r.object({series:r.array(l),totalAmount:r.number().int(),currency:r.string(),totalTransactions:r.number().int(),mrr:r.number().int().optional(),arpu:r.number().int().optional(),windowStart:r.string(),windowEnd:r.string()}),d=r.object({url:r.string(),device:r.enum([`mobile`,`desktop`]).optional(),lcp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),inp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),cls:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),ttfb:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),fcp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),samples:r.number().int()}),f=r.object({vitals:r.array(d),windowStart:r.string(),windowEnd:r.string()}),p=r.object({id:r.string(),name:r.string(),visitors:r.number().int(),conversions:r.number().int(),dropOff:r.number().min(0).max(1).optional()}),m=r.object({funnelId:r.string(),name:r.string(),steps:r.array(p),totalEntries:r.number().int(),totalCompletions:r.number().int(),conversionRate:r.number().min(0).max(1),windowStart:r.string(),windowEnd:r.string()}),h=r.object({id:r.string(),name:r.string(),stepCount:r.number().int(),lastEvaluatedAt:r.string().nullable().optional()}),g=r.object({funnels:r.array(h)}),_=r.object({visitors:r.number().int(),pageviews:r.number().int(),sessions:r.number().int(),bounceRate:r.number().min(0).max(1),avgSessionSec:r.number(),topPages:r.array(r.object({url:r.string(),views:r.number().int()})),topCountries:r.array(r.object({country:r.string(),visitors:r.number().int()})),windowStart:r.string(),windowEnd:r.string()}),v=r.object({id:r.string(),name:r.string(),type:r.enum([`event`,`pageview`,`revenue`]),conversions24h:r.number().int(),conversions7d:r.number().int()}),y=r.object({goals:r.array(v)}),b=r.object({id:r.string(),name:r.string(),domain:r.string().nullable().optional(),industry:r.string().nullable().optional(),employeeCount:r.number().int().nullable().optional(),visitorCount:r.number().int(),firstSeenAt:r.string(),lastSeenAt:r.string()}),x=r.object({type:r.enum([`company.identified`,`company.returning`]),company:b}),S=r.object({companies:r.array(b),total:r.number().int()}),C=r.object({type:r.literal(`error.captured`),id:r.string(),message:r.string(),stack:r.string().optional(),url:r.string().optional(),occurredAt:r.string(),count:r.number().int().optional(),spike:r.number().optional()}),w=r.object({id:r.string(),ts:r.string(),class:r.string(),message:r.string(),page:r.string().nullable(),device:r.string().nullable(),fingerprint:r.string().nullable()}),T=r.object({errors:r.array(w),total:r.number().int()}),E=r.object({id:r.string(),name:r.string(),domain:r.string().nullable(),industry:r.string().nullable(),employeeCount:r.number().int().nullable(),visitCount:r.number().int(),firstSeenAt:r.string(),lastSeenAt:r.string(),isNew:r.boolean()}),D=r.object({companies:r.array(E),total:r.number().int()}),O=r.object({columns:r.array(r.string()),rows:r.array(r.record(r.unknown())),row_count:r.number(),duration_ms:r.number(),truncated:r.boolean()}),k=r.object({id:r.string(),provider:r.literal(`github`),commit_sha:r.string(),commit_message:r.string().nullable(),commit_author:r.string().nullable(),branch:r.string().nullable(),repository:r.string().nullable(),commit_url:r.string().nullable(),pushed_at:r.string(),show_on_chart:r.boolean()}),A=r.object({deploys:r.array(k),total:r.number().int()}),j=r.object({id:r.string(),name:r.string(),domain:r.string().nullable(),tier:r.string(),pageviews24h:r.number().int(),isCurrent:r.boolean()}),M=r.object({projects:r.array(j)}),N=r.object({type:r.string(),bucket:r.string(),count:r.number().int()}),P=r.object({events:r.array(N),windowStart:r.string(),windowEnd:r.string()}),F=r.object({id:r.string(),receivedAt:r.string(),url:r.string(),method:r.string(),headers:r.record(r.string(),r.string()),body:r.string()}),I=r.object({columns:r.array(r.string()),rows:r.array(r.array(r.unknown())),rowCount:r.number().int(),durationMs:r.number(),truncated:r.boolean().optional()}),L=r.object({resource:r.string(),values:r.array(r.string()),cachedAt:r.string().optional()});function R(e,t){throw Error(`api-v2: ${e} not yet implemented; awaiting backend Wave ${t}`)}async function*z(e,t){R(e,t)}function B(e){switch(e){case`24h`:return 1;case`7d`:return 7;case`30d`:return 30;case`90d`:return 90;case`1y`:return 365;default:return 7}}var V=class extends e{v2Opts;v2Fetch;v2Token;constructor(e){super(e),this.v2Opts=e,this.v2Fetch=e.fetchImpl??fetch,this.v2Token=e.token??null}get v2ApiBase(){return this.v2Opts.config.apiBase}async v2Headers(e={}){let t=process.env.ZENOVAY_API_TOKEN;if(t&&t.trim())return{Accept:`application/json`,"User-Agent":`zenovay-cli/${this.v2Opts.cliVersion}`,"X-Zenovay-CLI-Version":this.v2Opts.cliVersion,Authorization:`Bearer ${t.trim()}`,...e};this.v2Token||=await n({apiBase:this.v2ApiBase});let r={Accept:`application/json`,"User-Agent":`zenovay-cli/${this.v2Opts.cliVersion}`,"X-Zenovay-CLI-Version":this.v2Opts.cliVersion,...e};return this.v2Token&&(r.Authorization=`${this.v2Token.tokenType} ${this.v2Token.accessToken}`),r}async v2Request(e,n,r={},i){let a=`${this.v2ApiBase}${e}`,o=await this.v2Headers(r.headers??{}),s=await this.v2Fetch(a,{...r,headers:o,signal:i});if(s.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers(r.headers??{});s=await this.v2Fetch(a,{...r,headers:e,signal:i})}if(!s.ok){let n=await s.text().catch(()=>``),i=n;try{i=JSON.parse(n)}catch{}throw new t(s.status,i,`${r.method??`GET`} ${e} → ${s.status}`)}let c=await s.json();return n.parse(c)}async v2RequestRaw(e,n={},r){let i=`${this.v2ApiBase}${e}`,a=await this.v2Headers(n.headers??{}),o=await this.v2Fetch(i,{...n,headers:a,signal:r});if(o.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers(n.headers??{});o=await this.v2Fetch(i,{...n,headers:e,signal:r})}if(!o.ok){let r=await o.text().catch(()=>``),i=r;try{i=JSON.parse(r)}catch{}throw new t(o.status,i,`${n.method??`GET`} ${e} → ${o.status}`)}let s=await o.json();return s?.data??s}async getVisitors(e,t,n){let r=new URLSearchParams({site_id:e});t?.since&&r.set(`since`,t.since),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/visitors?${r.toString()}`,{},n),o=new Date,s=new Date(Date.now()-24*3600*1e3),c=e=>{if(!e)return`unknown`;let t=e.toLowerCase();return t.includes(`mobile`)?`mobile`:t.includes(`tablet`)?`tablet`:t.includes(`desktop`)?`desktop`:`unknown`};return a.parse({total:i.liveCount??i.visitors?.length??0,visitors:(i.visitors??[]).map(e=>({id:e.sessionId,startedAt:e.lastSeen,country:e.country,city:null,device:c(e.device??null),page:e.currentPath??void 0,aiScore:typeof e.valueScore==`number`?Math.max(0,Math.min(100,e.valueScore)):null})),windowStart:s.toISOString(),windowEnd:o.toISOString()})}streamVisitors(e,t){return this.streamChannel(e,`visitors`,t)}async getSources(e,t=`30d`,n,r){let i=new URLSearchParams({site_id:e,period:t});n&&i.set(`compare`,n);let a=await this.v2RequestRaw(`/v1/cli/sources?${i.toString()}`,{},r),o=a.channels??[],s=a.top_utm_sources??[],l=o.reduce((e,t)=>e+t.visitors,0),u=new Set([`direct`,`organic`,`paid`,`social`,`referral`,`email`]),d=[...o.map(e=>({source:e.name,channel:u.has(e.name)?e.name:`other`,visitors:e.visitors,delta:typeof e.delta==`number`?e.delta/100:null})),...s.map(e=>({source:e.medium?`${e.source}/${e.medium}`:e.source,channel:`other`,visitors:e.visitors}))],f=new Date,p=new Date(Date.now()-B(t)*24*3600*1e3);return c.parse({sources:d,totalVisitors:l,windowStart:p.toISOString(),windowEnd:f.toISOString()})}async getRevenue(e,t=`30d`,n){let r=new URLSearchParams({site_id:e,window:t}),i=await this.v2RequestRaw(`/v1/cli/revenue?${r.toString()}`,{},n),a=(i.daily??[]).map(e=>({bucket:e.date,amount:e.cents,currency:i.currency??`USD`,transactions:e.transactions})),o=a.reduce((e,t)=>e+t.amount,0),s=a.reduce((e,t)=>e+t.transactions,0),c=new Date,l=new Date(Date.now()-B(t)*24*3600*1e3),d={series:a,totalAmount:o,currency:i.currency??`USD`,totalTransactions:s,windowStart:l.toISOString(),windowEnd:c.toISOString()};return typeof i.mrr_cents==`number`&&(d.mrr=i.mrr_cents),u.parse(d)}async getVitals(e,t,n){let r=new URLSearchParams({site_id:e});t?.url&&r.set(`url`,t.url),t?.device&&r.set(`device`,t.device),t?.window&&r.set(`window`,t.window);let i=await this.v2RequestRaw(`/v1/cli/vitals?${r.toString()}`,{},n),a=[];if(i.p75&&(i.sample_count??0)>0){let e=i.p75,n={url:`— site-wide aggregate —`,device:t?.device??void 0,samples:i.sample_count??0,...typeof e.lcp==`number`?{lcp:{p50:e.lcp,p75:e.lcp,p90:e.lcp}}:{},...typeof e.inp==`number`?{inp:{p50:e.inp,p75:e.inp,p90:e.inp}}:{},...typeof e.cls==`number`?{cls:{p50:e.cls,p75:e.cls,p90:e.cls}}:{},...typeof e.fcp==`number`?{fcp:{p50:e.fcp,p75:e.fcp,p90:e.fcp}}:{},...typeof e.ttfb==`number`?{ttfb:{p50:e.ttfb,p75:e.ttfb,p90:e.ttfb}}:{}};a.push(n)}for(let e of i.worst_pages??[])a.push({url:e.path,device:t?.device??void 0,samples:e.sample_count,lcp:{p50:e.lcp_p75,p75:e.lcp_p75,p90:e.lcp_p75}});let o=new Date,s=new Date(Date.now()-B(t?.window??`7d`)*24*3600*1e3);return f.parse({vitals:a,windowStart:s.toISOString(),windowEnd:o.toISOString()})}async getFunnel(e,t,n=`30d`,r){let i=new URLSearchParams({site_id:e,window:n}),a=await this.v2RequestRaw(`/v1/cli/funnels/${encodeURIComponent(t)}?${i.toString()}`,{},r),o=a.total_entries??0,s=(a.steps??[]).map(e=>({id:`step-${e.order}`,name:e.name,visitors:e.visitors,conversions:e.visitors,dropOff:Math.max(0,Math.min(1,e.dropoffPct/100))})),c=s[s.length-1],l=c?.visitors??0,u=o>0?Math.min(1,l/o):0,d=new Date,f=new Date(Date.now()-B(n)*24*3600*1e3);return m.parse({funnelId:a.id??t,name:a.name??t,steps:s,totalEntries:o,totalCompletions:l,conversionRate:u,windowStart:f.toISOString(),windowEnd:d.toISOString()})}async listFunnels(e,t){let n=new URLSearchParams({site_id:e}),r=await this.v2RequestRaw(`/v1/cli/funnels?${n.toString()}`,{},t);return g.parse({funnels:(r.funnels??[]).map(e=>({id:e.id,name:e.name,stepCount:e.step_count}))})}async getStats(e,t=`24h`,n){let r=new URLSearchParams({site_id:e,range:t}),i=await this.v2RequestRaw(`/v1/cli/stats?${r.toString()}`,{},n),a=i.visitors??0,o=i.pageviews??0,s=a,c=s>0?o/s:0,l=c>0?Math.max(0,Math.min(1,1/Math.max(1,c))):0,u=0,d=new Date,f=new Date(Date.now()-B(t)*24*3600*1e3);return _.parse({visitors:a,pageviews:o,sessions:s,bounceRate:l,avgSessionSec:u,topPages:i.topPage?[{url:i.topPage.path,views:i.topPage.views}]:[],topCountries:i.topSource?[{country:i.topSource.channel,visitors:i.topSource.visitors}]:[],windowStart:f.toISOString(),windowEnd:d.toISOString()})}async getGoals(e,t){let n=new URLSearchParams({site_id:e});return this.v2Request(`/v1/cli/goals?${n.toString()}`,y,{},t)}async getLive(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/live?${n.toString()}`,t)}async getPages(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/pages?${n.toString()}`,t)}async getDevices(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/devices?${n.toString()}`,t)}async getGeo(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/geo?${n.toString()}`,t)}async getRetention(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/retention?${n.toString()}`,t)}async getUptime(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/uptime?${n.toString()}`,t)}async getSessions(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/sessions?${n.toString()}`,t)}async getHeatmaps(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/heatmaps?${n.toString()}`,t)}async getJourneys(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/journeys?${n.toString()}`,t)}async getInsights(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/insights?${n.toString()}`,t)}async v2RawJson(e,n){let r=`${this.v2ApiBase}${e}`,i=await this.v2Headers(),a=await this.v2Fetch(r,{headers:i,signal:n});if(a.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers();a=await this.v2Fetch(r,{headers:e,signal:n})}if(!a.ok){let n=await a.text().catch(()=>``),r=n;try{r=JSON.parse(n)}catch{}throw new t(a.status,r,`GET ${e} → ${a.status}`)}return a.json()}streamCompaniesV2(e,t){return this.streamChannel(e,`companies`,t)}streamCompanies(e,t){return z(`streamCompanies`,2)}async getCompanies(e){R(`getCompanies`,2)}async getCompaniesSnapshot(e,t,n){let r=new URLSearchParams({site_id:e});t?.window&&r.set(`window`,t.window),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/companies?${r.toString()}`,{},n);return D.parse(i)}async runSqlQuery(e,n,r,i){let a=`${this.v2ApiBase}/v1/cli/query`,o=await this.v2Headers({"Content-Type":`application/json`}),s=await this.v2Fetch(a,{method:`POST`,headers:o,signal:i,body:JSON.stringify({site_id:e,sql:n,...r?.maxRows?{max_rows:r.maxRows}:{}})});if(!s.ok){let e=await s.text().catch(()=>``),n=e;try{n=JSON.parse(e)}catch{}throw new t(s.status,n,`POST /v1/cli/query → ${s.status}`)}let c=await s.json();return O.parse(c.data??c)}async getDeploys(e,t,n){let r=new URLSearchParams({site_id:e});t?.since&&r.set(`since`,t.since),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit)),t?.branch&&r.set(`branch`,t.branch),t?.onChartOnly&&r.set(`on_chart_only`,`true`);let i=await this.v2RequestRaw(`/v1/cli/deploys?${r.toString()}`,{},n);return A.parse(i)}async getProjects(e,t){let n=new URLSearchParams({site_id:e}),r=await this.v2RequestRaw(`/v1/cli/projects?${n.toString()}`,{},t);return M.parse(r)}async getErrors(e,t,n){let r=new URLSearchParams({site_id:e});t?.window&&r.set(`window`,t.window),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/errors?${r.toString()}`,{},n);return T.parse(i)}streamErrorsV2(e,t){return this.streamChannel(e,`errors`,t)}streamErrors(e,t){return z(`streamErrors`,2)}async getEventsHistory(e,t){R(`getEventsHistory`,2)}forwardWebhook(e,t){return z(`forwardWebhook`,2)}async registerTunnel(e,t){R(`registerTunnel`,2)}async queryRaw(e,t,n){R(`queryRaw`,3)}async getCompletions(e,t){R(`getCompletions`,3)}async*streamChannel(e,t,n){let{connectWs:r}=await import(`./ws-client-3QuvHd5K.js`),i=this.v2ApiBase.replace(/^https:\/\//,`wss://`).replace(/^http:\/\//,`ws://`),a=`${i}/v1/cli/stream/${encodeURIComponent(e)}?channels=${t}`,o=this.v2Token?.accessToken;for await(let e of r({url:a,bearer:o,signal:n})){if(e.type!==`message`)continue;let t=e.data;if(t&&typeof t==`object`){let e=t;yield e.event??t}}}async createTunnel(e,n,r){let i=`${this.v2ApiBase}/v1/cli/tunnels`,a=await this.v2Headers({"Content-Type":`application/json`}),o=await this.v2Fetch(i,{method:`POST`,headers:a,signal:r,body:JSON.stringify({site_id:e,target_pattern:n})});if(!o.ok){let e=await o.text().catch(()=>``);throw new t(o.status,e,`POST /v1/cli/tunnels → ${o.status}`)}let s=await o.json(),c=s.data??{};if(!c.tunnel_key||!c.public_url||!c.ws_url)throw new t(500,s,`createTunnel: malformed response`);return{tunnelKey:c.tunnel_key,publicUrl:c.public_url,wsUrl:c.ws_url,siteId:c.site_id??e}}tunnelClient(e){let t=this.v2Token?.accessToken;return{start:async(n,r)=>{let{WsTunnelClient:i}=await import(`./ws-client-3QuvHd5K.js`),a=new i({url:e,bearer:t,signal:r});await a.start(n)}}}};export{V as ApiV2Client};
package/dist/bin.js CHANGED
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{manifestSchema as t}from"./check-Comj8AkL.js";import{applyManifest as n}from"./apply-D2xZJdvQ.js";import{cac as r}from"cac";import{fork as i,spawn as a}from"node:child_process";import o from"node:path";import{fileURLToPath as s}from"node:url";import{readFileSync as c}from"node:fs";import l from"semver";import{z as u}from"zod";const d=2e3,f=3e4,p=5e3,m=5e3,h=new Set([`update`,`health`,`doctor`,`--version`,`-v`]),g=u.object({latest:u.string(),minSupported:u.string().optional(),platforms:u.record(u.string(),u.unknown()).optional(),downloads:u.record(u.string(),u.unknown()).optional()});async function _(e){if(v(e.argv))return;let t;try{t=await y()}catch(e){T(`update check failed: ${e.message}`);return}if(!t||!l.valid(e.currentVersion)||!l.valid(t.latest)||l.eq(e.currentVersion,t.latest)||l.lt(t.latest,e.currentVersion))return;let n=l.diff(e.currentVersion,t.latest);if(!n)return;let r=b();if(n===`patch`||n===`prepatch`){let n=await x(t,e,r);n&&w(e.argv);return}if(n===`minor`||n===`preminor`||n===`major`||n===`premajor`||n===`prerelease`){let n=await C(t.latest);if(!n){process.stderr.write(`Continuing with ${e.currentVersion}.\n`);return}let i=await x(t,e,r);i&&w(e.argv);return}}function v(e){if(process.env.ZENOVAY_NO_UPDATE_CHECK===`1`||process.env.CI===`true`||e.includes(`--no-update-check`))return!0;let t=e[2];return!!(t&&h.has(t))}async function y(){let n=await e(),r=`${n.cliBase}/version`,i=await fetch(r,{signal:AbortSignal.timeout(d)});if(!i.ok)return null;let a=await i.json(),o=t.safeParse(a);if(o.success)return o.data;let s=g.safeParse(a);return s.success?{latest:s.data.latest,minSupported:s.data.minSupported,platforms:{}}:null}function b(){let e=process.argv[1]??``;if(!e)return`unknown`;let t=e.replace(/\\/g,`/`);return t.includes(`/_npx/`)?`npm-local`:t.includes(`/node_modules/@zenovay/cli/`)?`npm-global`:t.includes(`/node_modules/.bin/zenovay`)?`npm-local`:t.includes(`/node_modules/`)?`unknown`:`binary`}async function x(t,r,i){if(i===`npm-local`)return process.stderr.write(`Update available — \`npm i -g @zenovay/cli@${t.latest}\` to upgrade.\n`),!1;if(i===`unknown`)return T(`unknown install method; skipping auto-update (latest ${t.latest})`),!1;if(i===`npm-global`)return await S(t.latest);try{let i=await e(),a=await Promise.race([n({currentVersion:r.currentVersion,cliBase:i.cliBase,binaryPath:r.binaryPath,manifest:t}),new Promise((e,t)=>setTimeout(()=>t(Error(`patch install timeout`)),p))]);return a.updated?!0:(T(`update skipped: ${a.reason??`unknown`}`),!1)}catch(e){return T(`update failed: ${e.message}`),!1}}function S(e){return new Promise(t=>{let n=process.platform===`win32`?`npm.cmd`:`npm`,r=[`install`,`-g`,`@zenovay/cli@${e}`],i={stdio:[`ignore`,`ignore`,`pipe`]},o=``,s=!1,c=a(n,r,i),l=setTimeout(()=>{if(!s){s=!0;try{c.kill(`SIGKILL`)}catch{}T(`npm install timed out after ${f/1e3}s; continuing with current version`),t(!1)}},f);c.stderr?.on(`data`,e=>{o+=e.toString(`utf8`)}),c.on(`error`,e=>{s||(s=!0,clearTimeout(l),T(`npm install error: ${e.message}`),t(!1))}),c.on(`exit`,n=>{if(!s){if(s=!0,clearTimeout(l),n===0){t(!0);return}/EACCES|permission denied/i.test(o)?process.stderr.write(`Auto-update needs sudo for the global npm prefix. Run: sudo npm i -g @zenovay/cli@${e}\n`):T(`npm install exited ${n}; continuing with current version`),t(!1)}})})}function C(e){return new Promise(t=>{if(!process.stdin.isTTY||!process.stderr.isTTY){t(!0);return}process.stderr.write(`New version ${e} available. Update? [Y/n] (auto-yes 5s) `);let n=!1,r=e=>{if(n)return;let r=e.toString(`utf8`).trim().toLowerCase();n=!0,i(),process.stderr.write(`
2
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{manifestSchema as t}from"./check-Comj8AkL.js";import{applyManifest as n}from"./apply-D2xZJdvQ.js";import{cac as r}from"cac";import{fork as i,spawn as a}from"node:child_process";import o from"node:path";import{fileURLToPath as s}from"node:url";import{readFileSync as c}from"node:fs";import l from"semver";import{z as u}from"zod";const d=2e3,f=3e4,p=5e3,m=5e3,h=new Set([`update`,`health`,`doctor`,`--version`,`-v`]),g=u.object({latest:u.string(),minSupported:u.string().optional(),platforms:u.record(u.string(),u.unknown()).optional(),downloads:u.record(u.string(),u.unknown()).optional()});async function _(e){if(v(e.argv))return;let t;try{t=await y()}catch(e){T(`update check failed: ${e.message}`);return}if(!t||!l.valid(e.currentVersion)||!l.valid(t.latest)||l.eq(e.currentVersion,t.latest)||l.lt(t.latest,e.currentVersion))return;let n=l.diff(e.currentVersion,t.latest);if(!n)return;let r=b();if(n===`patch`||n===`prepatch`){let n=await x(t,e,r);n&&w(e.argv);return}if(n===`minor`||n===`preminor`||n===`major`||n===`premajor`||n===`prerelease`){let n=await C(t.latest);if(!n){process.stderr.write(`Continuing with ${e.currentVersion}.\n`);return}let i=await x(t,e,r);i&&w(e.argv);return}}function v(e){if(process.env.ZENOVAY_NO_UPDATE_CHECK===`1`||process.env.CI===`true`||e.includes(`--no-update-check`))return!0;let t=e[2];return!!(t&&h.has(t))}async function y(){let n=b();if(n===`npm-global`||n===`npm-local`||n===`unknown`)try{let e=await fetch(`https://registry.npmjs.org/@zenovay/cli/latest`,{signal:AbortSignal.timeout(d),headers:{Accept:`application/json`}});if(!e.ok)return null;let t=await e.json();return t.version?{latest:t.version,platforms:{}}:null}catch{return null}let r=await e();try{let e=await fetch(`${r.cliBase}/version`,{signal:AbortSignal.timeout(d)});if(!e.ok)return null;let n=await e.json(),i=t.safeParse(n);if(i.success)return i.data;let a=g.safeParse(n);return a.success?{latest:a.data.latest,minSupported:a.data.minSupported,platforms:{}}:null}catch{return null}}function b(){let e=process.argv[1]??``;if(!e)return`unknown`;let t=e.replace(/\\/g,`/`);return t.includes(`/_npx/`)?`npm-local`:t.includes(`/node_modules/@zenovay/cli/`)?`npm-global`:t.includes(`/node_modules/.bin/zenovay`)?`npm-local`:t.includes(`/node_modules/`)?`unknown`:`binary`}async function x(t,r,i){if(i===`npm-local`)return process.stderr.write(`Update available — \`npm i -g @zenovay/cli@${t.latest}\` to upgrade.\n`),!1;if(i===`unknown`)return T(`unknown install method; skipping auto-update (latest ${t.latest})`),!1;if(i===`npm-global`)return await S(t.latest);try{let i=await e(),a=await Promise.race([n({currentVersion:r.currentVersion,cliBase:i.cliBase,binaryPath:r.binaryPath,manifest:t}),new Promise((e,t)=>setTimeout(()=>t(Error(`patch install timeout`)),p))]);return a.updated?!0:(T(`update skipped: ${a.reason??`unknown`}`),!1)}catch(e){return T(`update failed: ${e.message}`),!1}}function S(e){return new Promise(t=>{let n=process.platform===`win32`?`npm.cmd`:`npm`,r=[`install`,`-g`,`@zenovay/cli@${e}`],i={stdio:[`ignore`,`ignore`,`pipe`]},o=``,s=!1,c=a(n,r,i),l=setTimeout(()=>{if(!s){s=!0;try{c.kill(`SIGKILL`)}catch{}T(`npm install timed out after ${f/1e3}s; continuing with current version`),t(!1)}},f);c.stderr?.on(`data`,e=>{o+=e.toString(`utf8`)}),c.on(`error`,e=>{s||(s=!0,clearTimeout(l),T(`npm install error: ${e.message}`),t(!1))}),c.on(`exit`,n=>{if(!s){if(s=!0,clearTimeout(l),n===0){t(!0);return}/EACCES|permission denied/i.test(o)?process.stderr.write(`Auto-update needs sudo for the global npm prefix. Run: sudo npm i -g @zenovay/cli@${e}\n`):T(`npm install exited ${n}; continuing with current version`),t(!1)}})})}function C(e){return new Promise(t=>{if(!process.stdin.isTTY||!process.stderr.isTTY){t(!0);return}process.stderr.write(`New version ${e} available. Update? [Y/n] (auto-yes 5s) `);let n=!1,r=e=>{if(n)return;let r=e.toString(`utf8`).trim().toLowerCase();n=!0,i(),process.stderr.write(`
3
3
  `),t(r===``||r===`y`||r===`yes`)},i=()=>{clearTimeout(a),process.stdin.off(`data`,r);try{process.stdin.pause()}catch{}},a=setTimeout(()=>{n||(n=!0,i(),process.stderr.write(`
4
- `),t(!0))},m);try{process.stdin.resume(),process.stdin.on(`data`,r)}catch{i(),t(!0)}})}function w(e){try{let t=e.slice(1),n=a(process.execPath,t,{stdio:`inherit`});n.on(`exit`,e=>{process.exit(typeof e==`number`?e:0)}),n.on(`error`,()=>{})}catch{}}function T(e){try{process.stderr.write(`zenovay: ${e}\n`)}catch{}}const E=o.dirname(s(import.meta.url)),D=o.join(E,`..`,`package.json`),O=JSON.parse(c(D,`utf8`)),k=O.version,A=process.argv[0]??`zenovay`;function j(){if(process.env.ZENOVAY_BACKGROUND_UPDATE===`1`&&!(process.env.ZENOVAY_NO_UPDATE_CHECK===`1`||process.env.CI===`true`))try{let e=o.join(E,`lib`,`update`,`worker.js`),t=i(e,[],{detached:!0,stdio:`ignore`});t.unref()}catch{}}const M=r(`zenovay`);M.version(k),M.help(),M.command(`init`,`AI install wizard — add Zenovay tracking to your codebase`).option(`--json`,`Emit NDJSON events to stdout`).option(`--yes`,`Auto-approve all diffs (for CI)`).option(`--skip-mcp`,`Skip MCP client install`).option(`--skip-verify`,`Skip first-event verification`).action(async e=>{let{initCommand:t}=await import(`./init-BTJHpHNW.js`),n=await t({cliVersion:k,cwd:process.cwd(),json:e.json,yes:e.yes,skipMcp:e.skipMcp,skipVerify:e.skipVerify});process.exitCode=n}),M.command(`login`,`Authenticate via OAuth device flow`).option(`--json`,`Emit NDJSON events`).option(`--no-browser`,`Skip opening the browser automatically`).action(async e=>{let{loginCommand:t}=await import(`./login-Bb_At1Ov.js`);await t({cliVersion:k,json:e.json,openBrowser:e.browser!==!1,onCode:e=>{process.stdout.write(`\n Open this URL to authorize the CLI:\n ${e.verificationUriComplete??e.verificationUri}\n Or enter code: ${e.userCode}\n\n`)}})}),M.command(`logout`,`Revoke current session and delete local auth`).option(`--json`,``).action(async e=>{let{logoutCommand:t}=await import(`./logout-lHm-0I43.js`);await t({cliVersion:k,json:e.json})}),M.command(`ai`,`3-mode AI assistant (install / chat / mcp)`).option(`--mode <mode>`,`install | chat | mcp`).option(`--json`,``).action(async e=>{let{aiCommand:t}=await import(`./ai-gVD3a1tJ.js`),n=await t({cliVersion:k,cwd:process.cwd(),mode:e.mode,json:e.json});process.exitCode=n}),M.command(`watch`,`Live TUI dashboard`).option(`--site-id <id>`,`Site ID`).option(`--interval <ms>`,`Poll interval ms`,{default:15e3}).option(`--json`,``).action(async e=>{let{watchCommand:t}=await import(`./watch-eGS9kl-m.js`),n=await t({cliVersion:k,siteId:e.siteId,intervalMs:Number(e.interval),json:e.json});process.exitCode=n}),M.command(`events tail`,`Stream live events`).option(`--site-id <id>`,`Site ID`,{default:``}).option(`--filter <expr>`,`Filter expression (e.g. 'type=pageview AND country=US')`).option(`--forward-to <url>`,`POST each event to a webhook with HMAC-SHA256 signature`).option(`--replay-24h`,`Replay the last 24h before going live`).option(`--set-forward-secret <hex>`,`Persist the HMAC secret used by --forward-to`).option(`--json`,``).action(async e=>{let{eventsTailCommand:t}=await import(`./events-tail-BOLPhm8f.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json,filter:e.filter,forwardTo:e.forwardTo,replay24h:e.replay24h,setForwardSecret:e.setForwardSecret});process.exitCode=n}),M.command(`health`,`Run self-diagnostic checks`).option(`--json`,``).action(async e=>{let{healthCommand:t}=await import(`./health-DEbOYNUm.js`),n=await t({cliVersion:k,binaryPath:A,json:e.json});process.exitCode=n}),M.command(`doctor`,`AI-assisted self-healing`).option(`--json`,``).action(async e=>{let{doctorCommand:t}=await import(`./doctor-o833kcpO.js`),n=await t({cliVersion:k,binaryPath:A,json:e.json});process.exitCode=n}),M.command(`stats`,`One-shot dashboard summary (scriptable by default)`).option(`--site-id <id>`,`Site ID`).option(`--range <range>`,`Time range: 24h | 7d | 30d`,{default:`24h`}).option(`--watch`,`Auto-refresh every 60s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{statsCommand:t}=await import(`./stats-C1D7-kOD.js`),n=await t({cliVersion:k,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`sources`,`Traffic source breakdown with delta arrows`).option(`--site-id <id>`,`Site ID`).option(`--period <p>`,`Period: 7d | 30d | 90d | 1y`,{default:`30d`}).option(`--compare <c>`,`Comparison window (use "prev" for period-over-period)`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{sourcesCommand:t}=await import(`./sources-CG52LwT7.js`),n=await t({cliVersion:k,siteId:e.siteId,period:e.period,compare:e.compare,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`vitals`,`Core Web Vitals dashboard (LCP / INP / CLS / TTFB / FCP)`).option(`--site-id <id>`,`Site ID`).option(`--url <path>`,`Filter to a single URL`).option(`--device <type>`,`Filter by device: mobile | desktop`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`7d`}).option(`--watch`,`Auto-refresh every 5 minutes`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{vitalsCommand:t}=await import(`./vitals-Cdbqkwdt.js`),n=await t({cliVersion:k,siteId:e.siteId,url:e.url,device:e.device,window:e.window,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`revenue`,`MRR / ARR / transaction series`).option(`--site-id <id>`,`Site ID`).option(`--range <r>`,`Time range: 24h | 7d | 30d | 1y`,{default:`30d`}).option(`--watch`,`Auto-refresh every 5 minutes`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{revenueCommand:t}=await import(`./revenue-EPxBowpX.js`),n=await t({cliVersion:k,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`funnels`,`List available funnels`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{funnelCommand:t}=await import(`./funnel-2-RBc6Z6.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`themes`,`List available themes with colored swatches`).option(`--validate <path>`,`Validate a custom theme JSON file`).option(`--json`,`Emit themes JSON to stdout`).action(async e=>{let{themesCommand:t}=await import(`./themes-Dmj61mS1.js`),n=await t({cliVersion:k,validate:e.validate,json:e.json});process.exitCode=n}),M.command(`completions [shell]`,`Emit shell-completion script (bash | zsh | fish | nushell | pwsh)`).option(`--list`,`List supported shells`).action(async(e,t)=>{let{completionsCommand:n}=await import(`./completions-DHOrzR_j.js`),r=await n({shell:e,list:t.list});process.exitCode=r}),M.command(`query [sql]`,`Restricted SQL REPL over the analytics schema (Scale+)`).option(`--site-id <id>`,`Site ID`).option(`--max-rows <n>`,`Cap result row count`,{default:1e3}).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async(e,t)=>{let{queryCommand:n}=await import(`./query-CIAAVHLq.js`),r=await n({cliVersion:k,siteId:t.siteId,sql:e,maxRows:typeof t.maxRows==`string`?Number(t.maxRows):t.maxRows,json:t.json,csv:t.csv,tsv:t.tsv,ndjson:t.ndjson});process.exitCode=r}),M.command(`companies`,`B2B identification feed (Scale+)`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`24h`}).option(`--limit <n>`,`Max rows`,{default:100}).option(`--new-only`,`Show only newly identified companies (first-seen in last hour)`).option(`--watch`,`Auto-refresh every 30s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{companiesCommand:t}=await import(`./companies-BGeGKsvN.js`),n=await t({cliVersion:k,siteId:e.siteId,window:e.window,limit:typeof e.limit==`string`?Number(e.limit):e.limit,newOnly:e.newOnly,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`projects`,`List your tracked projects`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{projectsCommand:t}=await import(`./projects-CGvLylMB.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`deploys`,`Recent GitHub commits overlaid on charts (Wave 4 W5)`).option(`--site-id <id>`,`Site ID`).option(`--branch <name>`,`Filter to a single branch (e.g. main, develop)`).option(`--since <iso>`,`Only commits after this ISO timestamp`).option(`--limit <n>`,`Max rows`,{default:50}).option(`--connect`,`Print the GitHub-integration deep link in app.zenovay.com`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{deploysCommand:t}=await import(`./deploys-BdgjS9s8.js`),n=await t({cliVersion:k,siteId:e.siteId,branch:e.branch,since:e.since,limit:typeof e.limit==`string`?Number(e.limit):e.limit,connect:e.connect,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`webhooks forward`,`Forward webhook events to a local URL (stripe-listen-style; W3)`).option(`--to <url>`,`Local URL to POST events to (e.g. localhost:3000/webhook)`).option(`--site-id <id>`,`Site ID`).option(`--sign`,`HMAC-sign each forwarded request with X-Zenovay-Signature`).option(`--secret <hex>`,`HMAC secret (auto-derived from tunnel key if --sign without --secret)`).option(`--max-retries <n>`,`Per-request retry count`,{default:3}).action(async e=>{let{webhooksForwardCommand:t}=await import(`./webhooks-forward-DyNjdEfi.js`),n=await t({cliVersion:k,to:e.to,siteId:e.siteId,sign:e.sign,secret:e.secret,maxRetries:typeof e.maxRetries==`string`?Number(e.maxRetries):e.maxRetries});process.exitCode=n}),M.command(`errors`,`Recent error snapshot (Wave 2 lead-in; SSE coming in V2.1)`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`24h`}).option(`--limit <n>`,`Max errors to fetch`,{default:100}).option(`--search <q>`,`Filter by class or message substring`).option(`--watch`,`Auto-refresh every 30s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{errorsCommand:t}=await import(`./errors-CfBR-vTW.js`),n=await t({cliVersion:k,siteId:e.siteId,window:e.window,limit:typeof e.limit==`string`?Number(e.limit):e.limit,search:e.search,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`funnel <id>`,`Funnel drop-off chart for a specific funnel`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 7d | 30d`,{default:`30d`}).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async(e,t)=>{let{funnelCommand:n}=await import(`./funnel-2-RBc6Z6.js`),r=await n({cliVersion:k,siteId:t.siteId,funnelId:e,window:t.window,json:t.json,csv:t.csv,tsv:t.tsv,ndjson:t.ndjson});process.exitCode=r}),M.command(`use [site]`,`Set / show / reset your default site (used when --site-id is omitted)`).option(`--reset`,`Clear the stored default site`).option(`--show`,`Print the current default and exit`).option(`--json`,`Emit JSON`).action(async(e,t)=>{let{useCommand:n}=await import(`./use-jeUUaX-X.js`),r=await n({cliVersion:k,match:e,reset:t.reset,show:t.show,json:t.json});process.exitCode=r}),M.command(`update`,`Manually install the latest version`).option(`--check`,`Don't install — just print latest`).option(`--force-downgrade`,`Allow downgrading to an older version`).option(`--no-update-check`,`Disable auto-update for this invocation`).option(`--json`,``).action(async e=>{let{updateCommand:t}=await import(`./update-BQ026Ltb.js`);await t({cliVersion:k,binaryPath:A,check:e.check,forceDowngrade:e.forceDowngrade,json:e.json})}),M.parse(process.argv,{run:!1}),(async()=>{await _({binaryPath:A,currentVersion:k,argv:process.argv}),j();try{await M.runMatchedCommand()}catch(e){process.stderr.write(`\n✗ ${e.message}\n`),process.exit(1)}})();
4
+ `),t(!0))},m);try{process.stdin.resume(),process.stdin.on(`data`,r)}catch{i(),t(!0)}})}function w(e){try{let t=e.slice(1),n=a(process.execPath,t,{stdio:`inherit`});n.on(`exit`,e=>{process.exit(typeof e==`number`?e:0)}),n.on(`error`,()=>{})}catch{}}function T(e){if(process.env.ZENOVAY_DEBUG_UPDATE===`1`)try{process.stderr.write(`zenovay: ${e}\n`)}catch{}}const E=o.dirname(s(import.meta.url)),D=o.join(E,`..`,`package.json`),O=JSON.parse(c(D,`utf8`)),k=O.version,A=process.argv[0]??`zenovay`;function j(){if(process.env.ZENOVAY_BACKGROUND_UPDATE===`1`&&!(process.env.ZENOVAY_NO_UPDATE_CHECK===`1`||process.env.CI===`true`))try{let e=o.join(E,`lib`,`update`,`worker.js`),t=i(e,[],{detached:!0,stdio:`ignore`});t.unref()}catch{}}const M=r(`zenovay`);M.version(k),M.help(),M.command(`init`,`AI install wizard — add Zenovay tracking to your codebase`).option(`--json`,`Emit NDJSON events to stdout`).option(`--yes`,`Auto-approve all diffs (for CI)`).option(`--skip-mcp`,`Skip MCP client install`).option(`--skip-verify`,`Skip first-event verification`).action(async e=>{let{initCommand:t}=await import(`./init-BMNuKlUT.js`),n=await t({cliVersion:k,cwd:process.cwd(),json:e.json,yes:e.yes,skipMcp:e.skipMcp,skipVerify:e.skipVerify});process.exitCode=n}),M.command(`login`,`Authenticate via OAuth device flow`).option(`--json`,`Emit NDJSON events`).option(`--no-browser`,`Skip opening the browser automatically`).action(async e=>{let{loginCommand:t}=await import(`./login-Bb_At1Ov.js`),n=await t({cliVersion:k,json:e.json,openBrowser:e.browser!==!1,onCode:e=>{process.stdout.write(`\n Open this URL to authorize the CLI:\n ${e.verificationUriComplete??e.verificationUri}\n Or enter code: ${e.userCode}\n\n`)}});!e.json&&n.email?process.stdout.write(`\n ✔ Logged in as ${n.email}\n Try \`zenovay overview\` to see your dashboard, or \`zenovay --help\` for the full command list.\n\n`):e.json||process.stdout.write(`
5
+ ✔ Logged in.
6
+
7
+ `)}),M.command(`logout`,`Revoke current session and delete local auth`).option(`--json`,``).action(async e=>{let{logoutCommand:t}=await import(`./logout-B_-6rZdK.js`);await t({cliVersion:k,json:e.json})}),M.command(`ai`,`3-mode AI assistant (install / chat / mcp)`).option(`--mode <mode>`,`install | chat | mcp`).option(`--json`,``).action(async e=>{let{aiCommand:t}=await import(`./ai-4Yo74A1a.js`),n=await t({cliVersion:k,cwd:process.cwd(),mode:e.mode,json:e.json});process.exitCode=n}),M.command(`watch`,"[ANALYTICS] Alias for `overview` (dashboard summary)").option(`--site-id <id>`,`Site ID`).option(`--interval <ms>`,`Poll interval ms (legacy; ignored by overview)`,{default:15e3}).option(`--json`,``).action(async e=>{let{overviewCommand:t}=await import(`./overview-CNuR2Mx9.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`overview`,`[ANALYTICS] Landing dashboard — visitors, pageviews, bounce, top pages`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{overviewCommand:t}=await import(`./overview-CNuR2Mx9.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`live`,`[ANALYTICS] Real-time visitors + globe + recent events (2s polling)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{liveCommand:t}=await import(`./live-CUExJ1O5.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`pages`,`[ANALYTICS] Top pages by views — last 24h`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{pagesCommand:t}=await import(`./pages-CdoPyNQH.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`devices`,`[ANALYTICS] Device / browser / OS breakdown — last 24h`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{devicesCommand:t}=await import(`./devices-B4_ouB05.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`geo`,`[ANALYTICS] Countries + cities + globe — last 24h`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{geoCommand:t}=await import(`./geo-CInOewrI.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`retention`,`[BEHAVIOR] Cohort retention heatmap — D1 / D7 / D30 (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{retentionCommand:t}=await import(`./retention-B-fiW8Un.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`uptime`,`[BEHAVIOR] Uptime monitors with status + p95 (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{uptimeCommand:t}=await import(`./uptime-I4CzdPZv.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`sessions`,`[BEHAVIOR] Recent session-replay list (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{sessionsCommand:t}=await import(`./sessions-DYb8v1LG.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`heatmaps`,`[BEHAVIOR] Recent heatmap captures (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{heatmapsCommand:t}=await import(`./heatmaps-DfVR48Km.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`journeys`,`[BEHAVIOR] Page-to-page transition flow (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{journeysCommand:t}=await import(`./journeys-CCrSFXhO.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`insights`,`[INTELLIGENCE] AI-generated anomaly / trend / recommendation cards (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{insightsCommand:t}=await import(`./insights-Dd0HWA_M.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json});process.exitCode=n}),M.command(`events tail`,`Stream live events`).option(`--site-id <id>`,`Site ID`,{default:``}).option(`--filter <expr>`,`Filter expression (e.g. 'type=pageview AND country=US')`).option(`--forward-to <url>`,`POST each event to a webhook with HMAC-SHA256 signature`).option(`--replay-24h`,`Replay the last 24h before going live`).option(`--set-forward-secret <hex>`,`Persist the HMAC secret used by --forward-to`).option(`--json`,``).action(async e=>{let{eventsTailCommand:t}=await import(`./events-tail-CtoMkdkb.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json,filter:e.filter,forwardTo:e.forwardTo,replay24h:e.replay24h,setForwardSecret:e.setForwardSecret});process.exitCode=n}),M.command(`health`,`Run self-diagnostic checks`).option(`--json`,``).action(async e=>{let{healthCommand:t}=await import(`./health-DBiKIoYL.js`),n=await t({cliVersion:k,binaryPath:A,json:e.json});process.exitCode=n}),M.command(`doctor`,`AI-assisted self-healing`).option(`--json`,``).action(async e=>{let{doctorCommand:t}=await import(`./doctor-CjpTOujh.js`),n=await t({cliVersion:k,binaryPath:A,json:e.json});process.exitCode=n}),M.command(`stats`,`One-shot dashboard summary (scriptable by default)`).option(`--site-id <id>`,`Site ID`).option(`--range <range>`,`Time range: 24h | 7d | 30d`,{default:`24h`}).option(`--watch`,`Auto-refresh every 60s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{statsCommand:t}=await import(`./stats-Bf3LR7aS.js`),n=await t({cliVersion:k,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`sources`,`Traffic source breakdown with delta arrows`).option(`--site-id <id>`,`Site ID`).option(`--period <p>`,`Period: 7d | 30d | 90d | 1y`,{default:`30d`}).option(`--compare <c>`,`Comparison window (use "prev" for period-over-period)`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{sourcesCommand:t}=await import(`./sources-2Zhm5ihV.js`),n=await t({cliVersion:k,siteId:e.siteId,period:e.period,compare:e.compare,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`vitals`,`Core Web Vitals dashboard (LCP / INP / CLS / TTFB / FCP)`).option(`--site-id <id>`,`Site ID`).option(`--url <path>`,`Filter to a single URL`).option(`--device <type>`,`Filter by device: mobile | desktop`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`7d`}).option(`--watch`,`Auto-refresh every 5 minutes`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{vitalsCommand:t}=await import(`./vitals-XBfK3I8H.js`),n=await t({cliVersion:k,siteId:e.siteId,url:e.url,device:e.device,window:e.window,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`revenue`,`MRR / ARR / transaction series`).option(`--site-id <id>`,`Site ID`).option(`--range <r>`,`Time range: 24h | 7d | 30d | 1y`,{default:`30d`}).option(`--watch`,`Auto-refresh every 5 minutes`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{revenueCommand:t}=await import(`./revenue-D0DkXtgI.js`),n=await t({cliVersion:k,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`funnels`,`List available funnels`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{funnelCommand:t}=await import(`./funnel-CK0vfgfb.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`themes`,`List available themes with colored swatches`).option(`--validate <path>`,`Validate a custom theme JSON file`).option(`--json`,`Emit themes JSON to stdout`).action(async e=>{let{themesCommand:t}=await import(`./themes-Ty85UcjT.js`),n=await t({cliVersion:k,validate:e.validate,json:e.json});process.exitCode=n}),M.command(`completions [shell]`,`Emit shell-completion script (bash | zsh | fish | nushell | pwsh)`).option(`--list`,`List supported shells`).action(async(e,t)=>{let{completionsCommand:n}=await import(`./completions-hFMu39uk.js`),r=await n({shell:e,list:t.list});process.exitCode=r}),M.command(`query [sql]`,`Restricted SQL REPL over the analytics schema (Scale+)`).option(`--site-id <id>`,`Site ID`).option(`--max-rows <n>`,`Cap result row count`,{default:1e3}).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async(e,t)=>{let{queryCommand:n}=await import(`./query-BDppYLwt.js`),r=await n({cliVersion:k,siteId:t.siteId,sql:e,maxRows:typeof t.maxRows==`string`?Number(t.maxRows):t.maxRows,json:t.json,csv:t.csv,tsv:t.tsv,ndjson:t.ndjson});process.exitCode=r}),M.command(`companies`,`B2B identification feed (Scale+)`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`24h`}).option(`--limit <n>`,`Max rows`,{default:100}).option(`--new-only`,`Show only newly identified companies (first-seen in last hour)`).option(`--watch`,`Auto-refresh every 30s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{companiesCommand:t}=await import(`./companies-f2shersJ.js`),n=await t({cliVersion:k,siteId:e.siteId,window:e.window,limit:typeof e.limit==`string`?Number(e.limit):e.limit,newOnly:e.newOnly,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`projects`,`List your tracked projects`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{projectsCommand:t}=await import(`./projects-Cb8Jk1rh.js`),n=await t({cliVersion:k,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`deploys`,`Recent GitHub commits overlaid on charts (Wave 4 W5)`).option(`--site-id <id>`,`Site ID`).option(`--branch <name>`,`Filter to a single branch (e.g. main, develop)`).option(`--since <iso>`,`Only commits after this ISO timestamp`).option(`--limit <n>`,`Max rows`,{default:50}).option(`--connect`,`Print the GitHub-integration deep link in app.zenovay.com`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{deploysCommand:t}=await import(`./deploys-CudLAqUS.js`),n=await t({cliVersion:k,siteId:e.siteId,branch:e.branch,since:e.since,limit:typeof e.limit==`string`?Number(e.limit):e.limit,connect:e.connect,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`webhooks forward`,`Forward webhook events to a local URL (stripe-listen-style; W3)`).option(`--to <url>`,`Local URL to POST events to (e.g. localhost:3000/webhook)`).option(`--site-id <id>`,`Site ID`).option(`--sign`,`HMAC-sign each forwarded request with X-Zenovay-Signature`).option(`--secret <hex>`,`HMAC secret (auto-derived from tunnel key if --sign without --secret)`).option(`--max-retries <n>`,`Per-request retry count`,{default:3}).action(async e=>{let{webhooksForwardCommand:t}=await import(`./webhooks-forward-DcnCiBcP.js`),n=await t({cliVersion:k,to:e.to,siteId:e.siteId,sign:e.sign,secret:e.secret,maxRetries:typeof e.maxRetries==`string`?Number(e.maxRetries):e.maxRetries});process.exitCode=n}),M.command(`errors`,`Recent error snapshot (Wave 2 lead-in; SSE coming in V2.1)`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`24h`}).option(`--limit <n>`,`Max errors to fetch`,{default:100}).option(`--search <q>`,`Filter by class or message substring`).option(`--watch`,`Auto-refresh every 30s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{errorsCommand:t}=await import(`./errors-CEJ43Vd4.js`),n=await t({cliVersion:k,siteId:e.siteId,window:e.window,limit:typeof e.limit==`string`?Number(e.limit):e.limit,search:e.search,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),M.command(`funnel <id>`,`Funnel drop-off chart for a specific funnel`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 7d | 30d`,{default:`30d`}).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async(e,t)=>{let{funnelCommand:n}=await import(`./funnel-CK0vfgfb.js`),r=await n({cliVersion:k,siteId:t.siteId,funnelId:e,window:t.window,json:t.json,csv:t.csv,tsv:t.tsv,ndjson:t.ndjson});process.exitCode=r}),M.command(`use [site]`,`Set / show / reset your default site (used when --site-id is omitted)`).option(`--reset`,`Clear the stored default site`).option(`--show`,`Print the current default and exit`).option(`--json`,`Emit JSON`).action(async(e,t)=>{let{useCommand:n}=await import(`./use-DOxo6QgS.js`),r=await n({cliVersion:k,match:e,reset:t.reset,show:t.show,json:t.json});process.exitCode=r}),M.command(`update`,`Manually install the latest version`).option(`--check`,`Don't install — just print latest`).option(`--force-downgrade`,`Allow downgrading to an older version`).option(`--no-update-check`,`Disable auto-update for this invocation`).option(`--json`,``).action(async e=>{let{updateCommand:t}=await import(`./update-5mypMXp6.js`);await t({cliVersion:k,binaryPath:A,check:e.check,forceDowngrade:e.forceDowngrade,json:e.json})}),M.parse(process.argv,{run:!1}),(async()=>{await _({binaryPath:A,currentVersion:k,argv:process.argv}),j();try{await M.runMatchedCommand()}catch(e){process.stderr.write(`\n✗ ${e.message}\n`),process.exit(1)}})();
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{requireTier as l}from"./tier-Ceoo7ndQ.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function m(e){return e==null?`—`:e>=500?`Enterprise`:e>=50?`Growth`:`SMB`}async function h(h){let g=await e(),_=await t({strict:!1}),v=new c({config:g,cliVersion:h.cliVersion,token:_});try{await l(v,`scale`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let y;try{({siteId:y}=await s(v,{explicit:h.siteId,headless:!!(h.json||h.csv||h.tsv||h.ndjson),cliVersion:h.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let b=r(h),x=h.window??`24h`,S=h.limit??100,C=[{key:`lastSeenAt`,header:`when`,width:6,format:e=>p(String(e))},{key:`name`,header:`company`,width:24,format:e=>String(e).slice(0,24)},{key:`employeeCount`,header:`tier`,width:11,format:e=>m(typeof e==`number`?e:null)},{key:`industry`,header:`industry`,width:18,format:e=>String(e??`—`).slice(0,18)},{key:`visitCount`,header:`visits`,width:6,align:`right`},{key:`isNew`,header:``,width:5,format:e=>e?`NEW`:``}];return i({cliVersion:h.cliVersion,title:`companies · ${y} · ${x}`,commandName:`companies`,authToken:_?.accessToken??null,refreshIntervalMs:h.watch?3e4:0,fetcher:e=>v.getCompaniesSnapshot(y,{window:x,limit:S},e),format:b,headlessEmit:(e,t)=>{let r=h.newOnly?e.companies.filter(e=>e.isNew):e.companies;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of r)process.stdout.write(JSON.stringify(e)+`
2
+ `);else process.stdout.write(JSON.stringify({companies:r,total:r.length},null,2));return}process.stdout.write(n(r,[`name`,`domain`,`industry`,`employeeCount`,`visitCount`,`firstSeenAt`,`lastSeenAt`,`isNew`],t))},panels:[{id:`summary`,title:`Now`,render:e=>{let t=e.companies.filter(e=>e.isNew).length,n=e.companies.filter(e=>(e.employeeCount??0)>=500).length;return f.createElement(u,{flexDirection:`column`},f.createElement(d,null,f.createElement(d,{bold:!0},e.total),f.createElement(d,{color:`gray`},` companies in `,x)),f.createElement(d,{color:`gray`},f.createElement(d,{color:`green`},`● `,t,` new`),` · `,n,` enterprise`))}},{id:`feed`,title:`Feed`,render:e=>{let t=h.newOnly?e.companies.filter(e=>e.isNew):e.companies;return t.length===0?f.createElement(o,{reason:`no-data`,headline:`No ${h.newOnly?`new `:``}companies in window`,hint:`B2B identification fires when a tracked visitor matches a known company IP/domain.`}):f.createElement(a,{data:t.slice(0,30),columns:C})}}]})}export{h as companiesCommand};
@@ -0,0 +1 @@
1
+ import{useTheme as e}from"./panel-DZqvtaao.js";import{Box as t,Text as n}from"ink";import r from"react";function i(e,t){return e.length<=t?e:t<=1?e.slice(0,t):`${e.slice(0,t-1)}…`}function a(e,t,n){if(e.length>=t)return i(e,t);let r=t-e.length;return n===`right`?` `.repeat(r)+e:e+` `.repeat(r)}function o(e,t){return e.map(e=>{if(typeof e.width==`number`&&e.width>0)return e.width;let n=e.label.length;for(let r of t){let t=r[e.key],i=e.format?e.format(t,r):String(t??``);i.length>n&&(n=i.length)}return Math.max(3,n)})}function s({columns:i,data:s,zebra:c=!1}){let{theme:l}=e(),u=o(i,s),d=u.reduce((e,t)=>e+t,0)+i.length*3+1,f=(e,t,n)=>{let r=e;return u.forEach((e,i)=>{r+=`─`.repeat(e+2),r+=i===u.length-1?n:t}),r},p=f(`╭`,`┬`,`╮`),m=f(`├`,`┼`,`┤`),h=f(`╰`,`┴`,`╯`),g=i.map((e,t)=>a(e.label,u[t]??e.label.length,e.align??`left`)).join(` │ `);return r.createElement(t,{flexDirection:`column`,width:d},r.createElement(n,{color:l.border},p),r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:l.border},`│ `),r.createElement(n,{color:l.fg,bold:!0},g),r.createElement(n,{color:l.border},` │`)),r.createElement(n,{color:l.border},m),s.map((e,o)=>{let s=c&&o%2==1,d=s?l.muted:l.fg,f=i.map((t,n)=>{let r=e[t.key],i=t.format?t.format(r,e):String(r??``);return a(i,u[n]??i.length,t.align??`left`)}).join(` │ `);return r.createElement(t,{key:o,flexDirection:`row`},r.createElement(n,{color:l.border},`│ `),r.createElement(n,{color:d},f),r.createElement(n,{color:l.border},` │`))}),r.createElement(n,{color:l.border},h))}export{s as DataTable};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}async function p(p){if(p.connect){let t=await e(),n=t.apiBase.replace(`api.zenovay.com`,`app.zenovay.com`),r=`${n}/settings/integrations/github`;return process.stdout.write(`\n Connect GitHub to Zenovay:\n ${r}\n\n Open this URL in your browser. Zenovay re-uses the same GitHub\n OAuth app you already authorized for login (auth-zenovay), so\n no separate "Zenovay Deploys" app is needed. Pick the repos you\n want to track and deploys will appear here automatically.\n\n`),0}let m=await e(),h=await t({strict:!1}),g=new c({config:m,cliVersion:p.cliVersion,token:h}),_;try{({siteId:_}=await s(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let v=r(p),y=p.limit??50,b=[{key:`pushed_at`,header:`when`,width:6,format:e=>f(String(e))},{key:`branch`,header:`branch`,width:14,format:e=>String(e??`—`).slice(0,14)},{key:`commit_sha`,header:`commit`,width:9,format:e=>String(e).slice(0,8)},{key:`commit_author`,header:`author`,width:16,format:e=>String(e??`—`).slice(0,16)},{key:`commit_message`,header:`message`,width:40,format:e=>String(e??`—`).slice(0,40)},{key:`show_on_chart`,header:`chart`,width:5,format:e=>e?`●`:`○`}];return i({cliVersion:p.cliVersion,title:`deploys · ${_}`,commandName:`deploys`,authToken:h?.accessToken??null,refreshIntervalMs:0,fetcher:e=>g.getDeploys(_,{branch:p.branch,since:p.since,limit:y},e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.deploys)process.stdout.write(JSON.stringify(t)+`
2
+ `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(n(e.deploys,[`pushed_at`,`branch`,`commit_sha`,`commit_author`,`commit_message`,`repository`,`commit_url`,`show_on_chart`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>{let t=e.deploys.filter(e=>e.show_on_chart).length,n=new Set(e.deploys.map(e=>e.repository).filter(e=>!!e));return d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},e.total),d.createElement(u,{color:`gray`},` commits`,p.branch?` · branch=${p.branch}`:``)),d.createElement(u,{color:`gray`},d.createElement(u,{color:`magenta`},`● `,t,` on chart`),d.createElement(u,null,` · `),d.createElement(u,null,n.size,` `,n.size===1?`repo`:`repos`)))}},{id:`list`,title:`Recent`,render:e=>e.deploys.length===0?d.createElement(o,{reason:`no-data`,headline:`No commits yet`,hint:"Run `zenovay deploys --connect` to wire up the GitHub integration."}):d.createElement(a,{data:e.deploys.slice(0,30),columns:b})}]})}export{p as deploysCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{DataTable as u}from"./data-table-CDTM2qS0.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";async function b(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o}),u;try{({siteId:u}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getDevices(u);return n({type:`devices.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:s,siteId:u,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=m(),[l,p]=v(null),[b,x]=v(!0),[S,C]=v(null);if(h(e=>{e===`q`&&(c(),r(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getDevices(t);n||(p(r),x(!1))}catch(e){n||(C(e.message),x(!1))}})(),()=>{n=!0}},[e,t]),b)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`devices · ${t}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Fetching breakdown…`))));if(S)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`devices · ${t}`}),g.createElement(s,{reason:`error`,headline:`Failed to load`,hint:S}));let w=!l||l.devices.length===0&&l.browsers.length===0&&l.os.length===0;if(w)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`devices · ${t}`}),g.createElement(s,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let T=[{key:`name`,label:`name`,width:16},{key:`visitors`,label:`visitors`,align:`right`,width:8}];return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`devices · ${t}`}),g.createElement(d,{flexDirection:`row`},g.createElement(i,{title:`Devices`},l.devices.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(u,{columns:T,data:l.devices,zebra:!0})),g.createElement(i,{title:`Browsers`},l.browsers.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(u,{columns:T,data:l.browsers,zebra:!0})),g.createElement(i,{title:`OS`},l.os.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(u,{columns:T,data:l.os,zebra:!0}))),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{b as devicesCommand};
@@ -1,4 +1,4 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import"./check-Comj8AkL.js";import{ApiClient as t,readToken as n}from"./api-DXmhz2DM.js";import{parseSseStream as r}from"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import{emit as i,isHeadless as a}from"./emit-BmfLGjqr.js";import"./panel-DZqvtaao.js";import{runHealthChecks as o}from"./health-DEmXOsf7.js";async function s(s){let c=await o({cliVersion:s.cliVersion,binaryPath:s.binaryPath}),l=c.filter(e=>e.status===`fail`);if(l.length===0)return a(s)||process.stdout.write(`All checks pass — no healing needed.
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import"./check-Comj8AkL.js";import{ApiClient as t,readToken as n}from"./api-DXmhz2DM.js";import{parseSseStream as r}from"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import{emit as i,isHeadless as a}from"./emit-BmfLGjqr.js";import"./panel-DZqvtaao.js";import{runHealthChecks as o}from"./health-Bn_Bw6c_.js";async function s(s){let c=await o({cliVersion:s.cliVersion,binaryPath:s.binaryPath}),l=c.filter(e=>e.status===`fail`);if(l.length===0)return a(s)||process.stdout.write(`All checks pass — no healing needed.
2
2
  `),0;let u=await e(),d=await n({strict:!1});if(!d){for(let e of l)process.stderr.write(`[${e.name}] ${e.detail}\n`);return process.stderr.write(`
3
3
  Log in with \`zenovay login\` for AI-assisted diagnosis.
4
4
  `),1}let f=new t({config:u,cliVersion:s.cliVersion,token:d}),p={platform:process.platform,arch:process.arch,node:process.version,cliVersion:s.cliVersion},m=`The Zenovay CLI failed the following health checks. Diagnose and propose a fix.
@@ -0,0 +1 @@
1
+ import{useTheme as e}from"./panel-DZqvtaao.js";import{Box as t,Text as n}from"ink";import r from"react";const i={"no-data":`○`,"tier-gated":`◆`,error:`✗`},a=`https://app.zenovay.com/billing`;function o({headline:o,hint:s,reason:c=`no-data`,cta:l,width:u}){let{theme:d}=e(),f=i[c],p=c===`error`?d.error:c===`tier-gated`?d.accent2:d.muted,m=l??(c===`tier-gated`?`Upgrade → ${a}`:void 0);return r.createElement(t,{flexDirection:`column`,alignItems:`center`,width:u},r.createElement(n,{color:p,bold:!0},f),r.createElement(n,{color:d.typography.title.color,bold:d.typography.title.bold},o),s?r.createElement(n,{color:d.dim},s):null,m?r.createElement(n,{color:d.accent},m):null)}export{o as EmptyState};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import{spark as i}from"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as a}from"./analytical-screen-DI8ahq4z.js";import{Table as o}from"./ui-BtZp4Eh8.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function m(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}async function h(h){let g=await e(),_=await t({strict:!1}),v=new l({config:g,cliVersion:h.cliVersion,token:_}),y;try{({siteId:y}=await c(v,{explicit:h.siteId,headless:!!(h.json||h.csv||h.tsv||h.ndjson),cliVersion:h.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let b=r(h),x=h.window??`24h`,S=h.limit??100,C=[{key:`ts`,header:`when`,width:6,format:e=>m(String(e))},{key:`class`,header:`class`,width:18,format:e=>String(e)},{key:`message`,header:`message`,width:42,format:e=>p(String(e??``),42)},{key:`page`,header:`page`,width:24,format:e=>String(e??`—`)},{key:`device`,header:`device`,width:8,format:e=>String(e??`—`)}];return a({cliVersion:h.cliVersion,title:`errors · ${y} · ${x}`,commandName:`errors`,authToken:_?.accessToken??null,refreshIntervalMs:h.watch?3e4:0,fetcher:e=>v.getErrors(y,{window:x,limit:S},e),format:b,headlessEmit:(e,t)=>{let r=h.search?e.errors.filter(e=>e.class.toLowerCase().includes(h.search.toLowerCase())||e.message.toLowerCase().includes(h.search.toLowerCase())):e.errors;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of r)process.stdout.write(JSON.stringify(e)+`
2
+ `);else process.stdout.write(JSON.stringify({errors:r,total:r.length},null,2));return}process.stdout.write(n(r,[`ts`,`class`,`message`,`page`,`device`,`fingerprint`],t))},panels:[{id:`summary`,title:`Recent errors`,render:e=>{let t=h.search?e.errors.filter(e=>e.class.toLowerCase().includes(h.search.toLowerCase())||e.message.toLowerCase().includes(h.search.toLowerCase())):e.errors,n=new Map,r=Date.now(),a=60;for(let e of t){let t=new Date(e.ts).getTime(),i=Math.floor((r-t)/(60*1e3));if(i<0||i>=a)continue;let o=n.get(e.class)??Array(a).fill(0),s=a-1-i;o[s]+=1,n.set(e.class,o)}let o=[...n.entries()].sort((e,t)=>t[1].reduce((e,t)=>e+t,0)-e[1].reduce((e,t)=>e+t,0)).slice(0,6);return f.createElement(u,{flexDirection:`column`},f.createElement(d,null,f.createElement(d,{bold:!0},t.length),f.createElement(d,{color:`gray`},` errors in `,x)),o.length===0?null:f.createElement(u,{flexDirection:`column`,marginTop:1},o.map(([e,t])=>f.createElement(d,{key:e},f.createElement(d,{color:`red`},e.padEnd(20).slice(0,20)),` `,f.createElement(d,{color:`gray`},i(t,30))))))}},{id:`table`,title:`Detail`,render:e=>{let t=h.search?e.errors.filter(e=>e.class.toLowerCase().includes(h.search.toLowerCase())||e.message.toLowerCase().includes(h.search.toLowerCase())):e.errors;return t.length===0?f.createElement(s,{reason:`no-data`,headline:h.search?`No errors match "${h.search}"`:`No errors in window`,hint:h.search?`Try widening the time window or removing the search filter.`:`Nothing broken — or your tracker hasn't captured any JS exceptions yet.`}):f.createElement(o,{data:t.slice(0,30),columns:C})}}]})}export{h as errorsCommand};
@@ -0,0 +1,3 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{requireTier as l}from"./tier-Ceoo7ndQ.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e,t){let n=Math.round(e*t);return`█`.repeat(Math.max(0,Math.min(t,n)))+`░`.repeat(Math.max(0,t-n))}async function m(m){let g=await e(),_=await t({strict:!1}),v=new c({config:g,cliVersion:m.cliVersion,token:_});try{await l(v,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let y;try{({siteId:y}=await s(v,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let b=r(m);if(!m.funnelId){let e=[{key:`name`,header:`name`,width:30},{key:`stepCount`,header:`steps`,width:6,align:`right`},{key:`id`,header:`id`,width:36,format:e=>String(e).slice(0,36)}];return i({cliVersion:m.cliVersion,title:`funnels · ${y}`,commandName:`funnels`,authToken:_?.accessToken??null,refreshIntervalMs:0,fetcher:e=>v.listFunnels(y,e),format:b,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);return}process.stdout.write(n(e.funnels,[`id`,`name`,`stepCount`],t))},panels:[{id:`funnels`,title:`Funnels`,render:t=>t.funnels.length===0?f.createElement(o,{reason:`no-data`,headline:`No funnels defined`,hint:`Create a funnel in the dashboard at app.zenovay.com to track conversion steps here.`}):f.createElement(a,{data:t.funnels,columns:e})},{id:`hint`,title:`Next`,render:()=>f.createElement(d,{color:`gray`},"Run `zenovay funnel <id>` for drop-off detail.")}]})}let x=m.window??`30d`;return i({cliVersion:m.cliVersion,title:`funnel · ${m.funnelId} · ${x}`,commandName:`funnel`,authToken:_?.accessToken??null,refreshIntervalMs:0,fetcher:e=>v.getFunnel(y,m.funnelId,x,e),format:b,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
3
+ `);return}process.stdout.write(n(e.steps,[`id`,`name`,`visitors`,`conversions`],t))},panels:[{id:`overview`,title:h(`Overview`),render:e=>f.createElement(u,{flexDirection:`column`},f.createElement(d,{bold:!0},e.name),f.createElement(d,{color:`gray`},e.totalEntries.toLocaleString(),` entries · `,e.totalCompletions.toLocaleString(),` completed (`,(e.conversionRate*100).toFixed(1),`%)`))},{id:`flow`,title:`Flow`,render:e=>{let t=e.totalEntries||1;return f.createElement(u,{flexDirection:`column`},e.steps.map((n,r)=>{let i=n.visitors/t,a=e.steps[r-1],o=a?a.visitors-n.visitors:0,s=a?o/Math.max(1,a.visitors)*100:0;return f.createElement(u,{key:n.id,flexDirection:`column`},a?f.createElement(d,{color:`red`},` `,`↓ drop `,o.toLocaleString(),` (`,s.toFixed(1),`%)`):null,f.createElement(d,null,f.createElement(d,{bold:!0},`${r+1}. ${n.name}`.padEnd(22).slice(0,22)),` `,f.createElement(d,{color:`magenta`},p(i,30)),` `,f.createElement(d,null,(i*100).toFixed(1).padStart(5),`% `),f.createElement(d,{color:`gray`},n.visitors.toLocaleString())))}))}}]})}function h(e){return e}export{m as funnelCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{DataTable as u}from"./data-table-CDTM2qS0.js";import{Globe as d}from"./globe-1bi4DjwJ.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o}),u;try{({siteId:u}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getGeo(u);return n({type:`geo.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:s,siteId:u,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,m]=y(null),[x,S]=y(!0),[C,w]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getGeo(t);n||(m(r),S(!1))}catch(e){n||(w(e.message),S(!1))}})(),()=>{n=!0}},[e,t]),x)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`geo · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching geo…`))));if(C)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`geo · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:C}));let T=!l||l.countries.length===0&&l.cities.length===0;if(T)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`geo · ${t}`}),_.createElement(s,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let E=[{key:`country`,label:`country`,width:18},{key:`visitors`,label:`visitors`,align:`right`,width:8}],D=[{key:`city`,label:`city`,width:20},{key:`country`,label:`country`,width:12},{key:`visitors`,label:`visitors`,align:`right`,width:8}],O=process.stdout.columns??80;return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`geo · ${t}`}),_.createElement(f,{flexDirection:`row`},_.createElement(i,{title:`Countries`},l.countries.length===0?_.createElement(p,{color:`gray`},`— —`):_.createElement(u,{columns:E,data:l.countries.slice(0,15),zebra:!0})),_.createElement(i,{title:`Globe`},_.createElement(d,{data:[],width:Math.max(36,O-60),height:12}))),_.createElement(i,{title:`Cities`},l.cities.length===0?_.createElement(p,{color:`gray`},`— —`):_.createElement(u,{columns:D,data:l.cities.slice(0,20),zebra:!0})),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{x as geoCommand};
@@ -0,0 +1 @@
1
+ import{Box as e,Text as t}from"ink";import n from"react";const r=Math.PI*2;function i(e){let t=e,n=Math.PI*Math.sin(e);for(let e=0;e<6;e++){let e=2*t+Math.sin(2*t)-n,r=2+2*Math.cos(2*t);if(r===0)break;t-=e/r}return t}function a(e,t){if(e<-90||e>90||t<-180||t>180)return null;let n=e*Math.PI/180,r=t*Math.PI/180,a=i(n),o=r*Math.cos(a)/Math.PI,s=Math.sin(a);return{x:o,y:s}}function o(e){if(e)return!0;let t=process.env;if(t.NO_COLOR||t.ZENOVAY_GLOBE===`ascii`)return!0;let n=(t.LANG||t.LC_ALL||t.LC_CTYPE||``).toLowerCase();return!!(n&&!n.includes(`utf`))}function s(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function c(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function l(e){let t=e.dw/2,n=e.dh/2,i=e.dw/2-1,a=e.dh/2-1,o=Math.max(e.dw,e.dh)*2;for(let s=0;s<o;s++){let l=s/o*r,u=Math.round(t+i*Math.cos(l)),d=Math.round(n+a*Math.sin(l));c(e,u,d)}}function u(e){let t=Math.floor(e.dh/2);for(let n=0;n<e.dw;n+=4)c(e,n,t)}function d(e,t){let n=e.dw/2,r=e.dh/2,i=e.dw/2-1,o=e.dh/2-1;for(let s of t){let t=a(s.lat,s.lng);if(!t)continue;let l=Math.round(n+t.x*i),u=Math.round(r-t.y*o);c(e,l,u),c(e,l+1,u),c(e,l,u+1),c(e,l+1,u+1)}}const f=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function p(e,t,n){let r=0;for(let i=0;i<f.length;i++){let[a,o]=f[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function m(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`.`:r<=4?`:`:r<=6?`*`:`#`}function h({data:r,width:i=80,height:a=20,asciiOnly:c}){let f=o(c),h=s(i,a);l(h),u(h),d(h,r);let g=[];for(let e=0;e<a;e++){let t=``;for(let n=0;n<i;n++)t+=f?m(h,n,e):p(h,n,e);g.push(t)}return n.createElement(e,{flexDirection:`column`},g.map((e,r)=>n.createElement(t,{key:r,color:`magenta`},e)),n.createElement(t,{color:`gray`},r.length,` live · `,f?`ascii mode`:`braille mode`))}export{h as Globe};
@@ -1 +1 @@
1
- import"./config-CZ9IzjIH.js";import"./check-Comj8AkL.js";import"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import"./emit-BmfLGjqr.js";import"./panel-DZqvtaao.js";import{HealthReport as e,exitCodeFor as t,healthCommand as n,runHealthChecks as r}from"./health-DEmXOsf7.js";export{n as healthCommand};
1
+ import"./config-CZ9IzjIH.js";import"./check-Comj8AkL.js";import"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import"./emit-BmfLGjqr.js";import"./panel-DZqvtaao.js";import{HealthReport as e,exitCodeFor as t,healthCommand as n,runHealthChecks as r}from"./health-Bn_Bw6c_.js";export{n as healthCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{DataTable as d}from"./data-table-CDTM2qS0.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getHeatmaps(d);return n({type:`heatmaps.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,u]=y(null),[m,x]=y(!0),[S,C]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getHeatmaps(t);n||(u(r),x(!1))}catch(e){n||(C(e.message),x(!1))}})(),()=>{n=!0}},[e,t]),m)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`heatmaps · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching heatmaps…`))));if(S)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`heatmaps · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:S}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`heatmaps · ${t}`}),_.createElement(s,{reason:`no-data`,headline:`No heatmaps yet`,hint:`Enable heatmaps in your site settings`}));let w=[{key:`url`,label:`page`,width:36},{key:`type`,label:`type`,width:12},{key:`captureCount`,label:`captures`,align:`right`,width:10},{key:`createdAt`,label:`first seen`,width:24}];return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`heatmaps · ${t}`}),_.createElement(i,{title:`Heatmaps (${l.length})`},_.createElement(d,{columns:w,data:l,zebra:!0})),_.createElement(f,{marginTop:1},_.createElement(p,{color:`gray`},`Open any heatmap at https://app.zenovay.com/heatmaps`)),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{x as heatmapsCommand};
@@ -1 +1 @@
1
- import"./config-CZ9IzjIH.js";import"./api-DXmhz2DM.js";import{initCommand as e}from"./init-D3kngcY4.js";import"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import"./emit-BmfLGjqr.js";import"./login-DvMRHd3J.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";export{e as initCommand};
1
+ import"./config-CZ9IzjIH.js";import"./api-DXmhz2DM.js";import{initCommand as e}from"./init-HBcPrM1L.js";import"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import"./emit-BmfLGjqr.js";import"./login-DvMRHd3J.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";export{e as initCommand};
@@ -50,7 +50,7 @@ export default function App({ Component, pageProps }: AppProps) {
50
50
  `)+`
51
51
  `;if(o)await h.writeFile(i,f,`utf8`);else{let e=await h.open(i,`w`,384);try{await e.writeFile(f,`utf8`)}finally{await e.close()}}return{created:!o,existing:o,addedKeys:c,skippedKeys:l}}const Ve=`https://api.zenovay.com/mcp`,He=g.object({url:g.string().url(),headers:g.record(g.string(),g.string()).optional()}),Ue=g.object({mcpServers:g.record(g.string(),He).optional()}).passthrough();function We(e){return e.HOME??e.USERPROFILE??_.homedir()}function Ge(e){return e.APPDATA??null}function Ke(e,t){let n=We(t),r=Ge(t),i=[];return i.push({id:`cursor`,displayName:`Cursor`,configPath:m.join(n,`.cursor`,`mcp.json`)}),e===`win32`&&r&&i.push({id:`cursor`,displayName:`Cursor (AppData)`,configPath:m.join(r,`Cursor`,`User`,`globalStorage`,`cursor.mcp`,`mcp.json`)}),e===`darwin`?i.push({id:`claude-desktop`,displayName:`Claude Desktop`,configPath:m.join(n,`Library`,`Application Support`,`Claude`,`claude_desktop_config.json`)}):e===`win32`&&r?i.push({id:`claude-desktop`,displayName:`Claude Desktop`,configPath:m.join(r,`Claude`,`claude_desktop_config.json`)}):i.push({id:`claude-desktop`,displayName:`Claude Desktop`,configPath:m.join(n,`.config`,`Claude`,`claude_desktop_config.json`)}),i.push({id:`vscode`,displayName:`VS Code`,configPath:m.join(n,`.vscode`,`mcp.json`)}),i}async function qe(e){try{return await h.access(e),!0}catch{return!1}}async function Je(e){try{let t=await h.readFile(e,`utf8`);if(t.trim().length===0)return{};let n=JSON.parse(t),r=Ue.safeParse(n);return r.success?r.data:n&&typeof n==`object`?n:{}}catch{return{}}}function Ye(e){return{url:Ve,headers:{Authorization:`Bearer ${e}`}}}async function Y(e){let t=e.env??process.env,n=e.platform??process.platform,r=new Set(e.skip??[]),i=[],a=[],o=[],s=new Set,c=Ye(e.accessToken);for(let e of Ke(n,t)){if(r.has(e.id)){a.push(e.displayName);continue}if(s.has(e.configPath))continue;s.add(e.configPath);try{let t=await qe(e.configPath);if(!t){a.push(e.displayName);continue}let n=await Je(e.configPath),r=`${e.configPath}.bak`;await h.copyFile(e.configPath,r);let o={...n,mcpServers:{...n.mcpServers??{},zenovay:c}};await h.mkdir(m.dirname(e.configPath),{recursive:!0}),await h.writeFile(e.configPath,JSON.stringify(o,null,2)+`
52
52
  `,`utf8`),i.push(e.displayName)}catch(t){o.push({client:e.displayName,message:t instanceof Error?t.message:String(t)})}}return{installed:i,skipped:a,errors:o}}async function Xe(e,t,n){let r=n.timeoutMs??18e4,i=n.pollIntervalMs??2e3,a=n.now??(()=>Date.now()),o=n.sleep??(e=>new Promise(t=>setTimeout(t,e))),s=a(),c=s+r;for(n.onTick?.(0);;){let l=await n.api.getFirstEvent({siteId:e,since:t});if(l.received)return{received:!0,event:l.event};let u=a()-s;if(u>=r)return{received:!1};let d=c-a(),f=Math.min(i,Math.max(0,d));if(f<=0)return{received:!1};await o(f),n.onTick?.(a()-s)}}const Ze=g.object({path:g.string().min(1)}),Qe=g.object({path:g.string().min(1),content:g.string(),reason:g.string().min(1)}),$e=g.object({path:g.string().min(1),patch:g.string().min(1),reason:g.string().min(1)}),et=g.object({}),tt=g.object({question:g.string().min(1),choices:g.array(g.string()).optional()});async function nt(e,t){let n=Ze.safeParse(t);if(!n.success)return{ok:!1,content:null,error:`invalid_args`};try{let t=await e.safeRead(n.data.path),r=G.scrubSecrets(t);return{ok:!0,content:G.wrapForModel(n.data.path,r)}}catch(e){return{ok:!1,content:null,error:e.message}}}async function rt(e,t,n){let r=Qe.safeParse(t);if(!r.success)return{ok:!1,content:null,error:`invalid_args`};let{path:i,content:a,reason:o}=r.data,s=``;try{s=await e.safeRead(i)}catch{s=``}let c=await n.approve({path:i,oldContent:s,newContent:a,reason:o});if(c===`n`)return{ok:!1,content:null,error:`skipped_by_user`};if(c===`e`)return{ok:!1,content:null,error:`deferred_to_user_edit`};try{let{backupPath:t}=await e.safeWrite(i,a);return{ok:!0,content:{path:i,backupPath:t}}}catch(e){return{ok:!1,content:null,error:e.message}}}async function it(e,t,n){let r=$e.safeParse(t);if(!r.success)return{ok:!1,content:null,error:`invalid_args`};let{path:i,patch:a,reason:o}=r.data;if(/^\*\*\*\s+Begin Patch/m.test(a)||/^\*\*\*\s+Update File:/m.test(a))return{ok:!1,content:null,error:'unsupported_patch_format: This tool only accepts STANDARD unified diff with `--- a/...`, `+++ b/...`, and `@@ -N,M +N,M @@` headers. The "*** Begin Patch / *** Update File:" V4A format is NOT supported. Please call write_file with the full new file content instead.'};let s;try{s=await e.safeRead(i)}catch(e){return{ok:!1,content:null,error:e.message}}let c;try{c=A(s,a)}catch(e){return{ok:!1,content:null,error:`patch_failed: ${e.message}. Please call write_file with the full new file content instead — write_file is more reliable than patch_file for this use case.`}}return c===!1||typeof c!=`string`?{ok:!1,content:null,error:`patch_did_not_apply_cleanly. The patch context may not match the file. Please call write_file with the full new file content instead.`}:rt(e,{path:i,content:c,reason:o},n)}async function at(e){try{let t=q(e),{adapter:n,ranked:r}=await K(t);return{ok:!0,content:{matched:n!==null,adapter:n?.id,displayName:n?.displayName,ranked:r.map(e=>({id:e.adapter.id,confidence:e.result.confidence,reason:e.result.reason}))}}}catch(e){return{ok:!1,content:null,error:e.message}}}async function ot(e,t){let n=tt.safeParse(t);if(!n.success)return{ok:!1,content:null,error:`invalid_args`};try{let t=await e.ask(n.data);return{ok:!0,content:{answer:t}}}catch(e){return{ok:!1,content:null,error:e.message}}}async function st(e){let{api:t,sandbox:n,approval:r,prompter:a,handlers:o}=e,s=[...e.initialMessages],c=``,l=0;for(;l<V;){n.incrementRound(),l++;let u=await t.openAiStream(`install`,{messages:s,cwd_fingerprint:n.sessionId,diagnosis:e.diagnosis,targetTrackingCode:e.targetTrackingCode}),d=[],f=``;for await(let e of i(u))switch(e.type){case`delta`:f+=e.content,o?.onDelta?.(e.content);break;case`tool_start`:o?.onToolStart?.({id:e.id,name:e.name});break;case`tool_call`:{let t=await ct(e.name,e.arguments,{sandbox:n,cwd:n.cwd,approval:r,prompter:a});d.push({id:e.id,name:e.name,arguments:e.arguments,result:t}),o?.onToolResult?.({id:e.id,name:e.name,result:t});break}case`usage`:o?.onUsage?.(e);break;case`error`:throw o?.onError?.(e),Error(`[${e.code}] ${e.message}`);case`done`:break}if(f&&(c+=f),d.length===0){f&&s.push({role:`assistant`,content:f});break}s.push({role:`assistant`,content:f,toolCalls:d.map(e=>({id:e.id,type:`function`,function:{name:e.name,arguments:JSON.stringify(e.arguments)}}))});for(let e of d)s.push({role:`tool`,toolCallId:e.id,toolName:e.name,content:JSON.stringify(e.result)})}return{finalText:c,rounds:l}}async function ct(e,t,n){try{switch(e){case`read_file`:return await nt(n.sandbox,t);case`write_file`:return await rt(n.sandbox,t,n.approval);case`patch_file`:return await it(n.sandbox,t,n.approval);case`detect_framework`:return await at(n.cwd);case`ask_user`:return await ot(n.prompter,t);default:return{ok:!1,content:null,error:`unknown_tool:${e}`}}}catch(e){return{ok:!1,content:null,error:`tool_threw: ${e.message}`}}}const lt=e=>`<script defer\n data-id="${e}"\n data-allow-localhost="true"\n src="https://api.zenovay.com/z.js">\n</script>`;async function ut(e){let t={installed:[],skipped:[],errors:[]},n=await D([`**/*.html`,`!node_modules/**`,`!.git/**`,`!dist/**`,`!.next/**`,`!.nuxt/**`,`!build/**`,`!.output/**`],{cwd:e.cwd,gitignore:!0,absolute:!1});if(n.length===0)return t;let r=lt(e.trackingCode),i=RegExp(`data-id\\s*=\\s*["']${dt(e.trackingCode)}["']`);for(let a of n){let n=m.join(e.cwd,a),o;try{o=await h.readFile(n,`utf8`)}catch(e){t.errors.push({file:a,error:e.message});continue}if(U.test(o)&&i.test(o)){t.skipped.push({file:a,reason:`already installed with correct tracking code`});continue}let s;if(U.test(o))s=o.replace(/(<script[^>]*src\s*=\s*["']https:\/\/(?:api|cdn)\.zenovay\.com\/[^"']+["'][^>]*>)/i,t=>t.replace(/data-id\s*=\s*["']ZV_\w+["']/i,`data-id="${e.trackingCode}"`)),s===o&&(s=o.replace(/<script(\s)/i,`<script$1data-id="${e.trackingCode}"$1`));else if(e.updateOnly){t.skipped.push({file:a,reason:`updateOnly=true and no Zenovay tag present`});continue}else if(/<\/head>/i.test(o)){if(s=o.replace(/(\n[\t ]*)?<\/head>/i,(e,t)=>{let n=t??`
53
- `,i=r.replace(/\n/g,`${n}`);return`${n}${i}${n}</head>`}),s===o){t.skipped.push({file:a,reason:`</head> regex did not match unexpectedly`});continue}}else{t.skipped.push({file:a,reason:`no <head>...</head> in file (fragment or non-page)`});continue}let c=null;for(let{name:e,re:t}of W)if(t.test(o)&&!t.test(s)){c=e;break}if(c){t.errors.push({file:a,error:`would remove ${c} tracker — refusing to write`});continue}try{await h.writeFile(n,s,`utf8`),t.installed.push(a)}catch(e){t.errors.push({file:a,error:e.message})}}return t}function dt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function ft(){let e=[12,15,18,22,28,35,41,50,58,64,72,78],t=p(e,24);return[` ↑`,` ${t}`,` └────────────────────────`,` May Jun Jul Aug Sep`]}function pt(){return[` Landing page ████████████████████ 100%`,` ↓ -28%`,` Pricing ██████████████░░░░░░ 72%`,` ↓ -50%`,` Checkout ███████░░░░░░░░░░░░░ 36%`,` ↓ -64%`,` Purchased ███░░░░░░░░░░░░░░░░░ 13%`]}function mt(){return[` ▇▇▇▇▇▇▇▇▇▎ 89 Sarah K. /pricing 🇺🇸`,` ▇▇▇▇▇▇░░░░ 61 anon /docs 🇩🇪`,` ▇▇▇░░░░░░░ 34 anon /changelog 🇯🇵`]}function ht(){return[` LCP ● 2.1s good ████████████░░░░░░`,` INP ● 89ms good ██████████████████`,` CLS ⚠ 0.14 needs ████████████░░░░░░`,` TTFB ● 380ms good ███████████████░░░`]}const X=[{title:`Welcome`,body:[`The wizard is an agent — it handles the entire`,`Zenovay setup process on your behalf.`,``,`Reading your project, deciding where the tracker`,`belongs, and writing the snippet for you.`]},{title:`Events`,body:[`Events are the foundation of Zenovay analytics.`,``,`Every pageview, click, and custom action is an`,`event. Group them into Goals to track conversions.`]},{title:`Trends`,body:[`Use trends to measure growth.`,``,`See how visitors, signups, and revenue have`,`changed over the last week, month, or quarter.`],visual:ft},{title:`Funnels`,body:[`Funnels reveal where users drop off.`,``,`Define the steps you care about — landing,`,`pricing, checkout, purchase — and Zenovay shows`,`the per-step conversion rate.`],visual:pt},{title:`Live visitors`,body:[`Watch every visitor in real time, ranked by an`,`AI score that highlights high-intent traffic.`,``,"Use `zenovay visitors --live` after install."],visual:mt},{title:`Core Web Vitals`,body:[`LCP, INP, CLS — Google's page-experience metrics,`,`collected automatically once the tracker is in.`,``,"Use `zenovay vitals` to see them per page + device."],visual:ht},{title:`MCP integration`,body:[`Your CLI session can install Zenovay's MCP server`,`into Cursor / Claude Desktop / VS Code.`,``,`Then ask your AI: "what were my top pages today?"`,`and it queries Zenovay directly.`]},{title:`AI insights`,body:[`Zenovay watches your data and surfaces anomalies`,`automatically — traffic spikes, error bursts,`,`revenue drops — without you needing to ask.`,``,"Run `zenovay ai` after install to chat with them."]},{title:`Privacy-first`,body:[`No cookies required. No third-party trackers.`,`Cookieless mode is one toggle in your dashboard.`,``,`GDPR, CCPA, and PECR-compliant out of the box.`]}],gt=8e3,_t=({width:e,height:t})=>{let[n,r]=E(0);T(()=>{let e=setInterval(()=>{r(e=>(e+1)%X.length)},gt);return()=>clearInterval(e)},[]);let i=X[n],a=i.visual?i.visual():[],o=X.map((e,t)=>t===n?`●`:`·`).join(` `);return w.createElement(y,{flexDirection:`column`,width:e,height:t,paddingX:2,paddingY:1},w.createElement(y,{marginBottom:1},w.createElement(b,{color:`magentaBright`,bold:!0},`Learn`)),w.createElement(y,{marginBottom:1},w.createElement(b,{bold:!0,color:`white`},i.title)),i.body.map((e,t)=>w.createElement(b,{key:t,color:`gray`},e||` `)),a.length>0&&w.createElement(y,{flexDirection:`column`,marginTop:1},a.map((e,t)=>w.createElement(b,{key:t,color:`cyan`},e))),w.createElement(y,{flexGrow:1}),w.createElement(y,{marginTop:1},w.createElement(b,{color:`gray`,dimColor:!0},o,` · `,n+1,` / `,X.length)))},vt={pending:`·`,active:`⠋`,done:`✓`,error:`✗`},yt={pending:`gray`,active:`magenta`,done:`green`,error:`red`},bt=({tasks:e,width:t,height:n,liveLine:r})=>{let i=e.filter(e=>e.status===`done`).length;return w.createElement(y,{flexDirection:`column`,width:t,height:n,paddingX:2,paddingY:1},w.createElement(y,{marginBottom:1},w.createElement(b,{color:`magentaBright`,bold:!0},`Tasks`)),e.map(e=>w.createElement(y,{key:e.id,flexDirection:`column`},w.createElement(y,null,e.status===`active`?w.createElement(b,{color:`magenta`},w.createElement(O,{type:`dots`})):w.createElement(b,{color:yt[e.status]},vt[e.status]),w.createElement(b,null,` `),w.createElement(b,{color:e.status===`pending`?`gray`:`white`},e.label)),e.detail&&w.createElement(y,{paddingLeft:2},w.createElement(b,{color:`gray`,dimColor:!0},e.detail)))),w.createElement(y,{flexGrow:1}),r&&w.createElement(y,{marginTop:1},w.createElement(b,{color:`cyan`},`◆ `),w.createElement(b,{color:`white`},r)),w.createElement(y,{marginTop:1},w.createElement(b,{color:`gray`,dimColor:!0},i,` / `,e.length)))};async function xt(e){if(o(e))return St(e);let t=`quit`,n=null,r=await new Promise(r=>{let{unmount:i,waitUntilExit:a}=x(w.createElement(Ct,{opts:e,onExit:(e,a,o)=>{t=a??`quit`,n=o??null,i(),r(e)}}));a().catch(()=>r(1))});if(r!==0||t===`quit`||!n)return r;let i=n.id;if(t===`watch`){let{watchCommand:t}=await import(`./watch-eGS9kl-m.js`);return t({cliVersion:e.cliVersion,siteId:i})}if(t===`events`){let{eventsTailCommand:t}=await import(`./events-tail-BOLPhm8f.js`);return t({cliVersion:e.cliVersion,siteId:i})}return 0}async function St(t){try{let i=await e(),o=await Re(t.cwd);if(!o)return a({type:`error`,code:`no_framework`,message:`Could not detect framework (headless mode has no picker).`}),2;a({type:`framework.detected`,framework:o.id,confidence:1});let s=await r({strict:!1});if(!s&&!process.env.ZENOVAY_API_TOKEN)return a({type:`error`,code:`not_logged_in`,message:"Run `zenovay login` first (or set ZENOVAY_API_TOKEN)."}),2;let c=new n({config:i,cliVersion:t.cliVersion,token:s}),l=await c.getSites(),u=t.siteId?l.find(e=>e.id===t.siteId):l[0];if(!u&&t.siteId)return a({type:`error`,code:`site_not_found`,message:`Site ${t.siteId} not found.`}),2;if(!u)return a({type:`error`,code:`no_site`,message:`No sites exist; create one at app.zenovay.com or re-run interactively.`}),2;a({type:`info`,message:`Using site ${u.id} (${u.name}) trackingCode=${u.trackingCode??u.id}`});let d=await J(t.cwd,{[o.envVarName]:u.trackingCode??u.id});return a({type:`info`,message:`env vars added: ${d.addedKeys.join(`,`)}`}),a({type:`done`,command:`init`,exitCode:0}),0}catch(e){return a({type:`error`,code:`init_failed`,message:e.message}),1}}const Ct=({opts:t,onExit:i})=>{let{exit:a}=S(),[o,u]=E(`intro`),[d,p]=E(null),[m,h]=E([]),[g,_]=E(null),[v,x]=E(null),[C,D]=E(null),[k,A]=E([]),[j,M]=E(void 0),[N,P]=E(null),[F,I]=E(0),L=ee(!1);return T(()=>(process.stdout.isTTY&&process.stdout.write(`\x1B[?1049h\x1B[H`),()=>{process.stdout.isTTY&&process.stdout.write(`\x1B[?1049l`)}),[]),T(()=>{L.current||(L.current=!0,(async()=>{try{u(`detecting`);let i=await Re(t.cwd);if(!i){D(`Could not detect your framework. Supported: Next.js, Nuxt, SvelteKit, Astro, Remix, plain HTML.`),u(`error`);return}p(i);let a=await r({strict:!1});!process.env.ZENOVAY_API_TOKEN&&!a&&(u(`login`),await s({cliVersion:t.cliVersion})),u(`loading-sites`);let o=await e(),c=await r({strict:!1}),l=new n({config:o,cliVersion:t.cliVersion,token:c}),d=await l.getSites(),f=await Lt(t.cwd),m=Rt(d,f);if(h(d),_(f),d.length===0){u(`create-site`);return}if(t.siteId){let e=d.find(e=>e.id===t.siteId);if(!e){D(`Site ${t.siteId} not found in your account.`),u(`error`);return}x(e),Z(e,i,t,{setPhase:u,setErrorMsg:D,setTasks:A,setLiveLine:M,setSandboxStats:P});return}if(t.yes&&m){x(m),Z(m,i,t,{setPhase:u,setErrorMsg:D,setTasks:A,setLiveLine:M,setSandboxStats:P});return}u(`site-picker`)}catch(e){D(e.message),u(`error`)}})())},[]),T(()=>{o===`error`&&setTimeout(()=>{a(),i(1)},8e3)},[o]),w.createElement(y,{flexDirection:`column`},w.createElement(l,{version:t.cliVersion,subtitle:`AI install wizard`}),o===`intro`&&w.createElement(wt,null),o===`detecting`&&w.createElement(c,{title:`Scanning`,state:`busy`},w.createElement(y,null,w.createElement(b,{color:`magenta`},w.createElement(O,{type:`dots`})),w.createElement(b,null,` Detecting framework…`))),o===`login`&&w.createElement(c,{title:`Authenticating`,state:`busy`},w.createElement(b,null,`Opening browser for login… (paste ZENOVAY_API_TOKEN env var to skip)`)),o===`loading-sites`&&w.createElement(c,{title:`Loading your sites`,state:`busy`},w.createElement(y,null,w.createElement(b,{color:`magenta`},w.createElement(O,{type:`dots`})),w.createElement(b,null,` Fetching your Zenovay sites…`))),o===`site-picker`&&d&&w.createElement(Et,{sites:m,preselectHint:g,onPick:e=>{if(e===`create-new`){u(`create-site`);return}x(e),Z(e,d,t,{setPhase:u,setErrorMsg:D,setTasks:A,setLiveLine:M,setSandboxStats:P})}}),o===`create-site`&&w.createElement(c,{title:`Create a new site`,state:`warn`},w.createElement(b,{color:`yellow`},"No site picked (or none exist yet). Visit https://app.zenovay.com/websites to create one, then re-run `zenovay init`."),w.createElement(b,{color:`gray`},`(Inline site creation from the CLI is scheduled for V1.1 — it requires a plan-limit check.)`)),o===`agent`&&d&&v&&w.createElement(Tt,{adapter:d,site:v,tasks:k,liveLine:j}),o===`install-complete`&&d&&v&&w.createElement(kt,{adapter:d,site:v,stats:N,onCommit:()=>u(`commit-prompt`),onSkipCommit:()=>u(`deploy-prompt`)}),o===`commit-prompt`&&v&&w.createElement(At,{cwd:t.cwd,onDone:e=>{e.committed&&M(`Pushed ${e.shortSha} to ${e.branch}`),u(`deploy-prompt`)},onError:e=>{D(e),u(`error`)}}),o===`deploy-prompt`&&v&&w.createElement(jt,{site:v,onDeployed:()=>u(`visit-prompt`),onSkip:()=>u(`verify`)}),o===`visit-prompt`&&v&&w.createElement(Mt,{site:v,onContinue:()=>u(`verify`)}),o===`verify`&&v&&w.createElement(Pt,{site:v,elapsed:F,onTick:e=>I(e),onArrived:()=>u(`success`),onTimeout:()=>u(`success`)}),o===`success`&&d&&v&&w.createElement(Ot,{adapter:d,site:v,stats:N,onPick:e=>{a(),i(0,e,v)}}),o===`error`&&w.createElement(c,{title:`Install failed`,state:`err`},w.createElement(b,{color:`red`},C??`Unknown error`)),w.createElement(f,{items:[{key:`q`,label:`quit`},{key:`ctrl-c`,label:`abort`}]}))};async function Z(i,a,o,s){try{s.setPhase(`agent`);let c=await e(),l=await r({strict:!1}),u=new n({config:c,cliVersion:o.cliVersion,token:l}),d=new G({cwd:o.cwd}),f=i.trackingCode??i.id;await t({defaultSiteId:i.id,defaultSiteName:i.name}).catch(()=>void 0);let p=await L(o.cwd,f);if(p.recommendation===`no-op`){s.setTasks(e=>e.map(e=>e.id===`detect`||e.id===`read`||e.id===`write`?{...e,status:`done`,detail:`already installed correctly`}:e)),s.setLiveLine(p.summary),s.setSandboxStats?.({reads:0,writes:0,rounds:0}),!o.skipMcp&&l&&await Y({accessToken:l.accessToken}).catch(()=>void 0),s.setPhase(`install-complete`);return}p.competitors.length>0&&s.setLiveLine(`Detected ${p.competitors.map(e=>e.name).join(`, `)} — will install Zenovay alongside (won't touch their tags).`);let m=a.id===`plain-html`&&(p.recommendation===`fresh-install`||p.recommendation===`fresh-install-alongside-competitor`||p.recommendation===`update-tracking-code`);if(m){s.setTasks(e=>e.map(e=>e.id===`detect`?{...e,status:`done`,detail:`Plain HTML`}:e)),s.setLiveLine(`Plain HTML — using fast install path (no AI needed)…`);let e=await ut({cwd:o.cwd,trackingCode:f,updateOnly:p.recommendation===`update-tracking-code`});if(e.installed.length===0&&e.errors.length===0)throw Error(`No HTML files were modified. Either no .html files contain a <head>...</head> block, or every file already has the correct tracker.`);if(e.installed.length===0&&e.errors.length>0)throw Error(`Programmatic install failed for all ${e.errors.length} file(s). First error: ${e.errors[0].file}: ${e.errors[0].error}`);s.setTasks(t=>t.map(t=>t.id===`read`||t.id===`write`?{...t,status:`done`,detail:`${e.installed.length} file(s)`}:t)),s.setLiveLine(`Tracker added to ${e.installed.length} file(s). Skipped ${e.skipped.length}, errored ${e.errors.length}.`);let t=await J(o.cwd,{[a.envVarName]:f});if(s.setTasks(e=>e.map(e=>e.id===`env`?{...e,status:`done`,detail:`${t.addedKeys.length} key(s) added`}:e)),!o.skipMcp&&l){let e=await Y({accessToken:l.accessToken}).catch(()=>null);s.setTasks(t=>t.map(t=>t.id===`mcp`?{...t,status:`done`,detail:e&&e.installed.length>0?e.installed.join(`, `):`none detected`}:t))}else s.setTasks(e=>e.map(e=>e.id===`mcp`?{...e,status:`done`,detail:`skipped`}:e));s.setLiveLine(void 0),s.setSandboxStats?.({reads:e.installed.length,writes:e.installed.length,rounds:0}),s.setPhase(`install-complete`);return}let h=a.buildSnippets({trackingCode:f,siteId:i.id}),g=`Install Zenovay tracking into this ${a.displayName} project.\nSite: ${i.name} (trackingCode: ${f}).\n1. Call detect_framework to confirm the framework.\n2. Read the entry file(s) for this framework:\n`+a.files.map(e=>` - ${e.path}`).join(`
53
+ `,i=r.replace(/\n/g,`${n}`);return`${n}${i}${n}</head>`}),s===o){t.skipped.push({file:a,reason:`</head> regex did not match unexpectedly`});continue}}else{t.skipped.push({file:a,reason:`no <head>...</head> in file (fragment or non-page)`});continue}let c=null;for(let{name:e,re:t}of W)if(t.test(o)&&!t.test(s)){c=e;break}if(c){t.errors.push({file:a,error:`would remove ${c} tracker — refusing to write`});continue}try{await h.writeFile(n,s,`utf8`),t.installed.push(a)}catch(e){t.errors.push({file:a,error:e.message})}}return t}function dt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function ft(){let e=[12,15,18,22,28,35,41,50,58,64,72,78],t=p(e,24);return[` ↑`,` ${t}`,` └────────────────────────`,` May Jun Jul Aug Sep`]}function pt(){return[` Landing page ████████████████████ 100%`,` ↓ -28%`,` Pricing ██████████████░░░░░░ 72%`,` ↓ -50%`,` Checkout ███████░░░░░░░░░░░░░ 36%`,` ↓ -64%`,` Purchased ███░░░░░░░░░░░░░░░░░ 13%`]}function mt(){return[` ▇▇▇▇▇▇▇▇▇▎ 89 Sarah K. /pricing 🇺🇸`,` ▇▇▇▇▇▇░░░░ 61 anon /docs 🇩🇪`,` ▇▇▇░░░░░░░ 34 anon /changelog 🇯🇵`]}function ht(){return[` LCP ● 2.1s good ████████████░░░░░░`,` INP ● 89ms good ██████████████████`,` CLS ⚠ 0.14 needs ████████████░░░░░░`,` TTFB ● 380ms good ███████████████░░░`]}const X=[{title:`Welcome`,body:[`The wizard is an agent — it handles the entire`,`Zenovay setup process on your behalf.`,``,`Reading your project, deciding where the tracker`,`belongs, and writing the snippet for you.`]},{title:`Events`,body:[`Events are the foundation of Zenovay analytics.`,``,`Every pageview, click, and custom action is an`,`event. Group them into Goals to track conversions.`]},{title:`Trends`,body:[`Use trends to measure growth.`,``,`See how visitors, signups, and revenue have`,`changed over the last week, month, or quarter.`],visual:ft},{title:`Funnels`,body:[`Funnels reveal where users drop off.`,``,`Define the steps you care about — landing,`,`pricing, checkout, purchase — and Zenovay shows`,`the per-step conversion rate.`],visual:pt},{title:`Live visitors`,body:[`Watch every visitor in real time, ranked by an`,`AI score that highlights high-intent traffic.`,``,"Use `zenovay visitors --live` after install."],visual:mt},{title:`Core Web Vitals`,body:[`LCP, INP, CLS — Google's page-experience metrics,`,`collected automatically once the tracker is in.`,``,"Use `zenovay vitals` to see them per page + device."],visual:ht},{title:`MCP integration`,body:[`Your CLI session can install Zenovay's MCP server`,`into Cursor / Claude Desktop / VS Code.`,``,`Then ask your AI: "what were my top pages today?"`,`and it queries Zenovay directly.`]},{title:`AI insights`,body:[`Zenovay watches your data and surfaces anomalies`,`automatically — traffic spikes, error bursts,`,`revenue drops — without you needing to ask.`,``,"Run `zenovay ai` after install to chat with them."]},{title:`Privacy-first`,body:[`No cookies required. No third-party trackers.`,`Cookieless mode is one toggle in your dashboard.`,``,`GDPR, CCPA, and PECR-compliant out of the box.`]}],gt=8e3,_t=({width:e,height:t})=>{let[n,r]=E(0);T(()=>{let e=setInterval(()=>{r(e=>(e+1)%X.length)},gt);return()=>clearInterval(e)},[]);let i=X[n],a=i.visual?i.visual():[],o=X.map((e,t)=>t===n?`●`:`·`).join(` `);return w.createElement(y,{flexDirection:`column`,width:e,height:t,paddingX:2,paddingY:1},w.createElement(y,{marginBottom:1},w.createElement(b,{color:`magentaBright`,bold:!0},`Learn`)),w.createElement(y,{marginBottom:1},w.createElement(b,{bold:!0,color:`white`},i.title)),i.body.map((e,t)=>w.createElement(b,{key:t,color:`gray`},e||` `)),a.length>0&&w.createElement(y,{flexDirection:`column`,marginTop:1},a.map((e,t)=>w.createElement(b,{key:t,color:`cyan`},e))),w.createElement(y,{flexGrow:1}),w.createElement(y,{marginTop:1},w.createElement(b,{color:`gray`,dimColor:!0},o,` · `,n+1,` / `,X.length)))},vt={pending:`·`,active:`⠋`,done:`✓`,error:`✗`},yt={pending:`gray`,active:`magenta`,done:`green`,error:`red`},bt=({tasks:e,width:t,height:n,liveLine:r})=>{let i=e.filter(e=>e.status===`done`).length;return w.createElement(y,{flexDirection:`column`,width:t,height:n,paddingX:2,paddingY:1},w.createElement(y,{marginBottom:1},w.createElement(b,{color:`magentaBright`,bold:!0},`Tasks`)),e.map(e=>w.createElement(y,{key:e.id,flexDirection:`column`},w.createElement(y,null,e.status===`active`?w.createElement(b,{color:`magenta`},w.createElement(O,{type:`dots`})):w.createElement(b,{color:yt[e.status]},vt[e.status]),w.createElement(b,null,` `),w.createElement(b,{color:e.status===`pending`?`gray`:`white`},e.label)),e.detail&&w.createElement(y,{paddingLeft:2},w.createElement(b,{color:`gray`,dimColor:!0},e.detail)))),w.createElement(y,{flexGrow:1}),r&&w.createElement(y,{marginTop:1},w.createElement(b,{color:`cyan`},`◆ `),w.createElement(b,{color:`white`},r)),w.createElement(y,{marginTop:1},w.createElement(b,{color:`gray`,dimColor:!0},i,` / `,e.length)))};async function xt(e){if(o(e))return St(e);let t=`quit`,n=null,r=await new Promise(r=>{let{unmount:i,waitUntilExit:a}=x(w.createElement(Ct,{opts:e,onExit:(e,a,o)=>{t=a??`quit`,n=o??null,i(),r(e)}}));a().catch(()=>r(1))});if(r!==0||t===`quit`||!n)return r;let i=n.id;if(t===`watch`){let{watchCommand:t}=await import(`./watch-CawlqYPo.js`);return t({cliVersion:e.cliVersion,siteId:i})}if(t===`events`){let{eventsTailCommand:t}=await import(`./events-tail-CtoMkdkb.js`);return t({cliVersion:e.cliVersion,siteId:i})}return 0}async function St(t){try{let i=await e(),o=await Re(t.cwd);if(!o)return a({type:`error`,code:`no_framework`,message:`Could not detect framework (headless mode has no picker).`}),2;a({type:`framework.detected`,framework:o.id,confidence:1});let s=await r({strict:!1});if(!s&&!process.env.ZENOVAY_API_TOKEN)return a({type:`error`,code:`not_logged_in`,message:"Run `zenovay login` first (or set ZENOVAY_API_TOKEN)."}),2;let c=new n({config:i,cliVersion:t.cliVersion,token:s}),l=await c.getSites(),u=t.siteId?l.find(e=>e.id===t.siteId):l[0];if(!u&&t.siteId)return a({type:`error`,code:`site_not_found`,message:`Site ${t.siteId} not found.`}),2;if(!u)return a({type:`error`,code:`no_site`,message:`No sites exist; create one at app.zenovay.com or re-run interactively.`}),2;a({type:`info`,message:`Using site ${u.id} (${u.name}) trackingCode=${u.trackingCode??u.id}`});let d=await J(t.cwd,{[o.envVarName]:u.trackingCode??u.id});return a({type:`info`,message:`env vars added: ${d.addedKeys.join(`,`)}`}),a({type:`done`,command:`init`,exitCode:0}),0}catch(e){return a({type:`error`,code:`init_failed`,message:e.message}),1}}const Ct=({opts:t,onExit:i})=>{let{exit:a}=S(),[o,u]=E(`intro`),[d,p]=E(null),[m,h]=E([]),[g,_]=E(null),[v,x]=E(null),[C,D]=E(null),[k,A]=E([]),[j,M]=E(void 0),[N,P]=E(null),[F,I]=E(0),L=ee(!1);return T(()=>(process.stdout.isTTY&&process.stdout.write(`\x1B[?1049h\x1B[H`),()=>{process.stdout.isTTY&&process.stdout.write(`\x1B[?1049l`)}),[]),T(()=>{L.current||(L.current=!0,(async()=>{try{u(`detecting`);let i=await Re(t.cwd);if(!i){D(`Could not detect your framework. Supported: Next.js, Nuxt, SvelteKit, Astro, Remix, plain HTML.`),u(`error`);return}p(i);let a=await r({strict:!1});!process.env.ZENOVAY_API_TOKEN&&!a&&(u(`login`),await s({cliVersion:t.cliVersion})),u(`loading-sites`);let o=await e(),c=await r({strict:!1}),l=new n({config:o,cliVersion:t.cliVersion,token:c}),d=await l.getSites(),f=await Lt(t.cwd),m=Rt(d,f);if(h(d),_(f),d.length===0){u(`create-site`);return}if(t.siteId){let e=d.find(e=>e.id===t.siteId);if(!e){D(`Site ${t.siteId} not found in your account.`),u(`error`);return}x(e),Z(e,i,t,{setPhase:u,setErrorMsg:D,setTasks:A,setLiveLine:M,setSandboxStats:P});return}if(t.yes&&m){x(m),Z(m,i,t,{setPhase:u,setErrorMsg:D,setTasks:A,setLiveLine:M,setSandboxStats:P});return}u(`site-picker`)}catch(e){D(e.message),u(`error`)}})())},[]),T(()=>{o===`error`&&setTimeout(()=>{a(),i(1)},8e3)},[o]),w.createElement(y,{flexDirection:`column`},w.createElement(l,{version:t.cliVersion,subtitle:`AI install wizard`}),o===`intro`&&w.createElement(wt,null),o===`detecting`&&w.createElement(c,{title:`Scanning`,state:`busy`},w.createElement(y,null,w.createElement(b,{color:`magenta`},w.createElement(O,{type:`dots`})),w.createElement(b,null,` Detecting framework…`))),o===`login`&&w.createElement(c,{title:`Authenticating`,state:`busy`},w.createElement(b,null,`Opening browser for login… (paste ZENOVAY_API_TOKEN env var to skip)`)),o===`loading-sites`&&w.createElement(c,{title:`Loading your sites`,state:`busy`},w.createElement(y,null,w.createElement(b,{color:`magenta`},w.createElement(O,{type:`dots`})),w.createElement(b,null,` Fetching your Zenovay sites…`))),o===`site-picker`&&d&&w.createElement(Et,{sites:m,preselectHint:g,onPick:e=>{if(e===`create-new`){u(`create-site`);return}x(e),Z(e,d,t,{setPhase:u,setErrorMsg:D,setTasks:A,setLiveLine:M,setSandboxStats:P})}}),o===`create-site`&&w.createElement(c,{title:`Create a new site`,state:`warn`},w.createElement(b,{color:`yellow`},"No site picked (or none exist yet). Visit https://app.zenovay.com/websites to create one, then re-run `zenovay init`."),w.createElement(b,{color:`gray`},`(Inline site creation from the CLI is scheduled for V1.1 — it requires a plan-limit check.)`)),o===`agent`&&d&&v&&w.createElement(Tt,{adapter:d,site:v,tasks:k,liveLine:j}),o===`install-complete`&&d&&v&&w.createElement(kt,{adapter:d,site:v,stats:N,onCommit:()=>u(`commit-prompt`),onSkipCommit:()=>u(`deploy-prompt`)}),o===`commit-prompt`&&v&&w.createElement(At,{cwd:t.cwd,onDone:e=>{e.committed&&M(`Pushed ${e.shortSha} to ${e.branch}`),u(`deploy-prompt`)},onError:e=>{D(e),u(`error`)}}),o===`deploy-prompt`&&v&&w.createElement(jt,{site:v,onDeployed:()=>u(`visit-prompt`),onSkip:()=>u(`verify`)}),o===`visit-prompt`&&v&&w.createElement(Mt,{site:v,onContinue:()=>u(`verify`)}),o===`verify`&&v&&w.createElement(Pt,{site:v,elapsed:F,onTick:e=>I(e),onArrived:()=>u(`success`),onTimeout:()=>u(`success`)}),o===`success`&&d&&v&&w.createElement(Ot,{adapter:d,site:v,stats:N,onPick:e=>{a(),i(0,e,v)}}),o===`error`&&w.createElement(c,{title:`Install failed`,state:`err`},w.createElement(b,{color:`red`},C??`Unknown error`)),w.createElement(f,{items:[{key:`q`,label:`quit`},{key:`ctrl-c`,label:`abort`}]}))};async function Z(i,a,o,s){try{s.setPhase(`agent`);let c=await e(),l=await r({strict:!1}),u=new n({config:c,cliVersion:o.cliVersion,token:l}),d=new G({cwd:o.cwd}),f=i.trackingCode??i.id;await t({defaultSiteId:i.id,defaultSiteName:i.name}).catch(()=>void 0);let p=await L(o.cwd,f);if(p.recommendation===`no-op`){s.setTasks(e=>e.map(e=>e.id===`detect`||e.id===`read`||e.id===`write`?{...e,status:`done`,detail:`already installed correctly`}:e)),s.setLiveLine(p.summary),s.setSandboxStats?.({reads:0,writes:0,rounds:0}),!o.skipMcp&&l&&await Y({accessToken:l.accessToken}).catch(()=>void 0),s.setPhase(`install-complete`);return}p.competitors.length>0&&s.setLiveLine(`Detected ${p.competitors.map(e=>e.name).join(`, `)} — will install Zenovay alongside (won't touch their tags).`);let m=a.id===`plain-html`&&(p.recommendation===`fresh-install`||p.recommendation===`fresh-install-alongside-competitor`||p.recommendation===`update-tracking-code`);if(m){s.setTasks(e=>e.map(e=>e.id===`detect`?{...e,status:`done`,detail:`Plain HTML`}:e)),s.setLiveLine(`Plain HTML — using fast install path (no AI needed)…`);let e=await ut({cwd:o.cwd,trackingCode:f,updateOnly:p.recommendation===`update-tracking-code`});if(e.installed.length===0&&e.errors.length===0)throw Error(`No HTML files were modified. Either no .html files contain a <head>...</head> block, or every file already has the correct tracker.`);if(e.installed.length===0&&e.errors.length>0)throw Error(`Programmatic install failed for all ${e.errors.length} file(s). First error: ${e.errors[0].file}: ${e.errors[0].error}`);s.setTasks(t=>t.map(t=>t.id===`read`||t.id===`write`?{...t,status:`done`,detail:`${e.installed.length} file(s)`}:t)),s.setLiveLine(`Tracker added to ${e.installed.length} file(s). Skipped ${e.skipped.length}, errored ${e.errors.length}.`);let t=await J(o.cwd,{[a.envVarName]:f});if(s.setTasks(e=>e.map(e=>e.id===`env`?{...e,status:`done`,detail:`${t.addedKeys.length} key(s) added`}:e)),!o.skipMcp&&l){let e=await Y({accessToken:l.accessToken}).catch(()=>null);s.setTasks(t=>t.map(t=>t.id===`mcp`?{...t,status:`done`,detail:e&&e.installed.length>0?e.installed.join(`, `):`none detected`}:t))}else s.setTasks(e=>e.map(e=>e.id===`mcp`?{...e,status:`done`,detail:`skipped`}:e));s.setLiveLine(void 0),s.setSandboxStats?.({reads:e.installed.length,writes:e.installed.length,rounds:0}),s.setPhase(`install-complete`);return}let h=a.buildSnippets({trackingCode:f,siteId:i.id}),g=`Install Zenovay tracking into this ${a.displayName} project.\nSite: ${i.name} (trackingCode: ${f}).\n1. Call detect_framework to confirm the framework.\n2. Read the entry file(s) for this framework:\n`+a.files.map(e=>` - ${e.path}`).join(`
54
54
  `)+`
55
55
  3. Insert the tracker using the snippet below.
56
56
  4. Confirm the change with a diff before writing.
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";function b(e){return e===`critical`?`err`:e===`warning`?`warn`:`ok`}function x(e){return e===`anomaly`?`⚡ anomaly`:e===`recommendation`?`✦ recommendation`:`↗ trend`}async function S(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getInsights(d);return n({type:`insights.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(C,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=m(),[l,u]=v(null),[p,S]=v(!0),[C,w]=v(null);return h(e=>{e===`q`&&(c(),r(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getInsights(t);n||(u(r),S(!1))}catch(e){n||(w(e.message),S(!1))}})(),()=>{n=!0}},[e,t]),p?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`insights · ${t}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Fetching insights…`)))):C?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`insights · ${t}`}),g.createElement(s,{reason:`error`,headline:`Failed to load`,hint:C})):!l||l.length===0?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`insights · ${t}`}),g.createElement(s,{reason:`no-data`,headline:`No insights yet`,hint:`Insights are generated nightly — check back tomorrow`})):g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`insights · ${t}`}),l.map((e,t)=>g.createElement(i,{key:t,title:`${x(e.kind)} · ${e.severity}`,state:b(e.severity)},g.createElement(f,{bold:!0},e.title),e.body?g.createElement(f,{color:`gray`},e.body):null)),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{S as insightsCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";async function b(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getJourneys(d);return n({type:`journeys.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=m(),[l,u]=v(null),[p,b]=v(!0),[x,S]=v(null);if(h(e=>{e===`q`&&(c(),r(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getJourneys(t);n||(u(r.flows),b(!1))}catch(e){n||(S(e.message),b(!1))}})(),()=>{n=!0}},[e,t]),p)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`journeys · ${t}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Computing flows…`))));if(x)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`journeys · ${t}`}),g.createElement(s,{reason:`error`,headline:`Failed to load`,hint:x}));if(!l||l.length===0)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`journeys · ${t}`}),g.createElement(s,{reason:`no-data`,headline:`No journeys yet`,hint:`Need at least 2 page-views per session to compute flows`}));let C=Math.max(...l.map(e=>e.count),1),w=12;return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`journeys · ${t}`}),g.createElement(i,{title:`Top page transitions (${l.length})`},l.map((e,t)=>{let n=Math.max(1,Math.round(e.count/C*w));return g.createElement(d,{key:t,flexDirection:`row`},g.createElement(f,null,e.from.padEnd(22).slice(0,22)),g.createElement(f,{color:`cyan`},` → `),g.createElement(f,null,e.to.padEnd(22).slice(0,22)),g.createElement(f,{color:`magenta`},` `,`█`.repeat(n),`░`.repeat(w-n)),g.createElement(f,{color:`gray`},` ${e.count}`))})),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{b as journeysCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{Globe as u}from"./globe-1bi4DjwJ.js";import{MetricCard as d}from"./metric-card-W4GayhPO.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o}),u;try{({siteId:u}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getLive(u);return n({type:`live.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:s,siteId:u,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,m]=y(null),[x,S]=y(!0),[C,w]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1,r=async()=>{try{let r=await e.getLive(t);n||(m(r),S(!1),w(null))}catch(e){n||(w(e.message),S(!1))}};r();let i=setInterval(r,2e3);return()=>{n=!0,clearInterval(i)}},[e,t]),x)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`live · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Connecting…`))));if(C&&!l)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`live · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:C}));let T=process.stdout.columns??80,E=Math.max(20,Math.min(40,Math.floor(T/3)));return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`live · ${t}`}),_.createElement(f,{flexDirection:`row`},_.createElement(d,{title:`Active now`,value:l?.activeVisitors??0,format:`number`,width:E}),_.createElement(i,{title:`Globe`,width:Math.max(40,T-E-4)},_.createElement(u,{data:[],width:Math.max(36,T-E-10),height:10}))),_.createElement(i,{title:`Recent events`},!l||l.recentEvents.length===0?_.createElement(p,{color:`gray`},`— waiting for events —`):l.recentEvents.slice(0,15).map((e,t)=>_.createElement(f,{key:t},_.createElement(p,{color:`cyan`},(e.type??`pageview`).padEnd(10)),_.createElement(p,null,e.path.padEnd(36).slice(0,36)),_.createElement(p,{color:`gray`},e.country??`—`)))),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{x as liveCommand};
@@ -0,0 +1 @@
1
+ import{Panel as e,useTheme as t}from"./panel-DZqvtaao.js";import{spark as n}from"./sparkline-B6ueqPAB.js";import{Box as r,Text as i}from"ink";import a from"react";function o(e,t){if(typeof e==`string`)return e;switch(t){case`percent`:{let t=Math.abs(e)<=1?e*100:e;return`${t.toFixed(1)}%`}case`duration`:{if(e<60)return`${Math.round(e)}s`;let t=Math.floor(e/60),n=Math.round(e%60);return`${t}m ${n.toString().padStart(2,`0`)}s`}case`currency`:{let t=e/100;return`$${t.toLocaleString(void 0,{minimumFractionDigits:0,maximumFractionDigits:2})}`}case`number`:default:return e.toLocaleString()}}const s=[`• `,`•• `,`•••`,` ••`,` •`,` `];function c(){let[e,t]=a.useState(0);return a.useEffect(()=>{let e=setInterval(()=>{t(e=>(e+1)%s.length)},180);return()=>clearInterval(e)},[]),e}function l({title:l,value:u,series:d,delta:f,format:p=`number`,loading:m=!1,emptyHint:h,width:g}){let{theme:_}=t(),v=c(),y=a.createElement(i,{color:_.typography.label.color,dimColor:_.typography.label.dim},l.toUpperCase());if(m)return a.createElement(e,{width:g},y,a.createElement(i,{color:_.accent},s[v]));let b=typeof u==`number`?u:Number(u),x=(u===``||u===`—`||typeof u==`number`&&!Number.isFinite(b))&&(!d||d.length===0);if(x)return a.createElement(e,{width:g},y,a.createElement(i,{color:_.dim},h??`no data yet`));let S=o(u,p),C=typeof g==`number`?Math.max(8,g-6):16,w=d&&d.length>0?n(d,C):``,T=null;if(typeof f==`number`&&Number.isFinite(f)){let e=Math.abs(f*100);T=e<.5?a.createElement(i,{color:_.dim},` `,`→ `,e.toFixed(1),`%`):f>0?a.createElement(i,{color:_.success},` `,`↑ `,e.toFixed(1),`%`):a.createElement(i,{color:_.error},` `,`↓ `,e.toFixed(1),`%`)}return a.createElement(e,{width:g},y,a.createElement(i,{color:_.typography.headline.color,bold:_.typography.headline.bold},S),w?a.createElement(r,{flexDirection:`row`},a.createElement(i,{color:_.accent},w),T):T?a.createElement(r,{flexDirection:`row`},T):null)}export{l as MetricCard};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{DataTable as u}from"./data-table-CDTM2qS0.js";import{MetricCard as d}from"./metric-card-W4GayhPO.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o}),u;try{({siteId:u}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await S(s,u);return n({type:`overview.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(C,{api:s,siteId:u,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}async function S(e,t){let[n,r]=await Promise.all([e.getStats(t,`24h`).catch(()=>null),e.getPages(t).catch(()=>[])]),i=r.reduce((e,t)=>e+t.views,0);return{visitors:n?.visitors??0,pageviews:n?.pageviews??i,bounceRate:n?.bounceRate??null,avgSession:n?.avgSessionSec??null,series:[],topPages:r.slice(0,10)}}const C=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,m]=y(null),[x,C]=y(!0),[w,T]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await S(e,t);n||(m(r),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),x)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`overview · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching dashboard…`))));if(w)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`overview · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:w}));if(!l||l.visitors===0&&l.pageviews===0&&l.topPages.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`overview · ${t}`}),_.createElement(s,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let E=process.stdout.columns??80,D=Math.max(18,Math.floor(E/4)-1),O=[{key:`path`,label:`path`,width:32},{key:`views`,label:`views`,align:`right`,width:8},{key:`uniqueVisitors`,label:`visitors`,align:`right`,width:8},{key:`avgTime`,label:`avg time`,align:`right`,width:9,format:e=>typeof e==`number`?`${Math.round(e/1e3)}s`:`—`},{key:`bounceRate`,label:`bounce`,align:`right`,width:7,format:e=>typeof e==`number`?`${(e*100).toFixed(0)}%`:`—`}];return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`overview · ${t}`}),_.createElement(f,{flexDirection:`row`},_.createElement(d,{title:`Visitors`,value:l.visitors,format:`number`,width:D}),_.createElement(d,{title:`Pageviews`,value:l.pageviews,format:`number`,width:D}),_.createElement(d,{title:`Bounce rate`,value:l.bounceRate??``,emptyHint:`—`,format:`percent`,width:D}),_.createElement(d,{title:`Avg session`,value:l.avgSession??``,emptyHint:`—`,format:`duration`,width:D})),_.createElement(i,{title:`Top pages`},l.topPages.length===0?_.createElement(p,{color:`gray`},`— no pages yet —`):_.createElement(u,{columns:O,data:l.topPages,zebra:!0})),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{x as overviewCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{DataTable as u}from"./data-table-CDTM2qS0.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";async function b(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o}),u;try{({siteId:u}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getPages(u);return n({type:`pages.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:s,siteId:u,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=m(),[l,p]=v(null),[b,x]=v(!0),[S,C]=v(null);if(h(e=>{e===`q`&&(c(),r(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getPages(t);n||(p(r),x(!1))}catch(e){n||(C(e.message),x(!1))}})(),()=>{n=!0}},[e,t]),b)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`pages · ${t}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Fetching pages…`))));if(S)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`pages · ${t}`}),g.createElement(s,{reason:`error`,headline:`Failed to load`,hint:S}));if(!l||l.length===0)return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`pages · ${t}`}),g.createElement(s,{reason:`no-data`,headline:`No pages yet`,hint:`Visit your site to send the first event`}));let w=[{key:`path`,label:`path`,width:36},{key:`views`,label:`views`,align:`right`,width:8},{key:`uniqueVisitors`,label:`unique`,align:`right`,width:8},{key:`avgTime`,label:`avg time`,align:`right`,width:9,format:e=>typeof e==`number`?`${Math.round(e/1e3)}s`:`—`},{key:`bounceRate`,label:`bounce`,align:`right`,width:7,format:e=>typeof e==`number`?`${(e*100).toFixed(0)}%`:`—`}];return g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`pages · ${t}`}),g.createElement(i,{title:`Top pages (${l.length})`},g.createElement(u,{columns:w,data:l,zebra:!0})),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{b as pagesCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{Box as l,Text as u}from"ink";import d from"react";async function f(f){let p=await e(),m=await t({strict:!1}),h=new c({config:p,cliVersion:f.cliVersion,token:m}),g;try{({siteId:g}=await s(h,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let _=r(f),v=[{key:`isCurrent`,header:``,width:2,format:e=>e?`*`:` `},{key:`name`,header:`project`,width:26},{key:`domain`,header:`domain`,width:28,format:e=>String(e??`—`)},{key:`tier`,header:`tier`,width:10},{key:`pageviews24h`,header:`24h pv`,width:8,align:`right`},{key:`id`,header:`id`,width:38,format:e=>String(e).slice(0,38)}];return i({cliVersion:f.cliVersion,title:`projects · ${m?.teamId??`—`}`,commandName:`projects`,authToken:m?.accessToken??null,refreshIntervalMs:0,fetcher:e=>h.getProjects(g,e),format:_,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.projects)process.stdout.write(JSON.stringify(t)+`
2
+ `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(n(e.projects,[`id`,`name`,`domain`,`tier`,`pageviews24h`,`isCurrent`],t))},panels:[{id:`summary`,title:`Tracked sites`,render:e=>{let t=e.projects.find(e=>e.isCurrent);return d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},e.projects.length),d.createElement(u,{color:`gray`},` projects`)),t?d.createElement(u,{color:`gray`},`current: `,d.createElement(u,{color:`cyan`},t.name),` `,`(`,t.domain??`—`,`, `,t.tier,`)`):d.createElement(u,{color:`gray`},`no current project bound to this token`))}},{id:`list`,title:`List`,render:e=>e.projects.length===0?d.createElement(o,{reason:`no-data`,headline:`No projects yet`,hint:"Run `zenovay init` to install the tracker on your first site."}):d.createElement(a,{data:e.projects,columns:v})},{id:`hint`,title:`Switch`,render:()=>d.createElement(u,{color:`gray`},"To switch project: run `zenovay logout` then `zenovay login` (V2.1 adds a faster /switch flow).")}]})}export{f as projectsCommand};
@@ -0,0 +1,8 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{Table as o}from"./ui-BtZp4Eh8.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{requireTier as l}from"./tier-Ceoo7ndQ.js";import{Box as u,Text as d,useApp as f,useInput as p}from"ink";import m,{useMemo as h,useState as g}from"react";import _ from"ink-text-input";function v({api:e,siteId:t,maxRows:n}){let{exit:r}=f(),[s,c]=g(``),[l,v]=g(null),[y,b]=g(null),[x,S]=g(!1),[C,w]=g([]);p((e,t)=>{t.escape&&r()});let T=async i=>{if(i.trim()){if(i.trim()===`\\q`||i.trim()===`exit`||i.trim()===`quit`){r();return}w(e=>[...e,i]),S(!0),b(null);try{let r=await e.runSqlQuery(t,i,{maxRows:n});v(r)}catch(e){b(e.message),v(null)}finally{S(!1),c(``)}}},E=h(()=>l?l.columns.map(e=>({key:e,header:e,width:18,format:e=>e==null?`∅`:String(e).slice(0,18)})):[],[l]);return m.createElement(u,{flexDirection:`column`},m.createElement(a,{version:`query`}),m.createElement(i,{title:`History`,state:`idle`},C.length===0?m.createElement(d,{color:`gray`},`— no queries yet — Esc or \\q to exit —`):C.slice(-5).map((e,t)=>m.createElement(d,{key:t,color:`gray`},`> ${e.slice(0,80)}${e.length>80?`…`:``}`))),m.createElement(u,null,m.createElement(d,{color:`magenta`},`sql`,`>`,` `),m.createElement(_,{value:s,onChange:c,onSubmit:T})),x?m.createElement(d,{color:`gray`},`running…`):null,y?m.createElement(i,{title:`Error`,state:`err`},m.createElement(d,{color:`red`},y)):null,l?m.createElement(i,{title:`${l.row_count} rows · ${l.duration_ms}ms${l.truncated?` · truncated`:``}`,state:`ok`},l.row_count===0?m.createElement(d,{color:`gray`},`— empty —`):m.createElement(o,{data:l.rows.slice(0,50),columns:E})):null)}async function y(i){let a=await e(),o=await t({strict:!1}),u=new c({config:a,cliVersion:i.cliVersion,token:o});try{await l(u,`scale`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await s(u,{explicit:i.siteId,headless:!!(i.json||i.csv||i.tsv||i.ndjson),cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=i.maxRows??1e3,p=r(i);if(i.sql)try{let e=await u.runSqlQuery(d,i.sql,{maxRows:f});if(p===`json`)process.stdout.write(JSON.stringify(e,null,2)),process.stdout.write(`
2
+ `);else if(p===`ndjson`)for(let t of e.rows)process.stdout.write(JSON.stringify(t)+`
3
+ `);else if(p===`csv`||p===`tsv`)process.stdout.write(n(e.rows,e.columns,p));else{let t=e.columns.map(t=>Math.max(t.length,...e.rows.map(e=>String(e[t]??``).length))),n=`+`+t.map(e=>`-`.repeat(e+2)).join(`+`)+`+`;process.stdout.write(n+`
4
+ `),process.stdout.write(`|`+e.columns.map((e,n)=>` ${e.padEnd(t[n]??0)} `).join(`|`)+`|
5
+ `),process.stdout.write(n+`
6
+ `);for(let n of e.rows.slice(0,200))process.stdout.write(`|`+e.columns.map((e,r)=>` ${String(n[e]??``).padEnd(t[r]??0)} `).join(`|`)+`|
7
+ `);process.stdout.write(n+`
8
+ `),process.stdout.write(`${e.row_count} rows · ${e.duration_ms}ms${e.truncated?` · truncated`:``}\n`)}return 0}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}let{render:h}=await import(`ink`);return await h(m.createElement(v,{api:u,siteId:d,maxRows:f})).waitUntilExit(),0}export{y as queryCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";function b(e){return e>=.6?`magenta`:e>=.4?`cyan`:e>=.2?`blue`:`gray`}function x(e){return!Number.isFinite(e)||e===0?` — `:` ${(e*100).toFixed(0).padStart(3)}% `}async function S(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getRetention(d);return n({type:`retention.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(C,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const C=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=m(),[l,u]=v(null),[p,S]=v(!0),[C,w]=v(null);return h(e=>{e===`q`&&(c(),r(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getRetention(t);n||(u(r.cohorts),S(!1))}catch(e){n||(w(e.message),S(!1))}})(),()=>{n=!0}},[e,t]),p?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`retention · ${t}`}),g.createElement(i,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Crunching cohorts…`)))):C?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`retention · ${t}`}),g.createElement(s,{reason:`error`,headline:`Failed to load`,hint:C})):!l||l.length===0?g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`retention · ${t}`}),g.createElement(s,{reason:`no-data`,headline:`No retention data yet`,hint:`Retention needs at least 30 days of traffic`})):g.createElement(d,{flexDirection:`column`},g.createElement(a,{version:n,subtitle:`retention · ${t}`}),g.createElement(i,{title:`Cohort retention (D1 / D7 / D30)`},g.createElement(d,{flexDirection:`row`},g.createElement(f,{bold:!0},`cohort`.padEnd(12)),g.createElement(f,{bold:!0},` D1 `),g.createElement(f,{bold:!0},` D7 `),g.createElement(f,{bold:!0},` D30 `)),l.map(e=>g.createElement(d,{key:e.date,flexDirection:`row`},g.createElement(f,null,e.date.padEnd(12).slice(0,12)),g.createElement(f,{color:b(e.day1)},x(e.day1)),g.createElement(f,{color:b(e.day7)},x(e.day7)),g.createElement(f,{color:b(e.day30)},x(e.day30))))),g.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{S as retentionCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import{spark as i}from"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as a}from"./analytical-screen-DI8ahq4z.js";import"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e,t){let n=e/100,r=new Intl.NumberFormat(`en-US`,{minimumFractionDigits:0,maximumFractionDigits:0}).format(n),i=(t||`USD`).toUpperCase();return i===`USD`?`$${r}`:i===`EUR`?`€${r}`:i===`GBP`?`£${r}`:`${r} ${i}`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new c({config:m,cliVersion:p.cliVersion,token:h}),_;try{({siteId:_}=await s(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let v=r(p),y=p.range??`30d`;return a({cliVersion:p.cliVersion,title:`revenue · ${_} · ${y}`,commandName:`revenue`,authToken:h?.accessToken??null,refreshIntervalMs:p.watch?5*6e4:0,fetcher:e=>g.getRevenue(_,y,e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);return}process.stdout.write(n(e.series,[`bucket`,`amount`,`currency`,`transactions`],t))},panels:[{id:`totals`,title:`Top line`,render:e=>d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{color:`green`,bold:!0},f(e.totalAmount,e.currency)),` `,d.createElement(u,{color:`gray`},`total · `,e.totalTransactions,` transactions`)),typeof e.mrr==`number`?d.createElement(u,null,d.createElement(u,{bold:!0},`MRR `),d.createElement(u,{color:`magenta`},f(e.mrr,e.currency)),typeof e.arpu==`number`?d.createElement(u,{color:`gray`},` · ARPU `,f(e.arpu,e.currency)):null):null)},{id:`series`,title:`Daily (${y})`,render:e=>{let t=e.series.map(e=>e.amount);if(t.length===0)return d.createElement(o,{reason:`no-data`,headline:`No revenue events yet`,hint:"Send Stripe webhooks or `track('purchase', { amount })` events to populate this chart."});let n=Math.max(...t,1);return d.createElement(l,{flexDirection:`column`},d.createElement(u,{color:`magenta`},i(t,Math.min(60,t.length*2))),d.createElement(u,{color:`gray`},`peak: `,f(n,e.currency),` ·`,` `,`avg: `,f(e.totalAmount/Math.max(1,t.length),e.currency)))}},{id:`window`,title:`Window`,render:e=>d.createElement(u,{color:`gray`},new Date(e.windowStart).toISOString().slice(0,10),` →`,` `,new Date(e.windowEnd).toISOString().slice(0,10))}]})}export{p as revenueCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{DataTable as d}from"./data-table-CDTM2qS0.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";function x(e){if(!e||e<=0)return`—`;let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return`${n}m ${(t%60).toString().padStart(2,`0`)}s`}function S(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.max(0,Math.floor((Date.now()-t)/1e3));return n<60?`${n}s`:n<3600?`${Math.floor(n/60)}m`:n<86400?`${Math.floor(n/3600)}h`:`${Math.floor(n/86400)}d`}async function C(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getSessions(d);return n({type:`sessions.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(w,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,u]=y(null),[m,C]=y(!0),[w,T]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getSessions(t);n||(u(r),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),m)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`sessions · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching sessions…`))));if(w)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`sessions · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:w}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`sessions · ${t}`}),_.createElement(s,{reason:`no-data`,headline:`No replays yet`,hint:`Enable session replay in your site settings`}));let E=[{key:`id`,label:`session id`,width:24},{key:`visitor`,label:`visitor`,width:18},{key:`duration`,label:`duration`,align:`right`,width:9,format:e=>x(e)},{key:`startedAt`,label:`when`,align:`right`,width:6,format:e=>S(String(e))},{key:`pageCount`,label:`events`,align:`right`,width:7},{key:`deviceType`,label:`device`,width:8,format:e=>String(e??`—`)}];return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`sessions · ${t}`}),_.createElement(i,{title:`Recent sessions (${l.length})`},_.createElement(d,{columns:E,data:l,zebra:!0})),_.createElement(f,{marginTop:1},_.createElement(p,{color:`gray`},`Open any session for replay at https://app.zenovay.com/replay`)),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{C as sessionsCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e,t){let n=Math.round(e/100*t);return`█`.repeat(n)+`░`.repeat(Math.max(0,t-n))}function p(e){return e==null?{glyph:`·`,color:`gray`}:e>.5?{glyph:`▲`,color:`green`}:e<-.5?{glyph:`▼`,color:`red`}:{glyph:`→`,color:`gray`}}async function m(m){let h=await e(),g=await t({strict:!1}),_=new c({config:h,cliVersion:m.cliVersion,token:g}),v;try{({siteId:v}=await s(_,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=r(m),b=m.period??`30d`,x=[{key:`source`,header:`source`,width:22},{key:`channel`,header:`channel`,width:10,format:e=>String(e??`—`)},{key:`visitors`,header:`visitors`,width:8,align:`right`},{key:`delta`,header:`Δ`,width:6,align:`right`,format:e=>typeof e==`number`?`${e>0?`+`:``}${(e*100).toFixed(1)}%`:`—`}];return i({cliVersion:m.cliVersion,title:`sources · ${v} · ${b}`,commandName:`sources`,authToken:g?.accessToken??null,refreshIntervalMs:6e4,fetcher:e=>_.getSources(v,b,m.compare,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);return}process.stdout.write(n(e.sources,[`source`,`channel`,`visitors`,`conversions`,`revenue`,`delta`],t))},panels:[{id:`summary`,title:`Total`,render:e=>d.createElement(u,null,d.createElement(u,{bold:!0},e.totalVisitors.toLocaleString()),` `,d.createElement(u,{color:`gray`},`visitors · `,e.sources.length,` sources`))},{id:`channels`,title:`By channel`,render:e=>{if(e.sources.length===0)return d.createElement(o,{reason:`no-data`,headline:`No traffic yet`,hint:`Sources appear once visitors arrive from search, social or referrals.`});let t=e.totalVisitors||1,n=[...e.sources].sort((e,t)=>t.visitors-e.visitors).slice(0,12);return d.createElement(l,{flexDirection:`column`},n.map((e,n)=>{let r=e.visitors/t*100,i=p(e.delta);return d.createElement(l,{key:`${e.source}-${n}`},d.createElement(u,null,d.createElement(u,{color:`cyan`},e.source.padEnd(20).slice(0,20)),` `,d.createElement(u,{color:`magenta`},f(r,30)),` `,d.createElement(u,null,e.visitors.toString().padStart(6),` `),d.createElement(u,{color:`gray`},`(`,r.toFixed(1),`%)`),` `,d.createElement(u,{color:i.color},i.glyph)))}))}},{id:`table`,title:`Detail`,render:e=>e.sources.length===0?d.createElement(o,{reason:`no-data`,headline:`No source detail`,hint:`Detail rows fill in once traffic is attributed.`}):d.createElement(a,{data:e.sources.slice(0,20),columns:x})}]})}export{m as sourcesCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e){return`${(e*100).toFixed(1)}%`}function p(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.floor(e/60)}m ${Math.round(e%60)}s`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}async function m(m){let h=await e(),g=await t({strict:!1}),_=new c({config:h,cliVersion:m.cliVersion,token:g}),v;try{({siteId:v}=await s(_,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=r(m),b=m.range??`24h`,x=[{key:`url`,header:`page`,width:40,format:e=>String(e??`—`)},{key:`views`,header:`views`,width:8,align:`right`}],S=[{key:`country`,header:`country`,width:8},{key:`visitors`,header:`visitors`,width:8,align:`right`}];return i({cliVersion:m.cliVersion,title:`stats · ${v} · ${b}`,commandName:`stats`,authToken:g?.accessToken??null,refreshIntervalMs:m.watch?6e4:0,fetcher:e=>_.getStats(v,b,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);return}process.stdout.write(n([{range:b,visitors:e.visitors,pageviews:e.pageviews,sessions:e.sessions,bounceRate:f(e.bounceRate),avgSession:p(e.avgSessionSec)}],[`range`,`visitors`,`pageviews`,`sessions`,`bounceRate`,`avgSession`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},e.visitors.toLocaleString()),d.createElement(u,{color:`gray`},` visitors `),d.createElement(u,{bold:!0},e.pageviews.toLocaleString()),d.createElement(u,{color:`gray`},` pageviews `),d.createElement(u,{bold:!0},e.sessions.toLocaleString()),d.createElement(u,{color:`gray`},` sessions`)),d.createElement(u,{color:`gray`},`bounce `,f(e.bounceRate),` · avg session `,p(e.avgSessionSec)))},{id:`pages`,title:`Top pages`,render:e=>e.topPages.length===0?d.createElement(o,{reason:`no-data`,headline:`No pages tracked`,hint:`Pageviews appear once your tracker fires its first event.`}):d.createElement(a,{data:e.topPages.slice(0,10),columns:x})},{id:`countries`,title:`Top countries`,render:e=>e.topCountries.length===0?d.createElement(o,{reason:`no-data`,headline:`No country data`,hint:`Country breakdown unlocks once visitors reach the site.`}):d.createElement(a,{data:e.topCountries.slice(0,10),columns:S})}]})}export{m as statsCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e,updateConfig as t}from"./config-CZ9IzjIH.js";const n=5*60*1e3,r=new Set([`free`,`pro`,`scale`,`enterprise`]),i={free:0,pro:1,scale:2,enterprise:3},a=`https://app.zenovay.com/billing`;function o(e){let t=(e??`free`).trim().toLowerCase();return r.has(t)?t:`free`}async function s(r){let i=await e(),a=Date.now();if(i.cachedTier&&i.cachedTierAt&&a-i.cachedTierAt<n)return o(i.cachedTier);try{let e=await r.me(),n=o(e.team?.plan);return await t({cachedTier:n,cachedTierAt:a}),n}catch{return i.cachedTier?o(i.cachedTier):`free`}}async function c(e,t){let n=await s(e);if(i[n]>=i[t])return;let r=t.charAt(0).toUpperCase()+t.slice(1);throw Error(`This command requires the ${r} plan or higher (you're on ${n}). Upgrade at ${a}.`)}export{c as requireTier};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import"./formatter-BNYzdX5c.js";import{emit as n,isHeadless as r}from"./emit-BmfLGjqr.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import{Keybar as o}from"./keybar-DUC7w1HQ.js";import{EmptyState as s}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as c}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as l}from"./api-v2-CRj-zoG9.js";import{requireTier as u}from"./tier-Ceoo7ndQ.js";import{DataTable as d}from"./data-table-CDTM2qS0.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";function x(e){return e===`up`?{glyph:`● up`,color:`green`}:e===`down`?{glyph:`● down`,color:`red`}:{glyph:`○ unknown`,color:`gray`}}function S(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.round((t-Date.now())/(1e3*60*60*24));return`${n}d`}async function C(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new l({config:a,cliVersion:i.cliVersion,token:o});try{await u(s,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d;try{({siteId:d}=await c(s,{explicit:i.siteId,headless:!!i.json,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(r(i)){let e=await s.getUptime(d);return n({type:`uptime.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(w,{api:s,siteId:d,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,cliVersion:n,onExit:r})=>{let{exit:c}=h(),[l,u]=y(null),[m,C]=y(!0),[w,T]=y(null);if(g(e=>{e===`q`&&(c(),r(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getUptime(t);n||(u(r.monitors),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),m)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`uptime · ${t}`}),_.createElement(i,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching monitors…`))));if(w)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`uptime · ${t}`}),_.createElement(s,{reason:`error`,headline:`Failed to load`,hint:w}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`uptime · ${t}`}),_.createElement(s,{reason:`no-data`,headline:`No monitors configured`,hint:`Add one at app.zenovay.com/uptime`}));let E=[{key:`url`,label:`monitor`,width:36},{key:`status`,label:`status`,width:12,format:e=>x(String(e)).glyph},{key:`p95ms`,label:`p95 ms`,align:`right`,width:8,format:e=>typeof e==`number`?String(e):`—`},{key:`sslExpiry`,label:`ssl exp`,align:`right`,width:7,format:e=>S(e)}];return _.createElement(f,{flexDirection:`column`},_.createElement(a,{version:n,subtitle:`uptime · ${t}`}),_.createElement(i,{title:`Monitors (${l.length})`},_.createElement(d,{columns:E,data:l,zebra:!0})),_.createElement(o,{items:[{key:`q`,label:`quit`}]}))};export{C as uptimeCommand};
@@ -1,4 +1,4 @@
1
- import{readConfig as e,updateConfig as t}from"./config-CZ9IzjIH.js";import{ApiClient as n,readToken as r}from"./api-DXmhz2DM.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import{resolveSiteId as i}from"./resolve-site-D4W9yMVw.js";async function a(a){if(a.reset)return await t({defaultSiteId:void 0,defaultSiteName:void 0}),process.stdout.write(`Default site cleared.
1
+ import{readConfig as e,updateConfig as t}from"./config-CZ9IzjIH.js";import{ApiClient as n,readToken as r}from"./api-DXmhz2DM.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import{resolveSiteId as i}from"./resolve-site-B54mr0Bh.js";async function a(a){if(a.reset)return await t({defaultSiteId:void 0,defaultSiteName:void 0}),process.stdout.write(`Default site cleared.
2
2
  `),0;if(a.show){let t=await e();return t.defaultSiteId?process.stdout.write(a.json?`${JSON.stringify({defaultSiteId:t.defaultSiteId,defaultSiteName:t.defaultSiteName??null})}\n`:`Default site: ${t.defaultSiteName??t.defaultSiteId} (${t.defaultSiteId})\n`):process.stdout.write(a.json?`{"defaultSiteId":null}
3
3
  `:`No default site set.
4
4
  `),0}let s=await e(),c=await r({strict:!1});if(!c&&!process.env.ZENOVAY_API_TOKEN)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:s,cliVersion:a.cliVersion,token:c});if(a.match&&a.match.trim()){let e=a.match.trim().toLowerCase(),n=await l.getSites(),r=n.find(e=>e.id===a.match||e.trackingCode===a.match||e.url===a.match),i=r??n.find(t=>o(t.url).includes(e)||t.name.toLowerCase().includes(e));return i?(await t({defaultSiteId:i.id,defaultSiteName:i.name}),process.stdout.write(`Default site → ${i.name} (${i.url})\n`),0):(process.stderr.write(`No site matched "${a.match}". Your sites:\n${n.map(e=>` ${e.name} — ${e.url} — ${e.id}`).join(`
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{EmptyState as o}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as s}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as c}from"./api-v2-CRj-zoG9.js";import{Box as l,Text as u}from"ink";import d from"react";const f={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 p(e,t){let n=f[e];return t<=n.good?{label:`good`,color:`green`}:t<=n.poor?{label:`needs`,color:`yellow`}:{label:`poor`,color:`red`}}function m(e,t){return e===`cls`?t.toFixed(3):t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`}async function h(f){let h=await e(),g=await t({strict:!1}),_=new c({config:h,cliVersion:f.cliVersion,token:g}),v;try{({siteId:v}=await s(_,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=r(f),b=[{key:`url`,header:`url`,width:32},{key:`device`,header:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,header:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?m(`lcp`,e.p75):`—`},{key:`inp`,header:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?m(`inp`,e.p75):`—`},{key:`cls`,header:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?m(`cls`,e.p75):`—`},{key:`samples`,header:`n`,width:6,align:`right`}];return i({cliVersion:f.cliVersion,title:`vitals · ${v}`,commandName:`vitals`,authToken:g?.accessToken??null,refreshIntervalMs:f.watch?5*6e4:0,fetcher:e=>_.getVitals(v,{url:f.url,device:f.device,window:f.window},e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);return}process.stdout.write(n(e.vitals,[`url`,`device`,`samples`],t))},panels:[{id:`summary`,title:`Site-wide p75`,render:e=>{let t=t=>{let n=0,r=0;for(let i of e.vitals){let e=i[t]?.p75;typeof e==`number`&&(n+=e*i.samples,r+=i.samples)}return r>0?n/r:0},n=[`lcp`,`inp`,`cls`,`ttfb`,`fcp`];return d.createElement(l,{flexDirection:`column`},n.map(e=>{let n=t(e),r=p(e,n);return d.createElement(u,{key:e},d.createElement(u,{color:r.color},`● `),d.createElement(u,{bold:!0},e.toUpperCase().padEnd(5)),` `,d.createElement(u,null,m(e,n).padStart(8)),` `,d.createElement(u,{color:r.color},r.label))}))}},{id:`pages`,title:`Per-page`,render:e=>e.vitals.length===0?d.createElement(o,{reason:`no-data`,headline:`No vitals data yet`,hint:`Real-user LCP/INP/CLS samples appear once visitors load instrumented pages.`}):d.createElement(a,{data:e.vitals.slice(0,15),columns:b})}]})}export{h as vitalsCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{parseSseStream as n}from"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import{emit as r,isHeadless as i}from"./emit-BmfLGjqr.js";import{Panel as a}from"./panel-DZqvtaao.js";import{Banner as o}from"./prompt-DEng-me1.js";import{Keybar as s}from"./keybar-DUC7w1HQ.js";import{spark as c}from"./sparkline-B6ueqPAB.js";import{EmptyState as l}from"./empty-state-CNtcEPJ9.js";import{resolveSiteId as u}from"./resolve-site-B54mr0Bh.js";import{ApiV2Client as d}from"./api-v2-CRj-zoG9.js";import{Globe as f}from"./globe-1bi4DjwJ.js";import{z as p}from"zod";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";import C from"ink-text-input";const w=p.object({siteId:p.string().optional(),window:p.string().optional(),totalVisitors:p.number().optional(),visitors:p.object({count:p.number().optional(),series:p.array(p.number()).optional()}).optional(),topPages:p.array(p.object({path:p.string(),views:p.number().optional(),count:p.number().optional()})).optional(),sources:p.array(p.object({source:p.string(),visitors:p.number()})).optional()}).passthrough();async function T(n){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new d({config:a,cliVersion:n.cliVersion,token:o}),c;try{({siteId:c}=await u(s,{explicit:n.siteId,headless:!!n.json,cliVersion:n.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(i(n)){let e=await s.getDashboardSnapshot(c);return r({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:s,siteId:c,intervalMs:n.intervalMs??15e3,cliVersion:n.cliVersion,onExit:n=>{t(),e(n)}}))})}const E=({api:e,siteId:t,intervalMs:r,cliVersion:i,onExit:c})=>{let{exit:u}=_(),[d,p]=x(null),[g,C]=x(null),[T,E]=x(null),[P,F]=x([]),[I,L]=x(!0),[R,z]=x(null),[B,V]=x(1),[H,U]=x(!1),[W,G]=x(!1);v((e,t)=>{if(e===`q`){u(),c(0);return}if(e===`?`||e===`/`){G(e=>!e);return}if(e===`g`){U(e=>!e);return}if(t.tab){V(e=>{let n=t.shift?(e+4)%6+1:e%6+1;return n});return}(e===`1`||e===`2`||e===`3`||e===`4`||e===`5`||e===`6`)&&V(Number(e))});let[K,q]=x(!1);if(b(()=>{let n=!1,i=async()=>{try{let r=await e.getDashboardSnapshot(t);if(n)return;let i=w.safeParse(r);if(!i.success){q(!0),L(!1);return}q(!1);let a=i.data,o={visitors:a.visitors??(typeof a.totalVisitors==`number`?{count:a.totalVisitors}:void 0),topPages:a.topPages?.map(e=>({path:e.path,views:e.views??e.count??0})),sources:a.sources};p(o),e.getVitals(t).then(e=>{n||C(e)},()=>{}),e.getGoals(t).then(e=>{n||E(e)},()=>{}),L(!1),z(null)}catch(e){n||z(e.message)}};i();let a=setInterval(i,r);return()=>{n=!0,clearInterval(a)}},[e,t,r]),b(()=>{let r=new AbortController;return(async()=>{try{let i=await e.openEventsStream(t,r.signal);for await(let e of n(i))e.type===`error`&&F(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>r.abort()},[e,t]),I)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}`}),y.createElement(a,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching snapshot…`))));if(R&&!d)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}`}),y.createElement(a,{title:`Error`,state:`err`},y.createElement(h,{color:`red`},R)));if(K&&!d)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}`}),y.createElement(l,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let J=process.stdout.columns??80,Y=Math.max(20,Math.floor(J/3)-1),X=[];return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:i,subtitle:`watch · ${t}${H?` · globe`:``}`}),y.createElement(m,{flexDirection:`row`},y.createElement(m,{flexDirection:`column`},H?y.createElement(a,{title:`Live globe`,focused:B===1,width:Y},y.createElement(f,{data:X,width:Math.max(40,Y-4),height:12})):y.createElement(O,{snapshot:d,focused:B===1,width:Y}),y.createElement(j,{events:P,focused:B===4,width:Y})),y.createElement(m,{flexDirection:`column`},y.createElement(k,{snapshot:d,focused:B===2,width:Y}),y.createElement(M,{vitals:g,focused:B===5,width:Y})),y.createElement(m,{flexDirection:`column`},y.createElement(A,{snapshot:d,focused:B===3,width:Y}),y.createElement(N,{goals:T,focused:B===6,width:Y}))),W?y.createElement(D,{api:e,siteId:t,width:J-2}):null,y.createElement(s,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:H?`panels`:`globe`},{key:`?/`,label:W?`close chat`:`ai chat`},{key:`q`,label:`quit`}]}))},D=({api:e,siteId:t,width:r})=>{let[i,o]=x(``),[s,c]=x([]),[l,u]=x(!1),[d,f]=x(``),[p,g]=x(null),_=async r=>{let i=r.trim();if(!i||l)return;g(null),o(``);let a=[...s,{role:`user`,content:i}];c(a),u(!0),f(``);try{let r=a.map(e=>({role:e.role,content:e.content})),i=await e.openAiStream(`chat`,{messages:r,siteId:t},void 0),o=``;for await(let e of n(i))if(e.type===`delta`)o+=e.content,f(o);else if(e.type===`error`)g(`${e.code}: ${e.message}`);else if(e.type===`done`)break;c([...a,{role:`assistant`,content:o}]),f(``)}catch(e){g(e instanceof Error?e.message:`chat failed`)}finally{u(!1)}};return y.createElement(m,{marginTop:1},y.createElement(a,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:r},y.createElement(m,{flexDirection:`column`},s.slice(-6).map((e,t)=>y.createElement(m,{key:t,flexDirection:`column`,marginBottom:1},y.createElement(h,{color:e.role===`user`?`cyan`:`magenta`,bold:!0},e.role===`user`?`you`:`zenovay`),y.createElement(h,null,e.content))),l&&d?y.createElement(m,{flexDirection:`column`,marginBottom:1},y.createElement(h,{color:`magenta`,bold:!0},`zenovay`),y.createElement(h,null,d)):null,p?y.createElement(h,{color:`red`},`✗ `,p):null,y.createElement(m,null,y.createElement(h,{color:`cyan`},l?`⠋ `:`▸ `),y.createElement(C,{value:i,onChange:o,onSubmit:_,placeholder:l?`streaming…`:`ask anything about your analytics`})))))},O=({snapshot:e,focused:t,width:n})=>{let r=e?.visitors?.count??0,i=e?.visitors?.series??[];return y.createElement(a,{title:`Visitors`,focused:t,width:n},y.createElement(h,{bold:!0},r.toString()),y.createElement(h,{color:`gray`},i.length>0?c(i,Math.max(8,n-6)):`— no data —`))},k=({snapshot:e,focused:t,width:n})=>{let r=e?.topPages?.slice(0,5)??[];return y.createElement(a,{title:`Top pages`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.path},y.createElement(h,null,e.path.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.views))))},A=({snapshot:e,focused:t,width:n})=>{let r=e?.sources?.slice(0,5)??[];return y.createElement(a,{title:`Sources`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.source},y.createElement(h,null,e.source.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.visitors))))},j=({events:e,focused:t,width:n})=>y.createElement(a,{title:`Events`,focused:t,width:n},e.length===0?y.createElement(h,{color:`gray`},`— waiting —`):e.slice(-10).map((e,t)=>y.createElement(h,{key:t},e.slice(0,n-4)))),M=({vitals:e,focused:t,width:n})=>{let r=(e,t,n)=>y.createElement(m,{key:e},y.createElement(h,{bold:!0},e.padEnd(6)),y.createElement(h,{color:`gray`},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return y.createElement(a,{title:`Vitals`,focused:t,width:n},r(`LCP`,e?.lcpP75,`ms`),r(`INP`,e?.inpP75,`ms`),r(`CLS`,e?.clsP75?e.clsP75*1e3:void 0,`/1k`),r(`TTFB`,e?.ttfbP75,`ms`),r(`FCP`,e?.fcpP75,`ms`))},N=({goals:e,focused:t,width:n})=>{let r=e?.goals?.slice(0,5)??[];return y.createElement(a,{title:`Goals`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.name},y.createElement(h,null,e.name.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.completions))))};export{T as watchCommand};
@@ -1,3 +1,3 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{Panel as n}from"./panel-DZqvtaao.js";import{Banner as r}from"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import"./ui-BtZp4Eh8.js";import{ApiV2Client as i}from"./api-v2-BwYWSe9Y.js";import{Box as a,Text as o,render as s,useApp as c,useInput as l}from"ink";import u,{useEffect as d,useState as f}from"react";async function p(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]),i=await crypto.subtle.sign(`HMAC`,r,n.encode(t));return Array.from(new Uint8Array(i),e=>e.toString(16).padStart(2,`0`)).join(``)}function m({stats:e}){return u.createElement(n,{title:`webhooks forward`,state:e.connected?`ok`:`busy`},u.createElement(a,{flexDirection:`column`},u.createElement(o,null,u.createElement(o,{color:`gray`},`public URL `),u.createElement(o,{color:`cyan`},e.publicUrl)),u.createElement(o,null,u.createElement(o,{color:`gray`},`→ forwarding to `),u.createElement(o,{color:`magenta`},e.wsUrl)),u.createElement(o,null,e.connected?u.createElement(o,{color:`green`},`● connected`):u.createElement(o,{color:`yellow`},`○ connecting…`),u.createElement(o,{color:`gray`},` · `,e.total,` requests · `,e.ok,` ok · `),u.createElement(o,{color:e.err>0?`red`:`gray`},e.err,` err`),e.lastStatus===null?null:u.createElement(o,{color:`gray`},` · last: HTTP `,e.lastStatus)),e.lastError?u.createElement(o,{color:`red`},`last error: `,e.lastError.slice(0,80)):null))}async function h(n){let h=await e(),g=await t({strict:!1});if(!g?.accessToken)return process.stderr.write("Not authenticated. Run `zenovay login` first.\n"),2;let _=n.siteId??g.teamId??``;if(!_)return process.stderr.write(`No site selected — pass --site-id or set ZENOVAY_SITE.
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{Panel as n}from"./panel-DZqvtaao.js";import{Banner as r}from"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import"./ui-BtZp4Eh8.js";import{ApiV2Client as i}from"./api-v2-CRj-zoG9.js";import{Box as a,Text as o,render as s,useApp as c,useInput as l}from"ink";import u,{useEffect as d,useState as f}from"react";async function p(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]),i=await crypto.subtle.sign(`HMAC`,r,n.encode(t));return Array.from(new Uint8Array(i),e=>e.toString(16).padStart(2,`0`)).join(``)}function m({stats:e}){return u.createElement(n,{title:`webhooks forward`,state:e.connected?`ok`:`busy`},u.createElement(a,{flexDirection:`column`},u.createElement(o,null,u.createElement(o,{color:`gray`},`public URL `),u.createElement(o,{color:`cyan`},e.publicUrl)),u.createElement(o,null,u.createElement(o,{color:`gray`},`→ forwarding to `),u.createElement(o,{color:`magenta`},e.wsUrl)),u.createElement(o,null,e.connected?u.createElement(o,{color:`green`},`● connected`):u.createElement(o,{color:`yellow`},`○ connecting…`),u.createElement(o,{color:`gray`},` · `,e.total,` requests · `,e.ok,` ok · `),u.createElement(o,{color:e.err>0?`red`:`gray`},e.err,` err`),e.lastStatus===null?null:u.createElement(o,{color:`gray`},` · last: HTTP `,e.lastStatus)),e.lastError?u.createElement(o,{color:`red`},`last error: `,e.lastError.slice(0,80)):null))}async function h(n){let h=await e(),g=await t({strict:!1});if(!g?.accessToken)return process.stderr.write("Not authenticated. Run `zenovay login` first.\n"),2;let _=n.siteId??g.teamId??``;if(!_)return process.stderr.write(`No site selected — pass --site-id or set ZENOVAY_SITE.
2
2
  `),2;if(!n.to)return process.stderr.write(`Missing --to <url> (e.g. --to localhost:3000/webhook).
3
3
  `),2;let v=n.to.match(/^https?:\/\//)?n.to:`http://${n.to}`,y=new i({config:h,cliVersion:n.cliVersion,token:g}),b;try{b=await y.createTunnel(_,n.to)}catch(e){return process.stderr.write(`Failed to register tunnel: ${e.message}\n`),1}let x=n.sign?n.secret??b.tunnelKey:null,S=()=>{let{exit:e}=c(),[t,i]=f({total:0,ok:0,err:0,lastStatus:null,lastError:null,publicUrl:b.publicUrl,wsUrl:b.wsUrl,connected:!1});return l((t,n)=>{(t===`q`||n.escape)&&e()}),d(()=>{let e=new AbortController,t=async e=>{try{let t={...e.headers};delete t.host,delete t[`content-length`],x&&(t[`X-Zenovay-Signature`]=`sha256=${await p(x,e.body)}`);let n=await fetch(v,{method:e.method,headers:t,body:e.method===`GET`||e.method===`HEAD`?void 0:e.body}),r=await n.text(),a={};return n.headers.forEach((e,t)=>{a[t]=e}),i(e=>({...e,total:e.total+1,ok:e.ok+(n.ok?1:0),err:e.err+(n.ok?0:1),lastStatus:n.status,lastError:n.ok?null:`HTTP ${n.status}`})),{status:n.status,headers:a,body:r}}catch(e){let t=e instanceof Error?e.message:String(e);return i(e=>({...e,total:e.total+1,err:e.err+1,lastError:t})),{status:502,body:JSON.stringify({error:`cli_local_failed`,detail:t})}}};return(async()=>{let n=y.tunnelClient(b.wsUrl);i(e=>({...e,connected:!0}));try{await n.start(t,e.signal)}catch(e){i(t=>({...t,connected:!1,lastError:e.message}))}})(),()=>{e.abort()}},[]),u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:`webhooks forward`}),u.createElement(m,{stats:t}),u.createElement(o,{color:`gray`},`target: `,v,` `,n.sign?`· HMAC-signed`:``),u.createElement(o,{color:`gray`},`[q | Esc] quit`))},{waitUntilExit:C}=s(u.createElement(S,null));return await C(),0}export{h as webhooksForwardCommand};
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import(`./init-BTJHpHNW.js`).then(async({initCommand:e})=>{let{readFileSync:t}=await import(`node:fs`),n=await import(`node:path`),{fileURLToPath:r}=await import(`node:url`),i=n.dirname(r(import.meta.url)),a=JSON.parse(t(n.join(i,`..`,`package.json`),`utf8`)),o=process.argv.slice(2),s=o.includes(`--json`),c=o.includes(`--yes`),l=o.includes(`--skip-mcp`),u=o.includes(`--skip-verify`),d=await e({cliVersion:a.version,cwd:process.cwd(),json:s,yes:c,skipMcp:l,skipVerify:u});process.exit(d)});
2
+ import(`./init-BMNuKlUT.js`).then(async({initCommand:e})=>{let{readFileSync:t}=await import(`node:fs`),n=await import(`node:path`),{fileURLToPath:r}=await import(`node:url`),i=n.dirname(r(import.meta.url)),a=JSON.parse(t(n.join(i,`..`,`package.json`),`utf8`)),o=process.argv.slice(2),s=o.includes(`--json`),c=o.includes(`--yes`),l=o.includes(`--skip-mcp`),u=o.includes(`--skip-verify`),d=await e({cliVersion:a.version,cwd:process.cwd(),json:s,yes:c,skipMcp:l,skipVerify:u});process.exit(d)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenovay/cli",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Zenovay CLI — AI install wizard + full terminal analytics dashboard",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{resolveSiteId as o}from"./resolve-site-D4W9yMVw.js";import{ApiV2Client as s}from"./api-v2-BwYWSe9Y.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function f(e){return e==null?`—`:e>=500?`Enterprise`:e>=50?`Growth`:`SMB`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new s({config:m,cliVersion:p.cliVersion,token:h}),_;try{({siteId:_}=await o(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let v=r(p),y=p.window??`24h`,b=p.limit??100,x=[{key:`lastSeenAt`,header:`when`,width:6,format:e=>d(String(e))},{key:`name`,header:`company`,width:24,format:e=>String(e).slice(0,24)},{key:`employeeCount`,header:`tier`,width:11,format:e=>f(typeof e==`number`?e:null)},{key:`industry`,header:`industry`,width:18,format:e=>String(e??`—`).slice(0,18)},{key:`visitCount`,header:`visits`,width:6,align:`right`},{key:`isNew`,header:``,width:5,format:e=>e?`NEW`:``}];return i({cliVersion:p.cliVersion,title:`companies · ${_} · ${y}`,commandName:`companies`,authToken:h?.accessToken??null,refreshIntervalMs:p.watch?3e4:0,fetcher:e=>g.getCompaniesSnapshot(_,{window:y,limit:b},e),format:v,headlessEmit:(e,t)=>{let r=p.newOnly?e.companies.filter(e=>e.isNew):e.companies;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of r)process.stdout.write(JSON.stringify(e)+`
2
- `);else process.stdout.write(JSON.stringify({companies:r,total:r.length},null,2));return}process.stdout.write(n(r,[`name`,`domain`,`industry`,`employeeCount`,`visitCount`,`firstSeenAt`,`lastSeenAt`,`isNew`],t))},panels:[{id:`summary`,title:`Now`,render:e=>{let t=e.companies.filter(e=>e.isNew).length,n=e.companies.filter(e=>(e.employeeCount??0)>=500).length;return u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.total),u.createElement(l,{color:`gray`},` companies in `,y)),u.createElement(l,{color:`gray`},u.createElement(l,{color:`green`},`● `,t,` new`),` · `,n,` enterprise`))}},{id:`feed`,title:`Feed`,render:e=>{let t=p.newOnly?e.companies.filter(e=>e.isNew):e.companies;return t.length===0?u.createElement(l,{color:`gray`},`— no `,p.newOnly?`new `:``,`companies in window —`):u.createElement(a,{data:t.slice(0,30),columns:x})}}]})}export{p as companiesCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{resolveSiteId as o}from"./resolve-site-D4W9yMVw.js";import{ApiV2Client as s}from"./api-v2-BwYWSe9Y.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 s({config:p,cliVersion:f.cliVersion,token:m}),g;try{({siteId:g}=await o(h,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let _=r(f),v=f.limit??50,y=[{key:`pushed_at`,header:`when`,width:6,format:e=>d(String(e))},{key:`branch`,header:`branch`,width:14,format:e=>String(e??`—`).slice(0,14)},{key:`commit_sha`,header:`commit`,width:9,format:e=>String(e).slice(0,8)},{key:`commit_author`,header:`author`,width:16,format:e=>String(e??`—`).slice(0,16)},{key:`commit_message`,header:`message`,width:40,format:e=>String(e??`—`).slice(0,40)},{key:`show_on_chart`,header:`chart`,width:5,format:e=>e?`●`:`○`}];return i({cliVersion:f.cliVersion,title:`deploys · ${g}`,commandName:`deploys`,authToken:m?.accessToken??null,refreshIntervalMs:0,fetcher:e=>h.getDeploys(g,{branch:f.branch,since:f.since,limit:v},e),format:_,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.deploys)process.stdout.write(JSON.stringify(t)+`
2
- `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(n(e.deploys,[`pushed_at`,`branch`,`commit_sha`,`commit_author`,`commit_message`,`repository`,`commit_url`,`show_on_chart`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>{let t=e.deploys.filter(e=>e.show_on_chart).length,n=new Set(e.deploys.map(e=>e.repository).filter(e=>!!e));return 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(a,{data:e.deploys.slice(0,30),columns:y})}]})}export{f as deploysCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import{spark as i}from"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as a}from"./analytical-screen-DI8ahq4z.js";import{Table as o}from"./ui-BtZp4Eh8.js";import{resolveSiteId as s}from"./resolve-site-D4W9yMVw.js";import{ApiV2Client as c}from"./api-v2-BwYWSe9Y.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function p(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}async function m(m){let h=await e(),g=await t({strict:!1}),_=new c({config:h,cliVersion:m.cliVersion,token:g}),v;try{({siteId:v}=await s(_,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=r(m),b=m.window??`24h`,x=m.limit??100,S=[{key:`ts`,header:`when`,width:6,format:e=>p(String(e))},{key:`class`,header:`class`,width:18,format:e=>String(e)},{key:`message`,header:`message`,width:42,format:e=>f(String(e??``),42)},{key:`page`,header:`page`,width:24,format:e=>String(e??`—`)},{key:`device`,header:`device`,width:8,format:e=>String(e??`—`)}];return a({cliVersion:m.cliVersion,title:`errors · ${v} · ${b}`,commandName:`errors`,authToken:g?.accessToken??null,refreshIntervalMs:m.watch?3e4:0,fetcher:e=>_.getErrors(v,{window:b,limit:x},e),format:y,headlessEmit:(e,t)=>{let r=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of r)process.stdout.write(JSON.stringify(e)+`
2
- `);else process.stdout.write(JSON.stringify({errors:r,total:r.length},null,2));return}process.stdout.write(n(r,[`ts`,`class`,`message`,`page`,`device`,`fingerprint`],t))},panels:[{id:`summary`,title:`Recent errors`,render:e=>{let t=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors,n=new Map,r=Date.now(),a=60;for(let e of t){let t=new Date(e.ts).getTime(),i=Math.floor((r-t)/(60*1e3));if(i<0||i>=a)continue;let o=n.get(e.class)??Array(a).fill(0),s=a-1-i;o[s]+=1,n.set(e.class,o)}let o=[...n.entries()].sort((e,t)=>t[1].reduce((e,t)=>e+t,0)-e[1].reduce((e,t)=>e+t,0)).slice(0,6);return d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},t.length),d.createElement(u,{color:`gray`},` errors in `,b)),o.length===0?null:d.createElement(l,{flexDirection:`column`,marginTop:1},o.map(([e,t])=>d.createElement(u,{key:e},d.createElement(u,{color:`red`},e.padEnd(20).slice(0,20)),` `,d.createElement(u,{color:`gray`},i(t,30))))))}},{id:`table`,title:`Detail`,render:e=>{let t=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors;return t.length===0?d.createElement(u,{color:`gray`},`— no errors `,m.search?`matching "${m.search}"`:`in window`,` —`):d.createElement(o,{data:t.slice(0,30),columns:S})}}]})}export{m as errorsCommand};
@@ -1,3 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{resolveSiteId as o}from"./resolve-site-D4W9yMVw.js";import{ApiV2Client as s}from"./api-v2-BwYWSe9Y.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e,t){let n=Math.round(e*t);return`█`.repeat(Math.max(0,Math.min(t,n)))+`░`.repeat(Math.max(0,t-n))}async function f(f){let m=await e(),h=await t({strict:!1}),g=new s({config:m,cliVersion:f.cliVersion,token:h}),_;try{({siteId:_}=await o(g,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let v=r(f);if(!f.funnelId){let e=[{key:`name`,header:`name`,width:30},{key:`stepCount`,header:`steps`,width:6,align:`right`},{key:`id`,header:`id`,width:36,format:e=>String(e).slice(0,36)}];return i({cliVersion:f.cliVersion,title:`funnels · ${_}`,commandName:`funnels`,authToken:h?.accessToken??null,refreshIntervalMs:0,fetcher:e=>g.listFunnels(_,e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
- `);return}process.stdout.write(n(e.funnels,[`id`,`name`,`stepCount`],t))},panels:[{id:`funnels`,title:`Funnels`,render:t=>t.funnels.length===0?u.createElement(l,{color:`gray`},`— no funnels defined —`):u.createElement(a,{data:t.funnels,columns:e})},{id:`hint`,title:`Next`,render:()=>u.createElement(l,{color:`gray`},"Run `zenovay funnel <id>` for drop-off detail.")}]})}let y=f.window??`30d`;return i({cliVersion:f.cliVersion,title:`funnel · ${f.funnelId} · ${y}`,commandName:`funnel`,authToken:h?.accessToken??null,refreshIntervalMs:0,fetcher:e=>g.getFunnel(_,f.funnelId,y,e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
3
- `);return}process.stdout.write(n(e.steps,[`id`,`name`,`visitors`,`conversions`],t))},panels:[{id:`overview`,title:p(`Overview`),render:e=>u.createElement(c,{flexDirection:`column`},u.createElement(l,{bold:!0},e.name),u.createElement(l,{color:`gray`},e.totalEntries.toLocaleString(),` entries · `,e.totalCompletions.toLocaleString(),` completed (`,(e.conversionRate*100).toFixed(1),`%)`))},{id:`flow`,title:`Flow`,render:e=>{let t=e.totalEntries||1;return u.createElement(c,{flexDirection:`column`},e.steps.map((n,r)=>{let i=n.visitors/t,a=e.steps[r-1],o=a?a.visitors-n.visitors:0,s=a?o/Math.max(1,a.visitors)*100:0;return u.createElement(c,{key:n.id,flexDirection:`column`},a?u.createElement(l,{color:`red`},` `,`↓ drop `,o.toLocaleString(),` (`,s.toFixed(1),`%)`):null,u.createElement(l,null,u.createElement(l,{bold:!0},`${r+1}. ${n.name}`.padEnd(22).slice(0,22)),` `,u.createElement(l,{color:`magenta`},d(i,30)),` `,u.createElement(l,null,(i*100).toFixed(1).padStart(5),`% `),u.createElement(l,{color:`gray`},n.visitors.toLocaleString())))}))}}]})}function p(e){return e}export{f as funnelCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{resolveSiteId as o}from"./resolve-site-D4W9yMVw.js";import{ApiV2Client as s}from"./api-v2-BwYWSe9Y.js";import{Box as c,Text as l}from"ink";import u from"react";async function d(d){let f=await e(),p=await t({strict:!1}),m=new s({config:f,cliVersion:d.cliVersion,token:p}),h;try{({siteId:h}=await o(m,{explicit:d.siteId,headless:!!(d.json||d.csv||d.tsv||d.ndjson),cliVersion:d.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let g=r(d),_=[{key:`isCurrent`,header:``,width:2,format:e=>e?`*`:` `},{key:`name`,header:`project`,width:26},{key:`domain`,header:`domain`,width:28,format:e=>String(e??`—`)},{key:`tier`,header:`tier`,width:10},{key:`pageviews24h`,header:`24h pv`,width:8,align:`right`},{key:`id`,header:`id`,width:38,format:e=>String(e).slice(0,38)}];return i({cliVersion:d.cliVersion,title:`projects · ${p?.teamId??`—`}`,commandName:`projects`,authToken:p?.accessToken??null,refreshIntervalMs:0,fetcher:e=>m.getProjects(h,e),format:g,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.projects)process.stdout.write(JSON.stringify(t)+`
2
- `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(n(e.projects,[`id`,`name`,`domain`,`tier`,`pageviews24h`,`isCurrent`],t))},panels:[{id:`summary`,title:`Tracked sites`,render:e=>{let t=e.projects.find(e=>e.isCurrent);return u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.projects.length),u.createElement(l,{color:`gray`},` projects`)),t?u.createElement(l,{color:`gray`},`current: `,u.createElement(l,{color:`cyan`},t.name),` `,`(`,t.domain??`—`,`, `,t.tier,`)`):u.createElement(l,{color:`gray`},`no current project bound to this token`))}},{id:`list`,title:`List`,render:e=>e.projects.length===0?u.createElement(l,{color:`gray`},`— no projects yet —`):u.createElement(a,{data:e.projects,columns:_})},{id:`hint`,title:`Switch`,render:()=>u.createElement(l,{color:`gray`},"To switch project: run `zenovay logout` then `zenovay login` (V2.1 adds a faster /switch flow).")}]})}export{d as projectsCommand};
@@ -1,8 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import{Panel as i}from"./panel-DZqvtaao.js";import{Banner as a}from"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{Table as o}from"./ui-BtZp4Eh8.js";import{resolveSiteId as s}from"./resolve-site-D4W9yMVw.js";import{ApiV2Client as c}from"./api-v2-BwYWSe9Y.js";import{Box as l,Text as u,useApp as d,useInput as f}from"ink";import p,{useMemo as m,useState as h}from"react";import g from"ink-text-input";function _({api:e,siteId:t,maxRows:n}){let{exit:r}=d(),[s,c]=h(``),[_,v]=h(null),[y,b]=h(null),[x,S]=h(!1),[C,w]=h([]);f((e,t)=>{t.escape&&r()});let T=async i=>{if(i.trim()){if(i.trim()===`\\q`||i.trim()===`exit`||i.trim()===`quit`){r();return}w(e=>[...e,i]),S(!0),b(null);try{let r=await e.runSqlQuery(t,i,{maxRows:n});v(r)}catch(e){b(e.message),v(null)}finally{S(!1),c(``)}}},E=m(()=>_?_.columns.map(e=>({key:e,header:e,width:18,format:e=>e==null?`∅`:String(e).slice(0,18)})):[],[_]);return p.createElement(l,{flexDirection:`column`},p.createElement(a,{version:`query`}),p.createElement(i,{title:`History`,state:`idle`},C.length===0?p.createElement(u,{color:`gray`},`— no queries yet — Esc or \\q to exit —`):C.slice(-5).map((e,t)=>p.createElement(u,{key:t,color:`gray`},`> ${e.slice(0,80)}${e.length>80?`…`:``}`))),p.createElement(l,null,p.createElement(u,{color:`magenta`},`sql`,`>`,` `),p.createElement(g,{value:s,onChange:c,onSubmit:T})),x?p.createElement(u,{color:`gray`},`running…`):null,y?p.createElement(i,{title:`Error`,state:`err`},p.createElement(u,{color:`red`},y)):null,_?p.createElement(i,{title:`${_.row_count} rows · ${_.duration_ms}ms${_.truncated?` · truncated`:``}`,state:`ok`},_.row_count===0?p.createElement(u,{color:`gray`},`— empty —`):p.createElement(o,{data:_.rows.slice(0,50),columns:E})):null)}async function v(i){let a=await e(),o=await t({strict:!1}),l=new c({config:a,cliVersion:i.cliVersion,token:o}),u;try{({siteId:u}=await s(l,{explicit:i.siteId,headless:!!(i.json||i.csv||i.tsv||i.ndjson),cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let d=i.maxRows??1e3,f=r(i);if(i.sql)try{let e=await l.runSqlQuery(u,i.sql,{maxRows:d});if(f===`json`)process.stdout.write(JSON.stringify(e,null,2)),process.stdout.write(`
2
- `);else if(f===`ndjson`)for(let t of e.rows)process.stdout.write(JSON.stringify(t)+`
3
- `);else if(f===`csv`||f===`tsv`)process.stdout.write(n(e.rows,e.columns,f));else{let t=e.columns.map(t=>Math.max(t.length,...e.rows.map(e=>String(e[t]??``).length))),n=`+`+t.map(e=>`-`.repeat(e+2)).join(`+`)+`+`;process.stdout.write(n+`
4
- `),process.stdout.write(`|`+e.columns.map((e,n)=>` ${e.padEnd(t[n]??0)} `).join(`|`)+`|
5
- `),process.stdout.write(n+`
6
- `);for(let n of e.rows.slice(0,200))process.stdout.write(`|`+e.columns.map((e,r)=>` ${String(n[e]??``).padEnd(t[r]??0)} `).join(`|`)+`|
7
- `);process.stdout.write(n+`
8
- `),process.stdout.write(`${e.row_count} rows · ${e.duration_ms}ms${e.truncated?` · truncated`:``}\n`)}return 0}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}let{render:m}=await import(`ink`);return await m(p.createElement(_,{api:l,siteId:u,maxRows:d})).waitUntilExit(),0}export{v as queryCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import{spark as i}from"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as a}from"./analytical-screen-DI8ahq4z.js";import"./ui-BtZp4Eh8.js";import{resolveSiteId as o}from"./resolve-site-D4W9yMVw.js";import{ApiV2Client as s}from"./api-v2-BwYWSe9Y.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e,t){let n=e/100,r=new Intl.NumberFormat(`en-US`,{minimumFractionDigits:0,maximumFractionDigits:0}).format(n),i=(t||`USD`).toUpperCase();return i===`USD`?`$${r}`:i===`EUR`?`€${r}`:i===`GBP`?`£${r}`:`${r} ${i}`}async function f(f){let p=await e(),m=await t({strict:!1}),h=new s({config:p,cliVersion:f.cliVersion,token:m}),g;try{({siteId:g}=await o(h,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let _=r(f),v=f.range??`30d`;return a({cliVersion:f.cliVersion,title:`revenue · ${g} · ${v}`,commandName:`revenue`,authToken:m?.accessToken??null,refreshIntervalMs:f.watch?5*6e4:0,fetcher:e=>h.getRevenue(g,v,e),format:_,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
- `);return}process.stdout.write(n(e.series,[`bucket`,`amount`,`currency`,`transactions`],t))},panels:[{id:`totals`,title:`Top line`,render:e=>u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{color:`green`,bold:!0},d(e.totalAmount,e.currency)),` `,u.createElement(l,{color:`gray`},`total · `,e.totalTransactions,` transactions`)),typeof e.mrr==`number`?u.createElement(l,null,u.createElement(l,{bold:!0},`MRR `),u.createElement(l,{color:`magenta`},d(e.mrr,e.currency)),typeof e.arpu==`number`?u.createElement(l,{color:`gray`},` · ARPU `,d(e.arpu,e.currency)):null):null)},{id:`series`,title:`Daily (${v})`,render:e=>{let t=e.series.map(e=>e.amount);if(t.length===0)return u.createElement(l,{color:`gray`},`— no transactions —`);let n=Math.max(...t,1);return u.createElement(c,{flexDirection:`column`},u.createElement(l,{color:`magenta`},i(t,Math.min(60,t.length*2))),u.createElement(l,{color:`gray`},`peak: `,d(n,e.currency),` ·`,` `,`avg: `,d(e.totalAmount/Math.max(1,t.length),e.currency)))}},{id:`window`,title:`Window`,render:e=>u.createElement(l,{color:`gray`},new Date(e.windowStart).toISOString().slice(0,10),` →`,` `,new Date(e.windowEnd).toISOString().slice(0,10))}]})}export{f as revenueCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{resolveSiteId as o}from"./resolve-site-D4W9yMVw.js";import{ApiV2Client as s}from"./api-v2-BwYWSe9Y.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e,t){let n=Math.round(e/100*t);return`█`.repeat(n)+`░`.repeat(Math.max(0,t-n))}function f(e){return e==null?{glyph:`·`,color:`gray`}:e>.5?{glyph:`▲`,color:`green`}:e<-.5?{glyph:`▼`,color:`red`}:{glyph:`→`,color:`gray`}}async function p(p){let m=await e(),h=await t({strict:!1}),g=new s({config:m,cliVersion:p.cliVersion,token:h}),_;try{({siteId:_}=await o(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let v=r(p),y=p.period??`30d`,b=[{key:`source`,header:`source`,width:22},{key:`channel`,header:`channel`,width:10,format:e=>String(e??`—`)},{key:`visitors`,header:`visitors`,width:8,align:`right`},{key:`delta`,header:`Δ`,width:6,align:`right`,format:e=>typeof e==`number`?`${e>0?`+`:``}${(e*100).toFixed(1)}%`:`—`}];return i({cliVersion:p.cliVersion,title:`sources · ${_} · ${y}`,commandName:`sources`,authToken:h?.accessToken??null,refreshIntervalMs:6e4,fetcher:e=>g.getSources(_,y,p.compare,e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
- `);return}process.stdout.write(n(e.sources,[`source`,`channel`,`visitors`,`conversions`,`revenue`,`delta`],t))},panels:[{id:`summary`,title:`Total`,render:e=>u.createElement(l,null,u.createElement(l,{bold:!0},e.totalVisitors.toLocaleString()),` `,u.createElement(l,{color:`gray`},`visitors · `,e.sources.length,` sources`))},{id:`channels`,title:`By channel`,render:e=>{if(e.sources.length===0)return u.createElement(l,{color:`gray`},`— no source data —`);let t=e.totalVisitors||1,n=[...e.sources].sort((e,t)=>t.visitors-e.visitors).slice(0,12);return u.createElement(c,{flexDirection:`column`},n.map((e,n)=>{let r=e.visitors/t*100,i=f(e.delta);return u.createElement(c,{key:`${e.source}-${n}`},u.createElement(l,null,u.createElement(l,{color:`cyan`},e.source.padEnd(20).slice(0,20)),` `,u.createElement(l,{color:`magenta`},d(r,30)),` `,u.createElement(l,null,e.visitors.toString().padStart(6),` `),u.createElement(l,{color:`gray`},`(`,r.toFixed(1),`%)`),` `,u.createElement(l,{color:i.color},i.glyph)))}))}},{id:`table`,title:`Detail`,render:e=>e.sources.length===0?u.createElement(l,{color:`gray`},`— —`):u.createElement(a,{data:e.sources.slice(0,20),columns:b})}]})}export{p as sourcesCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{resolveSiteId as o}from"./resolve-site-D4W9yMVw.js";import{ApiV2Client as s}from"./api-v2-BwYWSe9Y.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){return`${(e*100).toFixed(1)}%`}function f(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.floor(e/60)}m ${Math.round(e%60)}s`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new s({config:m,cliVersion:p.cliVersion,token:h}),_;try{({siteId:_}=await o(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let v=r(p),y=p.range??`24h`,b=[{key:`url`,header:`page`,width:40,format:e=>String(e??`—`)},{key:`views`,header:`views`,width:8,align:`right`}],x=[{key:`country`,header:`country`,width:8},{key:`visitors`,header:`visitors`,width:8,align:`right`}];return i({cliVersion:p.cliVersion,title:`stats · ${_} · ${y}`,commandName:`stats`,authToken:h?.accessToken??null,refreshIntervalMs:p.watch?6e4:0,fetcher:e=>g.getStats(_,y,e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
- `);return}process.stdout.write(n([{range:y,visitors:e.visitors,pageviews:e.pageviews,sessions:e.sessions,bounceRate:d(e.bounceRate),avgSession:f(e.avgSessionSec)}],[`range`,`visitors`,`pageviews`,`sessions`,`bounceRate`,`avgSession`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.visitors.toLocaleString()),u.createElement(l,{color:`gray`},` visitors `),u.createElement(l,{bold:!0},e.pageviews.toLocaleString()),u.createElement(l,{color:`gray`},` pageviews `),u.createElement(l,{bold:!0},e.sessions.toLocaleString()),u.createElement(l,{color:`gray`},` sessions`)),u.createElement(l,{color:`gray`},`bounce `,d(e.bounceRate),` · avg session `,f(e.avgSessionSec)))},{id:`pages`,title:`Top pages`,render:e=>e.topPages.length===0?u.createElement(l,{color:`gray`},`— no pages —`):u.createElement(a,{data:e.topPages.slice(0,10),columns:b})},{id:`countries`,title:`Top countries`,render:e=>e.topCountries.length===0?u.createElement(l,{color:`gray`},`— no country data —`):u.createElement(a,{data:e.topCountries.slice(0,10),columns:x})}]})}export{p as statsCommand};
@@ -1,2 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{formatTabular as n,selectFormat as r}from"./formatter-BNYzdX5c.js";import"./panel-DZqvtaao.js";import"./prompt-DEng-me1.js";import"./keybar-DUC7w1HQ.js";import"./sparkline-B6ueqPAB.js";import{runAnalyticalScreen as i}from"./analytical-screen-DI8ahq4z.js";import{Table as a}from"./ui-BtZp4Eh8.js";import{resolveSiteId as o}from"./resolve-site-D4W9yMVw.js";import{ApiV2Client as s}from"./api-v2-BwYWSe9Y.js";import{Box as c,Text as l}from"ink";import u from"react";const d={lcp:{good:2500,poor:4e3},inp:{good:200,poor:500},cls:{good:.1,poor:.25},ttfb:{good:800,poor:1800},fcp:{good:1800,poor:3e3}};function f(e,t){let n=d[e];return t<=n.good?{label:`good`,color:`green`}:t<=n.poor?{label:`needs`,color:`yellow`}:{label:`poor`,color:`red`}}function p(e,t){return e===`cls`?t.toFixed(3):t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`}async function m(d){let m=await e(),h=await t({strict:!1}),g=new s({config:m,cliVersion:d.cliVersion,token:h}),_;try{({siteId:_}=await o(g,{explicit:d.siteId,headless:!!(d.json||d.csv||d.tsv||d.ndjson),cliVersion:d.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let v=r(d),y=[{key:`url`,header:`url`,width:32},{key:`device`,header:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,header:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`lcp`,e.p75):`—`},{key:`inp`,header:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`inp`,e.p75):`—`},{key:`cls`,header:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`cls`,e.p75):`—`},{key:`samples`,header:`n`,width:6,align:`right`}];return i({cliVersion:d.cliVersion,title:`vitals · ${_}`,commandName:`vitals`,authToken:h?.accessToken??null,refreshIntervalMs:d.watch?5*6e4:0,fetcher:e=>g.getVitals(_,{url:d.url,device:d.device,window:d.window},e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
- `);return}process.stdout.write(n(e.vitals,[`url`,`device`,`samples`],t))},panels:[{id:`summary`,title:`Site-wide p75`,render:e=>{let t=t=>{let n=0,r=0;for(let i of e.vitals){let e=i[t]?.p75;typeof e==`number`&&(n+=e*i.samples,r+=i.samples)}return r>0?n/r:0},n=[`lcp`,`inp`,`cls`,`ttfb`,`fcp`];return u.createElement(c,{flexDirection:`column`},n.map(e=>{let n=t(e),r=f(e,n);return u.createElement(l,{key:e},u.createElement(l,{color:r.color},`● `),u.createElement(l,{bold:!0},e.toUpperCase().padEnd(5)),` `,u.createElement(l,null,p(e,n).padStart(8)),` `,u.createElement(l,{color:r.color},r.label))}))}},{id:`pages`,title:`Per-page`,render:e=>e.vitals.length===0?u.createElement(l,{color:`gray`},`— no vitals data yet —`):u.createElement(a,{data:e.vitals.slice(0,15),columns:y})}]})}export{m as vitalsCommand};
@@ -1 +0,0 @@
1
- import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{parseSseStream as n}from"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import{emit as r,isHeadless as i}from"./emit-BmfLGjqr.js";import{Panel as a,useTheme as o}from"./panel-DZqvtaao.js";import{Banner as s}from"./prompt-DEng-me1.js";import{Keybar as c}from"./keybar-DUC7w1HQ.js";import{spark as l}from"./sparkline-B6ueqPAB.js";import{resolveSiteId as u}from"./resolve-site-D4W9yMVw.js";import{ApiV2Client as d}from"./api-v2-BwYWSe9Y.js";import{z as f}from"zod";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";import S from"ink-text-input";const C={"no-data":`○`,"tier-gated":`◆`,error:`✗`},w=`https://app.zenovay.com/billing`;function T({headline:e,hint:t,reason:n=`no-data`,cta:r,width:i}){let{theme:a}=o(),s=C[n],c=n===`error`?a.error:n===`tier-gated`?a.accent2:a.muted,l=r??(n===`tier-gated`?`Upgrade → ${w}`:void 0);return v.createElement(p,{flexDirection:`column`,alignItems:`center`,width:i},v.createElement(m,{color:c,bold:!0},s),v.createElement(m,{color:a.typography.title.color,bold:a.typography.title.bold},e),t?v.createElement(m,{color:a.dim},t):null,l?v.createElement(m,{color:a.accent},l):null)}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 i=k(r),a=A(t,n);M(a),N(a),P(a,e);let o=[];for(let e=0;e<n;e++){let n=``;for(let r=0;r<t;r++)n+=i?L(a,r,e):I(a,r,e);o.push(n)}return v.createElement(p,{flexDirection:`column`},o.map((e,t)=>v.createElement(m,{key:t,color:`magenta`},e)),v.createElement(m,{color:`gray`},e.length,` live · `,i?`ascii mode`:`braille mode`))}const z=f.object({siteId:f.string().optional(),window:f.string().optional(),totalVisitors:f.number().optional(),visitors:f.object({count:f.number().optional(),series:f.array(f.number()).optional()}).optional(),topPages:f.array(f.object({path:f.string(),views:f.number().optional(),count:f.number().optional()})).optional(),sources:f.array(f.object({source:f.string(),visitors:f.number()})).optional()}).passthrough();async function B(n){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new d({config:a,cliVersion:n.cliVersion,token:o}),c;try{({siteId:c}=await u(s,{explicit:n.siteId,headless:!!n.json,cliVersion:n.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(i(n)){let e=await s.getDashboardSnapshot(c);return r({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=h(v.createElement(V,{api:s,siteId:c,intervalMs:n.intervalMs??15e3,cliVersion:n.cliVersion,onExit:n=>{t(),e(n)}}))})}const V=({api:e,siteId:t,intervalMs:r,cliVersion:i,onExit:o})=>{let{exit:l}=g(),[u,d]=b(null),[f,h]=b(null),[S,C]=b(null),[w,E]=b([]),[D,O]=b(!0),[k,A]=b(null),[j,M]=b(1),[N,P]=b(!1),[F,I]=b(!1);_((e,t)=>{if(e===`q`){l(),o(0);return}if(e===`?`||e===`/`){I(e=>!e);return}if(e===`g`){P(e=>!e);return}if(t.tab){M(e=>{let n=t.shift?(e+4)%6+1:e%6+1;return n});return}(e===`1`||e===`2`||e===`3`||e===`4`||e===`5`||e===`6`)&&M(Number(e))});let[L,B]=b(!1);if(y(()=>{let n=!1,i=async()=>{try{let r=await e.getDashboardSnapshot(t);if(n)return;let i=z.safeParse(r);if(!i.success){B(!0),O(!1);return}B(!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};d(o),e.getVitals(t).then(e=>{n||h(e)},()=>{}),e.getGoals(t).then(e=>{n||C(e)},()=>{}),O(!1),A(null)}catch(e){n||A(e.message)}};i();let a=setInterval(i,r);return()=>{n=!0,clearInterval(a)}},[e,t,r]),y(()=>{let r=new AbortController;return(async()=>{try{let i=await e.openEventsStream(t,r.signal);for await(let e of n(i))e.type===`error`&&E(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>r.abort()},[e,t]),D)return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:i,subtitle:`watch · ${t}`}),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 snapshot…`))));if(k&&!u)return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:i,subtitle:`watch · ${t}`}),v.createElement(a,{title:`Error`,state:`err`},v.createElement(m,{color:`red`},k)));if(L&&!u)return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:i,subtitle:`watch · ${t}`}),v.createElement(T,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let V=process.stdout.columns??80,Y=Math.max(20,Math.floor(V/3)-1),X=[];return v.createElement(p,{flexDirection:`column`},v.createElement(s,{version:i,subtitle:`watch · ${t}${N?` · globe`:``}`}),v.createElement(p,{flexDirection:`row`},v.createElement(p,{flexDirection:`column`},N?v.createElement(a,{title:`Live globe`,focused:j===1,width:Y},v.createElement(R,{data:X,width:Math.max(40,Y-4),height:12})):v.createElement(U,{snapshot:u,focused:j===1,width:Y}),v.createElement(K,{events:w,focused:j===4,width:Y})),v.createElement(p,{flexDirection:`column`},v.createElement(W,{snapshot:u,focused:j===2,width:Y}),v.createElement(q,{vitals:f,focused:j===5,width:Y})),v.createElement(p,{flexDirection:`column`},v.createElement(G,{snapshot:u,focused:j===3,width:Y}),v.createElement(J,{goals:S,focused:j===6,width:Y}))),F?v.createElement(H,{api:e,siteId:t,width:V-2}):null,v.createElement(c,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:N?`panels`:`globe`},{key:`?/`,label:F?`close chat`:`ai chat`},{key:`q`,label:`quit`}]}))},H=({api:e,siteId:t,width:r})=>{let[i,o]=b(``),[s,c]=b([]),[l,u]=b(!1),[d,f]=b(``),[h,g]=b(null),_=async r=>{let i=r.trim();if(!i||l)return;g(null),o(``);let a=[...s,{role:`user`,content:i}];c(a),u(!0),f(``);try{let r=a.map(e=>({role:e.role,content:e.content})),i=await e.openAiStream(`chat`,{messages:r,siteId:t},void 0),o=``;for await(let e of n(i))if(e.type===`delta`)o+=e.content,f(o);else if(e.type===`error`)g(`${e.code}: ${e.message}`);else if(e.type===`done`)break;c([...a,{role:`assistant`,content:o}]),f(``)}catch(e){g(e instanceof Error?e.message:`chat failed`)}finally{u(!1)}};return v.createElement(p,{marginTop:1},v.createElement(a,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:r},v.createElement(p,{flexDirection:`column`},s.slice(-6).map((e,t)=>v.createElement(p,{key:t,flexDirection:`column`,marginBottom:1},v.createElement(m,{color:e.role===`user`?`cyan`:`magenta`,bold:!0},e.role===`user`?`you`:`zenovay`),v.createElement(m,null,e.content))),l&&d?v.createElement(p,{flexDirection:`column`,marginBottom:1},v.createElement(m,{color:`magenta`,bold:!0},`zenovay`),v.createElement(m,null,d)):null,h?v.createElement(m,{color:`red`},`✗ `,h):null,v.createElement(p,null,v.createElement(m,{color:`cyan`},l?`⠋ `:`▸ `),v.createElement(S,{value:i,onChange:o,onSubmit:_,placeholder:l?`streaming…`:`ask anything about your analytics`})))))},U=({snapshot:e,focused:t,width:n})=>{let r=e?.visitors?.count??0,i=e?.visitors?.series??[];return v.createElement(a,{title:`Visitors`,focused:t,width:n},v.createElement(m,{bold:!0},r.toString()),v.createElement(m,{color:`gray`},i.length>0?l(i,Math.max(8,n-6)):`— no data —`))},W=({snapshot:e,focused:t,width:n})=>{let r=e?.topPages?.slice(0,5)??[];return v.createElement(a,{title:`Top pages`,focused:t,width:n},r.length===0?v.createElement(m,{color:`gray`},`— no data —`):r.map(e=>v.createElement(p,{key:e.path},v.createElement(m,null,e.path.padEnd(n-10).slice(0,n-10)),v.createElement(m,{color:`gray`},` `,e.views))))},G=({snapshot:e,focused:t,width:n})=>{let r=e?.sources?.slice(0,5)??[];return v.createElement(a,{title:`Sources`,focused:t,width:n},r.length===0?v.createElement(m,{color:`gray`},`— no data —`):r.map(e=>v.createElement(p,{key:e.source},v.createElement(m,null,e.source.padEnd(n-10).slice(0,n-10)),v.createElement(m,{color:`gray`},` `,e.visitors))))},K=({events:e,focused:t,width:n})=>v.createElement(a,{title:`Events`,focused:t,width:n},e.length===0?v.createElement(m,{color:`gray`},`— waiting —`):e.slice(-10).map((e,t)=>v.createElement(m,{key:t},e.slice(0,n-4)))),q=({vitals:e,focused:t,width:n})=>{let r=(e,t,n)=>v.createElement(p,{key:e},v.createElement(m,{bold:!0},e.padEnd(6)),v.createElement(m,{color:`gray`},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return v.createElement(a,{title:`Vitals`,focused:t,width:n},r(`LCP`,e?.lcpP75,`ms`),r(`INP`,e?.inpP75,`ms`),r(`CLS`,e?.clsP75?e.clsP75*1e3:void 0,`/1k`),r(`TTFB`,e?.ttfbP75,`ms`),r(`FCP`,e?.fcpP75,`ms`))},J=({goals:e,focused:t,width:n})=>{let r=e?.goals?.slice(0,5)??[];return v.createElement(a,{title:`Goals`,focused:t,width:n},r.length===0?v.createElement(m,{color:`gray`},`— no data —`):r.map(e=>v.createElement(p,{key:e.name},v.createElement(m,null,e.name.padEnd(n-10).slice(0,n-10)),v.createElement(m,{color:`gray`},` `,e.completions))))};export{B as watchCommand};
File without changes
File without changes
File without changes
File without changes