@zenovay/cli 0.1.22 → 0.1.23

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 (101) hide show
  1. package/dist/agency-DUn-NIh0.js +11 -0
  2. package/dist/ai-RDEA2Hix.js +11 -0
  3. package/dist/{analytical-screen-DlNffR1j.js → analytical-screen-CwNWqdBR.js} +1 -1
  4. package/dist/analytics-DPokINId.js +1 -0
  5. package/dist/api-keys-DYwn4seK.js +10 -0
  6. package/dist/{api-v2-C7yrqNuV.js → api-v2-29EI1kBw.js} +1 -1
  7. package/dist/banner-BPQh2F8l.js +1 -0
  8. package/dist/bin.js +2 -2
  9. package/dist/companies-DgvAQeGq.js +2 -0
  10. package/dist/confirm-D_aKHknn.js +1 -0
  11. package/dist/{data-table-EsLUu8Hj.js → data-table-BVWqHy9m.js} +1 -1
  12. package/dist/deploys-CmCOWD6n.js +2 -0
  13. package/dist/devices-BE6QsOTr.js +1 -0
  14. package/dist/{doctor-C42TUuU1.js → doctor-DNV0LKB8.js} +1 -1
  15. package/dist/domains-DPxNGnlv.js +4 -0
  16. package/dist/{emit-BmfLGjqr.js → emit-D7VCOSNk.js} +1 -1
  17. package/dist/{empty-state-ETu78blH.js → empty-state-Dkho-_3J.js} +1 -1
  18. package/dist/errors-haaFzHX9.js +2 -0
  19. package/dist/{events-tail-Cytm6gdG.js → events-tail-DqabG_EK.js} +1 -1
  20. package/dist/funnel-uQBdZOJf.js +3 -0
  21. package/dist/geo-gAdKkjwd.js +1 -0
  22. package/dist/goals-DWv7cwPy.js +10 -0
  23. package/dist/{health-T70yG5po.js → health-YzE2Y8gL.js} +1 -1
  24. package/dist/health-w7N0y9PU.js +1 -0
  25. package/dist/heatmaps-J4JTJKQ3.js +1 -0
  26. package/dist/home-DS-SjD-L.js +2 -0
  27. package/dist/init-CM26WHgM.js +1 -0
  28. package/dist/{init-3WrfX1Fb.js → init-zU2l6vEv.js} +3 -3
  29. package/dist/insights-BGsYRVJh.js +1 -0
  30. package/dist/integrations-Bzl-4ZId.js +10 -0
  31. package/dist/journeys-kCDrWMj9.js +1 -0
  32. package/dist/{keybar-DO-sCbJB.js → keybar-C7YkmK1U.js} +1 -1
  33. package/dist/live-CNqH0IZ1.js +1 -0
  34. package/dist/login-Bo0VXzkT.js +1 -0
  35. package/dist/{login-DvMRHd3J.js → login-DWaz_EsV.js} +1 -1
  36. package/dist/{logout-B3V_2DRZ.js → logout-CR_HnofH.js} +1 -1
  37. package/dist/{metric-card-CtAoTOEP.js → metric-card-BfVg5VG6.js} +1 -1
  38. package/dist/notes-BP6Q4aav.js +10 -0
  39. package/dist/pages-C9eqXUO5.js +1 -0
  40. package/dist/plans-CaERwneA.js +7 -0
  41. package/dist/profile-DcloxRkt.js +4 -0
  42. package/dist/{progress-row-CeP9YRKn.js → progress-row-DFOvHAc5.js} +1 -1
  43. package/dist/projects-B2F-G3d3.js +1 -0
  44. package/dist/projects-CuRkKGbH.js +2 -0
  45. package/dist/prompt-BURfUNxp.js +1 -0
  46. package/dist/query-BUqZA3Gs.js +8 -0
  47. package/dist/{resolve-site-CKq90Xzu.js → resolve-site-D3e1i32Z.js} +1 -1
  48. package/dist/retention-D_QE69ky.js +1 -0
  49. package/dist/revenue-BT04dgtk.js +2 -0
  50. package/dist/sessions-HZH2gRZC.js +1 -0
  51. package/dist/settings-DauPM9xL.js +4 -0
  52. package/dist/sources-Bk2X2lSX.js +2 -0
  53. package/dist/stats-DIDWYBrs.js +2 -0
  54. package/dist/team-Cxe_JdvF.js +15 -0
  55. package/dist/themes-D3hAhR-s.js +4 -0
  56. package/dist/{ui-BLnL2HSo.js → ui-UH1mTEzT.js} +1 -1
  57. package/dist/{update-wMGBdUT-.js → update-gcfMIvHa.js} +1 -1
  58. package/dist/uptime-DvvS-pwV.js +1 -0
  59. package/dist/{use-DsHE5Eu7.js → use-C7b94Jib.js} +1 -1
  60. package/dist/visitors-BobD1lev.js +2 -0
  61. package/dist/vitals-y5wPRUrQ.js +2 -0
  62. package/dist/watch-Ba-aMHLj.js +1 -0
  63. package/dist/webhooks-forward-DAap5ujj.js +3 -0
  64. package/dist/wizard-bin.js +1 -1
  65. package/package.json +1 -1
  66. package/dist/ai-DGIoZ2aO.js +0 -11
  67. package/dist/companies-D30bvUbA.js +0 -2
  68. package/dist/deploys-CMVAZp4i.js +0 -2
  69. package/dist/devices-yq4dh7UD.js +0 -1
  70. package/dist/errors-BlVWrZ86.js +0 -2
  71. package/dist/funnel-B7yQXVJa.js +0 -3
  72. package/dist/geo-BqtzfNwp.js +0 -1
  73. package/dist/health-DOOluwxM.js +0 -1
  74. package/dist/heatmaps-DtbYa2K3.js +0 -1
  75. package/dist/init-4dY3jNh8.js +0 -1
  76. package/dist/insights-C0xGkTYG.js +0 -1
  77. package/dist/journeys-Bx08wXVO.js +0 -1
  78. package/dist/live-BGdMxOZ_.js +0 -1
  79. package/dist/login-Bb_At1Ov.js +0 -1
  80. package/dist/overview-BieuspgD.js +0 -1
  81. package/dist/pages-DXpXKnCy.js +0 -1
  82. package/dist/projects-DKQeDin5.js +0 -2
  83. package/dist/prompt-CIl9JOlh.js +0 -1
  84. package/dist/query-B88NMsPY.js +0 -8
  85. package/dist/retention-C75M6nUk.js +0 -1
  86. package/dist/revenue-Dsy6ODmG.js +0 -2
  87. package/dist/sessions-FXL5fAGa.js +0 -1
  88. package/dist/sources-DkEkhs1V.js +0 -2
  89. package/dist/stats-B4iRNAEW.js +0 -2
  90. package/dist/themes-DxPebZga.js +0 -4
  91. package/dist/uptime-DMK_yhMW.js +0 -1
  92. package/dist/vitals-pqv_u431.js +0 -2
  93. package/dist/watch-CbehE_bK.js +0 -1
  94. package/dist/webhooks-forward-C7gK3C6A.js +0 -3
  95. /package/dist/{client-vixcHdv-.js → client-WzSy90dG.js} +0 -0
  96. /package/dist/{completions-CnHbpLqp.js → completions-BbEmXZy8.js} +0 -0
  97. /package/dist/{formatter-BNYzdX5c.js → formatter-mW0Yk3Nt.js} +0 -0
  98. /package/dist/{globe-1bi4DjwJ.js → globe-BI6KG0jM.js} +0 -0
  99. /package/dist/{panel-Crm-x-5U.js → panel-uygscwY5.js} +0 -0
  100. /package/dist/{sparkline-ut0Tvv-E.js → sparkline-Bkfzqe4x.js} +0 -0
  101. /package/dist/{tier-DJvWU86k.js → tier-RjOGNzda.js} +0 -0
@@ -0,0 +1,11 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import{requireTier as r}from"./tier-RjOGNzda.js";import{confirmDestructive as i}from"./confirm-D_aKHknn.js";function a(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}function o(e){return e?new Date(e).toISOString().slice(0,10):`—`}async function s(s){let c=await e(),l=await t({strict:!1}),u=new n({config:c,cliVersion:s.cliVersion,token:l});try{await r(u,`scale`)}catch(e){return process.stderr.write(`✗ ${e.message}\n`),2}try{switch(s.action){case`clients-list`:{let{clients:e}=await u.listAgencyClients();if(s.json)return process.stdout.write(JSON.stringify({clients:e},null,2)+`
2
+ `),0;if(e.length===0)return process.stdout.write("No clients yet. Add one with `zenovay agency clients add --name <n> --email <e>`.\n"),0;let t=[14,30,30,12],n=e=>e.map((e,n)=>(e??``).padEnd(t[n])).join(` `);process.stdout.write(`
3
+ `+n([`id`,`name`,`domain`,`created`])+`
4
+ `),process.stdout.write(n(t.map(e=>`─`.repeat(e)))+`
5
+ `);for(let r of e)process.stdout.write(n([a(r.id),(r.name??`—`).slice(0,t[1]),(r.domain??`—`).slice(0,t[2]),o(r.createdAt)])+`
6
+ `);return process.stdout.write(`
7
+ `),0}case`clients-add`:{if(!s.name)return process.stderr.write("Error: --name <n> is required for `agency clients add`.\n"),2;let e=await u.addAgencyClient({name:s.name,email:s.email});return s.json?(process.stdout.write(JSON.stringify(e,null,2)+`
8
+ `),0):(process.stdout.write(`✔ Client added: ${e.name} (id ${e.id}${e.email?`, ${e.email}`:``}).\n`),0)}case`clients-remove`:{if(!s.id)return process.stderr.write("Error: client id is required for `agency clients remove`.\n"),2;let e=await i({resource:`agency client`,name:a(s.id),yes:s.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
9
+ `),1;let t=await u.removeAgencyClient(s.id);return s.json?(process.stdout.write(JSON.stringify(t)+`
10
+ `),0):(process.stdout.write(`✔ Removed agency client ${a(s.id)}.\n`),0)}case`report-send`:{if(!s.id)return process.stderr.write("Error: client id is required for `agency report send <client-id>`.\n"),2;let e=await u.sendAgencyReport(s.id);return s.json?(process.stdout.write(JSON.stringify(e,null,2)+`
11
+ `),0):(process.stdout.write(`✔ Report sent to ${e.recipient}.\n`),0)}}}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}}export{s as agencyCommand};
@@ -0,0 +1,11 @@
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-zU2l6vEv.js";import{parseSseStream as a}from"./client-WzSy90dG.js";import"./formatter-mW0Yk3Nt.js";import{emit as o,isHeadless as s}from"./emit-D7VCOSNk.js";import"./login-DWaz_EsV.js";import{Panel as c}from"./panel-uygscwY5.js";import"./banner-BPQh2F8l.js";import"./progress-row-DFOvHAc5.js";import{Select as l}from"./prompt-BURfUNxp.js";import"./keybar-C7YkmK1U.js";import"./sparkline-Bkfzqe4x.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
+ Zenovay · chat mode — type your question then press Enter. Ctrl-C to exit.
3
+
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(`
5
+ `);break}if(e.type===`error`)return process.stderr.write(`\n[${e.code}] ${e.message}\n`),1}return 0}async function _(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(`
6
+ Zenovay · MCP mode — describe what you want to create or change. Ctrl-C to exit.
7
+
8
+ > `);let c=await v();if(!c)return 0;let l=await s.openAiStream(`mcp`,{messages:[{role:`user`,content:c}]});for await(let e of a(l)){if(e.type===`delta`&&process.stdout.write(e.content),e.type===`tool_start`&&process.stdout.write(`\n[tool: ${e.name}] `),e.type===`tool_result`&&process.stdout.write(`
9
+ [result]`),e.type===`done`){process.stdout.write(`
10
+ `);break}if(e.type===`error`)return process.stderr.write(`\n[${e.code}] ${e.message}\n`),1}return 0}function v(){return new Promise(e=>{let t=``,n=r=>{let i=r.toString(`utf8`);i.includes(`
11
+ `)||i.includes(`\r`)?(t+=i.replace(/[\r\n]/g,``),process.stdin.off(`data`,n),process.stdin.pause(),e(t)):t+=i};process.stdin.resume(),process.stdin.on(`data`,n)})}export{m as aiCommand};
@@ -1 +1 @@
1
- import{ApiError as e}from"./api-DXmhz2DM.js";import{formatEvent as t}from"./formatter-BNYzdX5c.js";import{Panel as n}from"./panel-Crm-x-5U.js";import{Banner as r}from"./prompt-CIl9JOlh.js";import{Keybar as i}from"./keybar-DO-sCbJB.js";import{Box as a,Text as o,render as s,useApp as c,useInput as l}from"ink";import u,{useEffect as d,useMemo as f,useReducer as p,useRef as m}from"react";import h from"ink-spinner";function g(e,t){switch(t.type){case`set`:return{...e,data:t.data,status:`ready`,error:null};case`merge`:{let n=e.data?{...e.data,...t.partial}:t.partial;return{...e,data:n,status:`ready`,error:null}}case`error`:return{...e,status:`error`,error:{message:t.message,status:t.status,upgradeUrl:t.upgradeUrl}};case`refresh`:return{...e,refreshTick:e.refreshTick+1};case`focus`:return{...e,focusIndex:t.index};case`help-toggle`:return{...e,showHelp:!e.showHelp};default:return e}}async function _(e,n){let r=new AbortController,i=()=>r.abort();process.on(`SIGINT`,i);try{let i=await e.fetcher(r.signal);if(e.headlessEmit?e.headlessEmit(i,n):process.stdout.write(t(i,n)),e.streamer)for await(let i of e.streamer(r.signal))process.stdout.write(t(i,n));return 0}catch(e){if(e.name===`AbortError`)return 0;let t=e.message;return process.stderr.write(`${t}\n`),1}finally{process.off(`SIGINT`,i)}}const v=({cliVersion:e})=>u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:e,subtitle:`login required`}),u.createElement(n,{title:`Not logged in`,state:`warn`},u.createElement(o,null,`You need to authenticate before running this command.`),u.createElement(o,null,` `),u.createElement(o,{color:`gray`},`Run `),u.createElement(o,{color:`cyan`},`zenovay login`),u.createElement(o,{color:`gray`},` to start the device-flow.`)));function y(t){let{exit:s}=c(),[_,v]=p(g,{data:null,status:`loading`,error:null,refreshTick:0,focusIndex:0,showHelp:!1}),y=m(v);y.current=v;let b=f(()=>({q:{label:`quit`,handler:()=>{s(),t.onExit(0)}},r:{label:`refresh`,handler:()=>y.current({type:`refresh`})},"?":{label:`help`,handler:()=>y.current({type:`help-toggle`})}}),[s,t]),x=f(()=>({...t.keybindings??{},...b}),[t.keybindings,b]);if(l((e,n)=>{if(n.tab&&n.shift){v({type:`focus`,index:(_.focusIndex-1+t.panels.length)%t.panels.length});return}if(n.tab){v({type:`focus`,index:(_.focusIndex+1)%t.panels.length});return}if(e>=`1`&&e<=`9`){let n=Number(e)-1;n<t.panels.length&&v({type:`focus`,index:n});return}let r=x[e];r&&r.handler()}),d(()=>{let n=new AbortController,r=!1,i=async()=>{try{let e=await t.fetcher(n.signal);r||y.current({type:`set`,data:e})}catch(t){if(r)return;if(t instanceof e){if(t.status===402){let e=t.body,n=typeof e==`object`&&e&&`upgradeUrl`in e?e.upgradeUrl:void 0;y.current({type:`error`,message:`This command requires a higher plan.`,status:402,upgradeUrl:n});return}y.current({type:`error`,message:t.message,status:t.status});return}if(t.name===`AbortError`)return;y.current({type:`error`,message:t.message})}};i();let a=null,o=t.refreshIntervalMs??15e3;return o>0&&!t.streamer&&(a=setInterval(i,o)),()=>{r=!0,n.abort(),a&&clearInterval(a)}},[t.fetcher,t.refreshIntervalMs,t.streamer,_.refreshTick]),d(()=>{if(!t.streamer)return;let e=new AbortController,n=!1;return(async()=>{try{for await(let r of t.streamer(e.signal)){if(n)return;y.current({type:`merge`,partial:r})}}catch(e){if(n||e.name===`AbortError`)return;y.current({type:`error`,message:e.message})}})(),()=>{n=!0,e.abort()}},[t.streamer]),_.status===`loading`&&_.data===null)return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(n,{title:`Loading`,state:`busy`},u.createElement(a,null,u.createElement(o,{color:`magenta`},u.createElement(h,{type:`dots`})),u.createElement(o,null,` Fetching `,t.commandName,`…`))),u.createElement(i,{items:[{key:`q`,label:`quit`}]}));if(_.status===`error`&&_.error){let e=_.error.status===402;return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(n,{title:e?`Upgrade required`:`Error`,state:e?`warn`:`err`},u.createElement(o,{color:e?`yellow`:`red`},_.error.message),e&&_.error.upgradeUrl?u.createElement(u.Fragment,null,u.createElement(o,null,` `),u.createElement(o,{color:`gray`},`Upgrade: `),u.createElement(o,{color:`cyan`},_.error.upgradeUrl)):null),u.createElement(i,{items:[{key:`r`,label:`retry`},{key:`q`,label:`quit`}]}))}let S=_.data,C=Object.entries(x).map(([e,t])=>({key:e,label:t.label})),w=Math.ceil(t.panels.length/2),T=t.panels.slice(0,w),E=t.panels.slice(w);return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(a,{flexDirection:`row`},T.map((e,t)=>{let r=_.focusIndex===t;return u.createElement(a,{key:e.id,flexDirection:`column`,marginRight:1,flexGrow:1},u.createElement(n,{title:e.title,state:r?`busy`:`idle`},e.render(S,r)))})),E.length>0?u.createElement(a,{flexDirection:`row`},E.map((e,t)=>{let r=t+w,i=_.focusIndex===r;return u.createElement(a,{key:e.id,flexDirection:`column`,marginRight:1,flexGrow:1},u.createElement(n,{title:e.title,state:i?`busy`:`idle`},e.render(S,i)))})):null,_.showHelp?u.createElement(n,{title:`Help`,state:`idle`},Object.entries(x).map(([e,t])=>u.createElement(o,{key:e},`[`,e,`] `,t.label)),u.createElement(o,{color:`gray`},`[tab/shift+tab] cycle focus [1-9] focus panel`)):null,u.createElement(i,{items:C}))}async function b(e){return e.authToken===null?e.format?(process.stderr.write("Not logged in — run `zenovay login` first.\n"),2):new Promise(t=>{let{unmount:n}=s(u.createElement(v,{cliVersion:e.cliVersion}));setTimeout(()=>{n(),t(2)},50)}):e.format?_(e,e.format):new Promise(t=>{let{unmount:n}=s(u.createElement(y,{...e,onExit:e=>{n(),t(e)}}))})}export{b as runAnalyticalScreen};
1
+ import{ApiError as e}from"./api-DXmhz2DM.js";import{formatEvent as t}from"./formatter-mW0Yk3Nt.js";import{Panel as n}from"./panel-uygscwY5.js";import{Banner as r}from"./banner-BPQh2F8l.js";import{Keybar as i}from"./keybar-C7YkmK1U.js";import{Box as a,Text as o,render as s,useApp as c,useInput as l}from"ink";import u,{useEffect as d,useMemo as f,useReducer as p,useRef as m}from"react";import h from"ink-spinner";function g(e,t){switch(t.type){case`set`:return{...e,data:t.data,status:`ready`,error:null};case`merge`:{let n=e.data?{...e.data,...t.partial}:t.partial;return{...e,data:n,status:`ready`,error:null}}case`error`:return{...e,status:`error`,error:{message:t.message,status:t.status,upgradeUrl:t.upgradeUrl}};case`refresh`:return{...e,refreshTick:e.refreshTick+1};case`focus`:return{...e,focusIndex:t.index};case`help-toggle`:return{...e,showHelp:!e.showHelp};default:return e}}async function _(e,n){let r=new AbortController,i=()=>r.abort();process.on(`SIGINT`,i);try{let i=await e.fetcher(r.signal);if(e.headlessEmit?e.headlessEmit(i,n):process.stdout.write(t(i,n)),e.streamer)for await(let i of e.streamer(r.signal))process.stdout.write(t(i,n));return 0}catch(e){if(e.name===`AbortError`)return 0;let t=e.message;return process.stderr.write(`${t}\n`),1}finally{process.off(`SIGINT`,i)}}const v=({cliVersion:e})=>u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:e,subtitle:`login required`}),u.createElement(n,{title:`Not logged in`,state:`warn`},u.createElement(o,null,`You need to authenticate before running this command.`),u.createElement(o,null,` `),u.createElement(o,{color:`gray`},`Run `),u.createElement(o,{color:`cyan`},`zenovay login`),u.createElement(o,{color:`gray`},` to start the device-flow.`)));function y(t){let{exit:s}=c(),[_,v]=p(g,{data:null,status:`loading`,error:null,refreshTick:0,focusIndex:0,showHelp:!1}),y=m(v);y.current=v;let b=f(()=>({q:{label:`quit`,handler:()=>{s(),t.onExit(0)}},r:{label:`refresh`,handler:()=>y.current({type:`refresh`})},"?":{label:`help`,handler:()=>y.current({type:`help-toggle`})}}),[s,t]),x=f(()=>({...t.keybindings??{},...b}),[t.keybindings,b]);if(l((e,n)=>{if(n.tab&&n.shift){v({type:`focus`,index:(_.focusIndex-1+t.panels.length)%t.panels.length});return}if(n.tab){v({type:`focus`,index:(_.focusIndex+1)%t.panels.length});return}if(e>=`1`&&e<=`9`){let n=Number(e)-1;n<t.panels.length&&v({type:`focus`,index:n});return}let r=x[e];r&&r.handler()}),d(()=>{let n=new AbortController,r=!1,i=async()=>{try{let e=await t.fetcher(n.signal);r||y.current({type:`set`,data:e})}catch(t){if(r)return;if(t instanceof e){if(t.status===402){let e=t.body,n=typeof e==`object`&&e&&`upgradeUrl`in e?e.upgradeUrl:void 0;y.current({type:`error`,message:`This command requires a higher plan.`,status:402,upgradeUrl:n});return}y.current({type:`error`,message:t.message,status:t.status});return}if(t.name===`AbortError`)return;y.current({type:`error`,message:t.message})}};i();let a=null,o=t.refreshIntervalMs??15e3;return o>0&&!t.streamer&&(a=setInterval(i,o)),()=>{r=!0,n.abort(),a&&clearInterval(a)}},[t.fetcher,t.refreshIntervalMs,t.streamer,_.refreshTick]),d(()=>{if(!t.streamer)return;let e=new AbortController,n=!1;return(async()=>{try{for await(let r of t.streamer(e.signal)){if(n)return;y.current({type:`merge`,partial:r})}}catch(e){if(n||e.name===`AbortError`)return;y.current({type:`error`,message:e.message})}})(),()=>{n=!0,e.abort()}},[t.streamer]),_.status===`loading`&&_.data===null)return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(n,{title:`Loading`,state:`busy`},u.createElement(a,null,u.createElement(o,{color:`magenta`},u.createElement(h,{type:`dots`})),u.createElement(o,null,` Fetching `,t.commandName,`…`))),u.createElement(i,{items:[{key:`q`,label:`quit`}]}));if(_.status===`error`&&_.error){let e=_.error.status===402;return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(n,{title:e?`Upgrade required`:`Error`,state:e?`warn`:`err`},u.createElement(o,{color:e?`yellow`:`red`},_.error.message),e&&_.error.upgradeUrl?u.createElement(u.Fragment,null,u.createElement(o,null,` `),u.createElement(o,{color:`gray`},`Upgrade: `),u.createElement(o,{color:`cyan`},_.error.upgradeUrl)):null),u.createElement(i,{items:[{key:`r`,label:`retry`},{key:`q`,label:`quit`}]}))}let S=_.data,C=Object.entries(x).map(([e,t])=>({key:e,label:t.label})),w=Math.ceil(t.panels.length/2),T=t.panels.slice(0,w),E=t.panels.slice(w);return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(a,{flexDirection:`row`},T.map((e,t)=>{let r=_.focusIndex===t;return u.createElement(a,{key:e.id,flexDirection:`column`,marginRight:1,flexGrow:1},u.createElement(n,{title:e.title,state:r?`busy`:`idle`},e.render(S,r)))})),E.length>0?u.createElement(a,{flexDirection:`row`},E.map((e,t)=>{let r=t+w,i=_.focusIndex===r;return u.createElement(a,{key:e.id,flexDirection:`column`,marginRight:1,flexGrow:1},u.createElement(n,{title:e.title,state:i?`busy`:`idle`},e.render(S,i)))})):null,_.showHelp?u.createElement(n,{title:`Help`,state:`idle`},Object.entries(x).map(([e,t])=>u.createElement(o,{key:e},`[`,e,`] `,t.label)),u.createElement(o,{color:`gray`},`[tab/shift+tab] cycle focus [1-9] focus panel`)):null,u.createElement(i,{items:C}))}async function b(e){return e.authToken===null?e.format?(process.stderr.write("Not logged in — run `zenovay login` first.\n"),2):new Promise(t=>{let{unmount:n}=s(u.createElement(v,{cliVersion:e.cliVersion}));setTimeout(()=>{n(),t(2)},50)}):e.format?_(e,e.format):new Promise(t=>{let{unmount:n}=s(u.createElement(y,{...e,onExit:e=>{n(),t(e)}}))})}export{b as runAnalyticalScreen};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import"./formatter-mW0Yk3Nt.js";import{emit as r,isHeadless as i}from"./emit-D7VCOSNk.js";import{Panel as a}from"./panel-uygscwY5.js";import{Banner as o}from"./banner-BPQh2F8l.js";import"./prompt-BURfUNxp.js";import{Keybar as s}from"./keybar-C7YkmK1U.js";import"./sparkline-Bkfzqe4x.js";import{resolveSiteId as c}from"./resolve-site-D3e1i32Z.js";import{EmptyState as l}from"./empty-state-Dkho-_3J.js";import{MetricCard as u}from"./metric-card-BfVg5VG6.js";import{DataTable as d}from"./data-table-BVWqHy9m.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await S(l,u,`24h`);return r({type:`overview.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(C,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}async function S(e,t,n){let[r,i]=await Promise.all([e.getStats(t,n).catch(()=>null),e.getPages(t).catch(()=>[])]),a=i.reduce((e,t)=>e+t.views,0);return{visitors:r?.visitors??0,pageviews:r?.pageviews??a,bounceRate:r?.bounceRate??null,avgSession:r?.avgSessionSec??null,series:[],topPages:i.slice(0,10)}}const C=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=h(),[m,x]=y(null),[C,w]=y(!0),[T,E]=y(null),[D,O]=y(`24h`),[k,A]=y(t),[j,M]=y(n),[N,P]=y(!1),[F,I]=y([]);g(async t=>{if(t===`q`){c(),i(0);return}if(t===`1`){O(`24h`);return}if(t===`2`){O(`7d`);return}if(t===`3`){O(`30d`);return}if(t===`4`){O(`90d`);return}if(t===`s`){if(F.length===0)try{let t=await e.getSites();I(t)}catch{}P(e=>!e);return}}),v(()=>{let t=!1;return w(!0),(async()=>{try{let n=await S(e,k,D);t||(x(n),w(!1))}catch(e){t||(E(e.message),w(!1))}})(),()=>{t=!0}},[e,k,D]);let L=()=>_.createElement(a,{title:`Switch site`,state:`idle`},F.length===0?_.createElement(p,{color:`gray`},`Loading your sites…`):F.map(e=>_.createElement(f,{key:e.id},_.createElement(p,{color:e.id===k?`cyan`:`gray`},e.id===k?`› `:` `),_.createElement(p,{bold:e.id===k},e.name),_.createElement(p,{color:`gray`},` (`,e.url.replace(/^https?:\/\//,``).replace(/\/$/,``),`)`))),_.createElement(f,{marginTop:1},_.createElement(p,{color:`gray`},`Press `),_.createElement(p,{color:`cyan`},`[number]`),_.createElement(p,{color:`gray`},` to pick, `),_.createElement(p,{color:`cyan`},`[s]`),_.createElement(p,{color:`gray`},` to close.`)));g(e=>{if(!N)return;let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=F.length){let e=F[t-1];A(e.id),M(e.url.replace(/^https?:\/\//,``).replace(/\/$/,``)),P(!1)}},{isActive:N});let R=`overview · ${j} · ${D}`,z=[{key:`q`,label:`quit`},{key:`s`,label:`site`},{key:`1-4`,label:`range (24h/7d/30d/90d)`}];if(C)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:R}),_.createElement(a,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`cyan`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching dashboard…`))),N?L():null);if(T)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:R}),_.createElement(l,{reason:`error`,headline:`Failed to load`,hint:T}),N?L():null,_.createElement(s,{items:z}));if(!m||m.visitors===0&&m.pageviews===0&&m.topPages.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:R}),_.createElement(l,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event — or press [s] to switch to a different site, or [1-4] to widen the time range.`}),N?L():null,_.createElement(s,{items:z}));let B=process.stdout.columns??80,V=Math.max(18,Math.floor(B/4)-1),H=[{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(o,{version:r,subtitle:R}),_.createElement(f,{flexDirection:`row`},_.createElement(u,{title:`Visitors`,value:m.visitors,format:`number`,width:V}),_.createElement(u,{title:`Pageviews`,value:m.pageviews,format:`number`,width:V}),_.createElement(u,{title:`Bounce rate`,value:m.bounceRate??``,emptyHint:`—`,format:`percent`,width:V}),_.createElement(u,{title:`Avg session`,value:m.avgSession??``,emptyHint:`—`,format:`duration`,width:V})),_.createElement(a,{title:`Top pages (${D})`},m.topPages.length===0?_.createElement(p,{color:`gray`},`No pages with data in this window yet.`):_.createElement(d,{columns:H,data:m.topPages,zebra:!0})),N?L():null,_.createElement(s,{items:z}))};async function w(e){return x(e)}export{w as analyticsCommand};
@@ -0,0 +1,10 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import{confirmDestructive as r}from"./confirm-D_aKHknn.js";function i(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}function a(e){return e?new Date(e).toISOString().slice(0,10):`—`}async function o(o){let s=await e(),c=await t({strict:!1}),l=new n({config:s,cliVersion:o.cliVersion,token:c});try{switch(o.action){case`list`:{let{keys:e}=await l.listApiKeys();if(o.json)return process.stdout.write(JSON.stringify({keys:e},null,2)+`
2
+ `),0;if(e.length===0)return process.stdout.write("No API keys yet. Create one with `zenovay api-keys create --name <n>`.\n"),0;let t=[``,`id`,`name`,`scope`,`created`,`last used`],n=[1,14,24,6,10,19],r=e.map(e=>[e.isCurrent?`*`:` `,i(e.id),(e.name??``).slice(0,n[2]),e.scope,a(e.createdAt),e.lastUsedAt?new Date(e.lastUsedAt).toISOString().slice(0,19).replace(`T`,` `):`—`]),s=e=>e.map((e,t)=>(e??``).padEnd(n[t])).join(` `);process.stdout.write(s(t)+`
3
+ `),process.stdout.write(s(n.map(e=>`─`.repeat(e)))+`
4
+ `);for(let e of r)process.stdout.write(s(e)+`
5
+ `);return process.stdout.write(`
6
+ * = current CLI key
7
+ `),0}case`create`:{if(!o.name)return process.stderr.write("Error: --name is required for `api-keys create`.\n"),2;let e=o.scope===`write`?`write`:`read`,t=await l.createApiKey({name:o.name,scope:e});if(o.json)return process.stdout.write(JSON.stringify(t,null,2)+`
8
+ `),0;let n=`═`.repeat(64);return process.stdout.write(`\n${n}\n API key created: ${t.name} (${t.scope})\n id: ${t.id}\n token: ${t.token}\n${n}\n\n ⚠ Save this token NOW — it will not be shown again.\n Use it via the Authorization header: "Bearer ${t.token}"\n\n`),0}case`delete`:{if(!o.id)return process.stderr.write("Error: api-key id is required for `api-keys delete`.\n"),2;let e=await r({resource:`API key`,name:i(o.id),yes:o.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
9
+ `),1;let t=await l.deleteApiKey(o.id);return o.json?(process.stdout.write(JSON.stringify(t)+`
10
+ `),0):(process.stdout.write(`✔ Deleted API key ${i(o.id)}.\n`),0)}}}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}}export{o as apiKeysCommand};
@@ -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=i.avgSessionSec??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};
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=i.avgSessionSec??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 listApiKeys(e){return await this.v2RawJson(`/v1/cli/mutate/keys`,e)}async createApiKey(e,t){return await this.v2Mutate(`/v1/cli/mutate/keys`,`POST`,e,t)}async deleteApiKey(e,t){return await this.v2Mutate(`/v1/cli/mutate/keys/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async addDomain(e,t){return await this.v2Mutate(`/v1/cli/mutate/domains`,`POST`,e,t)}async deleteDomain(e,t){return await this.v2Mutate(`/v1/cli/mutate/domains/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async listTeam(e){return await this.v2RawJson(`/v1/cli/mutate/team`,e)}async inviteTeamMember(e,t){return await this.v2Mutate(`/v1/cli/mutate/team/invite`,`POST`,e,t)}async removeTeamMember(e,t){return await this.v2Mutate(`/v1/cli/mutate/team/members/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async updateTeamMemberRole(e,t,n){return await this.v2Mutate(`/v1/cli/mutate/team/members/${encodeURIComponent(e)}/role`,`PATCH`,{role:t},n)}async updateProfile(e,t){return await this.v2Mutate(`/v1/cli/mutate/profile`,`POST`,e,t)}async getPlanInfo(e){return await this.v2RawJson(`/v1/cli/mutate/plans/info`,e)}async upgradePlan(e,t){return await this.v2Mutate(`/v1/cli/mutate/plans/upgrade`,`POST`,{targetPlan:e},t)}async cancelPlan(e){return await this.v2Mutate(`/v1/cli/mutate/plans/cancel`,`POST`,{},e)}async getSettings(e){return await this.v2RawJson(`/v1/cli/mutate/settings`,e)}async setSetting(e,t,n){return await this.v2Mutate(`/v1/cli/mutate/settings`,`POST`,{key:e,value:t},n)}async listIntegrations(e){return await this.v2RawJson(`/v1/cli/mutate/integrations`,e)}async disconnectIntegration(e,t){return await this.v2Mutate(`/v1/cli/mutate/integrations/disconnect`,`POST`,{name:e},t)}async listGoals(e){return await this.v2RawJson(`/v1/cli/mutate/goals`,e)}async createGoal(e,t){return await this.v2Mutate(`/v1/cli/mutate/goals`,`POST`,e,t)}async deleteGoal(e,t){return await this.v2Mutate(`/v1/cli/mutate/goals/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async listNotes(e){return await this.v2RawJson(`/v1/cli/mutate/notes`,e)}async createNote(e,t){return await this.v2Mutate(`/v1/cli/mutate/notes`,`POST`,e,t)}async deleteNote(e,t){return await this.v2Mutate(`/v1/cli/mutate/notes/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async listAgencyClients(e){return await this.v2RawJson(`/v1/cli/mutate/agency/clients`,e)}async addAgencyClient(e,t){return await this.v2Mutate(`/v1/cli/mutate/agency/clients`,`POST`,e,t)}async removeAgencyClient(e,t){return await this.v2Mutate(`/v1/cli/mutate/agency/clients/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async sendAgencyReport(e,t){return await this.v2Mutate(`/v1/cli/mutate/agency/report/${encodeURIComponent(e)}`,`POST`,{},t)}async v2Mutate(e,n,r,i){let a=`${this.v2ApiBase}${e}`,o=await this.v2Headers(r===void 0?{}:{"Content-Type":`application/json`}),s={method:n,headers:o,signal:i};r!==void 0&&(s.body=JSON.stringify(r));let c=await this.v2Fetch(a,s);if(c.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers(r===void 0?{}:{"Content-Type":`application/json`});c=await this.v2Fetch(a,{...s,headers:e})}if(!c.ok){let r=await c.text().catch(()=>``),i=r;try{i=JSON.parse(r)}catch{}throw new t(c.status,i,`${n} ${e} → ${c.status}`)}let l=c.headers.get(`content-type`)??``;return l.includes(`application/json`)?c.json():{}}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};
@@ -0,0 +1 @@
1
+ import{useTheme as e}from"./panel-uygscwY5.js";import{Box as t,Text as n}from"ink";import r from"react";function i(){let e=process.stdout.columns;return typeof e==`number`&&e>0?e:80}function a({version:a,subtitle:o}){let{theme:s}=e(),c=i(),l=`ZENOVAY`,u=`v${a}`,d=`╭─ `,f=` · `,p=` `,m=`─╮`,h=d.length+l.length+f.length+u.length+p.length+m.length,g=Math.max(2,c-h),_=`─`.repeat(g),v=`─`.repeat(Math.max(2,c-2)),y=o??``,b=y.slice(0,Math.max(0,c-4)),x=` `.repeat(Math.max(1,c-2-1-b.length-1));return r.createElement(t,{flexDirection:`column`},r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:s.border},d),r.createElement(n,{color:s.accent,bold:!0},l),r.createElement(n,{color:s.dim},f,u),r.createElement(n,{color:s.border},p,_,m)),o?r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:s.border},`│ `),r.createElement(n,{color:s.fg},b),r.createElement(n,{color:s.border},x,`│`)):null,r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:s.border},`╰`,v,`╯`)))}export{a as Banner};
package/dist/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import{configDir as e,readConfig as t}from"./config-CZ9IzjIH.js";import{manifestSchema as n}from"./check-Comj8AkL.js";import{applyManifest as r}from"./apply-D2xZJdvQ.js";import{cac as i}from"cac";import{fork as a,spawn as o}from"node:child_process";import s from"node:path";import{fileURLToPath as c}from"node:url";import{promises as l,readFileSync as u}from"node:fs";import d from"semver";import{z as f}from"zod";const p=2e3,m=3e4,h=5e3,g=5e3,_=36e5,v=new Set([`update`,`health`,`doctor`,`--version`,`-v`]),y=f.object({checkedAt:f.number(),latest:f.string()});function b(){return s.join(e(),`update-cache.json`)}async function x(){try{let e=await l.readFile(b(),`utf8`),t=y.safeParse(JSON.parse(e));return t.success?t.data:null}catch{return null}}async function S(t){try{await l.mkdir(e(),{recursive:!0,mode:448}),await l.writeFile(b(),JSON.stringify(t),{mode:384})}catch{}}const C=f.object({latest:f.string(),minSupported:f.string().optional(),platforms:f.record(f.string(),f.unknown()).optional(),downloads:f.record(f.string(),f.unknown()).optional()});async function w(e){if(T(e.argv))return;let t=null,n=await x();if(n&&Date.now()-n.checkedAt<_)t={latest:n.latest,platforms:{}};else{try{t=await E()}catch(e){M(`update check failed: ${e.message}`);return}t&&await S({checkedAt:Date.now(),latest:t.latest})}if(!t||!d.valid(e.currentVersion)||!d.valid(t.latest)||d.eq(e.currentVersion,t.latest)||d.lt(t.latest,e.currentVersion))return;let r=d.diff(e.currentVersion,t.latest);if(!r)return;let i=D();if(r===`patch`||r===`prepatch`){let n=await O(t,e,i);if(n&&i===`npm-global`)return;n&&j(e.argv);return}if(r===`minor`||r===`preminor`||r===`major`||r===`premajor`||r===`prerelease`){let n=await A(t.latest);if(!n){process.stderr.write(`Continuing with ${e.currentVersion}.\n`);return}let r=await O(t,e,i);if(r&&i===`npm-global`)return;r&&j(e.argv);return}}function T(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&&v.has(t))}async function E(){let e=D();if(e===`npm-global`||e===`npm-local`||e===`unknown`)try{let e=await fetch(`https://registry.npmjs.org/@zenovay/cli/latest`,{signal:AbortSignal.timeout(p),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 t();try{let e=await fetch(`${r.cliBase}/version`,{signal:AbortSignal.timeout(p)});if(!e.ok)return null;let t=await e.json(),i=n.safeParse(t);if(i.success)return i.data;let a=C.safeParse(t);return a.success?{latest:a.data.latest,minSupported:a.data.minSupported,platforms:{}}:null}catch{return null}}function D(){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 O(e,n,i){if(i===`npm-local`)return process.stderr.write(`Update available — \`npm i -g @zenovay/cli@${e.latest}\` to upgrade.\n`),!1;if(i===`unknown`)return M(`unknown install method; skipping auto-update (latest ${e.latest})`),!1;if(i===`npm-global`)return await k(e.latest);try{let i=await t(),a=await Promise.race([r({currentVersion:n.currentVersion,cliBase:i.cliBase,binaryPath:n.binaryPath,manifest:e}),new Promise((e,t)=>setTimeout(()=>t(Error(`patch install timeout`)),h))]);return a.updated?!0:(M(`update skipped: ${a.reason??`unknown`}`),!1)}catch(e){return M(`update failed: ${e.message}`),!1}}function k(e){return new Promise(t=>{process.stderr.write(` Updating @zenovay/cli to ${e}...\n`);let n=process.platform===`win32`?`npm.cmd`:`npm`,r=[`install`,`-g`,`@zenovay/cli@${e}`],i={stdio:[`ignore`,`ignore`,`pipe`]},a=``,s=!1,c=o(n,r,i),l=setTimeout(()=>{if(!s){s=!0;try{c.kill(`SIGKILL`)}catch{}M(`npm install timed out after ${m/1e3}s; continuing with current version`),t(!1)}},m);c.stderr?.on(`data`,e=>{a+=e.toString(`utf8`)}),c.on(`error`,e=>{s||(s=!0,clearTimeout(l),M(`npm install error: ${e.message}`),t(!1))}),c.on(`exit`,n=>{s||(s=!0,clearTimeout(l),n===0&&(process.stderr.write(` ✔ Updated to ${e}. Re-run your command to use the new version.\n`),process.exit(0)),/EACCES|permission denied/i.test(a)?process.stderr.write(`Auto-update needs sudo for the global npm prefix. Run: sudo npm i -g @zenovay/cli@${e}\n`):M(`npm install exited ${n}; continuing with current version`),t(!1))})})}function A(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))},g);try{process.stdin.resume(),process.stdin.on(`data`,r)}catch{i(),t(!0)}})}function j(e){try{let t=e.slice(1),n=o(process.execPath,t,{stdio:`inherit`});n.on(`exit`,e=>{process.exit(typeof e==`number`?e:0)}),n.on(`error`,()=>{})}catch{}}function M(e){if(process.env.ZENOVAY_DEBUG_UPDATE===`1`)try{process.stderr.write(`zenovay: ${e}\n`)}catch{}}const N=s.dirname(c(import.meta.url)),P=s.join(N,`..`,`package.json`),F=JSON.parse(u(P,`utf8`)),I=F.version,L=process.argv[0]??`zenovay`;function R(){if(process.env.ZENOVAY_BACKGROUND_UPDATE===`1`&&!(process.env.ZENOVAY_NO_UPDATE_CHECK===`1`||process.env.CI===`true`))try{let e=s.join(N,`lib`,`update`,`worker.js`),t=a(e,[],{detached:!0,stdio:`ignore`});t.unref()}catch{}}const z=i(`zenovay`);z.version(I),z.help(),z.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-4dY3jNh8.js`),n=await t({cliVersion:I,cwd:process.cwd(),json:e.json,yes:e.yes,skipMcp:e.skipMcp,skipVerify:e.skipVerify});process.exitCode=n}),z.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:I,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(`
4
+ `),t(!0))},g);try{process.stdin.resume(),process.stdin.on(`data`,r)}catch{i(),t(!0)}})}function j(e){try{let t=e.slice(1),n=o(process.execPath,t,{stdio:`inherit`});n.on(`exit`,e=>{process.exit(typeof e==`number`?e:0)}),n.on(`error`,()=>{})}catch{}}function M(e){if(process.env.ZENOVAY_DEBUG_UPDATE===`1`)try{process.stderr.write(`zenovay: ${e}\n`)}catch{}}const N=s.dirname(c(import.meta.url)),P=s.join(N,`..`,`package.json`),F=JSON.parse(u(P,`utf8`)),I=F.version,L=process.argv[0]??`zenovay`;function R(){if(process.env.ZENOVAY_BACKGROUND_UPDATE===`1`&&!(process.env.ZENOVAY_NO_UPDATE_CHECK===`1`||process.env.CI===`true`))try{let e=s.join(N,`lib`,`update`,`worker.js`),t=a(e,[],{detached:!0,stdio:`ignore`});t.unref()}catch{}}const z=i(`zenovay`);z.version(I),z.help(),z.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-CM26WHgM.js`),n=await t({cliVersion:I,cwd:process.cwd(),json:e.json,yes:e.yes,skipMcp:e.skipMcp,skipVerify:e.skipVerify});process.exitCode=n}),z.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-Bo0VXzkT.js`),n=await t({cliVersion:I,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
5
  ✔ Logged in.
6
6
 
7
- `)}),z.command(`logout`,`Revoke current session and delete local auth`).option(`--json`,``).action(async e=>{let{logoutCommand:t}=await import(`./logout-B3V_2DRZ.js`);await t({cliVersion:I,json:e.json})}),z.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-DGIoZ2aO.js`),n=await t({cliVersion:I,cwd:process.cwd(),mode:e.mode,json:e.json});process.exitCode=n}),z.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-BieuspgD.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-BieuspgD.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-BGdMxOZ_.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-DXpXKnCy.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-yq4dh7UD.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-BqtzfNwp.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-C75M6nUk.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-DMK_yhMW.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-FXL5fAGa.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.command(`heatmaps`,`[BEHAVIOR] Recent heatmap captures (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{heatmapsCommand:t}=await import(`./heatmaps-DtbYa2K3.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-Bx08wXVO.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-C0xGkTYG.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-Cytm6gdG.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json,filter:e.filter,forwardTo:e.forwardTo,replay24h:e.replay24h,setForwardSecret:e.setForwardSecret});process.exitCode=n}),z.command(`health`,`Run self-diagnostic checks`).option(`--json`,``).action(async e=>{let{healthCommand:t}=await import(`./health-DOOluwxM.js`),n=await t({cliVersion:I,binaryPath:L,json:e.json});process.exitCode=n}),z.command(`doctor`,`AI-assisted self-healing`).option(`--json`,``).action(async e=>{let{doctorCommand:t}=await import(`./doctor-C42TUuU1.js`),n=await t({cliVersion:I,binaryPath:L,json:e.json});process.exitCode=n}),z.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-B4iRNAEW.js`),n=await t({cliVersion:I,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),z.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-DkEkhs1V.js`),n=await t({cliVersion:I,siteId:e.siteId,period:e.period,compare:e.compare,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),z.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-pqv_u431.js`),n=await t({cliVersion:I,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}),z.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-Dsy6ODmG.js`),n=await t({cliVersion:I,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),z.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-B7yQXVJa.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),z.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-DxPebZga.js`),n=await t({cliVersion:I,validate:e.validate,json:e.json});process.exitCode=n}),z.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-CnHbpLqp.js`),r=await n({shell:e,list:t.list});process.exitCode=r}),z.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-B88NMsPY.js`),r=await n({cliVersion:I,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}),z.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-D30bvUbA.js`),n=await t({cliVersion:I,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}),z.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-DKQeDin5.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),z.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-CMVAZp4i.js`),n=await t({cliVersion:I,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}),z.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-C7gK3C6A.js`),n=await t({cliVersion:I,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}),z.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-BlVWrZ86.js`),n=await t({cliVersion:I,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}),z.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-B7yQXVJa.js`),r=await n({cliVersion:I,siteId:t.siteId,funnelId:e,window:t.window,json:t.json,csv:t.csv,tsv:t.tsv,ndjson:t.ndjson});process.exitCode=r}),z.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-DsHE5Eu7.js`),r=await n({cliVersion:I,match:e,reset:t.reset,show:t.show,json:t.json});process.exitCode=r}),z.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-wMGBdUT-.js`);await t({cliVersion:I,binaryPath:L,check:e.check,forceDowngrade:e.forceDowngrade,json:e.json})}),z.parse(process.argv,{run:!1}),(async()=>{await w({binaryPath:L,currentVersion:I,argv:process.argv}),R();try{await z.runMatchedCommand()}catch(e){process.stderr.write(`\n✗ ${e.message}\n`),process.exit(1)}})();
7
+ `)}),z.command(`logout`,`Revoke current session and delete local auth`).option(`--json`,``).action(async e=>{let{logoutCommand:t}=await import(`./logout-CR_HnofH.js`);await t({cliVersion:I,json:e.json})}),z.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-RDEA2Hix.js`),n=await t({cliVersion:I,cwd:process.cwd(),mode:e.mode,json:e.json});process.exitCode=n}),z.command(`watch`,"[ANALYTICS] Alias for `analytics` (dashboard summary)").option(`--site-id <id>`,`Site ID`).option(`--interval <ms>`,`Poll interval ms (legacy; ignored by analytics)`,{default:15e3}).option(`--json`,``).action(async e=>{let{analyticsCommand:t}=await import(`./analytics-DPokINId.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.command(`analytics`,`[ANALYTICS] Landing dashboard — visitors, pageviews, bounce, top pages`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{analyticsCommand:t}=await import(`./analytics-DPokINId.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.command(`overview`,"[ANALYTICS] Alias for `analytics` (kept for back-compat with V1 scripts)").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{analyticsCommand:t}=await import(`./analytics-DPokINId.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.command(`home`,`[ACCOUNT] Top-level summary — sites + this-week deltas`).option(`--json`,``).action(async e=>{let{homeCommand:t}=await import(`./home-DS-SjD-L.js`);process.exitCode=await t({cliVersion:I,json:e.json})}),z.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-CNqH0IZ1.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-C9eqXUO5.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-BE6QsOTr.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-gAdKkjwd.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-D_QE69ky.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-DvvS-pwV.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-HZH2gRZC.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.command(`heatmaps`,`[BEHAVIOR] Recent heatmap captures (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{heatmapsCommand:t}=await import(`./heatmaps-J4JTJKQ3.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-kCDrWMj9.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-BGsYRVJh.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json});process.exitCode=n}),z.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-DqabG_EK.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json,filter:e.filter,forwardTo:e.forwardTo,replay24h:e.replay24h,setForwardSecret:e.setForwardSecret});process.exitCode=n}),z.command(`health`,`Run self-diagnostic checks`).option(`--json`,``).action(async e=>{let{healthCommand:t}=await import(`./health-w7N0y9PU.js`),n=await t({cliVersion:I,binaryPath:L,json:e.json});process.exitCode=n}),z.command(`doctor`,`AI-assisted self-healing`).option(`--json`,``).action(async e=>{let{doctorCommand:t}=await import(`./doctor-DNV0LKB8.js`),n=await t({cliVersion:I,binaryPath:L,json:e.json});process.exitCode=n}),z.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-DIDWYBrs.js`),n=await t({cliVersion:I,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),z.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-Bk2X2lSX.js`),n=await t({cliVersion:I,siteId:e.siteId,period:e.period,compare:e.compare,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),z.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-y5wPRUrQ.js`),n=await t({cliVersion:I,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}),z.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-BT04dgtk.js`),n=await t({cliVersion:I,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),z.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-uQBdZOJf.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),z.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-D3hAhR-s.js`),n=await t({cliVersion:I,validate:e.validate,json:e.json});process.exitCode=n}),z.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-BbEmXZy8.js`),r=await n({shell:e,list:t.list});process.exitCode=r}),z.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-BUqZA3Gs.js`),r=await n({cliVersion:I,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}),z.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-DgvAQeGq.js`),n=await t({cliVersion:I,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}),z.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-B2F-G3d3.js`),n=await t({cliVersion:I,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),z.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-CmCOWD6n.js`),n=await t({cliVersion:I,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}),z.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-DAap5ujj.js`),n=await t({cliVersion:I,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}),z.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-haaFzHX9.js`),n=await t({cliVersion:I,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}),z.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-uQBdZOJf.js`),r=await n({cliVersion:I,siteId:t.siteId,funnelId:e,window:t.window,json:t.json,csv:t.csv,tsv:t.tsv,ndjson:t.ndjson});process.exitCode=r}),z.command(`api-keys list`,`[MANAGE] List API keys for your team`).option(`--json`,``).action(async e=>{let{apiKeysCommand:t}=await import(`./api-keys-DYwn4seK.js`);process.exitCode=await t({cliVersion:I,action:`list`,json:e.json})}),z.command(`api-keys create`,`[MANAGE] Create a new API key (token shown ONCE)`).option(`--name <n>`,`Human-readable label for the key`).option(`--scope <scope>`,`read | write`,{default:`read`}).option(`--json`,``).action(async e=>{let{apiKeysCommand:t}=await import(`./api-keys-DYwn4seK.js`);process.exitCode=await t({cliVersion:I,action:`create`,name:e.name,scope:e.scope===`write`?`write`:`read`,json:e.json})}),z.command(`api-keys delete <id>`,`[MANAGE] Delete an API key (interactive confirm by default)`).option(`--yes`,`Skip confirmation`).option(`--json`,``).action(async(e,t)=>{let{apiKeysCommand:n}=await import(`./api-keys-DYwn4seK.js`);process.exitCode=await n({cliVersion:I,action:`delete`,id:e,yes:t.yes,json:t.json})}),z.command(`domains list`,"[MANAGE] List tracked domains (alias of `projects`)").option(`--json`,``).action(async e=>{let{domainsCommand:t}=await import(`./domains-DPxNGnlv.js`);process.exitCode=await t({cliVersion:I,action:`list`,json:e.json})}),z.command(`domains add <url>`,`[MANAGE] Track a new domain (idempotent)`).option(`--name <n>`,`Friendly project name (default: domain itself)`).option(`--json`,``).action(async(e,t)=>{let{domainsCommand:n}=await import(`./domains-DPxNGnlv.js`);process.exitCode=await n({cliVersion:I,action:`add`,url:e,name:t.name,json:t.json})}),z.command(`domains delete <id>`,`[MANAGE] Stop tracking a domain (interactive confirm by default)`).option(`--yes`,`Skip confirmation`).option(`--json`,``).action(async(e,t)=>{let{domainsCommand:n}=await import(`./domains-DPxNGnlv.js`);process.exitCode=await n({cliVersion:I,action:`delete`,id:e,yes:t.yes,json:t.json})}),z.command(`team list`,`[MANAGE] List team members + pending invites (Pro+)`).option(`--json`,``).action(async e=>{let{teamCommand:t}=await import(`./team-Cxe_JdvF.js`);process.exitCode=await t({cliVersion:I,action:`list`,json:e.json})}),z.command(`team invite <email>`,`[MANAGE] Invite a teammate by email (Pro+)`).option(`--role <role>`,`admin | member`,{default:`member`}).option(`--json`,``).action(async(e,t)=>{let{teamCommand:n}=await import(`./team-Cxe_JdvF.js`);process.exitCode=await n({cliVersion:I,action:`invite`,email:e,role:t.role===`admin`?`admin`:`member`,json:t.json})}),z.command(`team remove <userId>`,`[MANAGE] Remove a teammate (interactive confirm; Pro+)`).option(`--yes`,`Skip confirmation`).option(`--json`,``).action(async(e,t)=>{let{teamCommand:n}=await import(`./team-Cxe_JdvF.js`);process.exitCode=await n({cliVersion:I,action:`remove`,userId:e,yes:t.yes,json:t.json})}),z.command(`team role <userId> <newRole>`,`[MANAGE] Update a teammate's role (Pro+)`).option(`--json`,``).action(async(e,t,n)=>{let{teamCommand:r}=await import(`./team-Cxe_JdvF.js`);process.exitCode=await r({cliVersion:I,action:`role`,userId:e,role:t===`admin`?`admin`:`member`,json:n.json})}),z.command(`profile`,"[ACCOUNT] Show current user (alias of `profile show`)").option(`--json`,``).action(async e=>{let{profileCommand:t}=await import(`./profile-DcloxRkt.js`);process.exitCode=await t({cliVersion:I,action:`show`,json:e.json})}),z.command(`profile show`,`[ACCOUNT] Show current user (email, name, team, plan)`).option(`--json`,``).action(async e=>{let{profileCommand:t}=await import(`./profile-DcloxRkt.js`);process.exitCode=await t({cliVersion:I,action:`show`,json:e.json})}),z.command(`profile edit`,`[ACCOUNT] Update your name or notification preference`).option(`--name <n>`,`New display name`).option(`--notifications <pref>`,`email | none`).option(`--json`,``).action(async e=>{let t=e.notifications===`email`||e.notifications===`none`?e.notifications:void 0,{profileCommand:n}=await import(`./profile-DcloxRkt.js`);process.exitCode=await n({cliVersion:I,action:`edit`,name:e.name,notifications:t,json:e.json})}),z.command(`plans`,"[ACCOUNT] Alias of `plans info` (current plan + usage)").option(`--json`,``).action(async e=>{let{plansCommand:t}=await import(`./plans-CaERwneA.js`);process.exitCode=await t({cliVersion:I,action:`info`,json:e.json})}),z.command(`plans info`,`[ACCOUNT] Current plan, usage, next invoice`).option(`--json`,``).action(async e=>{let{plansCommand:t}=await import(`./plans-CaERwneA.js`);process.exitCode=await t({cliVersion:I,action:`info`,json:e.json})}),z.command(`plans upgrade <plan>`,`[ACCOUNT] Upgrade to pro | scale (Free → paid opens browser)`).option(`--json`,``).action(async(e,t)=>{let n=String(e).toLowerCase()===`pro`||String(e).toLowerCase()===`scale`||String(e).toLowerCase()===`enterprise`?String(e).toLowerCase():void 0,{plansCommand:r}=await import(`./plans-CaERwneA.js`);process.exitCode=await r({cliVersion:I,action:`upgrade`,targetPlan:n,json:t.json})}),z.command(`plans cancel`,`[ACCOUNT] Schedule subscription cancellation at period end (requires --yes)`).option(`--yes`,`Confirm — required, no interactive fallback for billing actions`).option(`--json`,``).action(async e=>{let{plansCommand:t}=await import(`./plans-CaERwneA.js`);process.exitCode=await t({cliVersion:I,action:`cancel`,yes:e.yes,json:e.json})}),z.command(`plans payment update`,`[ACCOUNT] Open Stripe Customer Portal to update payment method`).option(`--json`,``).action(async e=>{let{plansCommand:t}=await import(`./plans-CaERwneA.js`);process.exitCode=await t({cliVersion:I,action:`payment`,paymentAction:`update`,json:e.json})}),z.command(`billing`,"[ACCOUNT] Alias for `plans info`").option(`--json`,``).action(async e=>{let{plansCommand:t}=await import(`./plans-CaERwneA.js`);process.exitCode=await t({cliVersion:I,action:`info`,json:e.json})}),z.command(`billing info`,"[ACCOUNT] Alias for `plans info`").option(`--json`,``).action(async e=>{let{plansCommand:t}=await import(`./plans-CaERwneA.js`);process.exitCode=await t({cliVersion:I,action:`info`,json:e.json})}),z.command(`settings get [key]`,`[ACCOUNT] Show site-level settings (or one key)`).option(`--json`,``).action(async(e,t)=>{let{settingsCommand:n}=await import(`./settings-DauPM9xL.js`);process.exitCode=await n({cliVersion:I,action:`get`,key:e||void 0,json:t.json})}),z.command(`settings set <key> <value>`,`[ACCOUNT] Update one site-level setting`).option(`--json`,``).action(async(e,t,n)=>{let{settingsCommand:r}=await import(`./settings-DauPM9xL.js`);process.exitCode=await r({cliVersion:I,action:`set`,key:e,value:t,json:n.json})}),z.command(`integrations list`,`[ACCOUNT] List connected integrations (GSC, GitHub)`).option(`--json`,``).action(async e=>{let{integrationsCommand:t}=await import(`./integrations-Bzl-4ZId.js`);process.exitCode=await t({cliVersion:I,action:`list`,json:e.json})}),z.command(`integrations connect <name>`,`[ACCOUNT] Connect an integration (gsc | github) — opens browser`).option(`--json`,``).action(async(e,t)=>{let n=e===`gsc`||e===`github`?e:void 0,{integrationsCommand:r}=await import(`./integrations-Bzl-4ZId.js`);process.exitCode=await r({cliVersion:I,action:`connect`,name:n,json:t.json})}),z.command(`integrations disconnect <name>`,`[ACCOUNT] Disconnect an integration (interactive confirm by default)`).option(`--yes`,`Skip confirmation`).option(`--json`,``).action(async(e,t)=>{let n=e===`gsc`||e===`github`?e:void 0,{integrationsCommand:r}=await import(`./integrations-Bzl-4ZId.js`);process.exitCode=await r({cliVersion:I,action:`disconnect`,name:n,yes:t.yes,json:t.json})}),z.command(`goals list`,`[ACCOUNT] List goals for your site (Pro+)`).option(`--json`,``).action(async e=>{let{goalsCommand:t}=await import(`./goals-DWv7cwPy.js`);process.exitCode=await t({cliVersion:I,action:`list`,json:e.json})}),z.command(`goals create`,`[ACCOUNT] Create a new goal (Pro+)`).option(`--name <n>`,`Goal name`).option(`--type <t>`,`pageview | event`).option(`--target <v>`,`URL pattern (pageview) or event name (event)`).option(`--json`,``).action(async e=>{let t=e.type===`event`||e.type===`pageview`?e.type:void 0,{goalsCommand:n}=await import(`./goals-DWv7cwPy.js`);process.exitCode=await n({cliVersion:I,action:`create`,name:e.name,type:t,target:e.target,json:e.json})}),z.command(`goals delete <id>`,`[ACCOUNT] Delete a goal (interactive confirm by default; Pro+)`).option(`--yes`,`Skip confirmation`).option(`--json`,``).action(async(e,t)=>{let{goalsCommand:n}=await import(`./goals-DWv7cwPy.js`);process.exitCode=await n({cliVersion:I,action:`delete`,id:e,yes:t.yes,json:t.json})}),z.command(`notes list`,`[ACCOUNT] List your notes`).option(`--json`,``).action(async e=>{let{notesCommand:t}=await import(`./notes-BP6Q4aav.js`);process.exitCode=await t({cliVersion:I,action:`list`,json:e.json})}),z.command(`notes create`,`[ACCOUNT] Create a note`).option(`--content <text>`,`Note body`).option(`--site-id <id>`,`Attach to a specific site (defaults to current)`).option(`--json`,``).action(async e=>{let{notesCommand:t}=await import(`./notes-BP6Q4aav.js`);process.exitCode=await t({cliVersion:I,action:`create`,content:e.content,siteId:e.siteId,json:e.json})}),z.command(`notes delete <id>`,`[ACCOUNT] Delete a note (interactive confirm by default)`).option(`--yes`,`Skip confirmation`).option(`--json`,``).action(async(e,t)=>{let{notesCommand:n}=await import(`./notes-BP6Q4aav.js`);process.exitCode=await n({cliVersion:I,action:`delete`,id:e,yes:t.yes,json:t.json})}),z.command(`agency clients list`,`[ACCOUNT] List agency clients (Scale+)`).option(`--json`,``).action(async e=>{let{agencyCommand:t}=await import(`./agency-DUn-NIh0.js`);process.exitCode=await t({cliVersion:I,action:`clients-list`,json:e.json})}),z.command(`agency clients add`,`[ACCOUNT] Add an agency client (Scale+)`).option(`--email <e>`,`Client contact email`).option(`--name <n>`,`Client name`).option(`--json`,``).action(async e=>{let{agencyCommand:t}=await import(`./agency-DUn-NIh0.js`);process.exitCode=await t({cliVersion:I,action:`clients-add`,email:e.email,name:e.name,json:e.json})}),z.command(`agency clients remove <id>`,`[ACCOUNT] Remove an agency client (interactive confirm; Scale+)`).option(`--yes`,`Skip confirmation`).option(`--json`,``).action(async(e,t)=>{let{agencyCommand:n}=await import(`./agency-DUn-NIh0.js`);process.exitCode=await n({cliVersion:I,action:`clients-remove`,id:e,yes:t.yes,json:t.json})}),z.command(`agency report send <clientId>`,`[ACCOUNT] Email the analytics report to a client (Scale+)`).option(`--json`,``).action(async(e,t)=>{let{agencyCommand:n}=await import(`./agency-DUn-NIh0.js`);process.exitCode=await n({cliVersion:I,action:`report-send`,id:e,json:t.json})}),z.command(`analytics live`,"[ANALYTICS] Alias for `live`").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{liveCommand:t}=await import(`./live-CNqH0IZ1.js`);process.exitCode=await t({cliVersion:I,siteId:e.siteId,json:e.json})}),z.command(`analytics funnels`,"[ANALYTICS] Alias for `funnels`").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{funnelCommand:t}=await import(`./funnel-uQBdZOJf.js`);process.exitCode=await t({cliVersion:I,siteId:e.siteId,json:e.json})}),z.command(`analytics goals`,"[ANALYTICS] Alias for `goals list` (Pro+)").option(`--json`,``).action(async e=>{let{goalsCommand:t}=await import(`./goals-DWv7cwPy.js`);process.exitCode=await t({cliVersion:I,action:`list`,json:e.json})}),z.command(`analytics insights`,"[ANALYTICS] Alias for `insights` (Pro+)").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{insightsCommand:t}=await import(`./insights-BGsYRVJh.js`);process.exitCode=await t({cliVersion:I,siteId:e.siteId,json:e.json})}),z.command(`analytics profiles`,"[ANALYTICS] User-profiles list (NOT `profile`, which is current-user)").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{visitorsCommand:t}=await import(`./visitors-BobD1lev.js`);process.exitCode=await t({cliVersion:I,siteId:e.siteId,json:e.json})}),z.command(`analytics companies`,"[ANALYTICS] Alias for `companies` (Scale+)").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{companiesCommand:t}=await import(`./companies-DgvAQeGq.js`);process.exitCode=await t({cliVersion:I,siteId:e.siteId,json:e.json})}),z.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-C7b94Jib.js`),r=await n({cliVersion:I,match:e,reset:t.reset,show:t.show,json:t.json});process.exitCode=r}),z.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-gcfMIvHa.js`);await t({cliVersion:I,binaryPath:L,check:e.check,forceDowngrade:e.forceDowngrade,json:e.json})}),z.parse(process.argv,{run:!1}),(async()=>{await w({binaryPath:L,currentVersion:I,argv:process.argv}),R();try{await z.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{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import{formatTabular as r,selectFormat as i}from"./formatter-mW0Yk3Nt.js";import"./panel-uygscwY5.js";import"./banner-BPQh2F8l.js";import"./progress-row-DFOvHAc5.js";import"./prompt-BURfUNxp.js";import"./keybar-C7YkmK1U.js";import"./sparkline-Bkfzqe4x.js";import{resolveSiteId as a}from"./resolve-site-D3e1i32Z.js";import{runAnalyticalScreen as o}from"./analytical-screen-CwNWqdBR.js";import{Table as s}from"./ui-UH1mTEzT.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function f(e){return e==null?`—`:e>=500?`Enterprise`:e>=50?`Growth`:`SMB`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(p),b=p.window??`24h`,x=p.limit??100,S=[{key:`lastSeenAt`,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 o({cliVersion:p.cliVersion,title:`companies · ${_} · ${b}`,commandName:`companies`,authToken:h?.accessToken??null,refreshIntervalMs:p.watch?3e4:0,fetcher:e=>g.getCompaniesSnapshot(_,{window:b,limit:x},e),format:y,headlessEmit:(e,t)=>{let n=p.newOnly?e.companies.filter(e=>e.isNew):e.companies;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of n)process.stdout.write(JSON.stringify(e)+`
2
+ `);else process.stdout.write(JSON.stringify({companies:n,total:n.length},null,2));return}process.stdout.write(r(n,[`name`,`domain`,`industry`,`employeeCount`,`visitCount`,`firstSeenAt`,`lastSeenAt`,`isNew`],t))},panels:[{id:`summary`,title:`Now`,render:e=>{let t=e.companies.filter(e=>e.isNew).length,n=e.companies.filter(e=>(e.employeeCount??0)>=500).length;return u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.total),u.createElement(l,{color:`gray`},` companies in `,b)),u.createElement(l,{color:`gray`},u.createElement(l,{color:`green`},`● `,t,` new`),` · `,n,` enterprise`))}},{id:`feed`,title:`Feed`,render:e=>{let t=p.newOnly?e.companies.filter(e=>e.isNew):e.companies;return t.length===0?u.createElement(l,{color:`gray`},`— no `,p.newOnly?`new `:``,`companies in window —`):u.createElement(s,{data:t.slice(0,30),columns:S})}}]})}export{p as companiesCommand};
@@ -0,0 +1 @@
1
+ import{createInterface as e}from"node:readline";async function t(t){if(t.yes)return!0;if(!process.stdin.isTTY)return process.stderr.write(`Refusing to delete ${t.resource} "${t.name}" without --yes in non-interactive mode.\n`),!1;let n=t.destructive?`This cannot be undone. `:``,r=`${n}Delete ${t.resource} "${t.name}"? [y/N] `;return new Promise(t=>{let n=e({input:process.stdin,output:process.stdout});n.question(r,e=>{n.close();let r=e.trim().toLowerCase();t(r===`y`||r===`yes`)})})}export{t as confirmDestructive};
@@ -1 +1 @@
1
- import{useTheme as e}from"./panel-Crm-x-5U.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};
1
+ import{useTheme as e}from"./panel-uygscwY5.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{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import{formatTabular as r,selectFormat as i}from"./formatter-mW0Yk3Nt.js";import"./panel-uygscwY5.js";import"./banner-BPQh2F8l.js";import"./progress-row-DFOvHAc5.js";import"./prompt-BURfUNxp.js";import"./keybar-C7YkmK1U.js";import"./sparkline-Bkfzqe4x.js";import{resolveSiteId as a}from"./resolve-site-D3e1i32Z.js";import{runAnalyticalScreen as o}from"./analytical-screen-CwNWqdBR.js";import{Table as s}from"./ui-UH1mTEzT.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}async function f(f){if(f.connect){let t=await e(),n=t.apiBase.replace(`api.zenovay.com`,`app.zenovay.com`),r=`${n}/settings/integrations/github`;return process.stdout.write(`\n Connect GitHub to Zenovay:\n ${r}\n\n Open this URL in your browser. Zenovay re-uses the same GitHub\n OAuth app you already authorized for login (auth-zenovay), so\n no separate "Zenovay Deploys" app is needed. Pick the repos you\n want to track and deploys will appear here automatically.\n\n`),0}let p=await e(),m=await t({strict:!1}),h=new n({config:p,cliVersion:f.cliVersion,token:m}),g,_;try{({siteId:g,site:_}=await a(h,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let v=i(f),y=f.limit??50,b=[{key:`pushed_at`,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 o({cliVersion:f.cliVersion,title:`deploys · ${g}`,commandName:`deploys`,authToken:m?.accessToken??null,refreshIntervalMs:0,fetcher:e=>h.getDeploys(g,{branch:f.branch,since:f.since,limit:y},e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.deploys)process.stdout.write(JSON.stringify(t)+`
2
+ `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(r(e.deploys,[`pushed_at`,`branch`,`commit_sha`,`commit_author`,`commit_message`,`repository`,`commit_url`,`show_on_chart`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>{let t=e.deploys.filter(e=>e.show_on_chart).length,n=new Set(e.deploys.map(e=>e.repository).filter(e=>!!e));return u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.total),u.createElement(l,{color:`gray`},` commits`,f.branch?` · branch=${f.branch}`:``)),u.createElement(l,{color:`gray`},u.createElement(l,{color:`magenta`},`● `,t,` on chart`),u.createElement(l,null,` · `),u.createElement(l,null,n.size,` `,n.size===1?`repo`:`repos`)))}},{id:`list`,title:`Recent`,render:e=>e.deploys.length===0?u.createElement(c,{flexDirection:`column`},u.createElement(l,{color:`gray`},`— no commits yet —`),u.createElement(l,{color:`gray`},"Run `zenovay deploys --connect` to wire up the GitHub integration.")):u.createElement(s,{data:e.deploys.slice(0,30),columns:b})}]})}export{f as deploysCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import"./formatter-mW0Yk3Nt.js";import{emit as r,isHeadless as i}from"./emit-D7VCOSNk.js";import{Panel as a}from"./panel-uygscwY5.js";import{Banner as o}from"./banner-BPQh2F8l.js";import"./prompt-BURfUNxp.js";import{Keybar as s}from"./keybar-C7YkmK1U.js";import{resolveSiteId as c}from"./resolve-site-D3e1i32Z.js";import{EmptyState as l}from"./empty-state-Dkho-_3J.js";import{DataTable as u}from"./data-table-BVWqHy9m.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";async function b(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getDevices(u);return r({type:`devices.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=m(),[p,b]=v(null),[x,S]=v(!0),[C,w]=v(null);if(h(e=>{e===`q`&&(c(),i(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getDevices(t);n||(b(r),S(!1))}catch(e){n||(w(e.message),S(!1))}})(),()=>{n=!0}},[e,t]),x)return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(a,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Fetching breakdown…`))));if(C)return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(l,{reason:`error`,headline:`Failed to load`,hint:C}));let T=!p||p.devices.length===0&&p.browsers.length===0&&p.os.length===0;if(T)return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(l,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let E=[{key:`name`,label:`name`,width:16},{key:`visitors`,label:`visitors`,align:`right`,width:8}];return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(d,{flexDirection:`row`},g.createElement(a,{title:`Devices`},p.devices.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(u,{columns:E,data:p.devices,zebra:!0})),g.createElement(a,{title:`Browsers`},p.browsers.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(u,{columns:E,data:p.browsers,zebra:!0})),g.createElement(a,{title:`OS`},p.os.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(u,{columns:E,data:p.os,zebra:!0}))),g.createElement(s,{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-Crm-x-5U.js";import{runHealthChecks as o}from"./health-T70yG5po.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-WzSy90dG.js";import"./formatter-mW0Yk3Nt.js";import{emit as i,isHeadless as a}from"./emit-D7VCOSNk.js";import"./panel-uygscwY5.js";import{runHealthChecks as o}from"./health-YzE2Y8gL.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,4 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import{confirmDestructive as r}from"./confirm-D_aKHknn.js";import"./formatter-mW0Yk3Nt.js";import"./panel-uygscwY5.js";import"./banner-BPQh2F8l.js";import"./progress-row-DFOvHAc5.js";import"./prompt-BURfUNxp.js";import"./keybar-C7YkmK1U.js";import"./sparkline-Bkfzqe4x.js";import"./resolve-site-D3e1i32Z.js";import"./analytical-screen-CwNWqdBR.js";import"./ui-UH1mTEzT.js";import{projectsCommand as i}from"./projects-CuRkKGbH.js";function a(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}async function o(o){if(o.action===`list`)return i({cliVersion:o.cliVersion,json:o.json});let s=await e(),c=await t({strict:!1}),l=new n({config:s,cliVersion:o.cliVersion,token:c});try{switch(o.action){case`add`:{if(!o.url)return process.stderr.write("Error: <url> is required for `domains add`.\n"),2;let e=await l.addDomain({url:o.url,name:o.name});return o.json?(process.stdout.write(JSON.stringify(e,null,2)+`
2
+ `),0):e.already_exists?(process.stdout.write(`Domain "${e.domain}" is already tracked (id: ${e.id}, tracking code: ${e.trackingCode}).\n`),0):(process.stdout.write(`\n✔ Domain added.\n id: ${e.id}\n domain: ${e.domain}\n trackingCode: ${e.trackingCode}\n\n Add this script to your site:\n <script defer data-id="${e.trackingCode}" src="https://api.zenovay.com/z.js"></script>\n\n Or run \`zenovay init\` to install it automatically.\n\n`),0)}case`delete`:{if(!o.id)return process.stderr.write("Error: domain id is required for `domains delete`.\n"),2;let e=await r({resource:`domain`,name:a(o.id),yes:o.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
3
+ `),1;let t=await l.deleteDomain(o.id);return o.json?(process.stdout.write(JSON.stringify(t)+`
4
+ `),0):(process.stdout.write(`✔ Deleted domain ${a(o.id)}.\n`),0)}}}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}}export{o as domainsCommand};
@@ -1 +1 @@
1
- import{formatEvent as e,formatTabular as t}from"./formatter-BNYzdX5c.js";function n(e){return typeof e==`object`&&!!e&&Array.isArray(e._columns)&&Array.isArray(e._rows)}function r(){let e=process.argv;for(let t=0;t<e.length;t++){let n=e[t];if(n){if(n===`--json`)return`json`;if(n===`--csv`)return`csv`;if(n===`--tsv`)return`tsv`;if(n===`--ndjson`)return`ndjson`;if(n===`--format`&&t+1<e.length){let n=(e[t+1]??``).toLowerCase();if(n===`json`||n===`csv`||n===`tsv`||n===`ndjson`)return n}if(n.startsWith(`--format=`)){let e=n.slice(9).toLowerCase();if(e===`json`||e===`csv`||e===`tsv`||e===`ndjson`)return e}}}let t=(process.env.ZENOVAY_FORMAT??``).toLowerCase();return t===`json`||t===`csv`||t===`tsv`||t===`ndjson`?t:`ndjson`}function i(e={}){return e.json||e.csv||e.tsv||e.ndjson||process.env.CI===`true`||process.env.CI===`1`||process.env.ZENOVAY_FORMAT?!0:!process.stdout.isTTY}function a(i){let a=r();if(n(i)){process.stdout.write(t(i._rows,i._columns,a));return}if(a===`ndjson`){let e={ts:new Date().toISOString(),...i};process.stdout.write(`${JSON.stringify(e)}\n`);return}process.stdout.write(e({ts:new Date().toISOString(),...i},a))}export{a as emit,i as isHeadless};
1
+ import{formatEvent as e,formatTabular as t}from"./formatter-mW0Yk3Nt.js";function n(e){return typeof e==`object`&&!!e&&Array.isArray(e._columns)&&Array.isArray(e._rows)}function r(){let e=process.argv;for(let t=0;t<e.length;t++){let n=e[t];if(n){if(n===`--json`)return`json`;if(n===`--csv`)return`csv`;if(n===`--tsv`)return`tsv`;if(n===`--ndjson`)return`ndjson`;if(n===`--format`&&t+1<e.length){let n=(e[t+1]??``).toLowerCase();if(n===`json`||n===`csv`||n===`tsv`||n===`ndjson`)return n}if(n.startsWith(`--format=`)){let e=n.slice(9).toLowerCase();if(e===`json`||e===`csv`||e===`tsv`||e===`ndjson`)return e}}}let t=(process.env.ZENOVAY_FORMAT??``).toLowerCase();return t===`json`||t===`csv`||t===`tsv`||t===`ndjson`?t:`ndjson`}function i(e={}){return e.json||e.csv||e.tsv||e.ndjson||process.env.CI===`true`||process.env.CI===`1`||process.env.ZENOVAY_FORMAT?!0:!process.stdout.isTTY}function a(i){let a=r();if(n(i)){process.stdout.write(t(i._rows,i._columns,a));return}if(a===`ndjson`){let e={ts:new Date().toISOString(),...i};process.stdout.write(`${JSON.stringify(e)}\n`);return}process.stdout.write(e({ts:new Date().toISOString(),...i},a))}export{a as emit,i as isHeadless};
@@ -1 +1 @@
1
- import{useTheme as e}from"./panel-Crm-x-5U.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};
1
+ import{useTheme as e}from"./panel-uygscwY5.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{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import{formatTabular as r,selectFormat as i}from"./formatter-mW0Yk3Nt.js";import"./panel-uygscwY5.js";import"./banner-BPQh2F8l.js";import"./progress-row-DFOvHAc5.js";import"./prompt-BURfUNxp.js";import"./keybar-C7YkmK1U.js";import{spark as a}from"./sparkline-Bkfzqe4x.js";import{resolveSiteId as o}from"./resolve-site-D3e1i32Z.js";import{runAnalyticalScreen as s}from"./analytical-screen-CwNWqdBR.js";import{Table as c}from"./ui-UH1mTEzT.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function p(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}async function m(m){let h=await e(),g=await t({strict:!1}),_=new n({config:h,cliVersion:m.cliVersion,token:g}),v,y;try{({siteId:v,site:y}=await o(_,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let b=i(m),x=m.window??`24h`,S=m.limit??100,C=[{key:`ts`,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 s({cliVersion:m.cliVersion,title:`errors · ${v} · ${x}`,commandName:`errors`,authToken:g?.accessToken??null,refreshIntervalMs:m.watch?3e4:0,fetcher:e=>_.getErrors(v,{window:x,limit:S},e),format:b,headlessEmit:(e,t)=>{let n=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of n)process.stdout.write(JSON.stringify(e)+`
2
+ `);else process.stdout.write(JSON.stringify({errors:n,total:n.length},null,2));return}process.stdout.write(r(n,[`ts`,`class`,`message`,`page`,`device`,`fingerprint`],t))},panels:[{id:`summary`,title:`Recent errors`,render:e=>{let t=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors,n=new Map,r=Date.now(),i=60;for(let e of t){let t=new Date(e.ts).getTime(),a=Math.floor((r-t)/(60*1e3));if(a<0||a>=i)continue;let o=n.get(e.class)??Array(i).fill(0),s=i-1-a;o[s]+=1,n.set(e.class,o)}let o=[...n.entries()].sort((e,t)=>t[1].reduce((e,t)=>e+t,0)-e[1].reduce((e,t)=>e+t,0)).slice(0,6);return d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},t.length),d.createElement(u,{color:`gray`},` errors in `,x)),o.length===0?null:d.createElement(l,{flexDirection:`column`,marginTop:1},o.map(([e,t])=>d.createElement(u,{key:e},d.createElement(u,{color:`red`},e.padEnd(20).slice(0,20)),` `,d.createElement(u,{color:`gray`},a(t,30))))))}},{id:`table`,title:`Detail`,render:e=>{let t=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors;return t.length===0?d.createElement(u,{color:`gray`},`— no errors `,m.search?`matching "${m.search}"`:`in window`,` —`):d.createElement(c,{data:t.slice(0,30),columns:C})}}]})}export{m as errorsCommand};
@@ -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{parseSseStream as i}from"./client-vixcHdv-.js";import"./formatter-BNYzdX5c.js";import{isHeadless as a}from"./emit-BmfLGjqr.js";import{Panel as o}from"./panel-Crm-x-5U.js";import{Banner as s,TextInput as c}from"./prompt-CIl9JOlh.js";import{Keybar as l}from"./keybar-DO-sCbJB.js";import u from"node:path";import{promises as d}from"node:fs";import f from"node:os";import p from"node:crypto";import{Box as m,Static as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useRef as S,useState as C}from"react";const w=new Set([`type`,`page`,`country`,`device`,`user_id`,`sessionId`,`referrer`,`ts`,`url`,`method`,`status`]);function T(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(/\s/.test(r)){n+=1;continue}if(r===`(`){t.push({kind:`lparen`}),n+=1;continue}if(r===`)`){t.push({kind:`rparen`}),n+=1;continue}if(r===`"`||r===`'`){let i=r,a=n+1,o=``;for(;a<e.length&&e[a]!==i;)e[a]===`\\`&&a+1<e.length?(o+=e[a+1],a+=2):(o+=e[a],a+=1);if(a>=e.length)throw Error(`filter: unterminated string starting at column ${n+1}`);t.push({kind:`string`,value:o}),n=a+1;continue}if(r===`!`&&e[n+1]===`=`){t.push({kind:`op`,value:`!=`}),n+=2;continue}if(r===`!`&&e[n+1]===`~`){t.push({kind:`op`,value:`!~`}),n+=2;continue}if(r===`=`){t.push({kind:`op`,value:`=`}),n+=1;continue}if(r===`~`){t.push({kind:`op`,value:`~`}),n+=1;continue}let i=n;for(;n<e.length&&!/[\s()=!~]/.test(e[n])&&e[n]!==`"`&&e[n]!==`'`;)n+=1;let a=e.slice(i,n);if(a.length===0)throw Error(`filter: unexpected character at column ${i+1}`);let o=a.toUpperCase();o===`AND`?t.push({kind:`and`}):o===`OR`?t.push({kind:`or`}):t.push({kind:`ident`,value:a})}return t}function E(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function D(e,t,n){let r=e==null?``:String(e);switch(t){case`=`:return r===n;case`!=`:return r!==n;case`~`:{let e=new RegExp(E(n),`i`);return e.test(r)}case`!~`:{let e=new RegExp(E(n),`i`);return!e.test(r)}}}function O(e){return e.tokens[e.pos]}function k(e){let t=e.tokens[e.pos];return e.pos+=1,t}function A(e){let t=O(e);if(!t)throw Error(`filter: unexpected end of expression`);if(t.kind===`lparen`){k(e);let t=j(e),n=k(e);if(!n||n.kind!==`rparen`)throw Error(`filter: missing closing ")"`);return t}if(t.kind!==`ident`)throw Error(`filter: expected key, got ${t.kind}`);k(e);let n=t.value;if(!w.has(n))throw Error(`filter: unknown key "${n}". Allowed: ${[...w].join(`, `)}`);let r=k(e);if(!r||r.kind!==`op`)throw Error(`filter: expected operator after "${n}"`);let i=k(e);if(!i||i.kind!==`ident`&&i.kind!==`string`)throw Error(`filter: expected value after operator "${r.value}"`);let a=r.value,o=i.value;return e=>D(e[n],a,o)}function j(e){let t=A(e);for(;;){let n=O(e);if(!n)break;if(n.kind===`and`){k(e);let n=A(e),r=t;t=e=>r(e)&&n(e);continue}if(n.kind===`or`){k(e);let n=A(e),r=t;t=e=>r(e)||n(e);continue}break}return t}function M(e){if(typeof e!=`string`||e.trim().length===0)throw Error(`filter: expression is empty`);let t=T(e);if(t.length===0)throw Error(`filter: expression is empty`);let n={tokens:t,pos:0},r=j(n);if(n.pos!==t.length){let e=n.tokens[n.pos];throw Error(`filter: unexpected trailing token "${N(e)}"`)}return r}function N(e){return e.kind===`ident`||e.kind===`string`||e.kind===`op`?e.value:e.kind}const P=10*1024*1024;var F=class{currentBytes=0;initialized=!1;writeQueue=Promise.resolve();constructor(e,t=P){this.filePath=e,this.maxBytes=t}async init(){if(!this.initialized){this.initialized=!0;try{await d.mkdir(u.dirname(this.filePath),{recursive:!0,mode:448})}catch{}try{let e=await d.stat(this.filePath);this.currentBytes=e.size}catch{this.currentBytes=0}}}append(e){let t=(async()=>{await this.init();let t=e.endsWith(`
1
+ import{readConfig as e,updateConfig as t}from"./config-CZ9IzjIH.js";import{ApiClient as n,readToken as r}from"./api-DXmhz2DM.js";import{parseSseStream as i}from"./client-WzSy90dG.js";import"./formatter-mW0Yk3Nt.js";import{isHeadless as a}from"./emit-D7VCOSNk.js";import{Panel as o}from"./panel-uygscwY5.js";import{Banner as s}from"./banner-BPQh2F8l.js";import{TextInput as c}from"./prompt-BURfUNxp.js";import{Keybar as l}from"./keybar-C7YkmK1U.js";import u from"node:path";import{promises as d}from"node:fs";import f from"node:os";import p from"node:crypto";import{Box as m,Static as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useRef as S,useState as C}from"react";const w=new Set([`type`,`page`,`country`,`device`,`user_id`,`sessionId`,`referrer`,`ts`,`url`,`method`,`status`]);function T(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(/\s/.test(r)){n+=1;continue}if(r===`(`){t.push({kind:`lparen`}),n+=1;continue}if(r===`)`){t.push({kind:`rparen`}),n+=1;continue}if(r===`"`||r===`'`){let i=r,a=n+1,o=``;for(;a<e.length&&e[a]!==i;)e[a]===`\\`&&a+1<e.length?(o+=e[a+1],a+=2):(o+=e[a],a+=1);if(a>=e.length)throw Error(`filter: unterminated string starting at column ${n+1}`);t.push({kind:`string`,value:o}),n=a+1;continue}if(r===`!`&&e[n+1]===`=`){t.push({kind:`op`,value:`!=`}),n+=2;continue}if(r===`!`&&e[n+1]===`~`){t.push({kind:`op`,value:`!~`}),n+=2;continue}if(r===`=`){t.push({kind:`op`,value:`=`}),n+=1;continue}if(r===`~`){t.push({kind:`op`,value:`~`}),n+=1;continue}let i=n;for(;n<e.length&&!/[\s()=!~]/.test(e[n])&&e[n]!==`"`&&e[n]!==`'`;)n+=1;let a=e.slice(i,n);if(a.length===0)throw Error(`filter: unexpected character at column ${i+1}`);let o=a.toUpperCase();o===`AND`?t.push({kind:`and`}):o===`OR`?t.push({kind:`or`}):t.push({kind:`ident`,value:a})}return t}function E(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function D(e,t,n){let r=e==null?``:String(e);switch(t){case`=`:return r===n;case`!=`:return r!==n;case`~`:{let e=new RegExp(E(n),`i`);return e.test(r)}case`!~`:{let e=new RegExp(E(n),`i`);return!e.test(r)}}}function O(e){return e.tokens[e.pos]}function k(e){let t=e.tokens[e.pos];return e.pos+=1,t}function A(e){let t=O(e);if(!t)throw Error(`filter: unexpected end of expression`);if(t.kind===`lparen`){k(e);let t=j(e),n=k(e);if(!n||n.kind!==`rparen`)throw Error(`filter: missing closing ")"`);return t}if(t.kind!==`ident`)throw Error(`filter: expected key, got ${t.kind}`);k(e);let n=t.value;if(!w.has(n))throw Error(`filter: unknown key "${n}". Allowed: ${[...w].join(`, `)}`);let r=k(e);if(!r||r.kind!==`op`)throw Error(`filter: expected operator after "${n}"`);let i=k(e);if(!i||i.kind!==`ident`&&i.kind!==`string`)throw Error(`filter: expected value after operator "${r.value}"`);let a=r.value,o=i.value;return e=>D(e[n],a,o)}function j(e){let t=A(e);for(;;){let n=O(e);if(!n)break;if(n.kind===`and`){k(e);let n=A(e),r=t;t=e=>r(e)&&n(e);continue}if(n.kind===`or`){k(e);let n=A(e),r=t;t=e=>r(e)||n(e);continue}break}return t}function M(e){if(typeof e!=`string`||e.trim().length===0)throw Error(`filter: expression is empty`);let t=T(e);if(t.length===0)throw Error(`filter: expression is empty`);let n={tokens:t,pos:0},r=j(n);if(n.pos!==t.length){let e=n.tokens[n.pos];throw Error(`filter: unexpected trailing token "${N(e)}"`)}return r}function N(e){return e.kind===`ident`||e.kind===`string`||e.kind===`op`?e.value:e.kind}const P=10*1024*1024;var F=class{currentBytes=0;initialized=!1;writeQueue=Promise.resolve();constructor(e,t=P){this.filePath=e,this.maxBytes=t}async init(){if(!this.initialized){this.initialized=!0;try{await d.mkdir(u.dirname(this.filePath),{recursive:!0,mode:448})}catch{}try{let e=await d.stat(this.filePath);this.currentBytes=e.size}catch{this.currentBytes=0}}}append(e){let t=(async()=>{await this.init();let t=e.endsWith(`
2
2
  `)?e:`${e}\n`,n=Buffer.byteLength(t,`utf8`);this.currentBytes+n>this.maxBytes&&await this.rotate();try{await d.appendFile(this.filePath,t,{mode:384}),this.currentBytes+=n}catch(e){process.stderr.write(`[scrollback] append failed: ${e.message}\n`)}})();return this.writeQueue=this.writeQueue.then(()=>t,()=>t),t}async rotate(){let e=e=>{if(e===0)return this.filePath;let t=u.parse(this.filePath);return u.join(t.dir,`${t.name}.${e}${t.ext}`)};try{await d.unlink(e(3))}catch{}for(let t=2;t>=0;--t)try{await d.rename(e(t),e(t+1))}catch(n){n.code!==`ENOENT`&&process.stderr.write(`[scrollback] rotate ${e(t)} failed: ${n.message}\n`)}this.currentBytes=0}async close(){await this.writeQueue}};const I=5e3,L=33,R=`─── replay end, live below ───`;async function z(i){if(i.setForwardSecret)return await t({forwardSecret:i.setForwardSecret}),process.stdout.write(`Forward secret saved.
3
3
  `),0;let o=await e(),s=await r({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:i.cliVersion,token:s}),l=null;if(i.filter)try{l=M(i.filter)}catch(e){return process.stderr.write(`Invalid --filter expression: ${e.message}\n`),2}if(a(i))return H(c,i,l,o.forwardSecret);let d=i.scrollbackPath??u.join(f.homedir(),`.zenovay`,`events-scrollback.log`);return new Promise(e=>{let{unmount:t}=_(b.createElement(U,{api:c,opts:i,predicate:l,forwardSecret:o.forwardSecret,scrollbackPath:d,onExit:n=>{t(),e(n)}}))})}function B(e){return{raw:JSON.stringify(e),parsed:e}}async function V(e,t,n){let r=JSON.stringify(n),i=p.createHmac(`sha256`,t).update(r).digest(`hex`);try{await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Zenovay-Signature":`sha256=${i}`},body:r})}catch{}}async function H(e,t,n,r){let a=new AbortController;process.on(`SIGINT`,()=>a.abort());let o=()=>new Date().toISOString();try{let s=await e.openEventsStream(t.siteId,a.signal);for await(let e of i(s)){if(e.type===`error`)return process.stdout.write(`${JSON.stringify({ts:o(),type:`error`,code:e.code,message:e.message})}\n`),1;if(e.type===`done`)return 0;let i=e;if(n&&!n(i))continue;process.stdout.write(`${JSON.stringify({ts:o(),...i})}\n`),t.forwardTo&&r&&await V(t.forwardTo,r,{event:e,ts:o(),site_id:t.siteId})}return 0}catch(e){return process.stdout.write(`${JSON.stringify({ts:o(),type:`error`,code:`stream_failed`,message:e.message})}\n`),1}}const U=({api:e,opts:t,predicate:n,forwardSecret:r,scrollbackPath:a,onExit:u})=>{let{exit:f}=v(),p=S([]),_=S(null),[w,T]=C([]),[E,D]=C(null),[O,k]=C(!1),[A,j]=C(null);_.current||=new F(a),y(n=>{if(!O){if(E){D(null);return}if(n===`q`){f(),u(0);return}if(n===`f`){let e=p.current[p.current.length-1];e&&D(e);return}if(n===`w`){k(!0);return}if(n===`r`){G(e,t.siteId,p,j);return}}}),x(()=>{let e=setInterval(()=>{let e=p.current.slice(-100);T(e)},L);return()=>clearInterval(e)},[]),x(()=>{let a=new AbortController,o=!1;return(async()=>{t.replay24h&&await G(e,t.siteId,p,j);try{let s=await e.openEventsStream(t.siteId,a.signal);for await(let e of i(s)){if(o)break;if(e.type===`error`){let t={raw:`[ERR ${e.code}] ${e.message}`};W(p,t),_.current?.append(t.raw);continue}if(e.type===`done`)break;let i=e;if(n&&!n(i))continue;let a=B(e);W(p,a),_.current?.append(a.raw),t.forwardTo&&r&&V(t.forwardTo,r,{event:e,ts:new Date().toISOString(),site_id:t.siteId})}}catch(e){let t={raw:`[DISCONNECT] ${e.message}`};W(p,t)}})(),()=>{o=!0,a.abort(),_.current?.close()}},[e,t.siteId,t.replay24h,t.forwardTo,n,r]);let M=async e=>{let t=e.trim()||`events.ndjson`;try{let e=p.current.map(e=>e.raw).join(`
4
4
  `)+`
@@ -0,0 +1,3 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import{formatTabular as r,selectFormat as i}from"./formatter-mW0Yk3Nt.js";import"./panel-uygscwY5.js";import"./banner-BPQh2F8l.js";import"./progress-row-DFOvHAc5.js";import"./prompt-BURfUNxp.js";import"./keybar-C7YkmK1U.js";import"./sparkline-Bkfzqe4x.js";import{resolveSiteId as a}from"./resolve-site-D3e1i32Z.js";import{runAnalyticalScreen as o}from"./analytical-screen-CwNWqdBR.js";import{Table as s}from"./ui-UH1mTEzT.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e,t){let n=Math.round(e*t);return`█`.repeat(Math.max(0,Math.min(t,n)))+`░`.repeat(Math.max(0,t-n))}async function f(f){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:f.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(f);if(!f.funnelId){let e=[{key:`name`,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 o({cliVersion:f.cliVersion,title:`funnels · ${_}`,commandName:`funnels`,authToken:h?.accessToken??null,refreshIntervalMs:0,fetcher:e=>g.listFunnels(_,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
+ `);return}process.stdout.write(r(e.funnels,[`id`,`name`,`stepCount`],t))},panels:[{id:`funnels`,title:`Funnels`,render:t=>t.funnels.length===0?u.createElement(l,{color:`gray`},`— no funnels defined —`):u.createElement(s,{data:t.funnels,columns:e})},{id:`hint`,title:`Next`,render:()=>u.createElement(l,{color:`gray`},"Run `zenovay funnel <id>` for drop-off detail.")}]})}let b=f.window??`30d`;return o({cliVersion:f.cliVersion,title:`funnel · ${f.funnelId} · ${b}`,commandName:`funnel`,authToken:h?.accessToken??null,refreshIntervalMs:0,fetcher:e=>g.getFunnel(_,f.funnelId,b,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
3
+ `);return}process.stdout.write(r(e.steps,[`id`,`name`,`visitors`,`conversions`],t))},panels:[{id:`overview`,title:p(`Overview`),render:e=>u.createElement(c,{flexDirection:`column`},u.createElement(l,{bold:!0},e.name),u.createElement(l,{color:`gray`},e.totalEntries.toLocaleString(),` entries · `,e.totalCompletions.toLocaleString(),` completed (`,(e.conversionRate*100).toFixed(1),`%)`))},{id:`flow`,title:`Flow`,render:e=>{let t=e.totalEntries||1;return u.createElement(c,{flexDirection:`column`},e.steps.map((n,r)=>{let i=n.visitors/t,a=e.steps[r-1],o=a?a.visitors-n.visitors:0,s=a?o/Math.max(1,a.visitors)*100:0;return u.createElement(c,{key:n.id,flexDirection:`column`},a?u.createElement(l,{color:`red`},` `,`↓ drop `,o.toLocaleString(),` (`,s.toFixed(1),`%)`):null,u.createElement(l,null,u.createElement(l,{bold:!0},`${r+1}. ${n.name}`.padEnd(22).slice(0,22)),` `,u.createElement(l,{color:`magenta`},d(i,30)),` `,u.createElement(l,null,(i*100).toFixed(1).padStart(5),`% `),u.createElement(l,{color:`gray`},n.visitors.toLocaleString())))}))}}]})}function p(e){return e}export{f as funnelCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import"./formatter-mW0Yk3Nt.js";import{emit as r,isHeadless as i}from"./emit-D7VCOSNk.js";import{Panel as a}from"./panel-uygscwY5.js";import{Banner as o}from"./banner-BPQh2F8l.js";import"./prompt-BURfUNxp.js";import{Keybar as s}from"./keybar-C7YkmK1U.js";import{resolveSiteId as c}from"./resolve-site-D3e1i32Z.js";import{EmptyState as l}from"./empty-state-Dkho-_3J.js";import{DataTable as u}from"./data-table-BVWqHy9m.js";import{Globe as d}from"./globe-BI6KG0jM.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getGeo(u);return r({type:`geo.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=h(),[m,x]=y(null),[S,C]=y(!0),[w,T]=y(null);if(g(e=>{e===`q`&&(c(),i(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getGeo(t);n||(x(r),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),S)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(a,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching geo…`))));if(w)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(l,{reason:`error`,headline:`Failed to load`,hint:w}));let E=!m||m.countries.length===0&&m.cities.length===0;if(E)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(l,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let D=[{key:`country`,label:`country`,width:18},{key:`visitors`,label:`visitors`,align:`right`,width:8}],O=[{key:`city`,label:`city`,width:20},{key:`country`,label:`country`,width:12},{key:`visitors`,label:`visitors`,align:`right`,width:8}],k=process.stdout.columns??80;return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(f,{flexDirection:`row`},_.createElement(a,{title:`Countries`},m.countries.length===0?_.createElement(p,{color:`gray`},`— —`):_.createElement(u,{columns:D,data:m.countries.slice(0,15),zebra:!0})),_.createElement(a,{title:`Globe`},_.createElement(d,{data:[],width:Math.max(36,k-60),height:12}))),_.createElement(a,{title:`Cities`},m.cities.length===0?_.createElement(p,{color:`gray`},`— —`):_.createElement(u,{columns:O,data:m.cities.slice(0,20),zebra:!0})),_.createElement(s,{items:[{key:`q`,label:`quit`}]}))};export{x as geoCommand};
@@ -0,0 +1,10 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import{requireTier as r}from"./tier-RjOGNzda.js";import{confirmDestructive as i}from"./confirm-D_aKHknn.js";function a(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}function o(e){return e?new Date(e).toISOString().slice(0,10):`—`}async function s(s){let c=await e(),l=await t({strict:!1}),u=new n({config:c,cliVersion:s.cliVersion,token:l});try{await r(u,`pro`)}catch(e){return process.stderr.write(`✗ ${e.message}\n`),2}try{switch(s.action){case`list`:{let{goals:e}=await u.listGoals();if(s.json)return process.stdout.write(JSON.stringify({goals:e},null,2)+`
2
+ `),0;if(e.length===0)return process.stdout.write("No goals yet. Create one with `zenovay goals create --name <n> --type <pageview|event> --target <url-or-event>`.\n"),0;let t=[14,24,10,30,10],n=e=>e.map((e,n)=>(e??``).padEnd(t[n])).join(` `);process.stdout.write(`
3
+ `+n([`id`,`name`,`type`,`target`,`created`])+`
4
+ `),process.stdout.write(n(t.map(e=>`─`.repeat(e)))+`
5
+ `);for(let r of e)process.stdout.write(n([a(r.id),(r.name??``).slice(0,t[1]),r.type,(r.target??`—`).slice(0,t[3]),o(r.createdAt)])+`
6
+ `);return process.stdout.write(`
7
+ `),0}case`create`:{if(!s.name||!s.type||!s.target)return process.stderr.write("Error: --name, --type (pageview|event), and --target are required for `goals create`.\n"),2;if(s.type!==`pageview`&&s.type!==`event`)return process.stderr.write("Error: --type must be `pageview` or `event`.\n"),2;let e=await u.createGoal({name:s.name,type:s.type,target:s.target});return s.json?(process.stdout.write(JSON.stringify(e,null,2)+`
8
+ `),0):(process.stdout.write(`✔ Goal created: ${e.name} (${e.type} → ${e.target}, id ${e.id}).\n`),0)}case`delete`:{if(!s.id)return process.stderr.write("Error: goal id is required for `goals delete`.\n"),2;let e=await i({resource:`goal`,name:a(s.id),yes:s.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
9
+ `),1;let t=await u.deleteGoal(s.id);return s.json?(process.stdout.write(JSON.stringify(t)+`
10
+ `),0):(process.stdout.write(`✔ Deleted goal ${a(s.id)}.\n`),0)}}}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}}export{s as goalsCommand};
@@ -1 +1 @@
1
- import{configPath as e,readConfig as t}from"./config-CZ9IzjIH.js";import{fetchManifest as n}from"./check-Comj8AkL.js";import{ApiClient as r,readToken as i}from"./api-DXmhz2DM.js";import{isHeadless as a}from"./emit-BmfLGjqr.js";import{Panel as o}from"./panel-Crm-x-5U.js";import s from"node:path";import{promises as c}from"node:fs";import l from"node:os";import{Box as u,Text as d,render as f}from"ink";import p from"react";const m=6*60*60*1e3;function h(){return s.join(l.homedir(),`.zenovay`,`update.json`)}async function g(){try{let e=await c.readFile(h(),`utf8`);return JSON.parse(e)}catch{return null}}async function _(e){let t=h();await c.mkdir(s.dirname(t),{recursive:!0,mode:448}),await c.writeFile(t,JSON.stringify(e,null,2))}async function v(){let e=await t();if(e.noUpdateCheck||process.env.ZENOVAY_NO_UPDATE_CHECK===`1`||process.env.CI===`true`)return null;let r=await g();if(r&&Date.now()-r.fetchedAt<m)return r;try{let t=await n({cliBase:e.cliBase}),i={manifest:t,fetchedAt:Date.now(),lastNoticeAt:r?.lastNoticeAt};return await _(i),i}catch{return r}}async function y(){try{await v()}catch{}process.exit(0)}import.meta.url===`file://${process.argv[1]}`&&y();const b=2e3,x=5e3;async function S(e,t){let n=`${e}/mcp`,r=Date.now(),i=new AbortController,a=setTimeout(()=>i.abort(),b);try{let a=await t(n,{method:`GET`,signal:i.signal}),o=Date.now()-r;return a.ok?{name:`MCP server`,status:`pass`,detail:`${e}/mcp · ${o}ms`,latencyMs:o}:{name:`MCP server`,status:`fail`,detail:`HTTP ${a.status}`,latencyMs:o}}catch(e){return{name:`MCP server`,status:`fail`,detail:e.message}}finally{clearTimeout(a)}}async function C(){try{let t=await c.readFile(e(),`utf8`),n=JSON.parse(t),r=n.openaiApiKey;return typeof r==`string`&&r.trim().length>0?{name:`OpenAI key`,status:`pass`,detail:`configured`}:{name:`OpenAI key`,status:`warn`,detail:"not set (run `zenovay ai` to configure)"}}catch(e){return e.code===`ENOENT`?{name:`OpenAI key`,status:`warn`,detail:`no config file`}:{name:`OpenAI key`,status:`warn`,detail:`unreadable config`}}}async function w(){let e=l.homedir(),t=[s.join(e,`.zshrc`),s.join(e,`.bashrc`),s.join(e,`.config`,`fish`,`completions`,`zenovay.fish`)],n=[];for(let e of t)try{let t=await c.readFile(e,`utf8`);(/zenovay\s+(complet|--?complet)/i.test(t)||/_zenovay/.test(t)||/complete\s+-c\s+zenovay/.test(t))&&n.push(s.basename(e))}catch{}return n.length>0?{name:`Completions`,status:`pass`,detail:n.join(`, `)}:{name:`Completions`,status:`warn`,detail:"not installed (run `zenovay completions` after Wave 3)"}}async function T(e,t,n,r){if(!e||!t)return{name:`Events stream`,status:`skip`,detail:`not authenticated`};let i=new AbortController,a=setTimeout(()=>i.abort(),x),o=Date.now();try{let t=await e.openEventsStream(`probe`,i.signal),r=t.body?.getReader();if(r){let e=Promise.race([r.read().then(()=>`first`),new Promise(e=>setTimeout(()=>e(`timeout`),1500))]);await e;try{r.cancel()}catch{}}let a=Date.now()-o;return{name:`Events stream`,status:`pass`,detail:`${n}/v1/cli/events/tail · ${a}ms`,latencyMs:a}}catch(e){let t=e.message;return/40\d/.test(t)?{name:`Events stream`,status:`pass`,detail:`endpoint reachable (auth-gated)`}:{name:`Events stream`,status:`fail`,detail:t}}finally{clearTimeout(a)}}async function E(n){let a=n.fetchImpl??fetch,o=[],s=await t().catch(()=>null);o.push({name:`Binary`,status:`pass`,detail:`v${n.cliVersion} (${n.binaryPath})`}),o.push({name:`Config file`,status:s?`pass`:`warn`,detail:e()});let c=await i({strict:!1}).catch(()=>null);o.push({name:`Auth`,status:c?`pass`:`fail`,detail:c?`logged in${c.email?` as ${c.email}`:``}`:`not logged in`});let l=null;if(s)try{l=new r({config:s,cliVersion:n.cliVersion,token:c,fetchImpl:a});let e=await l.ping();o.push({name:`API connection`,status:`pass`,detail:`${s.apiBase.replace(/^https?:\/\//,``)} · ${e.latencyMs}ms`,latencyMs:e.latencyMs})}catch(e){o.push({name:`API connection`,status:`fail`,detail:`${e.message}`})}let u=await g().catch(()=>null);o.push({name:`Auto-update`,status:s?.noUpdateCheck?`warn`:`pass`,detail:s?.noUpdateCheck?`disabled`:u?`latest=${u.manifest.latest}`:`manifest not yet fetched`});let d=s?.apiBase??`https://api.zenovay.com`;return o.push(await S(d,a)),o.push(await C()),o.push(await w()),o.push(await T(l,!!c,d,a)),o}function D(e){return e.some(e=>e.status===`fail`)?1:0}async function O(e){let t=await E(e),n=D(t),r=n===0;return a({json:e.json})?(process.stdout.write(`${JSON.stringify({checks:t,passed:r})}\n`),n):new Promise(e=>{let{unmount:r}=f(p.createElement(k,{checks:t}),{exitOnCtrlC:!0});setImmediate(()=>{r(),e(n)})})}const k=({checks:e})=>p.createElement(o,{title:`Zenovay CLI health check`,state:`idle`},e.map(e=>p.createElement(u,{key:e.name},p.createElement(d,{color:j(e.status)},A(e.status)),p.createElement(d,null,` `),p.createElement(d,{bold:!0},e.name.padEnd(18)),p.createElement(d,{color:`gray`},e.detail))));function A(e){return e===`pass`?`✔`:e===`warn`?`⚠`:e===`skip`?`∼`:`✗`}function j(e){return e===`pass`?`green`:e===`warn`?`yellow`:e===`skip`?`gray`:`red`}export{k as HealthReport,D as exitCodeFor,O as healthCommand,E as runHealthChecks};
1
+ import{configPath as e,readConfig as t}from"./config-CZ9IzjIH.js";import{fetchManifest as n}from"./check-Comj8AkL.js";import{ApiClient as r,readToken as i}from"./api-DXmhz2DM.js";import{isHeadless as a}from"./emit-D7VCOSNk.js";import{Panel as o}from"./panel-uygscwY5.js";import s from"node:path";import{promises as c}from"node:fs";import l from"node:os";import{Box as u,Text as d,render as f}from"ink";import p from"react";const m=6*60*60*1e3;function h(){return s.join(l.homedir(),`.zenovay`,`update.json`)}async function g(){try{let e=await c.readFile(h(),`utf8`);return JSON.parse(e)}catch{return null}}async function _(e){let t=h();await c.mkdir(s.dirname(t),{recursive:!0,mode:448}),await c.writeFile(t,JSON.stringify(e,null,2))}async function v(){let e=await t();if(e.noUpdateCheck||process.env.ZENOVAY_NO_UPDATE_CHECK===`1`||process.env.CI===`true`)return null;let r=await g();if(r&&Date.now()-r.fetchedAt<m)return r;try{let t=await n({cliBase:e.cliBase}),i={manifest:t,fetchedAt:Date.now(),lastNoticeAt:r?.lastNoticeAt};return await _(i),i}catch{return r}}async function y(){try{await v()}catch{}process.exit(0)}import.meta.url===`file://${process.argv[1]}`&&y();const b=2e3,x=5e3;async function S(e,t){let n=`${e}/mcp`,r=Date.now(),i=new AbortController,a=setTimeout(()=>i.abort(),b);try{let a=await t(n,{method:`GET`,signal:i.signal}),o=Date.now()-r;return a.ok?{name:`MCP server`,status:`pass`,detail:`${e}/mcp · ${o}ms`,latencyMs:o}:{name:`MCP server`,status:`fail`,detail:`HTTP ${a.status}`,latencyMs:o}}catch(e){return{name:`MCP server`,status:`fail`,detail:e.message}}finally{clearTimeout(a)}}async function C(){try{let t=await c.readFile(e(),`utf8`),n=JSON.parse(t),r=n.openaiApiKey;return typeof r==`string`&&r.trim().length>0?{name:`OpenAI key`,status:`pass`,detail:`configured`}:{name:`OpenAI key`,status:`warn`,detail:"not set (run `zenovay ai` to configure)"}}catch(e){return e.code===`ENOENT`?{name:`OpenAI key`,status:`warn`,detail:`no config file`}:{name:`OpenAI key`,status:`warn`,detail:`unreadable config`}}}async function w(){let e=l.homedir(),t=[s.join(e,`.zshrc`),s.join(e,`.bashrc`),s.join(e,`.config`,`fish`,`completions`,`zenovay.fish`)],n=[];for(let e of t)try{let t=await c.readFile(e,`utf8`);(/zenovay\s+(complet|--?complet)/i.test(t)||/_zenovay/.test(t)||/complete\s+-c\s+zenovay/.test(t))&&n.push(s.basename(e))}catch{}return n.length>0?{name:`Completions`,status:`pass`,detail:n.join(`, `)}:{name:`Completions`,status:`warn`,detail:"not installed (run `zenovay completions` after Wave 3)"}}async function T(e,t,n,r){if(!e||!t)return{name:`Events stream`,status:`skip`,detail:`not authenticated`};let i=new AbortController,a=setTimeout(()=>i.abort(),x),o=Date.now();try{let t=await e.openEventsStream(`probe`,i.signal),r=t.body?.getReader();if(r){let e=Promise.race([r.read().then(()=>`first`),new Promise(e=>setTimeout(()=>e(`timeout`),1500))]);await e;try{r.cancel()}catch{}}let a=Date.now()-o;return{name:`Events stream`,status:`pass`,detail:`${n}/v1/cli/events/tail · ${a}ms`,latencyMs:a}}catch(e){let t=e.message;return/40\d/.test(t)?{name:`Events stream`,status:`pass`,detail:`endpoint reachable (auth-gated)`}:{name:`Events stream`,status:`fail`,detail:t}}finally{clearTimeout(a)}}async function E(n){let a=n.fetchImpl??fetch,o=[],s=await t().catch(()=>null);o.push({name:`Binary`,status:`pass`,detail:`v${n.cliVersion} (${n.binaryPath})`}),o.push({name:`Config file`,status:s?`pass`:`warn`,detail:e()});let c=await i({strict:!1}).catch(()=>null);o.push({name:`Auth`,status:c?`pass`:`fail`,detail:c?`logged in${c.email?` as ${c.email}`:``}`:`not logged in`});let l=null;if(s)try{l=new r({config:s,cliVersion:n.cliVersion,token:c,fetchImpl:a});let e=await l.ping();o.push({name:`API connection`,status:`pass`,detail:`${s.apiBase.replace(/^https?:\/\//,``)} · ${e.latencyMs}ms`,latencyMs:e.latencyMs})}catch(e){o.push({name:`API connection`,status:`fail`,detail:`${e.message}`})}let u=await g().catch(()=>null);o.push({name:`Auto-update`,status:s?.noUpdateCheck?`warn`:`pass`,detail:s?.noUpdateCheck?`disabled`:u?`latest=${u.manifest.latest}`:`manifest not yet fetched`});let d=s?.apiBase??`https://api.zenovay.com`;return o.push(await S(d,a)),o.push(await C()),o.push(await w()),o.push(await T(l,!!c,d,a)),o}function D(e){return e.some(e=>e.status===`fail`)?1:0}async function O(e){let t=await E(e),n=D(t),r=n===0;return a({json:e.json})?(process.stdout.write(`${JSON.stringify({checks:t,passed:r})}\n`),n):new Promise(e=>{let{unmount:r}=f(p.createElement(k,{checks:t}),{exitOnCtrlC:!0});setImmediate(()=>{r(),e(n)})})}const k=({checks:e})=>p.createElement(o,{title:`Zenovay CLI health check`,state:`idle`},e.map(e=>p.createElement(u,{key:e.name},p.createElement(d,{color:j(e.status)},A(e.status)),p.createElement(d,null,` `),p.createElement(d,{bold:!0},e.name.padEnd(18)),p.createElement(d,{color:`gray`},e.detail))));function A(e){return e===`pass`?`✔`:e===`warn`?`⚠`:e===`skip`?`∼`:`✗`}function j(e){return e===`pass`?`green`:e===`warn`?`yellow`:e===`skip`?`gray`:`red`}export{k as HealthReport,D as exitCodeFor,O as healthCommand,E as runHealthChecks};
@@ -0,0 +1 @@
1
+ import"./config-CZ9IzjIH.js";import"./check-Comj8AkL.js";import"./api-DXmhz2DM.js";import"./formatter-mW0Yk3Nt.js";import"./emit-D7VCOSNk.js";import"./panel-uygscwY5.js";import{HealthReport as e,exitCodeFor as t,healthCommand as n,runHealthChecks as r}from"./health-YzE2Y8gL.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{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import{requireTier as r}from"./tier-RjOGNzda.js";import"./formatter-mW0Yk3Nt.js";import{emit as i,isHeadless as a}from"./emit-D7VCOSNk.js";import{Panel as o}from"./panel-uygscwY5.js";import{Banner as s}from"./banner-BPQh2F8l.js";import"./prompt-BURfUNxp.js";import{Keybar as c}from"./keybar-C7YkmK1U.js";import{resolveSiteId as l}from"./resolve-site-D3e1i32Z.js";import{EmptyState as u}from"./empty-state-Dkho-_3J.js";import{DataTable as d}from"./data-table-BVWqHy9m.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getHeatmaps(d);return i({type:`heatmaps.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=h(),[l,m]=y(null),[x,S]=y(!0),[C,w]=y(null);if(g(e=>{e===`q`&&(a(),i(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getHeatmaps(t);n||(m(r),S(!1))}catch(e){n||(w(e.message),S(!1))}})(),()=>{n=!0}},[e,t]),x)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(o,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching heatmaps…`))));if(C)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(u,{reason:`error`,headline:`Failed to load`,hint:C}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(u,{reason:`no-data`,headline:`No heatmaps yet`,hint:`Enable heatmaps in your site settings`}));let T=[{key:`url`,label:`page`,width:36},{key:`type`,label:`type`,width:12},{key:`captureCount`,label:`captures`,align:`right`,width:10},{key:`createdAt`,label:`first seen`,width:24}];return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(o,{title:`Heatmaps (${l.length})`},_.createElement(d,{columns:T,data:l,zebra:!0})),_.createElement(f,{marginTop:1},_.createElement(p,{color:`gray`},`Open any heatmap at https://app.zenovay.com/heatmaps`)),_.createElement(c,{items:[{key:`q`,label:`quit`}]}))};export{x as heatmapsCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-CZ9IzjIH.js";import{readToken as t}from"./api-DXmhz2DM.js";import{ApiV2Client as n}from"./api-v2-29EI1kBw.js";import"./formatter-mW0Yk3Nt.js";import{isHeadless as r}from"./emit-D7VCOSNk.js";import{Panel as i}from"./panel-uygscwY5.js";import{Banner as a}from"./banner-BPQh2F8l.js";import{Keybar as o}from"./keybar-C7YkmK1U.js";import{EmptyState as s}from"./empty-state-Dkho-_3J.js";import{DataTable as c}from"./data-table-BVWqHy9m.js";import{Box as l,Text as u,render as d,useApp as f,useInput as p}from"ink";import m,{useEffect as h,useState as g}from"react";import _ from"ink-spinner";function v(e){if(!e)return`—`;let t=new Date(e);return Number.isNaN(t.getTime())?`—`:t.toISOString().slice(0,10)}async function y(e){let t=await e.me().catch(()=>null),n=t?.user.name?.trim()||t?.user.email||`you`,r=await e.getSites().catch(()=>[]),i=r.map(e=>({id:e.id,name:e.name,domain:e.url.replace(/^https?:\/\//,``).replace(/\/$/,``),lastActive:e.lastActiveAt??null})),a={visitors:0,pageviews:0,deltaPct:null};if(r.length>0){let t=r[0].id,[n,i]=await Promise.all([e.getStats(t,`7d`).catch(()=>null),e.getSources(t,`7d`,`prev`).catch(()=>null)]);n&&(a.visitors=n.visitors,a.pageviews=n.pageviews);let o=i?.sources?.filter(e=>typeof e.delta==`number`)??[];if(o.length>0){let e=o.reduce((e,t)=>e+(t.delta??0),0);a.deltaPct=e/o.length*100}}return{sites:i,weekly:a,userLabel:n}}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 n({config:a,cliVersion:i.cliVersion,token:o});if(r(i))try{let e=await y(s);return process.stdout.write(JSON.stringify({sites:e.sites,weekly:{visitors:e.weekly.visitors,pageviews:e.weekly.pageviews,deltaPct:e.weekly.deltaPct}},null,2)+`
2
+ `),0}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}return new Promise(e=>{let{unmount:t}=d(m.createElement(x,{api:s,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,cliVersion:t,onExit:n})=>{let{exit:r}=f(),[d,b]=g(null),[x,S]=g(!0),[C,w]=g(null);p(e=>{e===`q`&&(r(),n(0))}),h(()=>{let t=!1;return(async()=>{try{let n=await y(e);t||(b(n),S(!1))}catch(e){t||(w(e.message),S(!1))}})(),()=>{t=!0}},[e]);let T=`home · ${d?.userLabel??`…`}`,E=[{key:`q`,label:`quit`}];if(x)return m.createElement(l,{flexDirection:`column`},m.createElement(a,{version:t,subtitle:T}),m.createElement(i,{title:`Loading`,state:`busy`},m.createElement(l,null,m.createElement(u,{color:`cyan`},m.createElement(_,{type:`dots`})),m.createElement(u,null,` Fetching your home dashboard…`))));if(C)return m.createElement(l,{flexDirection:`column`},m.createElement(a,{version:t,subtitle:T}),m.createElement(s,{reason:`error`,headline:`Failed to load`,hint:C}),m.createElement(o,{items:E}));if(!d)return m.createElement(l,{flexDirection:`column`},m.createElement(a,{version:t,subtitle:T}),m.createElement(s,{reason:`no-data`,headline:`No data`}),m.createElement(o,{items:E}));let D=[{key:`name`,label:`site`,width:24},{key:`domain`,label:`domain`,width:32},{key:`lastActive`,label:`last active`,width:12,format:e=>v(e)}],O=d.weekly.deltaPct===null?`—`:`${d.weekly.deltaPct>=0?`+`:``}${d.weekly.deltaPct.toFixed(1)}%`;return m.createElement(l,{flexDirection:`column`},m.createElement(a,{version:t,subtitle:T}),m.createElement(i,{title:`Your sites (${d.sites.length})`},d.sites.length===0?m.createElement(u,{color:`gray`},"No sites yet — run `zenovay init` to add one."):m.createElement(c,{columns:D,data:d.sites,zebra:!0})),m.createElement(i,{title:`This week`},m.createElement(u,null,m.createElement(u,{color:`cyan`},`Visitors`),` `,d.weekly.visitors.toLocaleString(),` `,m.createElement(u,{color:`cyan`},`Pageviews`),` `,d.weekly.pageviews.toLocaleString(),` `,m.createElement(u,{color:`cyan`},`Δ vs last week`),` `,O)),m.createElement(o,{items:E}))};export{b as homeCommand};
@@ -0,0 +1 @@
1
+ import"./config-CZ9IzjIH.js";import"./api-DXmhz2DM.js";import{initCommand as e}from"./init-zU2l6vEv.js";import"./client-WzSy90dG.js";import"./formatter-mW0Yk3Nt.js";import"./emit-D7VCOSNk.js";import"./login-DWaz_EsV.js";import"./panel-uygscwY5.js";import"./banner-BPQh2F8l.js";import"./progress-row-DFOvHAc5.js";import"./prompt-BURfUNxp.js";import"./keybar-C7YkmK1U.js";import"./sparkline-Bkfzqe4x.js";export{e as initCommand};