@zenovay/cli 0.1.33 → 0.1.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -0
- package/dist/{agency-DEixFVRT.js → agency-Ba8f5PMP.js} +1 -1
- package/dist/ai-Dz_MAHHV.js +11 -0
- package/dist/alerts-qoMz5CX-.js +3 -0
- package/dist/{analytical-screen-BpTK5dCY.js → analytical-screen-BGMW3z_2.js} +1 -1
- package/dist/analytics-5ztZSLLH.js +1 -0
- package/dist/api-CJnD6Auw.js +1 -0
- package/dist/api-keys-D85DV2qg.js +4 -0
- package/dist/api-v2-CfYUL93L.js +1 -0
- package/dist/{api-v2-B_kZhVxd.js → api-v2-UJJ6ube8.js} +1 -1
- package/dist/{apply-D2xZJdvQ.js → apply-oUMOH7u2.js} +1 -1
- package/dist/{audit-CfOJ3rNW.js → audit-DqPlGP-B.js} +1 -1
- package/dist/{banner-BPQh2F8l.js → banner-gVm7GaJF.js} +1 -1
- package/dist/{bar-BNmNGwlD.js → bar-BPHTpgfb.js} +1 -1
- package/dist/bin.js +5 -3
- package/dist/{commands-DbkdKFGz.js → commands-BrU-VT7M.js} +1 -1
- package/dist/companies-CH3F-hmU.js +2 -0
- package/dist/completions-Ba0Zr-G3.js +135 -0
- package/dist/{config-Cmi_f_SY.js → config-CG7B8fR0.js} +1 -1
- package/dist/config-CUWIr4Qh.js +1 -0
- package/dist/{data-table-BUyOP6Nc.js → data-table-BnWXIW9M.js} +1 -1
- package/dist/deploys-B79-S9yT.js +2 -0
- package/dist/devices-BQnWRrD3.js +1 -0
- package/dist/{doctor-K37xh3M7.js → doctor-DjmsSn5Z.js} +1 -1
- package/dist/domains-Bg3Tt8bm.js +8 -0
- package/dist/emit-B8RbnBJe.js +2 -0
- package/dist/{empty-state-Dkho-_3J.js → empty-state-BkS6DKWZ.js} +1 -1
- package/dist/error-codes-CCK850J9.js +2 -0
- package/dist/errors-CmbIkaPX.js +2 -0
- package/dist/{events-tail-CXJUK5ka.js → events-tail-CE5QxNmF.js} +1 -1
- package/dist/examples-B8b7EpXo.js +1 -0
- package/dist/export-CNhqB2nk.js +4 -0
- package/dist/{funnel-nm9X3Od7.js → funnel-4A9Q_ZCD.js} +1 -1
- package/dist/geo-BAXdGLKJ.js +1 -0
- package/dist/globe-DMOyP2MN.js +2 -0
- package/dist/goals-B32fvItX.js +7 -0
- package/dist/health-CAnAYv9x.js +1 -0
- package/dist/health-DAyE161Z.js +1 -0
- package/dist/heatmaps-DkY7BW0E.js +1 -0
- package/dist/home-DL_Ty0eK.js +2 -0
- package/dist/init-C13-OX68.js +79 -0
- package/dist/init-C8KOSKzO.js +1 -0
- package/dist/insights-BDxlGN5s.js +1 -0
- package/dist/{integrations-B6IO1dM0.js → integrations-Eu2LbV95.js} +1 -1
- package/dist/journeys-CQMP6cvE.js +1 -0
- package/dist/{keybar-C7YkmK1U.js → keybar-BYQ2Bam1.js} +1 -1
- package/dist/live-BO8Wl0Q3.js +1 -0
- package/dist/login-CYaCSVUe.js +1 -0
- package/dist/login-D2ll-nBp.js +2 -0
- package/dist/logout-Cp7T5T1Y.js +2 -0
- package/dist/{metric-card-BRHv93Un.js → metric-card-DHIjVzNg.js} +1 -1
- package/dist/{notes-Cepz-K00.js → notes-BsegG0Q-.js} +1 -1
- package/dist/pages-Bi57FO27.js +1 -0
- package/dist/{plans-D8aqF_lo.js → plans-BXm8QsVF.js} +1 -1
- package/dist/{profile-DQJdZ-s_.js → profile-GGQyYHdV.js} +1 -1
- package/dist/{progress-row-DFOvHAc5.js → progress-row-C7gQLX4T.js} +1 -1
- package/dist/projects-t5f3WFmw.js +2 -0
- package/dist/{prompt-BURfUNxp.js → prompt-Db9Y7CVt.js} +1 -1
- package/dist/query-BmeQkD1w.js +8 -0
- package/dist/resolve-site-CZEwJoBj.js +2 -0
- package/dist/retention-6HhdWwsd.js +1 -0
- package/dist/revenue-CdXv5fdi.js +2 -0
- package/dist/secrets-A956dF9B.js +1 -0
- package/dist/secrets-BszMfkn1.js +1 -0
- package/dist/self-test-BSSwSeXl.js +4 -0
- package/dist/sessions-CvSKjWsw.js +1 -0
- package/dist/{settings-BsczzB3M.js → settings-CtEE3MFe.js} +1 -1
- package/dist/{share-BQjP_Anq.js → share-5a0qKu3z.js} +1 -1
- package/dist/sources-Dtp05gd2.js +2 -0
- package/dist/sparkline-BlAQSlYZ.js +1 -0
- package/dist/stats-DRRgb-C3.js +2 -0
- package/dist/{team-Bg-ggtky.js → team-q747Nwe6.js} +1 -1
- package/dist/{teams-Dvh7_Gkg.js → teams-nDIrOaly.js} +1 -1
- package/dist/{themes-CRvhjrRx.js → themes-DVChFf6Y.js} +1 -1
- package/dist/{tier-DyX4EObq.js → tier-uaU5pkTz.js} +1 -1
- package/dist/token-store-C1AqhmDP.js +1 -0
- package/dist/token-store-DpyCOgNw.js +1 -0
- package/dist/tour-Dp2WmQUO.js +8 -0
- package/dist/{update-DWBRR_PD.js → update-DrsZLYAQ.js} +1 -1
- package/dist/uptime-Bmg-epd-.js +1 -0
- package/dist/usage-ZJK4hekT.js +3 -0
- package/dist/use-SGwWI1Rq.js +3 -0
- package/dist/visitors-D7FmGVz1.js +2 -0
- package/dist/vitals-CRE0nVgp.js +2 -0
- package/dist/watch-DeWYzdo4.js +1 -0
- package/dist/webhooks-Ck6zBgz3.js +10 -0
- package/dist/webhooks-forward-X4iUnLrU.js +3 -0
- package/dist/wizard-bin.js +1 -1
- package/dist/{ws-client-_BBjvKCb.js → ws-client-Cp_nIj_N.js} +1 -1
- package/package.json +3 -2
- package/dist/ai-B8r28ZBm.js +0 -11
- package/dist/analytics-akHOj-51.js +0 -1
- package/dist/api-CeB_9iPg.js +0 -1
- package/dist/api-keys-DsQR075b.js +0 -7
- package/dist/companies-BToqUnFi.js +0 -2
- package/dist/completions-CXAOfyWo.js +0 -113
- package/dist/deploys-CgNr5r7M.js +0 -2
- package/dist/devices-C8xVqaBs.js +0 -1
- package/dist/domains-Bfx2vdwv.js +0 -11
- package/dist/emit-DBbMG9mK.js +0 -1
- package/dist/errors-BXwphY11.js +0 -2
- package/dist/geo-BaCNZ7-S.js +0 -1
- package/dist/globe-B4iKPH4T.js +0 -2
- package/dist/goals-D1qL286b.js +0 -10
- package/dist/health-ChZuTNP2.js +0 -1
- package/dist/health-DfgPNC1A.js +0 -1
- package/dist/heatmaps-e1Q72VWJ.js +0 -1
- package/dist/home-CtsY-gj0.js +0 -2
- package/dist/init-BVUEPvVr.js +0 -62
- package/dist/init-CJ1Py9a8.js +0 -1
- package/dist/insights-wx3wIgGV.js +0 -1
- package/dist/journeys-zPmCha98.js +0 -1
- package/dist/live-k32y1phk.js +0 -1
- package/dist/login-BSDS_gNS.js +0 -1
- package/dist/login-B_CW06vS.js +0 -1
- package/dist/logout-1ohk4uie.js +0 -2
- package/dist/pages-CAYP4Abn.js +0 -1
- package/dist/projects-BC8pmo7u.js +0 -2
- package/dist/query-X38xyHCI.js +0 -8
- package/dist/resolve-site-BUpzvcMz.js +0 -2
- package/dist/retention-DQPI6wVN.js +0 -1
- package/dist/revenue-CD1YwoZj.js +0 -2
- package/dist/sessions-Dv-Z29cQ.js +0 -1
- package/dist/sources-DL_o-kkA.js +0 -2
- package/dist/sparkline-Bkfzqe4x.js +0 -1
- package/dist/stats-DRy2d3At.js +0 -2
- package/dist/uptime-DACm8Hdh.js +0 -1
- package/dist/usage-BhLXHEkY.js +0 -3
- package/dist/use-DJ0b_xNo.js +0 -5
- package/dist/visitors-CrF-_BuG.js +0 -2
- package/dist/vitals-lpeK0mbA.js +0 -2
- package/dist/watch-BMrHdnHX.js +0 -1
- package/dist/webhooks-Ddhz2P7n.js +0 -15
- package/dist/webhooks-forward-BUoKx2Dz.js +0 -3
- /package/dist/{check-Comj8AkL.js → check-D9G0N7NB.js} +0 -0
- /package/dist/{client-WzSy90dG.js → client-CN2wyAL7.js} +0 -0
- /package/dist/{confirm-D_aKHknn.js → confirm-Dk3CEdpn.js} +0 -0
- /package/dist/{fmt-DSJbiH8w.js → fmt-CdJ3NqAG.js} +0 -0
- /package/dist/{formatter-mW0Yk3Nt.js → formatter-KOe_hjhc.js} +0 -0
- /package/dist/{globe-BrlflaZ1.js → globe-WYN8kVDK.js} +0 -0
- /package/dist/{panel-uygscwY5.js → panel-jycoT562.js} +0 -0
- /package/dist/{ui-BRls3_H3.js → ui-hZ5oXnwY.js} +0 -0
- /package/dist/{wrapper-BgssVzXH.js → wrapper-Ce_PZUZ9.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./panel-
|
|
1
|
+
import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./panel-jycoT562.js";import{Banner as a}from"./banner-gVm7GaJF.js";import"./progress-row-C7gQLX4T.js";import"./prompt-Db9Y7CVt.js";import"./keybar-BYQ2Bam1.js";import"./sparkline-BlAQSlYZ.js";import"./data-table-BnWXIW9M.js";import"./bar-BPHTpgfb.js";import"./ui-hZ5oXnwY.js";import{promises as o}from"node:fs";import{Box as s,Text as c,render as l}from"ink";import u from"react";const d=[{name:`mocha`,theme:n,mode:`dark`},{name:`latte`,theme:t,mode:`light`},{name:`dracula`,theme:e,mode:`dark`},{name:`tokyoNight`,theme:i,mode:`dark`},{name:`nord`,theme:r,mode:`dark`}],f=[`name`,`bg`,`fg`,`muted`,`accent`,`accent2`,`success`,`warn`,`error`,`border`,`dim`];function p({name:e,theme:t,mode:n}){let r=[t.accent,t.accent2,t.success,t.warn,t.error];return u.createElement(s,{flexDirection:`row`},u.createElement(c,{bold:!0},e.padEnd(14)),u.createElement(c,{color:`gray`},n.padEnd(7)),r.map((e,t)=>u.createElement(c,{key:t,color:e},`████`,` `)),u.createElement(c,{color:`gray`},t.bg))}function m({themes:e}){return u.createElement(s,{flexDirection:`column`},u.createElement(a,{version:`themes`}),u.createElement(s,{marginTop:1,marginBottom:1},u.createElement(c,{color:`gray`},e.length,` themes — pass --theme <name> to any command, or set in your config.`)),u.createElement(s,{flexDirection:`column`},u.createElement(s,null,u.createElement(c,{bold:!0},`name`.padEnd(14)),u.createElement(c,{bold:!0},`mode`.padEnd(7)),u.createElement(c,{bold:!0},`swatch`.padEnd(28)),u.createElement(c,{bold:!0},`bg`)),e.map(({name:e,theme:t,mode:n})=>u.createElement(p,{key:e,name:e,theme:t,mode:n}))))}async function h(e){if(e.validate){let t;try{let n=await o.readFile(e.validate,`utf8`);t=JSON.parse(n)}catch(t){return process.stderr.write(`✗ Failed to read ${e.validate}: ${t.message}\n`),1}let n=f.filter(e=>t[e]==null);return n.length>0?(process.stderr.write(`✗ Missing required tokens: ${n.join(`, `)}\n`),e.json&&process.stdout.write(JSON.stringify({ok:!1,missing:n},null,2)+`
|
|
2
2
|
`),1):(process.stdout.write(`✔ Valid theme (${f.length} tokens present).\n`),e.json&&process.stdout.write(JSON.stringify({ok:!0,theme:t},null,2)+`
|
|
3
3
|
`),0)}if(e.json)return process.stdout.write(JSON.stringify({themes:d.map(({name:e,theme:t,mode:n})=>({name:e,mode:n,background:t.bg,foreground:t.fg,accent:t.accent}))},null,2)+`
|
|
4
4
|
`),0;let{waitUntilExit:t}=l(u.createElement(m,{themes:d}));return await t(),0}export{h as themesCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readConfig as e,updateConfig as t}from"./config-
|
|
1
|
+
import{readConfig as e,updateConfig as t}from"./config-CG7B8fR0.js";const n=5*60*1e3,r=new Set([`free`,`pro`,`scale`,`enterprise`]),i={free:0,pro:1,scale:2,enterprise:3},a=`https://app.zenovay.com/billing`;function o(e){let t=(e??`free`).trim().toLowerCase();return r.has(t)?t:`free`}async function s(r){let i=await e(),a=Date.now();if(i.cachedTier&&i.cachedTierAt&&a-i.cachedTierAt<n)return o(i.cachedTier);try{let e=await r.me(),n=o(e.team?.plan);return await t({cachedTier:n,cachedTierAt:a}),n}catch{return i.cachedTier?o(i.cachedTier):`free`}}async function c(e,t){let n=await s(e);if(i[n]>=i[t])return;let r=t.charAt(0).toUpperCase()+t.slice(1);throw Error(`This command requires the ${r} plan or higher (you're on ${n}). Upgrade at ${a}.`)}export{s as getCachedTier,c as requireTier};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{configDir as e}from"./config-CG7B8fR0.js";import t from"node:path";import{promises as n}from"node:fs";import{z as r}from"zod";const i=r.object({accessToken:r.string().min(1),refreshToken:r.string().min(1),expiresAt:r.number(),tokenType:r.literal(`Bearer`).default(`Bearer`),scope:r.string().optional(),userId:r.string().optional(),teamId:r.string().optional(),email:r.string().email().optional(),region:r.string().optional(),cliVersionAtIssue:r.string().optional()});function a(){return t.join(e(),`auth.json`)}async function o(e){let r=a(),o;try{o=await n.stat(r)}catch(e){if(e.code===`ENOENT`)return null;throw e}if(process.platform!==`win32`){let n=o.mode&511;if(n&63){let i=e?.strict??!0;if(i)throw Error(`Refusing to read ${r}: file has insecure permissions ${n.toString(8).padStart(3,`0`)} (expected 600). Fix: chmod 600 "${r}" && chmod 700 "${t.dirname(r)}"`)}}let s=await n.readFile(r,`utf8`),c;try{c=JSON.parse(s)}catch{throw Error(`Auth file at ${r} is not valid JSON. Run \`zenovay login\` again.`)}let l=i.safeParse(c);if(!l.success)throw Error(`Auth file at ${r} is malformed. Run \`zenovay login\` again.`);return l.data}async function s(t){let r=e();await n.mkdir(r,{recursive:!0,mode:448});let o=a(),s=i.parse(t),c=JSON.stringify(s,null,2);if(await n.writeFile(o,c,{mode:384}),process.platform!==`win32`){await n.chmod(o,384);try{await n.chmod(r,448)}catch{}}}async function c(){try{await n.unlink(a())}catch(e){if(e.code!==`ENOENT`)throw e}}function l(e,t=3e4){return Date.now()>=e.expiresAt-t}export{a as authPath,c as clearToken,l as isExpired,o as readToken,i as tokenStateSchema,s as writeToken};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./config-CG7B8fR0.js";import{authPath as e,clearToken as t,isExpired as n,readToken as r,tokenStateSchema as i,writeToken as a}from"./token-store-C1AqhmDP.js";export{r as readToken};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{Panel as e,useTheme as t}from"./panel-jycoT562.js";import{Banner as n}from"./banner-gVm7GaJF.js";import{spawn as r}from"node:child_process";import{Box as i,Text as a,render as o,useApp as s,useInput as c}from"ink";import l,{useEffect as u,useState as d}from"react";import f from"ink-spinner";const p=[{title:`Identify`,explainer:"Who you are and which team you’re acting on. CLI uses your saved bearer token from `zenovay login`.",command:`profile show`},{title:`Tracked sites`,explainer:`The websites your account can read.`,command:`domains list`},{title:`Today's analytics`,explainer:`What visitors did on your sites in the last 24 hours.`,command:`analytics --range 1d`},{title:`Traffic sources`,explainer:`Where visitors come from — direct, organic, referrals.`,command:`sources --range 7d`},{title:`Recent sessions`,explainer:`Replay-style listing of recorded sessions (Pro+).`,command:`sessions --limit 5`,tierGated:!0},{title:`Alert configs`,explainer:`Threshold-based alerts you’ve set up.`,command:`alerts list`,tierGated:!0},{title:`Export today`,explainer:`Bulk-export analytics data to CSV.`,command:`export analytics --range 1d --format csv`,csvPreview:!0},{title:`Self-test`,explainer:`One-command verification that everything works.`,command:`self-test --quick`,maxLines:24}],m=p.length;async function h(e){let t=process.argv[1]??process.execPath;return e.nonInteractive?g(t,e.cliVersion):new Promise(n=>{let{unmount:r}=o(l.createElement(y,{cliVersion:e.cliVersion,binPath:t,onDone:e=>{r(),n(e)}}))})}async function g(e,t){process.stdout.write(`Zenovay CLI v${t} — tour (non-interactive)\n`),process.stdout.write(`────────────────────────────────────────────────────
|
|
2
|
+
|
|
3
|
+
`);for(let t=0;t<p.length;t++){let n=p[t];process.stdout.write(`[${t+1}/${m}] ${n.title}\n`),process.stdout.write(` ${n.explainer}\n`),process.stdout.write(` $ zenovay ${n.command}\n\n`);let r=await v(e,n);if(r.tierSkipped){process.stdout.write(` → Skipping (requires Pro plan)
|
|
4
|
+
|
|
5
|
+
`);continue}let i=r.text.split(`
|
|
6
|
+
`),a=n.csvPreview?10:n.maxLines??12,o=i.slice(0,a);for(let e of o)process.stdout.write(` ${e}\n`);i.length>a&&process.stdout.write(` … (${i.length-a} more lines)\n`),process.stdout.write(`
|
|
7
|
+
`)}return process.stdout.write("Tour complete. Run `zenovay self-test` for full verification.\n"),0}const _=2e4;function v(e,t){return new Promise(n=>{let i=t.command.split(` `).filter(Boolean);t.csvPreview||i.push(`--json`);let a=r(`node`,[e,...i],{env:{...process.env,ZENOVAY_NO_UPDATE_CHECK:`1`,NO_COLOR:`1`},stdio:[`ignore`,`pipe`,`pipe`]}),o=``,s=``,c=setTimeout(()=>{try{a.kill(`SIGKILL`)}catch{}},_);a.stdout?.on(`data`,e=>{o+=e.toString(`utf8`),o.length>524288&&(o=o.slice(0,524288))}),a.stderr?.on(`data`,e=>{s+=e.toString(`utf8`),s.length>524288&&(s=s.slice(0,524288))}),a.on(`error`,e=>{clearTimeout(c),n({text:`[spawn error: ${e.message}]`,exitCode:-1,tierSkipped:!1})}),a.on(`close`,e=>{clearTimeout(c);let r=o||s,i=t.tierGated===!0&&/tier_insufficient/.test(o+s);n({text:r.trimEnd(),exitCode:e??0,tierSkipped:i})})})}const y=({cliVersion:e,binPath:t,onDone:r})=>{let[o,f]=d(0),[h,g]=d(null),[_,y]=d(!0),{exit:C}=s(),w=p[o];return u(()=>{if(!w){setTimeout(()=>{C(),r(0)},30);return}let e=!1;return y(!0),g(null),v(t,w).then(t=>{e||(g(t),y(!1))}),()=>{e=!0}},[o]),c((e,t)=>{if(t.return){_||f(e=>e+1);return}if(e===`s`||e===`S`){_||f(e=>e+1);return}(e===`q`||e===`Q`||t.escape||t.ctrl&&e===`c`)&&(C(),r(0))}),w?l.createElement(i,{flexDirection:`column`},l.createElement(n,{version:e,subtitle:`tour · step ${o+1} of ${m}`}),l.createElement(i,{flexDirection:`column`,marginTop:1},l.createElement(b,{index:o,step:w}),l.createElement(i,{marginTop:1},l.createElement(x,{step:w,output:h,running:_})),l.createElement(i,{marginTop:1},l.createElement(S,{running:_})))):l.createElement(i,{flexDirection:`column`},l.createElement(n,{version:e,subtitle:`tour complete`}),l.createElement(i,{marginTop:1},l.createElement(a,null,`All 8 steps done. Run `),l.createElement(a,{bold:!0},`zenovay self-test`),l.createElement(a,null,` for the full verification suite.`)))},b=({index:e,step:n})=>{let{theme:r}=t();return l.createElement(i,{flexDirection:`column`},l.createElement(i,{flexDirection:`row`},l.createElement(a,{color:r.accent,bold:!0},`[`,e+1,`/`,m,`]`),l.createElement(a,null,` `),l.createElement(a,{color:r.fg,bold:!0},n.title)),l.createElement(i,null,l.createElement(a,{color:r.dim},n.explainer)),l.createElement(i,null,l.createElement(a,{color:r.dim},`$ `),l.createElement(a,{color:r.fg},`zenovay `,n.command)))},x=({step:n,output:r,running:o})=>{let{theme:s}=t();if(o||!r)return l.createElement(e,{title:`output`,state:`busy`},l.createElement(i,null,l.createElement(a,{color:s.accent},l.createElement(f,{type:`dots`})),l.createElement(a,null,` `),l.createElement(a,{color:s.dim},`running…`)));if(r.tierSkipped)return l.createElement(e,{title:`output`,state:`warn`,pillColor:s.warn},l.createElement(i,null,l.createElement(a,{color:s.warn},`→ Skipping (requires Pro plan)`)));let c=r.text.split(`
|
|
8
|
+
`),u=n.csvPreview?10:n.maxLines??12,d=c.slice(0,u),p=c.length-u,m=r.exitCode===0?`ok`:`err`,h=r.exitCode===0?s.success:s.error;return l.createElement(e,{title:`output (exit ${r.exitCode})`,state:m,pillColor:h},d.map((e,t)=>l.createElement(i,{key:t},l.createElement(a,{color:s.fg},e||` `))),p>0?l.createElement(i,null,l.createElement(a,{color:s.dim},`… (`,p,` more lines)`)):null)},S=({running:e})=>{let{theme:n}=t();return e?l.createElement(a,{color:n.dim},`(working… [q] quit)`):l.createElement(i,{flexDirection:`row`},l.createElement(a,{color:n.accent,bold:!0},`[Enter]`),l.createElement(a,{color:n.dim},` continue · `),l.createElement(a,{color:n.accent,bold:!0},`[s]`),l.createElement(a,{color:n.dim},` skip · `),l.createElement(a,{color:n.accent,bold:!0},`[q]`),l.createElement(a,{color:n.dim},` quit`))};export{h as tourCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import{classifyBump as t,fetchManifest as n}from"./check-D9G0N7NB.js";import{applyUpdate as r}from"./apply-oUMOH7u2.js";import"./formatter-KOe_hjhc.js";import{emit as i,isHeadless as a}from"./emit-B8RbnBJe.js";async function o(o){let s=await e(),c=await n({cliBase:s.cliBase}),l=t(o.cliVersion,c.latest);if(o.check)return a({json:o.json})?i({type:`info`,message:`latest=${c.latest} current=${o.cliVersion} bump=${l}`}):process.stdout.write(`Current: ${o.cliVersion}\nLatest: ${c.latest}\nBump: ${l}\n`),{updated:!1,from:o.cliVersion,to:c.latest};if(l===`none`)return a({json:o.json})||process.stdout.write(`Already on latest (${o.cliVersion}).\n`),{updated:!1,from:o.cliVersion,to:c.latest};if(l===`downgrade`&&!o.forceDowngrade)throw Error(`Refused to downgrade ${o.cliVersion} → ${c.latest}. Pass --force-downgrade if you really want this.`);let u=await r({currentVersion:o.cliVersion,cliBase:s.cliBase,binaryPath:o.binaryPath,forceDowngrade:o.forceDowngrade});return a({json:o.json})?u.updated&&i({type:`update.applied`,from:u.from,to:u.to}):u.updated?process.stdout.write(`Updated ${u.from} → ${u.to}\n`):process.stdout.write(`Not updated (${u.reason??`unknown`}).\n`),u}export{o as updateCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-UJJ6ube8.js";import{requireTier as r}from"./tier-uaU5pkTz.js";import"./formatter-KOe_hjhc.js";import{emit as i,isHeadless as a}from"./emit-B8RbnBJe.js";import{Panel as o}from"./panel-jycoT562.js";import{Banner as s}from"./banner-gVm7GaJF.js";import"./prompt-Db9Y7CVt.js";import{Keybar as c}from"./keybar-BYQ2Bam1.js";import{resolveSiteId as l}from"./resolve-site-CZEwJoBj.js";import{DataTable as u}from"./data-table-BnWXIW9M.js";import{EmptyState as d}from"./empty-state-BkS6DKWZ.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";function x(e){return e===`up`?{glyph:`● up`,color:`green`}:e===`down`?{glyph:`● down`,color:`red`}:{glyph:`○ unknown`,color:`gray`}}function S(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.round((t-Date.now())/(1e3*60*60*24));return`${n}d`}async function C(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getUptime(d);return i({type:`uptime.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(w,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const w=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=h(),[l,m]=y(null),[C,w]=y(!0),[T,E]=y(null);if(g(e=>{e===`q`&&(a(),i(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getUptime(t);n||(m(r.monitors),w(!1))}catch(e){n||(E(e.message),w(!1))}})(),()=>{n=!0}},[e,t]),C)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`uptime · ${n}`}),_.createElement(o,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching monitors…`))));if(T)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`uptime · ${n}`}),_.createElement(d,{reason:`error`,headline:`Failed to load`,hint:T}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`uptime · ${n}`}),_.createElement(d,{reason:`no-data`,headline:`No monitors configured`,hint:`Add one at app.zenovay.com/uptime`}));let D=[{key:`url`,label:`monitor`,width:36},{key:`status`,label:`status`,width:12,format:e=>x(String(e)).glyph},{key:`p95ms`,label:`p95 ms`,align:`right`,width:8,format:e=>typeof e==`number`?String(e):`—`},{key:`sslExpiry`,label:`ssl exp`,align:`right`,width:7,format:e=>S(e)}];return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`uptime · ${n}`}),_.createElement(o,{title:`Monitors (${l.length})`},_.createElement(u,{columns:D,data:l,zebra:!0})),_.createElement(c,{items:[{key:`q`,label:`quit`}]}))};export{C as uptimeCommand};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-UJJ6ube8.js";import{fmtDate as r,fmtNumber as i}from"./fmt-CdJ3NqAG.js";const a=1e8,o=e=>e<=0||e>=a;function s(e,t,n=24){if(o(t))return`─`.repeat(n);let r=Math.min(1,e/t),i=Math.round(r*n);return`█`.repeat(i)+`░`.repeat(Math.max(0,n-i))}function c(e,t){if(o(t))return`—`;let n=e/t*100;return`${n.toFixed(0)}%`}function l(e,t){if(o(t))return``;let n=e/t;return n>=1?`⚠ over limit`:n>=.8?`⚠ near limit`:``}function u(e,t){return o(e)?`∞`:t(e)}async function d(a){let o=await e(),d=await t({strict:!1});if(!d)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let f=new n({config:o,cliVersion:a.cliVersion,token:d}),p;try{p=await f.getUsage()}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}if(a.json)return process.stdout.write(JSON.stringify(p,null,2)+`
|
|
2
|
+
`),0;let m=[{label:`events this month`,used:p.events.thisMonth,limit:p.events.monthlyLimit,format:i},{label:`events today`,used:p.events.today,limit:p.events.dailyLimit,format:i},{label:`websites`,used:p.websites.used,limit:p.websites.limit},{label:`team members`,used:p.teamMembers.used,limit:p.teamMembers.limit}],h=18,g=8,_=9,v=[];v.push(``),v.push(` plan: ${p.plan}`),v.push(``);for(let e of m){let t=e.format??i,n=t(e.used).padStart(g),r=u(e.limit,t).padStart(_),a=s(e.used,e.limit),o=c(e.used,e.limit).padStart(5),d=l(e.used,e.limit);v.push(` ${e.label.padEnd(h)} ${n} / ${r} ${a} ${o} ${d}`.trimEnd())}return v.push(` ${`api keys`.padEnd(h)} ${i(p.apiKeys.used).padStart(g)} / ${`—`.padStart(_)} ${`─`.repeat(24)} ${`—`.padStart(5)}`),v.push(``),v.push(` data retention: ${p.dataRetentionDays} days`),v.push(` last event: ${r(p.events.lastEventAt,`datetime`)}`),v.push(``),process.stdout.write(v.join(`
|
|
3
|
+
`)),0}export{d as usageCommand};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{readConfig as e,updateConfig as t}from"./config-CG7B8fR0.js";import{ApiClient as n}from"./api-CJnD6Auw.js";import{readToken as r}from"./token-store-C1AqhmDP.js";import"./formatter-KOe_hjhc.js";import{emitEnvelope as i,wrapSnapshot as a}from"./emit-B8RbnBJe.js";async function o(o){if(o.reset)return await t({defaultSiteId:void 0,defaultSiteName:void 0}),o.json?(i(a({reset:!0,defaultSiteId:null},`use.reset`)),0):(process.stdout.write(`Default site cleared.
|
|
2
|
+
`),0);if(!o.match||!o.match.trim()){let t=await e();if(t.defaultSiteId){let e={siteId:t.defaultSiteId,name:t.defaultSiteName??null,domain:t.defaultSiteName??null};return o.json?(i(a(e,`use.current`,{siteId:t.defaultSiteId})),0):(process.stdout.write(`Default site: ${e.name??e.siteId} (${t.defaultSiteId})\n`),0)}return o.json?(i(a(null,`use.current`,{})),0):(process.stdout.write("No default site set. Run `zenovay use <domain>` to set one.\n"),0)}let c=await e(),l=await r({strict:!1});if(!l&&!process.env.ZENOVAY_API_TOKEN)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:c,cliVersion:o.cliVersion,token:l}),d=o.match.trim().toLowerCase(),f=await u.getSites(),p=f.find(e=>e.id===o.match||e.trackingCode===o.match||e.url===o.match),m=p??f.find(e=>s(e.url).includes(d)||e.name.toLowerCase().includes(d));return m?(await t({defaultSiteId:m.id,defaultSiteName:m.name}),o.json?(i(a({siteId:m.id,name:m.name,domain:s(m.url)},`use.set`,{siteId:m.id})),0):(process.stdout.write(`Default site → ${m.name} (${m.url})\n`),0)):(process.stderr.write(`No site matched "${o.match}". Your sites:\n${f.map(e=>` ${e.name} — ${e.url} — ${e.id}`).join(`
|
|
3
|
+
`)}\n`),2)}function s(e){return e.toLowerCase().replace(/^https?:\/\//,``).replace(/\/.*$/,``)}export{o as useCommand};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-UJJ6ube8.js";import{formatTabular as r,selectFormat as i}from"./formatter-KOe_hjhc.js";import"./panel-jycoT562.js";import"./banner-gVm7GaJF.js";import"./prompt-Db9Y7CVt.js";import"./keybar-BYQ2Bam1.js";import{brailleSpark as a,spark as o}from"./sparkline-BlAQSlYZ.js";import{resolveSiteId as s}from"./resolve-site-CZEwJoBj.js";import{DataTable as c}from"./data-table-BnWXIW9M.js";import{runAnalyticalScreen as l}from"./analytical-screen-BGMW3z_2.js";import{Box as u,Text as d}from"ink";import f from"react";function p(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function m(e){let t=e,n=t.events??t.timeseries;return Array.isArray(n)&&n.length>0?o(n,8):`▁▁▁▁▁▁▁▁`}function h(e){let t=e;if(typeof t.sessionDurationSec==`number`)return t.sessionDurationSec;if(typeof t.sessionDurationMs==`number`)return Math.floor(t.sessionDurationMs/1e3);if(typeof t.durationMs==`number`)return Math.floor(t.durationMs/1e3);if(typeof t.duration==`number`)return Math.floor(t.duration/1e3);let n=Date.parse(e.startedAt);return Number.isNaN(n)?0:Math.max(0,Math.floor((Date.now()-n)/1e3))}async function g(o){let g=await e(),_=await t({strict:!1}),v=new n({config:g,cliVersion:o.cliVersion,token:_}),y,b;try{({siteId:y,site:b}=await s(v,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let x=i(o),S=o.limit??50,C=typeof o.minDuration==`number`&&o.minDuration>0?o.minDuration:0,w=e=>C<=0?e:e.filter(e=>h(e)>=C),T=[{key:`startedAt`,label:`when`,width:6,format:e=>p(String(e))},{key:`country`,label:`country`,width:7,format:e=>String(e??`—`)},{key:`city`,label:`city`,width:14,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`page`,label:`page`,width:26,format:e=>String(e??`—`)},{key:`id`,label:`24h`,width:8,format:(e,t)=>m(t)}];return l({cliVersion:o.cliVersion,title:`visitors · ${y}`,commandName:`visitors`,authToken:_?.accessToken??null,refreshIntervalMs:1e4,fetcher:e=>v.getVisitors(y,{limit:S},e),format:x,headlessEmit:(e,t)=>{let n={...e,visitors:w(e.visitors)};if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(n,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
|
|
2
|
+
`);return}let i=[`startedAt`,`country`,`city`,`device`,`page`];process.stdout.write(r(n.visitors,i,t))},panels:[{id:`live`,title:`Now`,render:e=>{let t=w(e.visitors),n=[...t].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)),r=n[0],i=Array(24*6).fill(0),o=Date.now();for(let e of t){let t=o-new Date(e.startedAt).getTime(),n=Math.floor(t/(10*60*1e3));n>=0&&n<i.length&&(i[i.length-1-n]+=1)}return f.createElement(u,{flexDirection:`column`},f.createElement(d,{bold:!0},t.length,` live`),f.createElement(d,{color:`gray`},a(i,40)),r?f.createElement(d,{color:`gray`},`top: `,r.city??r.country??`—`,` · `,r.page??`—`):null)}},{id:`visitors`,title:`Active sessions`,render:e=>{let t=w(e.visitors),n=[...t].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)).slice(0,S);return n.length===0?f.createElement(d,{color:`gray`},`— no visitors yet —`):f.createElement(c,{columns:T,data:n,headerStyle:`accent`})}}]})}export{g as visitorsCommand};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-UJJ6ube8.js";import{formatTabular as r,selectFormat as i}from"./formatter-KOe_hjhc.js";import"./panel-jycoT562.js";import"./banner-gVm7GaJF.js";import"./prompt-Db9Y7CVt.js";import"./keybar-BYQ2Bam1.js";import{resolveSiteId as a}from"./resolve-site-CZEwJoBj.js";import{DataTable as o}from"./data-table-BnWXIW9M.js";import{runAnalyticalScreen as s}from"./analytical-screen-BGMW3z_2.js";import{Box as c,Text as l}from"ink";import u from"react";const d={lcp:{good:2500,poor:4e3},inp:{good:200,poor:500},cls:{good:.1,poor:.25},ttfb:{good:800,poor:1800},fcp:{good:1800,poor:3e3}};function f(e,t){let n=d[e];return t<=n.good?{label:`good`,color:`green`}:t<=n.poor?{label:`needs`,color:`yellow`}:{label:`poor`,color:`red`}}function p(e,t){return e===`cls`?t.toFixed(3):t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`}async function m(d){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:d.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:d.siteId,headless:!!(d.json||d.csv||d.tsv||d.ndjson),cliVersion:d.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(d),b=[{key:`url`,label:`url`,width:32},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,label:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`lcp`,e.p75):`—`},{key:`inp`,label:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`inp`,e.p75):`—`},{key:`cls`,label:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?p(`cls`,e.p75):`—`},{key:`samples`,label:`n`,width:6,align:`right`}];return s({cliVersion:d.cliVersion,title:`vitals · ${_}`,commandName:`vitals`,authToken:h?.accessToken??null,refreshIntervalMs:d.watch?5*6e4:0,fetcher:e=>g.getVitals(_,{url:d.url,device:d.device,window:d.window},e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
|
|
2
|
+
`);return}process.stdout.write(r(e.vitals,[`url`,`device`,`samples`],t))},panels:[{id:`summary`,title:`Site-wide p75`,render:e=>{let t=t=>{let n=0,r=0;for(let i of e.vitals){let e=i[t]?.p75;typeof e==`number`&&(n+=e*i.samples,r+=i.samples)}return r>0?n/r:0},n=[`lcp`,`inp`,`cls`,`ttfb`,`fcp`];return u.createElement(c,{flexDirection:`column`},n.map(e=>{let n=t(e),r=f(e,n);return u.createElement(l,{key:e},u.createElement(l,{color:r.color},`● `),u.createElement(l,{bold:!0},e.toUpperCase().padEnd(5)),` `,u.createElement(l,null,p(e,n).padStart(8)),` `,u.createElement(l,{color:r.color},r.label))}))}},{id:`pages`,title:`Per-page`,render:e=>e.vitals.length===0?u.createElement(l,{color:`gray`},`— no vitals data yet —`):u.createElement(o,{data:e.vitals.slice(0,15),columns:b,headerStyle:`accent`})}]})}export{m as vitalsCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-UJJ6ube8.js";import{parseSseStream as r}from"./client-CN2wyAL7.js";import"./formatter-KOe_hjhc.js";import{emit as i,isHeadless as a}from"./emit-B8RbnBJe.js";import{Panel as o}from"./panel-jycoT562.js";import{Banner as s}from"./banner-gVm7GaJF.js";import"./prompt-Db9Y7CVt.js";import{Keybar as c}from"./keybar-BYQ2Bam1.js";import{spark as l}from"./sparkline-BlAQSlYZ.js";import{resolveSiteId as u}from"./resolve-site-CZEwJoBj.js";import{EmptyState as d}from"./empty-state-BkS6DKWZ.js";import{Globe as f}from"./globe-WYN8kVDK.js";import{z as p}from"zod";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";import C from"ink-text-input";const w=p.object({siteId:p.string().optional(),window:p.string().optional(),totalVisitors:p.number().optional(),visitors:p.object({count:p.number().optional(),series:p.array(p.number()).optional()}).optional(),topPages:p.array(p.object({path:p.string(),views:p.number().optional(),count:p.number().optional()})).optional(),sources:p.array(p.object({source:p.string(),visitors:p.number()})).optional()}).passthrough();async function T(r){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:r.cliVersion,token:s}),l;try{({siteId:l}=await u(c,{explicit:r.siteId,headless:!!r.json,cliVersion:r.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(a(r)){let e=await c.getDashboardSnapshot(l);return i({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:c,siteId:l,intervalMs:r.intervalMs??15e3,cliVersion:r.cliVersion,onExit:n=>{t(),e(n)}}))})}const E=({api:e,siteId:t,intervalMs:n,cliVersion:i,onExit:a})=>{let{exit:l}=_(),[u,p]=x(null),[g,C]=x(null),[T,E]=x(null),[P,F]=x([]),[I,L]=x(!0),[R,z]=x(null),[B,V]=x(1),[H,U]=x(!1),[W,G]=x(!1);v((e,t)=>{if(e===`q`){l(),a(0);return}if(e===`?`||e===`/`){G(e=>!e);return}if(e===`g`){U(e=>!e);return}if(t.tab){V(e=>{let n=t.shift?(e+4)%6+1:e%6+1;return n});return}(e===`1`||e===`2`||e===`3`||e===`4`||e===`5`||e===`6`)&&V(Number(e))});let[K,q]=x(!1);if(b(()=>{let r=!1,i=async()=>{try{let n=await e.getDashboardSnapshot(t);if(r)return;let i=w.safeParse(n);if(!i.success){q(!0),L(!1);return}q(!1);let a=i.data,o={visitors:a.visitors??(typeof a.totalVisitors==`number`?{count:a.totalVisitors}:void 0),topPages:a.topPages?.map(e=>({path:e.path,views:e.views??e.count??0})),sources:a.sources};p(o),e.getVitals(t).then(e=>{r||C(e)},()=>{}),e.getGoals(t).then(e=>{r||E(e)},()=>{}),L(!1),z(null)}catch(e){r||z(e.message)}};i();let a=setInterval(i,n);return()=>{r=!0,clearInterval(a)}},[e,t,n]),b(()=>{let n=new AbortController;return(async()=>{try{let i=await e.openEventsStream(t,n.signal);for await(let e of r(i))e.type===`error`&&F(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>n.abort()},[e,t]),I)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:i,subtitle:`watch · ${t}`}),y.createElement(o,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`magenta`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching snapshot…`))));if(R&&!u)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:i,subtitle:`watch · ${t}`}),y.createElement(o,{title:`Error`,state:`err`},y.createElement(h,{color:`red`},R)));if(K&&!u)return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:i,subtitle:`watch · ${t}`}),y.createElement(d,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let J=process.stdout.columns??80,Y=Math.max(20,Math.floor(J/3)-1),X=[];return y.createElement(m,{flexDirection:`column`},y.createElement(s,{version:i,subtitle:`watch · ${t}${H?` · globe`:``}`}),y.createElement(m,{flexDirection:`row`},y.createElement(m,{flexDirection:`column`},H?y.createElement(o,{title:`Live globe`,focused:B===1,width:Y},y.createElement(f,{data:X,width:Math.max(40,Y-4),height:12})):y.createElement(O,{snapshot:u,focused:B===1,width:Y}),y.createElement(j,{events:P,focused:B===4,width:Y})),y.createElement(m,{flexDirection:`column`},y.createElement(k,{snapshot:u,focused:B===2,width:Y}),y.createElement(M,{vitals:g,focused:B===5,width:Y})),y.createElement(m,{flexDirection:`column`},y.createElement(A,{snapshot:u,focused:B===3,width:Y}),y.createElement(N,{goals:T,focused:B===6,width:Y}))),W?y.createElement(D,{api:e,siteId:t,width:J-2}):null,y.createElement(c,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:H?`panels`:`globe`},{key:`?/`,label:W?`close chat`:`ai chat`},{key:`q`,label:`quit`}]}))},D=({api:e,siteId:t,width:n})=>{let[i,a]=x(``),[s,c]=x([]),[l,u]=x(!1),[d,f]=x(``),[p,g]=x(null),_=async n=>{let i=n.trim();if(!i||l)return;g(null),a(``);let o=[...s,{role:`user`,content:i}];c(o),u(!0),f(``);try{let n=o.map(e=>({role:e.role,content:e.content})),i=await e.openAiStream(`chat`,{messages:n,siteId:t},void 0),a=``;for await(let e of r(i))if(e.type===`delta`)a+=e.content,f(a);else if(e.type===`error`)g(`${e.code}: ${e.message}`);else if(e.type===`done`)break;c([...o,{role:`assistant`,content:a}]),f(``)}catch(e){g(e instanceof Error?e.message:`chat failed`)}finally{u(!1)}};return y.createElement(m,{marginTop:1},y.createElement(o,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:n},y.createElement(m,{flexDirection:`column`},s.slice(-6).map((e,t)=>y.createElement(m,{key:t,flexDirection:`column`,marginBottom:1},y.createElement(h,{color:e.role===`user`?`cyan`:`magenta`,bold:!0},e.role===`user`?`you`:`zenovay`),y.createElement(h,null,e.content))),l&&d?y.createElement(m,{flexDirection:`column`,marginBottom:1},y.createElement(h,{color:`magenta`,bold:!0},`zenovay`),y.createElement(h,null,d)):null,p?y.createElement(h,{color:`red`},`✗ `,p):null,y.createElement(m,null,y.createElement(h,{color:`cyan`},l?`⠋ `:`▸ `),y.createElement(C,{value:i,onChange:a,onSubmit:_,placeholder:l?`streaming…`:`ask anything about your analytics`})))))},O=({snapshot:e,focused:t,width:n})=>{let r=e?.visitors?.count??0,i=e?.visitors?.series??[];return y.createElement(o,{title:`Visitors`,focused:t,width:n},y.createElement(h,{bold:!0},r.toString()),y.createElement(h,{color:`gray`},i.length>0?l(i,Math.max(8,n-6)):`— no data —`))},k=({snapshot:e,focused:t,width:n})=>{let r=e?.topPages?.slice(0,5)??[];return y.createElement(o,{title:`Top pages`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.path},y.createElement(h,null,e.path.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.views))))},A=({snapshot:e,focused:t,width:n})=>{let r=e?.sources?.slice(0,5)??[];return y.createElement(o,{title:`Sources`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.source},y.createElement(h,null,e.source.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.visitors))))},j=({events:e,focused:t,width:n})=>y.createElement(o,{title:`Events`,focused:t,width:n},e.length===0?y.createElement(h,{color:`gray`},`— waiting —`):e.slice(-10).map((e,t)=>y.createElement(h,{key:t},e.slice(0,n-4)))),M=({vitals:e,focused:t,width:n})=>{let r=(e,t,n)=>y.createElement(m,{key:e},y.createElement(h,{bold:!0},e.padEnd(6)),y.createElement(h,{color:`gray`},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return y.createElement(o,{title:`Vitals`,focused:t,width:n},r(`LCP`,e?.lcpP75,`ms`),r(`INP`,e?.inpP75,`ms`),r(`CLS`,e?.clsP75?e.clsP75*1e3:void 0,`/1k`),r(`TTFB`,e?.ttfbP75,`ms`),r(`FCP`,e?.fcpP75,`ms`))},N=({goals:e,focused:t,width:n})=>{let r=e?.goals?.slice(0,5)??[];return y.createElement(o,{title:`Goals`,focused:t,width:n},r.length===0?y.createElement(h,{color:`gray`},`— no data —`):r.map(e=>y.createElement(m,{key:e.name},y.createElement(h,null,e.name.padEnd(n-10).slice(0,n-10)),y.createElement(h,{color:`gray`},` `,e.completions))))};export{T as watchCommand};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{emitErrorEnvelope as n}from"./error-codes-CCK850J9.js";import{ApiV2Client as r}from"./api-v2-UJJ6ube8.js";import{confirmDestructive as i}from"./confirm-Dk3CEdpn.js";import"./formatter-KOe_hjhc.js";import{emitEnvelope as a,wrapItem as o,wrapList as s}from"./emit-B8RbnBJe.js";function c(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}function l(e){return e?new Date(e).toISOString().slice(0,10):`—`}async function u(u){let d=await e(),f=await t({strict:!1}),p=new r({config:d,cliVersion:u.cliVersion,token:f});try{switch(u.action){case`list`:{let{webhooks:e}=await p.listWebhooks();if(u.json)return a(s(e,`webhooks.list`),{legacyKey:`webhooks`,legacyValue:e}),0;if(e.length===0)return process.stdout.write("No webhooks yet. Add one with `zenovay webhooks add <https-url> --events <e1,e2>`.\n"),0;let t=[``,`id`,`url`,`events`,`created`],n=[1,14,40,28,10],r=e=>e.map((e,t)=>(e??``).padEnd(n[t])).join(` `);process.stdout.write(r(t)+`
|
|
2
|
+
`),process.stdout.write(r(n.map(e=>`─`.repeat(e)))+`
|
|
3
|
+
`);for(let t of e){let e=t.status===`disabled`?`○`:`●`,i=t.url.length>n[2]?`${t.url.slice(0,n[2]-1)}…`:t.url,a=t.events.join(`,`),o=a.length>n[3]?`${a.slice(0,n[3]-1)}…`:a;process.stdout.write(r([e,c(t.id),i,o,l(t.createdAt)])+`
|
|
4
|
+
`)}return process.stdout.write(`
|
|
5
|
+
● = active, ○ = disabled
|
|
6
|
+
`),0}case`add`:{if(!u.url)return process.stderr.write("Error: webhook URL is required — e.g. `zenovay webhooks add https://example.com/hook --events traffic_spike`.\n"),2;if(!u.url.startsWith(`https://`))return process.stderr.write(`Error: webhook URL must use https://.
|
|
7
|
+
`),2;let e=(u.events??``).split(`,`).map(e=>e.trim()).filter(Boolean);if(e.length===0)return process.stderr.write(`Error: --events is required (comma-separated). Examples: traffic_spike, traffic_drop, goal_completed, error_spike, website_down, website_up.
|
|
8
|
+
`),2;let t=await p.createWebhook({url:u.url,events:e});if(u.json)return a(o(t,`webhooks.item`)),0;let n=`═`.repeat(72);return process.stdout.write(`\n${n}\n Webhook created\n id: ${t.id}\n url: ${t.url}\n events: ${t.events.join(`, `)}\n secret: ${t.secret}\n${n}\n\n ⚠ Save this secret NOW — it will not be shown again.\n Verify inbound payloads via the X-Zenovay-Signature header (HMAC-SHA256).\n\n`),0}case`delete`:{if(!u.id)return process.stderr.write("Error: webhook id is required for `webhooks delete`.\n"),2;let e=await i({resource:`webhook`,name:c(u.id),yes:u.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
|
|
9
|
+
`),1;let t=await p.deleteWebhook(u.id);return u.json?(a(o(t,`webhooks.deleted`)),0):(process.stdout.write(`✔ Deleted webhook ${c(u.id)}.\n`),0)}case`rotate`:{if(!u.id)return process.stderr.write("Error: webhook id is required for `webhooks rotate`.\n"),2;let e=await i({resource:`webhook secret`,name:c(u.id),yes:u.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
|
|
10
|
+
`),1;let t=await p.rotateWebhookSecret(u.id);if(u.json)return a(o(t,`webhooks.rotated`)),0;let n=`═`.repeat(72);return process.stdout.write(`\n${n}\n Webhook secret rotated\n id: ${c(u.id)}\n rotatedAt: ${t.rotatedAt}\n secret: ${t.secret}\n${n}\n\n ⚠ Save this secret NOW — it will not be shown again.\n The previous secret is no longer valid.\n\n`),0}case`test`:{if(!u.id)return process.stderr.write("Error: webhook id is required for `webhooks test`.\n"),2;let e=await p.testWebhook(u.id);if(u.json)return a(o(e,`webhooks.tested`)),0;let t=e.ok?`✔`:`✗`;return process.stdout.write(`${t} Test fired to webhook ${c(u.id)} — HTTP ${e.status} in ${e.durationMs}ms.\n`),e.ok?0:1}}}catch(e){return n(e,{command:`webhooks ${u.action}`})}}export{u as webhooksCommand};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-UJJ6ube8.js";import{Panel as r}from"./panel-jycoT562.js";import{Banner as i}from"./banner-gVm7GaJF.js";import"./progress-row-C7gQLX4T.js";import"./prompt-Db9Y7CVt.js";import"./keybar-BYQ2Bam1.js";import"./sparkline-BlAQSlYZ.js";import"./data-table-BnWXIW9M.js";import"./bar-BPHTpgfb.js";import"./ui-hZ5oXnwY.js";import{Box as a,Text as o,render as s,useApp as c,useInput as l}from"ink";import u,{useEffect as d,useState as f}from"react";async function p(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]),i=await crypto.subtle.sign(`HMAC`,r,n.encode(t));return Array.from(new Uint8Array(i),e=>e.toString(16).padStart(2,`0`)).join(``)}function m({stats:e}){return u.createElement(r,{title:`webhooks forward`,state:e.connected?`ok`:`busy`},u.createElement(a,{flexDirection:`column`},u.createElement(o,null,u.createElement(o,{color:`gray`},`public URL `),u.createElement(o,{color:`cyan`},e.publicUrl)),u.createElement(o,null,u.createElement(o,{color:`gray`},`→ forwarding to `),u.createElement(o,{color:`magenta`},e.wsUrl)),u.createElement(o,null,e.connected?u.createElement(o,{color:`green`},`● connected`):u.createElement(o,{color:`yellow`},`○ connecting…`),u.createElement(o,{color:`gray`},` · `,e.total,` requests · `,e.ok,` ok · `),u.createElement(o,{color:e.err>0?`red`:`gray`},e.err,` err`),e.lastStatus===null?null:u.createElement(o,{color:`gray`},` · last: HTTP `,e.lastStatus)),e.lastError?u.createElement(o,{color:`red`},`last error: `,e.lastError.slice(0,80)):null))}async function h(r){let h=await e(),g=await t({strict:!1});if(!g?.accessToken)return process.stderr.write("Not authenticated. Run `zenovay login` first.\n"),2;let _=r.siteId??g.teamId??``;if(!_)return process.stderr.write(`No site selected — pass --site-id or set ZENOVAY_SITE.
|
|
2
|
+
`),2;if(!r.to)return process.stderr.write(`Missing --to <url> (e.g. --to localhost:3000/webhook).
|
|
3
|
+
`),2;let v=r.to.match(/^https?:\/\//)?r.to:`http://${r.to}`,y=new n({config:h,cliVersion:r.cliVersion,token:g}),b;try{b=await y.createTunnel(_,r.to)}catch(e){return process.stderr.write(`Failed to register tunnel: ${e.message}\n`),1}let x=r.sign?r.secret??b.tunnelKey:null,S=()=>{let{exit:e}=c(),[t,n]=f({total:0,ok:0,err:0,lastStatus:null,lastError:null,publicUrl:b.publicUrl,wsUrl:b.wsUrl,connected:!1});return l((t,n)=>{(t===`q`||n.escape)&&e()}),d(()=>{let e=new AbortController,t=async e=>{try{let t={...e.headers};delete t.host,delete t[`content-length`],x&&(t[`X-Zenovay-Signature`]=`sha256=${await p(x,e.body)}`);let r=await fetch(v,{method:e.method,headers:t,body:e.method===`GET`||e.method===`HEAD`?void 0:e.body}),i=await r.text(),a={};return r.headers.forEach((e,t)=>{a[t]=e}),n(e=>({...e,total:e.total+1,ok:e.ok+(r.ok?1:0),err:e.err+(r.ok?0:1),lastStatus:r.status,lastError:r.ok?null:`HTTP ${r.status}`})),{status:r.status,headers:a,body:i}}catch(e){let t=e instanceof Error?e.message:String(e);return n(e=>({...e,total:e.total+1,err:e.err+1,lastError:t})),{status:502,body:JSON.stringify({error:`cli_local_failed`,detail:t})}}};return(async()=>{let r=y.tunnelClient(b.wsUrl);n(e=>({...e,connected:!0}));try{await r.start(t,e.signal)}catch(e){n(t=>({...t,connected:!1,lastError:e.message}))}})(),()=>{e.abort()}},[]),u.createElement(a,{flexDirection:`column`},u.createElement(i,{version:`webhooks forward`}),u.createElement(m,{stats:t}),u.createElement(o,{color:`gray`},`target: `,v,` `,r.sign?`· HMAC-signed`:``),u.createElement(o,{color:`gray`},`[q | Esc] quit`))},{waitUntilExit:C}=s(u.createElement(S,null));return await C(),0}export{h as webhooksForwardCommand};
|
package/dist/wizard-bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import(`./init-
|
|
2
|
+
import(`./init-C8KOSKzO.js`).then(async({initCommand:e})=>{let{readFileSync:t}=await import(`node:fs`),n=await import(`node:path`),{fileURLToPath:r}=await import(`node:url`),i=n.dirname(r(import.meta.url)),a=JSON.parse(t(n.join(i,`..`,`package.json`),`utf8`)),o=process.argv.slice(2),s=o.includes(`--json`),c=o.includes(`--yes`),l=o.includes(`--skip-mcp`),u=o.includes(`--skip-verify`),d=await e({cliVersion:a.version,cwd:process.cwd(),json:s,yes:c,skipMcp:l,skipVerify:u});process.exit(d)});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=[500,1e3,2e3,4e3,8e3,16e3,32e3,6e4];let t=null;async function n(){if(t)return t;let e=globalThis.WebSocket;if(typeof e==`function`)return t=e,e;try{let e=await import(`./wrapper-
|
|
1
|
+
const e=[500,1e3,2e3,4e3,8e3,16e3,32e3,6e4];let t=null;async function n(){if(t)return t;let e=globalThis.WebSocket;if(typeof e==`function`)return t=e,e;try{let e=await import(`./wrapper-Ce_PZUZ9.js`),n=e.default??e.WebSocket;if(!n)throw Error(`ws package missing default export`);return t=n,n}catch(e){throw Error(`WebSocket unavailable: install Node 22+ or add the 'ws' dependency (${e.message})`)}}function r(e,t){return new Promise((n,r)=>{if(t?.aborted){r(t.reason??Error(`aborted`));return}let i=setTimeout(()=>{t?.removeEventListener(`abort`,a),n()},e),a=()=>{clearTimeout(i),r(t?.reason??Error(`aborted`))};t?.addEventListener(`abort`,a,{once:!0})})}function i(t){return e[Math.min(t-1,e.length-1)]??6e4}function a(e,t){if(!t)return e;let n=e.includes(`?`)?`&`:`?`;return`${e}${n}access_token=${encodeURIComponent(t)}`}async function o(e,t,n,r){let i=a(e,n),o;try{o=n?new t(i,{headers:{Authorization:`Bearer ${n}`}}):new t(i)}catch(e){throw Error(`ws connect failed: ${e.message}`)}return await new Promise((e,t)=>{let n=!1,i=()=>{n||(n=!0,c(),e({socket:o,open:!0}))},a=e=>{if(n)return;n=!0,c();let r=e?.message??(typeof e==`string`?e:`ws connection error`);t(Error(r))},s=()=>{if(!n){n=!0,c();try{o.close()}catch{}t(r?.reason??Error(`aborted`))}},c=()=>{o.onopen=null,o.onerror=null,r?.removeEventListener(`abort`,s)};o.onopen=i,o.onerror=a,r?.addEventListener(`abort`,s,{once:!0})})}async function*s(e){let t=e.webSocketImpl??await n(),a=e.pingIntervalMs??3e4,s=e.maxReconnectAttempts??10,c=0;for(;;){if(e.signal?.aborted)return;let n;try{n=await o(e.url,t,e.bearer,e.signal)}catch(t){if(e.signal?.aborted)return;if(c++,c>s)throw t;let n=i(c);e.onReconnect?.(c,n);try{await r(n,e.signal)}catch{return}continue}yield{type:`open`};let l=[],u=[],d=!1,f=Date.now(),p=!1,m=e=>{f=Date.now();let t=u.shift();t?t(e):l.push(e)},h=()=>{if(!d)for(d=!0;u.length;)u.shift()(null)};n.socket.onmessage=e=>{m({type:`message`,data:e.data})},n.socket.onclose=()=>{m({type:`close`}),h()},n.socket.onerror=e=>{let t=e?.message??`ws error`;m({type:`error`,data:t})};let g=()=>{try{n.socket.close()}catch{}h()};e.signal?.addEventListener(`abort`,g,{once:!0});let _=null;a>0&&(_=setInterval(()=>{if(Date.now()-f>a*1.5){try{n.socket.close()}catch{}h()}},Math.max(1e3,Math.floor(a/2))));try{for(;;){if(e.signal?.aborted)return;let t;if(t=l.length>0?l.shift():d?null:await new Promise(e=>u.push(e)),t===null||(t.type===`message`&&(p=!0),yield t,t.type===`close`))break}}finally{_&&clearInterval(_),e.signal?.removeEventListener(`abort`,g);try{n.socket.close()}catch{}}if(e.signal?.aborted)return;if(p&&(c=0),c++,c>s)throw Error(`ws connection exceeded reconnect cap`);let v=i(c);e.onReconnect?.(c,v);try{await r(v,e.signal)}catch{return}}}var c=class{opts;ac=null;socket=null;running=!1;constructor(e){this.opts=e}async start(e){this.running=!0,this.ac=new AbortController;let t=l(this.ac.signal,this.opts.signal),a=this.opts.webSocketImpl??await n(),s=this.opts.maxReconnectAttempts??10,c=0;for(;this.running;){if(t.aborted)return;let n;try{n=await o(this.opts.url,a,this.opts.bearer,t)}catch(e){if(t.aborted)return;if(c++,c>s)throw e;let n=i(c);this.opts.onReconnect?.(c,n);try{await r(n,t)}catch{return}continue}this.socket=n.socket;let l=!1;if(await new Promise(r=>{n.socket.onmessage=t=>{l=!0;let r=typeof t.data==`string`?t.data:String(t.data),i=null;try{i=JSON.parse(r)}catch{return}!i||typeof i.correlationId!=`string`||e(i).then(e=>{let t={correlationId:i.correlationId,status:e.status,headers:e.headers,body:e.body};try{n.socket.send(JSON.stringify(t))}catch{}}).catch(e=>{let t={correlationId:i.correlationId,status:502,body:JSON.stringify({error:e.message})};try{n.socket.send(JSON.stringify(t))}catch{}})},n.socket.onclose=()=>r(),n.socket.onerror=()=>r(),t.addEventListener(`abort`,()=>{try{n.socket.close()}catch{}r()},{once:!0})}),this.socket=null,t.aborted||!this.running)return;if(l&&(c=0),c++,c>s)throw Error(`ws tunnel exceeded reconnect cap`);let u=i(c);this.opts.onReconnect?.(c,u);try{await r(u,t)}catch{return}}}async stop(){this.running=!1,this.ac?.abort();try{this.socket?.close()}catch{}this.socket=null}};function l(e,t){if(!t)return e;let n=new AbortController,r=()=>n.abort(e.reason),i=()=>n.abort(t.reason);return e.aborted?n.abort(e.reason):e.addEventListener(`abort`,r,{once:!0}),t.aborted?n.abort(t.reason):t.addEventListener(`abort`,i,{once:!0}),n.signal}export{c as WsTunnelClient,s as connectWs};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenovay/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.35",
|
|
4
4
|
"description": "Zenovay CLI — AI install wizard + full terminal analytics dashboard",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"build": "tsdown",
|
|
18
18
|
"build:binaries": "tsx scripts/build-binaries.ts",
|
|
19
19
|
"typecheck": "tsc --noEmit",
|
|
20
|
-
"lint": "
|
|
20
|
+
"lint": "node -e \"console.log('lint: TypeScript ESLint v9 setup pending — see eslint.config.mjs');\"",
|
|
21
21
|
"test": "vitest run",
|
|
22
22
|
"test:watch": "vitest",
|
|
23
23
|
"test:all": "vitest run tests/unit tests/integration tests/security",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"test:smoke": "vitest run tests/smoke --testTimeout=60000",
|
|
26
26
|
"test:update-golden": "UPDATE_GOLDEN=1 vitest run tests/e2e",
|
|
27
27
|
"render:globe": "tsx scripts/render-globe.ts",
|
|
28
|
+
"smoke": "bash scripts/smoke-test.sh",
|
|
28
29
|
"prepare": "husky install"
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
package/dist/ai-B8r28ZBm.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-Cmi_f_SY.js";import{ApiClient as t,readToken as n}from"./api-CeB_9iPg.js";import{detectInstalled as r,initCommand as i}from"./init-BVUEPvVr.js";import{parseSseStream as a}from"./client-WzSy90dG.js";import"./formatter-mW0Yk3Nt.js";import{emit as o,isHeadless as s}from"./emit-DBbMG9mK.js";import"./login-BSDS_gNS.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 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-Cmi_f_SY.js";import{readToken as t}from"./api-CeB_9iPg.js";import{ApiV2Client as n}from"./api-v2-B_kZhVxd.js";import"./formatter-mW0Yk3Nt.js";import{emit as r,isHeadless as i}from"./emit-DBbMG9mK.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-BUpzvcMz.js";import{EmptyState as l}from"./empty-state-Dkho-_3J.js";import{MetricCard as u}from"./metric-card-BRHv93Un.js";import{DataTable as d}from"./data-table-BUyOP6Nc.js";import{Bar as f}from"./bar-BNmNGwlD.js";import{stripUrlPrefix as p}from"./fmt-DSJbiH8w.js";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";function C(e){if(!e||e.length!==2)return``;let t=e.toUpperCase();if(!/^[A-Z]{2}$/.test(t))return``;let n=127397;return String.fromCodePoint(n+t.charCodeAt(0))+String.fromCodePoint(n+t.charCodeAt(1))}async function w(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 E(l,u,`24h`);return r({type:`overview.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(D,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}function T(e){return e===`24h`?`7d`:e}async function E(e,t,n){let[r,i,a,o,s]=await Promise.all([e.getStats(t,n).catch(()=>null),e.getPages(t).catch(()=>[]),e.getSources(t,T(n),`prev`).catch(()=>null),e.getGeo(t).catch(()=>null),e.getDevices(t).catch(()=>null)]),c=i.reduce((e,t)=>e+t.views,0),l=(r?.daily??[]).map(e=>e.visitors),u=(r?.daily??[]).map(e=>e.pageviews),d=Math.floor(l.length/2),f=l.slice(0,d).reduce((e,t)=>e+t,0),p=u.slice(0,d).reduce((e,t)=>e+t,0),m=(a?.sources??[]).filter(e=>e.channel!==`other`||!e.source.includes(`/`)).slice(0,6).map(e=>({name:e.source,visitors:e.visitors,delta:e.delta??null}));return{visitors:r?.visitors??0,pageviews:r?.pageviews??c,bounceRate:r?.bounceRate??null,avgSession:r?.avgSessionSec??null,series:l,pageviewsSeries:u,prevVisitors:f,prevPageviews:p,topPages:i.slice(0,10),channels:m,countries:(o?.countries??[]).slice(0,8),browsers:(s?.browsers??[]).slice(0,5),devices:(s?.devices??[]).slice(0,5)}}const D=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=_(),[g,w]=x(null),[T,D]=x(!0),[O,k]=x(null),[A,j]=x(`24h`),[M,N]=x(t),[P,F]=x(n),[I,L]=x(!1),[R,z]=x([]);v(async t=>{if(t===`q`){c(),i(0);return}if(t===`1`){j(`24h`);return}if(t===`2`){j(`7d`);return}if(t===`3`){j(`30d`);return}if(t===`4`){j(`90d`);return}if(t===`s`){if(R.length===0)try{let t=await e.getSites();z(t)}catch{}L(e=>!e);return}}),b(()=>{let t=!1;return D(!0),(async()=>{try{let n=await E(e,M,A);t||(w(n),D(!1))}catch(e){t||(k(e.message),D(!1))}})(),()=>{t=!0}},[e,M,A]);let B=()=>y.createElement(a,{title:`Switch site`,state:`idle`},R.length===0?y.createElement(h,{color:`gray`},`Loading your sites…`):R.map(e=>y.createElement(m,{key:e.id},y.createElement(h,{color:e.id===M?`cyan`:`gray`},e.id===M?`› `:` `),y.createElement(h,{bold:e.id===M},e.name),y.createElement(h,{color:`gray`},` (`,e.url.replace(/^https?:\/\//,``).replace(/\/$/,``),`)`))),y.createElement(m,{marginTop:1},y.createElement(h,{color:`gray`},`Press `),y.createElement(h,{color:`cyan`},`[number]`),y.createElement(h,{color:`gray`},` to pick, `),y.createElement(h,{color:`cyan`},`[s]`),y.createElement(h,{color:`gray`},` to close.`)));v(e=>{if(!I)return;let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=R.length){let e=R[t-1];N(e.id),F(e.url.replace(/^https?:\/\//,``).replace(/\/$/,``)),L(!1)}},{isActive:I});let V=`overview · ${P} · ${A}`,H=[{key:`q`,label:`quit`},{key:`s`,label:`site`},{key:`1-4`,label:`range (24h/7d/30d/90d)`}];if(T)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:V}),y.createElement(a,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`cyan`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching dashboard…`))),I?B():null);if(O)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:V}),y.createElement(l,{reason:`error`,headline:`Failed to load`,hint:O}),I?B():null,y.createElement(s,{items:H}));if(!g||g.visitors===0&&g.pageviews===0&&g.topPages.length===0)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:V}),y.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.`}),I?B():null,y.createElement(s,{items:H}));let U=process.stdout.columns??80,W=Math.max(18,Math.floor(U/4)-1),G=Math.max(28,Math.floor(U/2)-2),K=[{key:`path`,label:`path`,width:32,format:e=>p(String(e??``))},{key:`views`,label:`views`,align:`right`,width:8},{key:`uniqueVisitors`,label:`visitors`,align:`right`,width:8},{key:`avgTime`,label:`avg time`,align:`right`,width:9,format:e=>typeof e==`number`?`${Math.round(e/1e3)}s`:`—`},{key:`bounceRate`,label:`bounce`,align:`right`,width:7,format:e=>typeof e==`number`?`${(e*100).toFixed(0)}%`:`—`}],q=g.prevVisitors>0?(g.visitors-g.prevVisitors)/g.prevVisitors:void 0,J=g.prevPageviews>0?(g.pageviews-g.prevPageviews)/g.prevPageviews:void 0,Y=Math.max(1,...g.channels.map(e=>e.visitors)),X=Math.max(1,...g.countries.map(e=>e.visitors)),Z=Math.max(1,...g.browsers.map(e=>e.visitors)),Q=Math.max(1,...g.devices.map(e=>e.visitors)),$=Math.max(8,Math.floor(G/3));return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:V}),y.createElement(m,{flexDirection:`row`},y.createElement(u,{title:`Visitors`,value:g.visitors,format:`number`,width:W,series:g.series,...typeof q==`number`?{delta:q}:{}}),y.createElement(u,{title:`Pageviews`,value:g.pageviews,format:`number`,width:W,series:g.pageviewsSeries,...typeof J==`number`?{delta:J}:{}}),y.createElement(u,{title:`Bounce rate`,value:g.bounceRate??``,emptyHint:`—`,format:`percent`,width:W}),y.createElement(u,{title:`Avg session`,value:g.avgSession??``,emptyHint:`—`,format:`duration`,width:W})),y.createElement(m,{flexDirection:`row`,flexWrap:`wrap`},y.createElement(m,{width:G,flexDirection:`column`},y.createElement(a,{title:`Channels`},g.channels.length===0?y.createElement(h,{color:`gray`},`No channel data yet.`):g.channels.map(e=>y.createElement(m,{key:e.name,flexDirection:`row`},y.createElement(m,{width:12},y.createElement(h,null,e.name)),y.createElement(f,{value:e.visitors,max:Y,width:$,...typeof e.delta==`number`?{delta:e.delta}:{}}),y.createElement(h,{color:`gray`},` `,e.visitors))))),y.createElement(m,{width:G,flexDirection:`column`},y.createElement(a,{title:`Top countries`},g.countries.length===0?y.createElement(h,{color:`gray`},`No geo data yet.`):g.countries.map(e=>{let t=C(e.country);return y.createElement(m,{key:e.country,flexDirection:`row`},y.createElement(m,{width:4},y.createElement(h,null,t||` `)),y.createElement(m,{width:6},y.createElement(h,null,e.country)),y.createElement(f,{value:e.visitors,max:X,width:$}),y.createElement(h,{color:`gray`},` `,e.visitors))})))),y.createElement(m,{flexDirection:`row`,flexWrap:`wrap`},y.createElement(m,{width:G,flexDirection:`column`},y.createElement(a,{title:`Top browsers`},g.browsers.length===0?y.createElement(h,{color:`gray`},`No browser data yet.`):g.browsers.map(e=>y.createElement(m,{key:e.name,flexDirection:`row`},y.createElement(m,{width:12},y.createElement(h,null,e.name)),y.createElement(f,{value:e.visitors,max:Z,width:$}),y.createElement(h,{color:`gray`},` `,e.visitors))))),y.createElement(m,{width:G,flexDirection:`column`},y.createElement(a,{title:`Top devices`},g.devices.length===0?y.createElement(h,{color:`gray`},`No device data yet.`):g.devices.map(e=>y.createElement(m,{key:e.name,flexDirection:`row`},y.createElement(m,{width:12},y.createElement(h,null,e.name)),y.createElement(f,{value:e.visitors,max:Q,width:$}),y.createElement(h,{color:`gray`},` `,e.visitors)))))),y.createElement(a,{title:`Top pages (${A})`},g.topPages.length===0?y.createElement(h,{color:`gray`},`No pages with data in this window yet.`):y.createElement(d,{columns:K,data:g.topPages,zebra:!0})),I?B():null,y.createElement(s,{items:H}))};async function O(e){return w(e)}export{O as analyticsCommand};
|
package/dist/api-CeB_9iPg.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{configDir as e}from"./config-Cmi_f_SY.js";import t from"node:path";import{promises as n}from"node:fs";import{z as r}from"zod";const i=r.object({device_code:r.string(),user_code:r.string(),verification_uri:r.string().url(),verification_uri_complete:r.string().url().optional(),expires_in:r.number().int().positive(),interval:r.number().int().positive().default(5)}),a=r.object({access_token:r.string(),refresh_token:r.string(),token_type:r.literal(`Bearer`).default(`Bearer`),expires_in:r.number().int().positive(),scope:r.string().optional()}),o=r.object({error:r.enum([`authorization_pending`,`slow_down`,`access_denied`,`expired_token`,`invalid_client`,`invalid_grant`,`invalid_scope`]),error_description:r.string().optional()});async function s(e){let{apiBase:t,clientId:n=`cli-zenovay`,scope:r=`cli:full`}=e,a=e.fetchImpl??fetch,o=new URLSearchParams({client_id:n,scope:r}),s=await a(`${t}/oauth/device_authorization`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:o.toString()});if(!s.ok){let e=await s.text();throw Error(`Device authorization failed: ${s.status} ${e}`)}let c=await s.json();return i.parse(c)}async function c(e){let{apiBase:t,deviceCode:n,clientId:r=`cli-zenovay`,expiresIn:i}=e,s=e.fetchImpl??fetch,c=e.sleep??(e=>new Promise(t=>setTimeout(t,e))),l=e.interval,u=Date.now(),d=u+i*1e3;for(;Date.now()<d;){if(e.signal?.aborted)throw Error(`Polling aborted`);await c(l*1e3),e.onTick?.(Date.now()-u);let i=new URLSearchParams({grant_type:`urn:ietf:params:oauth:grant-type:device_code`,device_code:n,client_id:r}),d=await s(`${t}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:i.toString()}),f=await d.json().catch(()=>({}));if(d.ok){let e=a.parse(f);return{accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:Date.now()+e.expires_in*1e3,tokenType:`Bearer`,scope:e.scope}}let p=o.safeParse(f);if(!p.success)throw Error(`Token poll failed (${d.status}): ${JSON.stringify(f)}`);let{error:m}=p.data;if(m!==`authorization_pending`){if(m===`slow_down`){l=Math.min(l*2,30);continue}throw m===`access_denied`?Error(`Device authorization denied by user.`):m===`expired_token`?Error("Device code expired — run `zenovay login` again."):Error(`Device token error: ${m}`)}}throw Error("Device code expired — run `zenovay login` again.")}const l=r.object({accessToken:r.string().min(1),refreshToken:r.string().min(1),expiresAt:r.number(),tokenType:r.literal(`Bearer`).default(`Bearer`),scope:r.string().optional(),userId:r.string().optional(),teamId:r.string().optional(),email:r.string().email().optional(),region:r.string().optional(),cliVersionAtIssue:r.string().optional()});function u(){return t.join(e(),`auth.json`)}async function d(e){let r=u(),i;try{i=await n.stat(r)}catch(e){if(e.code===`ENOENT`)return null;throw e}if(process.platform!==`win32`){let n=i.mode&511;if(n&63){let i=e?.strict??!0;if(i)throw Error(`Refusing to read ${r}: file has insecure permissions ${n.toString(8).padStart(3,`0`)} (expected 600). Fix: chmod 600 "${r}" && chmod 700 "${t.dirname(r)}"`)}}let a=await n.readFile(r,`utf8`),o;try{o=JSON.parse(a)}catch{throw Error(`Auth file at ${r} is not valid JSON. Run \`zenovay login\` again.`)}let s=l.safeParse(o);if(!s.success)throw Error(`Auth file at ${r} is malformed. Run \`zenovay login\` again.`);return s.data}async function f(t){let r=e();await n.mkdir(r,{recursive:!0,mode:448});let i=u(),a=l.parse(t),o=JSON.stringify(a,null,2);if(await n.writeFile(i,o,{mode:384}),process.platform!==`win32`){await n.chmod(i,384);try{await n.chmod(r,448)}catch{}}}async function p(){try{await n.unlink(u())}catch(e){if(e.code!==`ENOENT`)throw e}}function m(e,t=3e4){return Date.now()>=e.expiresAt-t}async function h(e){let t=await d({strict:!0});return t?m(t)?g(t,e):t:null}async function g(e,t){let{apiBase:n,clientId:r=`cli-zenovay`}=t,i=t.fetchImpl??fetch,o=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e.refreshToken,client_id:r}),s=await i(`${n}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:o.toString()}),c=await s.json().catch(()=>({}));if(!s.ok){let e=c&&typeof c==`object`&&`error`in c?c.error:String(c);throw e===`invalid_grant`?(await p(),Error("Refresh token rejected by server — your session has been revoked. Run `zenovay login` again.")):Error(`Token refresh failed (${s.status}): ${JSON.stringify(c)}`)}let l=a.parse(c),u={...e,accessToken:l.access_token,refreshToken:l.refresh_token,expiresAt:Date.now()+l.expires_in*1e3,tokenType:`Bearer`,scope:l.scope??e.scope};return await f(u),u}const _=r.object({id:r.string(),name:r.string(),url:r.string().url(),trackingCode:r.string().optional(),lastActiveAt:r.string().nullable().optional()}),v=r.object({user:r.object({id:r.string(),email:r.string().email(),name:r.string().optional().nullable()}),team:r.object({id:r.string(),name:r.string(),plan:r.string()}).optional().nullable(),teams:r.array(r.object({id:r.string(),name:r.string(),plan:r.string(),role:r.string(),siteCount:r.number().int(),isCurrent:r.boolean()})).optional()});var y=class extends Error{constructor(e,t,n){super(n),this.status=e,this.body=t,this.name=`ApiError`}},b=class{fetchImpl;token;constructor(e){this.opts=e,this.fetchImpl=e.fetchImpl??fetch,this.token=e.token??null}get apiBase(){return this.opts.config.apiBase}async authedHeaders(e={}){let t=process.env.ZENOVAY_TEAM_ID,n=t&&t.trim()?{"X-Zenovay-Team-Id":t.trim()}:{},r=process.env.ZENOVAY_API_TOKEN;if(r&&r.trim())return{Accept:`application/json`,"User-Agent":`zenovay-cli/${this.opts.cliVersion}`,"X-Zenovay-CLI-Version":this.opts.cliVersion,Authorization:`Bearer ${r.trim()}`,...n,...e};this.token||=await h({apiBase:this.apiBase});let i={Accept:`application/json`,"User-Agent":`zenovay-cli/${this.opts.cliVersion}`,"X-Zenovay-CLI-Version":this.opts.cliVersion,...n,...e};return this.token&&(i.Authorization=`${this.token.tokenType} ${this.token.accessToken}`),i}async request(e,t){let n=`${this.apiBase}${e}`,r=await this.fetchImpl(n,{...t,headers:{...await this.authedHeaders(),...t.headers}});if(r.status===401&&this.token&&(this.token=null,r=await this.fetchImpl(n,{...t,headers:{...await this.authedHeaders(),...t.headers}})),!r.ok){let n=await r.text().catch(()=>``);throw new y(r.status,n,`${t.method??`GET`} ${e} → ${r.status}`)}let i=await r.json();return t.schema.parse(i)}async getSites(){return this.request(`/v1/cli/sites`,{schema:r.array(_)})}async createSite(e){return this.request(`/v1/cli/sites`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),schema:r.object({id:r.string()})})}async getFirstEvent(e){let t=new URLSearchParams({site_id:e.siteId,since:String(e.since)});return this.request(`/v1/cli/first-event?${t.toString()}`,{schema:r.object({received:r.boolean(),event:r.unknown().optional()})})}async me(){return this.request(`/v1/cli/me`,{schema:v})}async revokeCurrentToken(){this.token&&await this.fetchImpl(`${this.apiBase}/oauth/revoke`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`,...await this.authedHeaders()},body:new URLSearchParams({token:this.token.refreshToken,token_type_hint:`refresh_token`,client_id:`cli-zenovay`}).toString()})}async openAiStream(e,t,n){let r=await this.authedHeaders({"Content-Type":`application/json`,Accept:`text/event-stream`}),i=await this.fetchImpl(`${this.apiBase}/ai/cli/${e}`,{method:`POST`,headers:r,body:JSON.stringify(t),signal:n});if(!i.ok){let t=await i.text().catch(()=>``);throw new y(i.status,t,`POST /ai/cli/${e} → ${i.status}`)}return i}async openEventsStream(e,t){let n=await this.authedHeaders({Accept:`text/event-stream`}),r=await this.fetchImpl(`${this.apiBase}/v1/cli/events/tail?site_id=${e}`,{method:`GET`,headers:n,signal:t});if(!r.ok){let e=await r.text().catch(()=>``);throw new y(r.status,e,`GET events tail → ${r.status}`)}return r}async getDashboardSnapshot(e){return this.request(`/v1/cli/dashboard?site_id=${e}`,{schema:r.unknown()})}async ping(){let e=Date.now(),t=await this.fetchImpl(`${this.apiBase}/v1/cli/ping`,{headers:await this.authedHeaders()});if(!t.ok)throw new y(t.status,await t.text().catch(()=>``),`ping failed`);return{ok:!0,latencyMs:Date.now()-e}}};export{b as ApiClient,y as ApiError,p as clearToken,h as ensureFreshToken,c as pollDeviceToken,d as readToken,s as startDeviceAuthorization,f as writeToken};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-Cmi_f_SY.js";import{readToken as t}from"./api-CeB_9iPg.js";import{ApiV2Client as n}from"./api-v2-B_kZhVxd.js";import{confirmDestructive as r}from"./confirm-D_aKHknn.js";import{fmtDate as i,formatTable as a,shortId as o}from"./fmt-DSJbiH8w.js";async function s(s){let c=await e(),l=await t({strict:!1}),u=new n({config:c,cliVersion:s.cliVersion,token:l});try{switch(s.action){case`list`:{let{keys:e}=await u.listApiKeys();if(s.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=[{key:`isCurrent`,header:``,width:1,format:e=>e?`*`:` `},{key:`id`,header:`id`,width:14,format:e=>o(String(e))},{key:`name`,header:`name`,width:24,format:e=>String(e??``)},{key:`scope`,header:`scope`,width:6},{key:`createdAt`,header:`created`,width:10,format:e=>i(e)},{key:`lastUsedAt`,header:`last used`,width:19,format:e=>i(e,`datetime`)}];return process.stdout.write(a({rows:e,cols:t})),process.stdout.write(`
|
|
3
|
-
* = current CLI key
|
|
4
|
-
`),0}case`create`:{if(!s.name)return process.stderr.write("Error: --name is required for `api-keys create`.\n"),2;let e=s.scope===`write`?`write`:`read`,t=await u.createApiKey({name:s.name,scope:e});if(s.json)return process.stdout.write(JSON.stringify(t,null,2)+`
|
|
5
|
-
`),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(!s.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:o(s.id),yes:s.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
|
|
6
|
-
`),1;let t=await u.deleteApiKey(s.id);return s.json?(process.stdout.write(JSON.stringify(t)+`
|
|
7
|
-
`),0):(process.stdout.write(`✔ Deleted API key ${o(s.id)}.\n`),0)}}}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}}export{s as apiKeysCommand};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-Cmi_f_SY.js";import{readToken as t}from"./api-CeB_9iPg.js";import{ApiV2Client as n}from"./api-v2-B_kZhVxd.js";import{formatTabular as r,selectFormat as i}from"./formatter-mW0Yk3Nt.js";import"./panel-uygscwY5.js";import"./banner-BPQh2F8l.js";import"./prompt-BURfUNxp.js";import"./keybar-C7YkmK1U.js";import{resolveSiteId as a}from"./resolve-site-BUpzvcMz.js";import{DataTable as o}from"./data-table-BUyOP6Nc.js";import{runAnalyticalScreen as s}from"./analytical-screen-BpTK5dCY.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function f(e){return e==null?`—`:e>=500?`Enterprise`:e>=50?`Growth`:`SMB`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(p),b=p.window??`24h`,x=p.limit??100,S=[{key:`lastSeenAt`,label:`when`,width:6,format:e=>d(String(e))},{key:`name`,label:`company`,width:24,format:e=>String(e).slice(0,24)},{key:`employeeCount`,label:`tier`,width:11,format:e=>f(typeof e==`number`?e:null)},{key:`industry`,label:`industry`,width:18,format:e=>String(e??`—`).slice(0,18)},{key:`visitCount`,label:`visits`,width:6,align:`right`},{key:`isNew`,label:``,width:5,format:e=>e?`NEW`:``}];return s({cliVersion:p.cliVersion,title:`companies · ${_} · ${b}`,commandName:`companies`,authToken:h?.accessToken??null,refreshIntervalMs:p.watch?3e4:0,fetcher:e=>g.getCompaniesSnapshot(_,{window:b,limit:x},e),format:y,headlessEmit:(e,t)=>{let n=p.newOnly?e.companies.filter(e=>e.isNew):e.companies;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of n)process.stdout.write(JSON.stringify(e)+`
|
|
2
|
-
`);else process.stdout.write(JSON.stringify({companies:n,total:n.length},null,2));return}process.stdout.write(r(n,[`name`,`domain`,`industry`,`employeeCount`,`visitCount`,`firstSeenAt`,`lastSeenAt`,`isNew`],t))},panels:[{id:`summary`,title:`Now`,render:e=>{let t=e.companies.filter(e=>e.isNew).length,n=e.companies.filter(e=>(e.employeeCount??0)>=500).length;return u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.total),u.createElement(l,{color:`gray`},` companies in `,b)),u.createElement(l,{color:`gray`},u.createElement(l,{color:`green`},`● `,t,` new`),` · `,n,` enterprise`))}},{id:`feed`,title:`Feed`,render:e=>{let t=p.newOnly?e.companies.filter(e=>e.isNew):e.companies;return t.length===0?u.createElement(l,{color:`gray`},`— no `,p.newOnly?`new `:``,`companies in window —`):u.createElement(o,{data:t.slice(0,30),columns:S,headerStyle:`accent`})}}]})}export{p as companiesCommand};
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
const e=[{name:`init`,description:`AI install wizard`},{name:`login`,description:`Authenticate via OAuth device flow`},{name:`logout`,description:`Revoke session and clear local auth`},{name:`ai`,description:`3-mode AI assistant`},{name:`watch`,description:`Live TUI dashboard`},{name:`events`,description:`Stream live events`},{name:`health`,description:`Self-diagnostic checks`},{name:`doctor`,description:`AI-assisted self-healing`},{name:`update`,description:`Install latest version`},{name:`visitors`,description:`Live visitor table`},{name:`sources`,description:`Traffic source breakdown`},{name:`vitals`,description:`Core Web Vitals dashboard`},{name:`revenue`,description:`MRR / ARR / transaction series`},{name:`funnel`,description:`Funnel drop-off chart`},{name:`funnels`,description:`List funnels`},{name:`stats`,description:`One-shot dashboard summary`},{name:`errors`,description:`Recent error snapshot`},{name:`companies`,description:`B2B identification feed`},{name:`projects`,description:`List tracked projects`},{name:`query`,description:`SQL REPL over analytics schema`},{name:`completions`,description:`Emit shell-completion script`}],t=[`--site-id`,`--json`,`--csv`,`--tsv`,`--ndjson`,`--watch`,`--limit`,`--window`,`--period`,`--range`,`--device`,`--url`,`--compare`,`--max-rows`,`--filter`,`--forward-to`,`--replay-24h`,`--search`,`--new-only`,`--help`,`--version`],n=[`catppuccin-mocha`,`catppuccin-latte`,`dracula`,`tokyo-night`,`nord`];function r(){let r=e.map(e=>e.name).join(` `),i=t.join(` `);return`# zenovay bash completion
|
|
2
|
-
# Install: zenovay completions bash > /usr/local/etc/bash_completion.d/zenovay
|
|
3
|
-
_zenovay() {
|
|
4
|
-
local cur prev opts
|
|
5
|
-
COMPREPLY=()
|
|
6
|
-
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
7
|
-
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
8
|
-
if [[ "\${COMP_CWORD}" == "1" ]]; then
|
|
9
|
-
opts="${r}"
|
|
10
|
-
COMPREPLY=( $(compgen -W "\${opts}" -- "\${cur}") )
|
|
11
|
-
return 0
|
|
12
|
-
fi
|
|
13
|
-
case "\${prev}" in
|
|
14
|
-
--theme) COMPREPLY=( $(compgen -W "${n.join(` `)}" -- "\${cur}") ); return 0 ;;
|
|
15
|
-
--window) COMPREPLY=( $(compgen -W "24h 7d 30d 90d 1y" -- "\${cur}") ); return 0 ;;
|
|
16
|
-
--period) COMPREPLY=( $(compgen -W "7d 30d 90d 1y" -- "\${cur}") ); return 0 ;;
|
|
17
|
-
--range) COMPREPLY=( $(compgen -W "24h 7d 30d 90d" -- "\${cur}") ); return 0 ;;
|
|
18
|
-
--device) COMPREPLY=( $(compgen -W "mobile desktop tablet" -- "\${cur}") ); return 0 ;;
|
|
19
|
-
--compare) COMPREPLY=( $(compgen -W "prev none" -- "\${cur}") ); return 0 ;;
|
|
20
|
-
--format) COMPREPLY=( $(compgen -W "json csv tsv ndjson" -- "\${cur}") ); return 0 ;;
|
|
21
|
-
esac
|
|
22
|
-
COMPREPLY=( $(compgen -W "${i}" -- "\${cur}") )
|
|
23
|
-
}
|
|
24
|
-
complete -F _zenovay zenovay zv
|
|
25
|
-
`}function i(){let t=e.map(e=>` '${e.name}:${e.description}'`).join(` \\
|
|
26
|
-
`);return`#compdef zenovay zv
|
|
27
|
-
# zenovay zsh completion
|
|
28
|
-
# Install: zenovay completions zsh > ~/.zsh/completions/_zenovay && compinit
|
|
29
|
-
_zenovay() {
|
|
30
|
-
local -a commands
|
|
31
|
-
commands=(
|
|
32
|
-
${t}
|
|
33
|
-
)
|
|
34
|
-
_arguments -C \\
|
|
35
|
-
'1: :->command' \\
|
|
36
|
-
'*: :->args'
|
|
37
|
-
case $state in
|
|
38
|
-
command) _describe 'command' commands ;;
|
|
39
|
-
args)
|
|
40
|
-
case "\${words[2]}" in
|
|
41
|
-
*)
|
|
42
|
-
_arguments \\
|
|
43
|
-
'--site-id[Site ID]:site:' \\
|
|
44
|
-
'--json[Emit JSON to stdout]' \\
|
|
45
|
-
'--csv[Emit CSV to stdout]' \\
|
|
46
|
-
'--tsv[Emit TSV to stdout]' \\
|
|
47
|
-
'--ndjson[Emit NDJSON streaming]' \\
|
|
48
|
-
'--watch[Auto-refresh]' \\
|
|
49
|
-
'--limit[Max rows]:n:' \\
|
|
50
|
-
'--window[Time window]:w:(24h 7d 30d 90d 1y)' \\
|
|
51
|
-
'--period[Period]:p:(7d 30d 90d 1y)' \\
|
|
52
|
-
'--range[Range]:r:(24h 7d 30d 90d)' \\
|
|
53
|
-
'--device[Device type]:d:(mobile desktop tablet)' \\
|
|
54
|
-
'--theme[Theme]:t:(${n.join(` `)})' \\
|
|
55
|
-
'--max-rows[Max query rows]:n:'
|
|
56
|
-
;;
|
|
57
|
-
esac
|
|
58
|
-
;;
|
|
59
|
-
esac
|
|
60
|
-
}
|
|
61
|
-
_zenovay "$@"
|
|
62
|
-
`}function a(){let r=[`# zenovay fish completion`,`# Install: zenovay completions fish > ~/.config/fish/completions/zenovay.fish`,``];for(let t of e)r.push(`complete -c zenovay -n "__fish_use_subcommand" -a ${t.name} -d '${t.description.replace(/'/g,`\\'`)}'`),r.push(`complete -c zv -n "__fish_use_subcommand" -a ${t.name} -d '${t.description.replace(/'/g,`\\'`)}'`);for(let e of t){let t=e.replace(/^--/,``);r.push(`complete -c zenovay -l ${t}`)}return r.push(`complete -c zenovay -l theme -a "${n.join(` `)}"`),r.push(`complete -c zenovay -l window -a "24h 7d 30d 90d 1y"`),r.push(`complete -c zenovay -l period -a "7d 30d 90d 1y"`),r.push(`complete -c zenovay -l range -a "24h 7d 30d 90d"`),r.push(`complete -c zenovay -l device -a "mobile desktop tablet"`),r.push(`complete -c zenovay -l compare -a "prev none"`),r.push(`complete -c zenovay -l format -a "json csv tsv ndjson"`),r.join(`
|
|
63
|
-
`)+`
|
|
64
|
-
`}function o(){return`# zenovay nushell completion
|
|
65
|
-
# Add to your config.nu (or source as a separate file)
|
|
66
|
-
def "nu-complete zenovay-commands" [] {
|
|
67
|
-
[
|
|
68
|
-
${e.map(e=>` { value: "${e.name}", description: "${e.description}" }`).join(`,
|
|
69
|
-
`)}
|
|
70
|
-
]
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
extern "zenovay" [
|
|
74
|
-
command?: string@"nu-complete zenovay-commands"
|
|
75
|
-
--site-id: string
|
|
76
|
-
--json
|
|
77
|
-
--csv
|
|
78
|
-
--tsv
|
|
79
|
-
--ndjson
|
|
80
|
-
--watch
|
|
81
|
-
--limit: int
|
|
82
|
-
--window: string
|
|
83
|
-
--period: string
|
|
84
|
-
--range: string
|
|
85
|
-
--device: string
|
|
86
|
-
--theme: string
|
|
87
|
-
--max-rows: int
|
|
88
|
-
--help
|
|
89
|
-
--version
|
|
90
|
-
]
|
|
91
|
-
|
|
92
|
-
extern "zv" [
|
|
93
|
-
command?: string@"nu-complete zenovay-commands"
|
|
94
|
-
]
|
|
95
|
-
`}function s(){let t=e.map(e=>`'${e.name}'`).join(`, `);return`# zenovay PowerShell completion
|
|
96
|
-
# Install: zenovay completions pwsh >> $PROFILE
|
|
97
|
-
$scriptBlock = {
|
|
98
|
-
param($wordToComplete, $commandAst, $cursorPosition)
|
|
99
|
-
$commands = @(${t})
|
|
100
|
-
$commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
101
|
-
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
Register-ArgumentCompleter -CommandName zenovay -ScriptBlock $scriptBlock
|
|
105
|
-
Register-ArgumentCompleter -CommandName zv -ScriptBlock $scriptBlock
|
|
106
|
-
`}async function c(e){let t=e.shell?.toLowerCase();if(e.list||!t)return process.stdout.write(`Available shells: bash, zsh, fish, nushell, pwsh
|
|
107
|
-
Usage:
|
|
108
|
-
zenovay completions bash > /usr/local/etc/bash_completion.d/zenovay
|
|
109
|
-
zenovay completions zsh > ~/.zsh/completions/_zenovay
|
|
110
|
-
zenovay completions fish > ~/.config/fish/completions/zenovay.fish
|
|
111
|
-
zenovay completions nushell >> $env.HOME/.config/nushell/config.nu
|
|
112
|
-
zenovay completions pwsh >> $PROFILE
|
|
113
|
-
`),0;switch(t){case`bash`:return process.stdout.write(r()),0;case`zsh`:return process.stdout.write(i()),0;case`fish`:return process.stdout.write(a()),0;case`nu`:case`nushell`:return process.stdout.write(o()),0;case`pwsh`:case`powershell`:return process.stdout.write(s()),0;default:return process.stderr.write(`✗ Unknown shell '${t}'. Supported: bash, zsh, fish, nushell, pwsh.\n`),2}}export{c as completionsCommand};
|
package/dist/deploys-CgNr5r7M.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-Cmi_f_SY.js";import{readToken as t}from"./api-CeB_9iPg.js";import{ApiV2Client as n}from"./api-v2-B_kZhVxd.js";import{formatTabular as r,selectFormat as i}from"./formatter-mW0Yk3Nt.js";import"./panel-uygscwY5.js";import"./banner-BPQh2F8l.js";import"./prompt-BURfUNxp.js";import"./keybar-C7YkmK1U.js";import{resolveSiteId as a}from"./resolve-site-BUpzvcMz.js";import{DataTable as o}from"./data-table-BUyOP6Nc.js";import{runAnalyticalScreen as s}from"./analytical-screen-BpTK5dCY.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}async function f(f){if(f.connect){let t=await e(),n=t.apiBase.replace(`api.zenovay.com`,`app.zenovay.com`),r=`${n}/settings/integrations/github`;return process.stdout.write(`\n Connect GitHub to Zenovay:\n ${r}\n\n Open this URL in your browser. Zenovay re-uses the same GitHub\n OAuth app you already authorized for login (auth-zenovay), so\n no separate "Zenovay Deploys" app is needed. Pick the repos you\n want to track and deploys will appear here automatically.\n\n`),0}let p=await e(),m=await t({strict:!1}),h=new n({config:p,cliVersion:f.cliVersion,token:m}),g,_;try{({siteId:g,site:_}=await a(h,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let v=i(f),y=f.limit??50,b=[{key:`pushed_at`,label:`when`,width:6,format:e=>d(String(e))},{key:`branch`,label:`branch`,width:14,format:e=>String(e??`—`).slice(0,14)},{key:`commit_sha`,label:`commit`,width:9,format:e=>String(e).slice(0,8)},{key:`commit_author`,label:`author`,width:16,format:e=>String(e??`—`).slice(0,16)},{key:`commit_message`,label:`message`,width:40,format:e=>String(e??`—`).slice(0,40)},{key:`show_on_chart`,label:`chart`,width:5,format:e=>e?`●`:`○`}];return s({cliVersion:f.cliVersion,title:`deploys · ${g}`,commandName:`deploys`,authToken:m?.accessToken??null,refreshIntervalMs:0,fetcher:e=>h.getDeploys(g,{branch:f.branch,since:f.since,limit:y},e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.deploys)process.stdout.write(JSON.stringify(t)+`
|
|
2
|
-
`);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(r(e.deploys,[`pushed_at`,`branch`,`commit_sha`,`commit_author`,`commit_message`,`repository`,`commit_url`,`show_on_chart`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>{let t=e.deploys.filter(e=>e.show_on_chart).length,n=new Set(e.deploys.map(e=>e.repository).filter(e=>!!e));return u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.total),u.createElement(l,{color:`gray`},` commits`,f.branch?` · branch=${f.branch}`:``)),u.createElement(l,{color:`gray`},u.createElement(l,{color:`magenta`},`● `,t,` on chart`),u.createElement(l,null,` · `),u.createElement(l,null,n.size,` `,n.size===1?`repo`:`repos`)))}},{id:`list`,title:`Recent`,render:e=>e.deploys.length===0?u.createElement(c,{flexDirection:`column`},u.createElement(l,{color:`gray`},`— no commits yet —`),u.createElement(l,{color:`gray`},"Run `zenovay deploys --connect` to wire up the GitHub integration.")):u.createElement(o,{data:e.deploys.slice(0,30),columns:b,headerStyle:`accent`})}]})}export{f as deploysCommand};
|
package/dist/devices-C8xVqaBs.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-Cmi_f_SY.js";import{readToken as t}from"./api-CeB_9iPg.js";import{ApiV2Client as n}from"./api-v2-B_kZhVxd.js";import"./formatter-mW0Yk3Nt.js";import{emit as r,isHeadless as i}from"./emit-DBbMG9mK.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-BUpzvcMz.js";import{EmptyState as l}from"./empty-state-Dkho-_3J.js";import{DataTable as u}from"./data-table-BUyOP6Nc.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};
|
package/dist/domains-Bfx2vdwv.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-Cmi_f_SY.js";import{readToken as t}from"./api-CeB_9iPg.js";import{ApiV2Client as n}from"./api-v2-B_kZhVxd.js";import{confirmDestructive as r}from"./confirm-D_aKHknn.js";import"./panel-uygscwY5.js";import"./banner-BPQh2F8l.js";import"./prompt-BURfUNxp.js";import{resolveSiteId as i}from"./resolve-site-BUpzvcMz.js";import{fmtNumber as a,formatTable as o,shortId as s}from"./fmt-DSJbiH8w.js";async function c(r){let c=await e(),l=await t({strict:!1});if(!l)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:c,cliVersion:r.cliVersion,token:l}),d;try{({siteId:d}=await i(u,{explicit:void 0,headless:!0,cliVersion:r.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f;try{f=await u.getProjects(d)}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}if(r.json)return process.stdout.write(JSON.stringify(f,null,2)+`
|
|
2
|
-
`),0;let p=f.projects??[];if(p.length===0)return process.stdout.write(`
|
|
3
|
-
No domains tracked yet — add one with \`zenovay domains add <url>\`.
|
|
4
|
-
|
|
5
|
-
`),0;let m=[{key:`isCurrent`,header:``,width:1,format:e=>e?`*`:` `},{key:`name`,header:`name`,width:18,format:e=>String(e??`—`)},{key:`domain`,header:`domain`,width:28,format:e=>String(e??`—`)},{key:`tier`,header:`tier`,width:6,format:e=>String(e??`—`)},{key:`pageviews24h`,header:`24h pv`,width:8,align:`right`,format:e=>a(Number(e??0))},{key:`id`,header:`id`,width:14,format:e=>s(String(e))}];return process.stdout.write(`
|
|
6
|
-
`),process.stdout.write(` domains · ${p.length} tracked\n\n`),process.stdout.write(o({rows:p,cols:m})),process.stdout.write(`
|
|
7
|
-
* = current default site (set with \`zenovay use <name>\`)
|
|
8
|
-
`),process.stdout.write(" Add with `zenovay domains add <url>`, remove with `zenovay domains delete <id>`.\n\n"),0}async function l(i){if(i.action===`list`)return c(i);let a=await e(),o=await t({strict:!1}),l=new n({config:a,cliVersion:i.cliVersion,token:o});try{switch(i.action){case`add`:{if(!i.url)return process.stderr.write("Error: <url> is required for `domains add`.\n"),2;let e=await l.addDomain({url:i.url,name:i.name});return i.json?(process.stdout.write(JSON.stringify(e,null,2)+`
|
|
9
|
-
`),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(!i.id)return process.stderr.write("Error: domain id is required for `domains delete`.\n"),2;let e=await r({resource:`domain`,name:s(i.id),yes:i.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
|
|
10
|
-
`),1;let t=await l.deleteDomain(i.id);return i.json?(process.stdout.write(JSON.stringify(t)+`
|
|
11
|
-
`),0):(process.stdout.write(`✔ Deleted domain ${s(i.id)}.\n`),0)}}}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}}export{l as domainsCommand};
|
package/dist/emit-DBbMG9mK.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
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={}){if(e.json||e.csv||e.tsv||e.ndjson||!process.stdout.isTTY||process.env.CI===`true`||process.env.CI===`1`||process.env.NO_COLOR!=null&&process.env.NO_COLOR!==``)return!0;let t=(process.env.ZENOVAY_FORMAT??``).toLowerCase();return t===`json`||t===`ndjson`||t===`csv`||t===`tsv`}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};
|
package/dist/errors-BXwphY11.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-Cmi_f_SY.js";import{readToken as t}from"./api-CeB_9iPg.js";import{ApiV2Client as n}from"./api-v2-B_kZhVxd.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-BUpzvcMz.js";import{DataTable as s}from"./data-table-BUyOP6Nc.js";import"./bar-BNmNGwlD.js";import{runAnalyticalScreen as c}from"./analytical-screen-BpTK5dCY.js";import"./ui-BRls3_H3.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function p(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}async function m(m){let h=await e(),g=await t({strict:!1}),_=new n({config:h,cliVersion:m.cliVersion,token:g}),v,y;try{({siteId:v,site:y}=await o(_,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let b=i(m),x=m.window??`24h`,S=m.limit??100,C=[{key:`ts`,label:`when`,width:6,format:e=>p(String(e))},{key:`class`,label:`class`,width:18,format:e=>String(e)},{key:`message`,label:`message`,width:42,format:e=>f(String(e??``),42)},{key:`page`,label:`page`,width:24,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:8,format:e=>String(e??`—`)}];return c({cliVersion:m.cliVersion,title:`errors · ${v} · ${x}`,commandName:`errors`,authToken:g?.accessToken??null,refreshIntervalMs:m.watch?3e4:0,fetcher:e=>_.getErrors(v,{window:x,limit:S},e),format:b,headlessEmit:(e,t)=>{let n=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of n)process.stdout.write(JSON.stringify(e)+`
|
|
2
|
-
`);else process.stdout.write(JSON.stringify({errors:n,total:n.length},null,2));return}process.stdout.write(r(n,[`ts`,`class`,`message`,`page`,`device`,`fingerprint`],t))},panels:[{id:`summary`,title:`Recent errors`,render:e=>{let t=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors,n=new Map,r=Date.now(),i=60;for(let e of t){let t=new Date(e.ts).getTime(),a=Math.floor((r-t)/(60*1e3));if(a<0||a>=i)continue;let o=n.get(e.class)??Array(i).fill(0),s=i-1-a;o[s]+=1,n.set(e.class,o)}let o=[...n.entries()].sort((e,t)=>t[1].reduce((e,t)=>e+t,0)-e[1].reduce((e,t)=>e+t,0)).slice(0,6);return d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},t.length),d.createElement(u,{color:`gray`},` errors in `,x)),o.length===0?null:d.createElement(l,{flexDirection:`column`,marginTop:1},o.map(([e,t])=>d.createElement(u,{key:e},d.createElement(u,{color:`red`},e.padEnd(20).slice(0,20)),` `,d.createElement(u,{color:`gray`},a(t,30))))))}},{id:`table`,title:`Detail`,render:e=>{let t=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors;return t.length===0?d.createElement(u,{color:`gray`},`— no errors `,m.search?`matching "${m.search}"`:`in window`,` —`):d.createElement(s,{data:t.slice(0,30),columns:C,headerStyle:`accent`})}}]})}export{m as errorsCommand};
|
package/dist/geo-BaCNZ7-S.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-Cmi_f_SY.js";import{readToken as t}from"./api-CeB_9iPg.js";import{ApiV2Client as n}from"./api-v2-B_kZhVxd.js";import"./formatter-mW0Yk3Nt.js";import{emit as r,isHeadless as i}from"./emit-DBbMG9mK.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-BUpzvcMz.js";import{EmptyState as l}from"./empty-state-Dkho-_3J.js";import{DataTable as u}from"./data-table-BUyOP6Nc.js";import{Globe as d}from"./globe-BrlflaZ1.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};
|
package/dist/globe-B4iKPH4T.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-Cmi_f_SY.js";import{readToken as t}from"./api-CeB_9iPg.js";import{ApiV2Client as n}from"./api-v2-B_kZhVxd.js";import"./formatter-mW0Yk3Nt.js";import{emit as r,isHeadless as i}from"./emit-DBbMG9mK.js";import{Panel as a,useTheme 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-BUpzvcMz.js";import{EmptyState as u}from"./empty-state-Dkho-_3J.js";import{Bar as d}from"./bar-BNmNGwlD.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useMemo as y,useRef as b,useState as x}from"react";import ee from"ink-spinner";import S from"open";const C={DZ:{lat:28.0339,lng:1.6596,name:`Algeria`,spread:8},EG:{lat:26.8206,lng:30.8025,name:`Egypt`,spread:6},ET:{lat:9.145,lng:40.4897,name:`Ethiopia`,spread:6},GH:{lat:7.9465,lng:-1.0232,name:`Ghana`,spread:3},KE:{lat:-.0236,lng:37.9062,name:`Kenya`,spread:4},MA:{lat:31.7917,lng:-7.0926,name:`Morocco`,spread:5},NG:{lat:9.082,lng:8.6753,name:`Nigeria`,spread:5},ZA:{lat:-30.5595,lng:22.9375,name:`South Africa`,spread:7},TZ:{lat:-6.369,lng:34.8888,name:`Tanzania`,spread:5},UG:{lat:1.3733,lng:32.2903,name:`Uganda`,spread:3},TN:{lat:33.8869,lng:9.5375,name:`Tunisia`,spread:3},SN:{lat:14.4974,lng:-14.4524,name:`Senegal`,spread:3},CI:{lat:7.54,lng:-5.5471,name:`Côte d'Ivoire`,spread:3},CM:{lat:7.3697,lng:12.3547,name:`Cameroon`,spread:4},AO:{lat:-11.2027,lng:17.8739,name:`Angola`,spread:6},MZ:{lat:-18.6657,lng:35.5296,name:`Mozambique`,spread:6},ZW:{lat:-19.0154,lng:29.1549,name:`Zimbabwe`,spread:4},ZM:{lat:-13.1339,lng:27.8493,name:`Zambia`,spread:5},RW:{lat:-1.9403,lng:29.8739,name:`Rwanda`,spread:1.5},MG:{lat:-18.7669,lng:46.8691,name:`Madagascar`,spread:5},LY:{lat:26.3351,lng:17.2283,name:`Libya`,spread:8},SD:{lat:12.8628,lng:30.2176,name:`Sudan`,spread:7},US:{lat:39.0902,lng:-98.5795,name:`United States`,spread:18},CA:{lat:56.1304,lng:-106.3468,name:`Canada`,spread:22},MX:{lat:23.6345,lng:-102.5528,name:`Mexico`,spread:9},BR:{lat:-10.235,lng:-51.9253,name:`Brazil`,spread:18},AR:{lat:-38.4161,lng:-63.6167,name:`Argentina`,spread:11},CL:{lat:-35.6751,lng:-71.543,name:`Chile`,spread:11},CO:{lat:4.5709,lng:-74.2973,name:`Colombia`,spread:6},PE:{lat:-9.19,lng:-75.0152,name:`Peru`,spread:7},VE:{lat:6.4238,lng:-66.5897,name:`Venezuela`,spread:6},EC:{lat:-1.8312,lng:-78.1834,name:`Ecuador`,spread:3},BO:{lat:-16.2902,lng:-63.5887,name:`Bolivia`,spread:6},UY:{lat:-32.5228,lng:-55.7658,name:`Uruguay`,spread:2.5},PY:{lat:-23.4425,lng:-58.4438,name:`Paraguay`,spread:4},GT:{lat:15.7835,lng:-90.2308,name:`Guatemala`,spread:2},CU:{lat:21.5218,lng:-77.7812,name:`Cuba`,spread:3},DO:{lat:18.7357,lng:-70.1627,name:`Dominican Republic`,spread:1.5},CR:{lat:9.7489,lng:-83.7534,name:`Costa Rica`,spread:1.2},PA:{lat:8.538,lng:-80.7821,name:`Panama`,spread:1.5},HN:{lat:15.2,lng:-86.2419,name:`Honduras`,spread:2},PR:{lat:18.2208,lng:-66.5901,name:`Puerto Rico`,spread:.6},JM:{lat:18.1096,lng:-77.2975,name:`Jamaica`,spread:.7},TT:{lat:10.6918,lng:-61.2225,name:`Trinidad and Tobago`,spread:.6},GB:{lat:55.3781,lng:-3.436,name:`United Kingdom`,spread:3},IE:{lat:53.4129,lng:-8.2439,name:`Ireland`,spread:2},FR:{lat:46.6034,lng:1.8883,name:`France`,spread:4},DE:{lat:51.1657,lng:10.4515,name:`Germany`,spread:3.5},IT:{lat:41.8719,lng:12.5674,name:`Italy`,spread:3.5},ES:{lat:40.4637,lng:-3.7492,name:`Spain`,spread:4},PT:{lat:39.3999,lng:-8.2245,name:`Portugal`,spread:2},NL:{lat:52.1326,lng:5.2913,name:`Netherlands`,spread:1.2},BE:{lat:50.5039,lng:4.4699,name:`Belgium`,spread:1},CH:{lat:46.8182,lng:8.2275,name:`Switzerland`,spread:1.4},AT:{lat:47.5162,lng:14.5501,name:`Austria`,spread:2},PL:{lat:51.9194,lng:19.1451,name:`Poland`,spread:3.5},CZ:{lat:49.8175,lng:15.473,name:`Czechia`,spread:1.8},SE:{lat:60.1282,lng:18.6435,name:`Sweden`,spread:5},NO:{lat:60.472,lng:8.4689,name:`Norway`,spread:5},FI:{lat:61.9241,lng:25.7482,name:`Finland`,spread:4},DK:{lat:56.2639,lng:9.5018,name:`Denmark`,spread:1.5},IS:{lat:64.9631,lng:-19.0208,name:`Iceland`,spread:3},GR:{lat:39.0742,lng:21.8243,name:`Greece`,spread:3},TR:{lat:38.9637,lng:35.2433,name:`Turkey`,spread:6},RO:{lat:45.9432,lng:24.9668,name:`Romania`,spread:3},HU:{lat:47.1625,lng:19.5033,name:`Hungary`,spread:2},UA:{lat:48.3794,lng:31.1656,name:`Ukraine`,spread:5},RU:{lat:61.524,lng:80,name:`Russia`,spread:28},BG:{lat:42.7339,lng:25.4858,name:`Bulgaria`,spread:2},HR:{lat:45.1,lng:15.2,name:`Croatia`,spread:2},RS:{lat:44.0165,lng:21.0059,name:`Serbia`,spread:2},SK:{lat:48.669,lng:19.699,name:`Slovakia`,spread:1.8},SI:{lat:46.1512,lng:14.9955,name:`Slovenia`,spread:1.2},LT:{lat:55.1694,lng:23.8813,name:`Lithuania`,spread:1.5},LV:{lat:56.8796,lng:24.6032,name:`Latvia`,spread:1.5},EE:{lat:58.5953,lng:25.0136,name:`Estonia`,spread:1.5},BY:{lat:53.7098,lng:27.9534,name:`Belarus`,spread:3},MD:{lat:47.4116,lng:28.3699,name:`Moldova`,spread:1.2},AL:{lat:41.1533,lng:20.1683,name:`Albania`,spread:1},MK:{lat:41.6086,lng:21.7453,name:`North Macedonia`,spread:1},BA:{lat:43.9159,lng:17.6791,name:`Bosnia and Herzegovina`,spread:1.2},ME:{lat:42.7087,lng:19.3744,name:`Montenegro`,spread:.8},XK:{lat:42.6026,lng:20.903,name:`Kosovo`,spread:.7},LU:{lat:49.8153,lng:6.1296,name:`Luxembourg`,spread:.4},MT:{lat:35.9375,lng:14.3754,name:`Malta`,spread:.3},CY:{lat:35.1264,lng:33.4299,name:`Cyprus`,spread:.6},CN:{lat:35.8617,lng:104.1954,name:`China`,spread:18},JP:{lat:36.2048,lng:138.2529,name:`Japan`,spread:5},KR:{lat:35.9078,lng:127.7669,name:`South Korea`,spread:2},IN:{lat:20.5937,lng:78.9629,name:`India`,spread:12},ID:{lat:-2.7893,lng:113.9213,name:`Indonesia`,spread:12},PH:{lat:12.8797,lng:121.774,name:`Philippines`,spread:5},VN:{lat:14.0583,lng:108.2772,name:`Vietnam`,spread:5},TH:{lat:15.87,lng:100.9925,name:`Thailand`,spread:4},MY:{lat:4.2105,lng:101.9758,name:`Malaysia`,spread:4},SG:{lat:1.3521,lng:103.8198,name:`Singapore`,spread:.3},PK:{lat:30.3753,lng:69.3451,name:`Pakistan`,spread:6},BD:{lat:23.685,lng:90.3563,name:`Bangladesh`,spread:3},LK:{lat:7.8731,lng:80.7718,name:`Sri Lanka`,spread:2},MM:{lat:21.9162,lng:95.956,name:`Myanmar`,spread:6},KH:{lat:12.5657,lng:104.991,name:`Cambodia`,spread:3},LA:{lat:19.8563,lng:102.4955,name:`Laos`,spread:3},NP:{lat:28.3949,lng:84.124,name:`Nepal`,spread:3},IR:{lat:32.4279,lng:53.688,name:`Iran`,spread:7},IQ:{lat:33.2232,lng:43.6793,name:`Iraq`,spread:4},IL:{lat:31.0461,lng:34.8516,name:`Israel`,spread:1},SA:{lat:23.8859,lng:45.0792,name:`Saudi Arabia`,spread:8},AE:{lat:23.4241,lng:53.8478,name:`UAE`,spread:2},QA:{lat:25.3548,lng:51.1839,name:`Qatar`,spread:.6},KW:{lat:29.3117,lng:47.4818,name:`Kuwait`,spread:.8},OM:{lat:21.4735,lng:55.9754,name:`Oman`,spread:4},JO:{lat:30.5852,lng:36.2384,name:`Jordan`,spread:2},LB:{lat:33.8547,lng:35.8623,name:`Lebanon`,spread:.7},SY:{lat:34.8021,lng:38.9968,name:`Syria`,spread:3},YE:{lat:15.5527,lng:48.5164,name:`Yemen`,spread:4},AF:{lat:33.9391,lng:67.71,name:`Afghanistan`,spread:5},KZ:{lat:48.0196,lng:66.9237,name:`Kazakhstan`,spread:13},UZ:{lat:41.3775,lng:64.5853,name:`Uzbekistan`,spread:5},TM:{lat:38.9697,lng:59.5563,name:`Turkmenistan`,spread:5},KG:{lat:41.2044,lng:74.7661,name:`Kyrgyzstan`,spread:3},TJ:{lat:38.861,lng:71.2761,name:`Tajikistan`,spread:3},AZ:{lat:40.1431,lng:47.5769,name:`Azerbaijan`,spread:2},GE:{lat:42.3154,lng:43.3569,name:`Georgia`,spread:2},AM:{lat:40.0691,lng:45.0382,name:`Armenia`,spread:1.2},HK:{lat:22.3193,lng:114.1694,name:`Hong Kong`,spread:.3},TW:{lat:23.6978,lng:120.9605,name:`Taiwan`,spread:1.5},AU:{lat:-25.2744,lng:133.7751,name:`Australia`,spread:18},NZ:{lat:-40.9006,lng:174.886,name:`New Zealand`,spread:5},PG:{lat:-6.314,lng:143.9555,name:`Papua New Guinea`,spread:5},FJ:{lat:-16.578,lng:179.4144,name:`Fiji`,spread:1}},w=Object.fromEntries(Object.entries(C).map(([e,t])=>[e,{lat:t.lat,lng:t.lng}]));function T(e){return!e||e.length!==2?null:C[e.toUpperCase()]??null}function E(e,t){let n=T(e);if(!n||t<=0)return[];let r=[],i=0;for(let t=0;t<e.length;t++)i=i*31+e.charCodeAt(t)>>>0;for(let e=0;e<t;e++){i=i+1831565813>>>0;let e=i;e=Math.imul(e^e>>>15,e|1)>>>0,e=(e^e+(Math.imul(e^e>>>7,e|61)>>>0))>>>0;let t=((e^e>>>14)>>>0)/4294967296;i=i+2246822507>>>0;let a=i;a=Math.imul(a^a>>>15,a|1)>>>0,a=(a^a+(Math.imul(a^a>>>7,a|61)>>>0))>>>0;let o=((a^a>>>14)>>>0)/4294967296,s=n.spread*Math.sqrt(t),c=o*2*Math.PI;r.push({lat:n.lat+s*Math.sin(c)*.7,lng:n.lng+s*Math.cos(c)/Math.max(.3,Math.cos(n.lat*Math.PI/180))})}return r}const D=360,O=180,k=new Uint8Array(D*O),A=new Uint8Array(D*O),j=[`__OCEAN__`];function M(e){let t=(e%360+360)%360;return Math.floor(t)}function N(e){return Math.max(0,Math.min(O-1,Math.floor(90-e)))}function P(e,t,n){let r=N(e),i=M(t);k[r*D+i]=1,A[r*D+i]=n}for(let e of Object.keys(C)){let t=C[e];j.push(e);let n=j.length-1,r=Math.max(.5,t.spread*.85),i=Math.max(.25,Math.cos(t.lat*Math.PI/180)),a=Math.max(.5,t.spread/i),o=Math.floor(t.lat-r),s=Math.ceil(t.lat+r),c=Math.floor(t.lng-a),l=Math.ceil(t.lng+a);for(let e=o;e<=s;e++)for(let i=c;i<=l;i++){let o=(e-t.lat)/r,s=(i-t.lng)/a;s*s+o*o>1||P(e,i,n)}}const F=new Uint8Array(k);for(let e=1;e<O-1;e++)for(let t=0;t<D;t++){if(k[e*D+t])continue;let n=0,r=0;for(let i=-1;i<=1;i++)for(let a=-1;a<=1;a++){if(i===0&&a===0)continue;let o=(t+a+D)%D;k[(e+i)*D+o]&&(n++,r||=A[(e+i)*D+o]??0)}n>=4&&(F[e*D+t]=1,A[e*D+t]=r)}k.set(F);const I=new Uint8Array(D*O);for(let e=0;e<O;e++)for(let t=0;t<D;t++){let n=A[e*D+t];if(!n)continue;let r=e>0?A[(e-1)*D+t]:0,i=e<O-1?A[(e+1)*D+t]:0,a=A[e*D+(t-1+D)%D],o=A[e*D+(t+1)%D];(r!==n||i!==n||a!==n||o!==n)&&(I[e*D+t]=1)}function L(e,t){if(e<-90||e>90)return 0;let n=Math.max(0,Math.min(O-1,Math.floor(90-e))),r=(t%360+360)%360,i=Math.floor(r);return k[n*D+i]===1?1:0}function R(e,t){if(e<-90||e>90)return 0;let n=Math.max(0,Math.min(O-1,Math.floor(90-e))),r=(t%360+360)%360,i=Math.floor(r);return I[n*D+i]===1?1:0}function z(e){return e*Math.PI/180}function B(e,t){let n=z(e),r=z(t);return{x:Math.cos(n)*Math.sin(r),y:Math.sin(n),z:Math.cos(n)*Math.cos(r)}}function V(e,t){let n=Math.cos(t),r=Math.sin(t);return{x:n*e.x+r*e.z,y:e.y,z:-r*e.x+n*e.z}}function H(e,t){let n=Math.cos(t),r=Math.sin(t);return{x:e.x,y:n*e.y-r*e.z,z:r*e.y+n*e.z}}function U(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function W(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function G(e,t,n,r){let i=r*r;for(let a=-r;a<=r;a++)for(let o=-r;o<=r;o++)o*o+a*a<=i&&W(e,Math.round(t+o),Math.round(n+a))}const K=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function q(e,t,n){let r=0;for(let i=0;i<K.length;i++){let[a,o]=K[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function J(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`·`:r<=5?`○`:`●`}function Y(e){if(e)return!0;let t=process.env;if(t.NO_COLOR||t.ZENOVAY_GLOBE===`ascii`)return!0;let n=(t.LANG||t.LC_ALL||t.LC_CTYPE||``).toLowerCase();return!!(n&&!n.includes(`utf`))}function X(e,t,n){if(e.z<0)return null;let r=t/2,i=n/2,a=Math.min(t,n/2)*.95;return{x:r+e.x*a,y:i-e.y*a}}function Z(e){let t=e.dw/2,n=e.dh/2,r=Math.min(e.dw,e.dh/2)*.95,i=Math.round(2*Math.PI*r);for(let a=0;a<i;a++){let o=a/i*2*Math.PI,s=Math.round(t+r*Math.cos(o)),c=Math.round(n+r*Math.sin(o));W(e,s,c)}}function te(e,t,n){for(let r of[-60,-30,0,30,60])for(let i=-180;i<=180;i+=4){let a=H(V(B(r,i),t),n),o=X(a,e.dw,e.dh);o&&W(e,Math.round(o.x),Math.round(o.y))}for(let r=-180;r<180;r+=30)for(let i=-85;i<=85;i+=4){let a=H(V(B(i,r),t),n),o=X(a,e.dw,e.dh);o&&W(e,Math.round(o.x),Math.round(o.y))}}function ne({visitors:e,highlight:t,width:n=50,height:r=25,rotationDeg:i=0,tiltDeg:a=20,gridlines:s=!0,asciiOnly:c}){let{theme:l}=o(),u=Y(c),d=U(n,r),m=U(n,r),h=U(n,r),g=U(n,r),v=U(n,r),y=z(i),b=z(-a);Z(d),s&&te(d,y,b);{let e=m.dw/2,t=m.dh/2,n=Math.min(m.dw,m.dh/2)*.95,r=Math.cos(y),i=Math.sin(y),a=Math.cos(b),o=Math.sin(b);for(let s=0;s<m.dh;s++){let c=(t-s)/n;if(!(c<-1||c>1))for(let t=0;t<m.dw;t++){let l=(t-e)/n,u=l*l+c*c;if(u>1)continue;let d=Math.sqrt(1-u),f=l,p=c,g=a*p+o*d,_=-o*p+a*d,v=r*f-i*_,y=i*f+r*_,b=Math.asin(g)*(180/Math.PI),x=Math.atan2(v,y)*(180/Math.PI);L(b,x)&&(W(m,t,s),R(b,x)&&W(h,t,s))}}}for(let t of e){let e=H(V(B(t.lat,t.lng),y),b),n=X(e,g.dw,g.dh);if(!n)continue;let r=typeof t.freshness==`number`?t.freshness:.5;G(g,n.x,n.y,r>.7?2:1)}if(t&&t.length>0)for(let e of t){let t=H(V(B(e.lat,e.lng),y),b),n=X(t,v.dw,v.dh);if(!n)continue;G(v,n.x,n.y,2)}let x=[];for(let e=0;e<r;e++){let t=[],r=null,i=(e,n)=>{r&&r.color===e?r.text+=n:(r={color:e,text:n},t.push(r))};for(let r=0;r<n;r++){let n=u?J(v,r,e):q(v,r,e);if(n!==` `){i(l.warn,n);continue}let a=u?J(g,r,e):q(g,r,e);if(a!==` `){i(l.accent,a);continue}let o=u?J(h,r,e):q(h,r,e);if(o!==` `){i(l.fg,o);continue}let s=u?J(m,r,e):q(m,r,e);if(s!==` `){i(l.success,s);continue}let c=u?J(d,r,e):q(d,r,e);if(c!==` `){i(l.muted,c);continue}let f=t.length>0?t[t.length-1]:void 0;i(f?f.color:l.muted,` `)}x.push(_.createElement(f,{key:e},_.createElement(p,null,t.map((e,t)=>_.createElement(p,{key:t,color:e.color,bold:!0},e.text)))))}return _.createElement(f,{flexDirection:`column`},x)}async function Q(e,t,n){let r=await e.getGeo(t).catch(()=>({countries:[],cities:[]})),i=(r.countries??[]).map(e=>{let t=T(e.country),r=n.get(e.country)??0;return{code:e.country,visitors:e.visitors,lat:t?.lat,lng:t?.lng,freshness:e.visitors>r?1:.4}});return{countries:i,totalVisitors:i.reduce((e,t)=>e+t.visitors,0),unknownCount:i.filter(e=>typeof e.lat!=`number`).reduce((e,t)=>e+t.visitors,0),lastFetchedAt:Date.now()}}async function re(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await l(c,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(a.browser){let e=`https://app.zenovay.com/domains/${encodeURIComponent(u)}?tab=globe`;a.json?process.stdout.write(JSON.stringify({openedUrl:e})+`
|
|
2
|
-
`):process.stdout.write(`\n Opening Mapbox globe in your default browser:\n ${e}\n\n`);try{await S(e)}catch{}return 0}if(i(a)){let e=await Q(c,u,new Map);return r({type:`globe.snapshot`,data:{countries:e.countries,total:e.totalVisitors,unknownCount:e.unknownCount}}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement($,{api:c,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const ie=5e3,ae=60,oe=1,se=80,$=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:l}=h(),{theme:m}=o(),[C,w]=x(null),[D,O]=x(!0),[k,A]=x(null),[j,M]=x(0),[N,P]=x(!1),[F,I]=x(20),[L,R]=x(1),[z,B]=x(0),V=b(new Map);g(n=>{if(n===`q`){l(),i(0);return}if(n===` `){P(e=>!e);return}if(n===`+`||n===`=`){R(e=>Math.min(1.6,e+.1));return}if(n===`-`||n===`_`){R(e=>Math.max(.7,e-.1));return}if(n===`t`){I(e=>(e+15)%60);return}if(n===`j`){B(e=>e+1);return}if(n===`k`){B(e=>Math.max(0,e-1));return}if(n===`w`){let e=`https://app.zenovay.com/domains/${encodeURIComponent(t)}?tab=globe`;S(e).catch(()=>{});return}if(n===`o`&&C){let e=C.countries[z];e?.lng!==void 0&&(M(-e.lng),P(!0));return}n===`r`&&(async()=>{try{let n=await Q(e,t,V.current);V.current=new Map(n.countries.map(e=>[e.code,e.visitors])),w(n)}catch(e){A(e.message)}})()}),v(()=>{let n=!1,r=null,i=async()=>{try{let r=await Q(e,t,V.current);if(n)return;V.current=new Map(r.countries.map(e=>[e.code,e.visitors])),w(r),O(!1)}catch(e){n||(A(e.message),O(!1))}n||(r=setTimeout(i,ie))};return i(),()=>{n=!0,r&&clearTimeout(r)}},[e,t]),v(()=>{if(N)return;let e=setInterval(()=>{M(e=>(e+oe)%360)},ae);return()=>clearInterval(e)},[N]);let H=y(()=>{if(!C)return[];let e=[];for(let t of C.countries){if(typeof t.lat!=`number`||typeof t.lng!=`number`)continue;let n=Math.min(se,Math.max(3,t.visitors*5));for(let r of E(t.code,n))e.push({lat:r.lat,lng:r.lng,freshness:t.freshness})}return e},[C]),U=y(()=>{if(!C)return[];let e=C.countries[Math.min(z,C.countries.length-1)];return!e||typeof e.lat!=`number`?[]:E(e.code,Math.min(80,Math.max(8,e.visitors*4)))},[C,z]),W=`globe · ${n} · live`,G=[{key:`q`,label:`quit`},{key:`j/k`,label:`select country`},{key:`o`,label:`orbit to selected`},{key:`space`,label:N?`resume`:`pause`},{key:`t`,label:`tilt ${F}°`},{key:`+/-`,label:`zoom`},{key:`w`,label:`open Mapbox view in browser`},{key:`r`,label:`refresh`}];if(D)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),_.createElement(a,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`cyan`},_.createElement(ee,{type:`dots`})),_.createElement(p,null,` Spinning up Earth…`))));if(k)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),_.createElement(u,{reason:`error`,headline:`Failed to load`,hint:k}),_.createElement(c,{items:G}));if(!C||C.countries.length===0&&C.unknownCount===0)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),_.createElement(u,{reason:`no-data`,headline:`No geolocated visitors yet`,hint:`Visit your site to populate the map.`}),_.createElement(c,{items:G}));let K=process.stdout.columns??100,q=36,J=Math.max(40,Math.min(90,K-q-4)),Y=Math.round(J*L),X=Math.round(Y*.5),Z=C.countries.slice(0,12),te=Math.max(1,...Z.map(e=>e.visitors)),re=Math.max(1,Math.floor((Date.now()-C.lastFetchedAt)/1e3)),$=C.countries[Math.min(z,C.countries.length-1)],ce=$?T($.code):null;return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),$?_.createElement(f,{flexDirection:`row`,marginBottom:1},_.createElement(f,{width:2}),_.createElement(f,{borderStyle:`round`,borderColor:m.warn,paddingX:1},_.createElement(p,{color:m.warn,bold:!0},ce?.name??$.code),_.createElement(p,{color:m.dim},` · `),_.createElement(p,{color:m.fg},$.visitors,` visitor`,$.visitors===1?``:`s`))):null,_.createElement(f,{flexDirection:`row`},_.createElement(f,{flexDirection:`column`,marginRight:2},_.createElement(ne,{visitors:H,highlight:U,width:Y,height:X,rotationDeg:j,tiltDeg:F}),_.createElement(f,{marginTop:1},_.createElement(p,{color:m.dim},C.totalVisitors,` visitors · `,C.countries.length,` countries`,C.unknownCount>0?` · ${C.unknownCount} unmapped`:``,` · `,N?`rotation paused`:`↻ ${oe}°/${ae}ms`,` · refreshed `,re,`s ago`))),_.createElement(f,{flexDirection:`column`,width:q},_.createElement(a,{title:`Live by country`},Z.map((e,t)=>{let n=t===Math.min(z,C.countries.length-1),r=e.freshness>.7,i=n?m.warn:r?m.success:m.fg;return _.createElement(f,{key:e.code,flexDirection:`row`},_.createElement(f,{width:2},_.createElement(p,{color:m.warn},n?`›`:` `)),_.createElement(f,{width:3},_.createElement(p,{color:i,bold:n},e.code)),_.createElement(d,{value:e.visitors,max:te,width:14,showPercent:!1}),_.createElement(f,{width:6},_.createElement(p,{color:m.muted},String(e.visitors).padStart(5))))})),C.countries.length>12?_.createElement(f,{marginTop:1},_.createElement(p,{color:m.muted},`+`,C.countries.length-12,` more (j/k to scroll)`)):null)),_.createElement(c,{items:G}))};export{re as globeCommand};
|
package/dist/goals-D1qL286b.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-Cmi_f_SY.js";import{readToken as t}from"./api-CeB_9iPg.js";import{ApiV2Client as n}from"./api-v2-B_kZhVxd.js";import{requireTier as r}from"./tier-DyX4EObq.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};
|
package/dist/health-ChZuTNP2.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{configPath as e,readConfig as t}from"./config-Cmi_f_SY.js";import{fetchManifest as n}from"./check-Comj8AkL.js";import{ApiClient as r,readToken as i}from"./api-CeB_9iPg.js";import{isHeadless as a}from"./emit-DBbMG9mK.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};
|
package/dist/health-DfgPNC1A.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./config-Cmi_f_SY.js";import"./check-Comj8AkL.js";import"./api-CeB_9iPg.js";import"./formatter-mW0Yk3Nt.js";import"./emit-DBbMG9mK.js";import"./panel-uygscwY5.js";import{HealthReport as e,exitCodeFor as t,healthCommand as n,runHealthChecks as r}from"./health-ChZuTNP2.js";export{n as healthCommand};
|