@zenovay/cli 0.1.65 → 0.1.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agency-C69JHza5.js → agency-BxYMejNb.js} +1 -1
- package/dist/{ai-eSlGP6ay.js → ai-DbtIo6k2.js} +1 -1
- package/dist/{alerts-CcKnqwmm.js → alerts-DKQa_K77.js} +1 -1
- package/dist/{analytical-screen-BrOFDrQ_.js → analytical-screen-B_wWUnT4.js} +1 -1
- package/dist/{analytics-B8yy7gjr.js → analytics-BO22Zeas.js} +1 -1
- package/dist/{annotation-BiviGSmz.js → annotation-CL1q8mjr.js} +1 -1
- package/dist/{api-keys-DQob1q69.js → api-keys-lfjOVUIe.js} +1 -1
- package/dist/{api-v2-CI5hxW-O.js → api-v2-CPUUcP1i.js} +1 -1
- package/dist/{api-v2-CTc_U2Gw.js → api-v2-D9N_2hdW.js} +1 -1
- package/dist/{apply-oUMOH7u2.js → apply-B19bFTz0.js} +1 -1
- package/dist/{audit-B4a5u54T.js → audit-DfKQdrug.js} +1 -1
- package/dist/{banner-MAYlzjcP.js → banner-DdgwXGzt.js} +1 -1
- package/dist/{bar-DG-MqgGx.js → bar-C1Zrfe9H.js} +1 -1
- package/dist/bin.js +6 -6
- package/dist/{chat-panel-dXLm3hUn.js → chat-panel-ZlKZ0W6J.js} +1 -1
- package/dist/{commands-B-NMyq2s.js → commands-NsH5CS-H.js} +1 -1
- package/dist/{companies-CpDnB5NR.js → companies-CtZ2vGQs.js} +1 -1
- package/dist/{completions-Cy6kF9kp.js → completions-Bem7-lcb.js} +1 -1
- package/dist/csv-emit-BWWv60mT.js +1 -0
- package/dist/csv-emit-CVO5kebZ.js +1 -0
- package/dist/{data-table-BvnWCG-w.js → data-table-DJzT7bAr.js} +1 -1
- package/dist/{deploys-CI88FRFO.js → deploys-CUbSa8S5.js} +1 -1
- package/dist/{devices-DNkzamfH.js → devices-CrkIxfde.js} +1 -1
- package/dist/{doctor-DJbNKwdF.js → doctor-D5HWdhgv.js} +1 -1
- package/dist/{domains-BoRRxWzR.js → domains-V4sD09io.js} +1 -1
- package/dist/{emit-D4YlMlzk.js → emit-C9vAopcy.js} +1 -1
- package/dist/{empty-state-DdLBcz4h.js → empty-state-DbToIL5T.js} +1 -1
- package/dist/{errors-BtGhPNBy.js → errors-D3fS1kYu.js} +1 -1
- package/dist/{events-tail-ig5nAsbQ.js → events-tail-DGRZewwc.js} +1 -1
- package/dist/{export-CTI3xHqF.js → export-FjEyji8r.js} +1 -1
- package/dist/{funnel-DkcJHeX6.js → funnel-C7DmrdUC.js} +1 -1
- package/dist/{geo-UBu3aUHh.js → geo-C9OcRStg.js} +1 -1
- package/dist/{globe-GU2r8P23.js → globe-PiPL3Bei.js} +1 -1
- package/dist/{goals-CcA4qOM5.js → goals-CVRryIri.js} +1 -1
- package/dist/{health-am28BgPf.js → health-DMiTjQ9Z.js} +1 -1
- package/dist/{health-C-efHHs0.js → health-vxoiMF8G.js} +1 -1
- package/dist/{heatmaps-C6ynBgMW.js → heatmaps-G3Nf95tV.js} +1 -1
- package/dist/{home-B0miYclo.js → home-CXwRtMge.js} +1 -1
- package/dist/init-BuyESMBj.js +79 -0
- package/dist/init-WmEUW4Em.js +1 -0
- package/dist/{insights-C8PBisLR.js → insights-J99-8Rcu.js} +1 -1
- package/dist/{integrations-CS16nG51.js → integrations-CWPrMJfZ.js} +1 -1
- package/dist/{journeys-DaqlziL4.js → journeys-BLxqoeFu.js} +1 -1
- package/dist/{keybar-BcHUm3hI.js → keybar-QgnmSion.js} +1 -1
- package/dist/{live-cIPlpoWN.js → live-CWSLgkC2.js} +1 -1
- package/dist/login-CaDs2Peq.js +2 -0
- package/dist/login-wpGuU_Zm.js +1 -0
- package/dist/{logout-BSSOsDr7.js → logout-BkeT6Hke.js} +1 -1
- package/dist/{metric-card-CaFIymSQ.js → metric-card-bQ-j_G6l.js} +1 -1
- package/dist/{notes-ZXJfqA4H.js → notes-C8cba6QA.js} +1 -1
- package/dist/{pages-3tis8juF.js → pages-CKs5X38q.js} +1 -1
- package/dist/{panel-DB1HLxAw.js → panel-B-XxdP-N.js} +1 -1
- package/dist/{plans-DCon6c8N.js → plans-oxxMSOdB.js} +1 -1
- package/dist/{profile-CY1_dG5d.js → profile-CD9QVZ2I.js} +1 -1
- package/dist/{progress-row-BS7fwhn_.js → progress-row-5ns2IsFh.js} +1 -1
- package/dist/{projects-B7xPHSK2.js → projects-hIQqeDYq.js} +1 -1
- package/dist/{prompt-D7Ek9MYk.js → prompt-B4s3o9G7.js} +1 -1
- package/dist/{query-CC7wPhmz.js → query-BLHvu1IF.js} +1 -1
- package/dist/{resolve-site-DYBsBK4c.js → resolve-site-DQVcWhjG.js} +1 -1
- package/dist/{retention-DeG_P1-s.js → retention-B8bgiVux.js} +1 -1
- package/dist/{revenue-Dobs3EQH.js → revenue-BiViSloE.js} +1 -1
- package/dist/secrets-M60NENIa.js +1 -0
- package/dist/{self-test-DKOYwgHD.js → self-test-CSST_zHj.js} +3 -3
- package/dist/{sessions-DM4XGC2N.js → sessions-lUUiiNYc.js} +1 -1
- package/dist/{settings-C_st_Aqq.js → settings-CFFiWmGO.js} +1 -1
- package/dist/{share-6Dt695rC.js → share-Cx62AEP-.js} +1 -1
- package/dist/{sources-BofnMkYR.js → sources-D-KqX0Sg.js} +1 -1
- package/dist/{stats-DkrgaDDP.js → stats-BzTqFpJL.js} +1 -1
- package/dist/{status-agent-CQ955HRn.js → status-agent-TIyEIKOj.js} +1 -1
- package/dist/{team-N-Ycc7Mh.js → team-BRebgNMO.js} +1 -1
- package/dist/{teams-BmzDAiAn.js → teams-DhrkUkt8.js} +1 -1
- package/dist/{themes-lGJ4GHVu.js → themes-gluHmb6E.js} +1 -1
- package/dist/{tour-BA4g04Qt.js → tour-STZ66G7K.js} +1 -1
- package/dist/{update-CYLXsiSE.js → update-BCgHj5O4.js} +1 -1
- package/dist/{uptime-I3klxuzW.js → uptime-CwG6bqir.js} +1 -1
- package/dist/{usage-DIzd9nzk.js → usage-BFCTeA8E.js} +1 -1
- package/dist/{use-DlyoJe6I.js → use-baQFldqI.js} +1 -1
- package/dist/{visitors-BFBitwBV.js → visitors-BtriXh9k.js} +1 -1
- package/dist/{vitals-Bq1y2LBt.js → vitals-BgAwONID.js} +1 -1
- package/dist/{watch-BYIKjsGC.js → watch-Cv4FtwSJ.js} +1 -1
- package/dist/{webhooks-DKBhl3fL.js → webhooks-PRWhMVgS.js} +1 -1
- package/dist/{webhooks-forward-Cfzd9veV.js → webhooks-forward-BDxi2TcF.js} +1 -1
- package/dist/wizard-bin.js +1 -1
- package/dist/ws-client-BZMMGeRe.js +1 -0
- package/package.json +2 -1
- package/dist/csv-emit-DYTuKBke.js +0 -1
- package/dist/csv-emit-XJfJC5e2.js +0 -1
- package/dist/init-CqcqX8o5.js +0 -79
- package/dist/init-awEnG3zC.js +0 -1
- package/dist/login-CiJG9-gq.js +0 -1
- package/dist/login-RVU9FkAl.js +0 -2
- package/dist/secrets-BBaEWu03.js +0 -1
- package/dist/wrapper-Dl9i0Nh7.js +0 -6
- package/dist/ws-client-MoEdfqAO.js +0 -1
- /package/dist/{client-I4GTcUcm.js → client-Dm8uGVCy.js} +0 -0
- /package/dist/{confirm-DS5wux0g.js → confirm-CIdxMt7N.js} +0 -0
- /package/dist/{examples-C0LrZPUl.js → examples-CFatZcPz.js} +0 -0
- /package/dist/{fmt-iR2sYwsO.js → fmt-xxIPQJX-.js} +0 -0
- /package/dist/{formatter-C4YSOKuq.js → formatter-DDG2TSOz.js} +0 -0
- /package/dist/{keybar-deep-link-Dagnpllp.js → keybar-deep-link-DbmPjAEz.js} +0 -0
- /package/dist/{open-url-dPoDcwsm.js → open-url-BxXbZzWS.js} +0 -0
- /package/dist/{secrets-DzueUVGL.js → secrets-DPf_7SkN.js} +0 -0
- /package/dist/{sparkline-8ucKVUV7.js → sparkline-CpoBjjlc.js} +0 -0
- /package/dist/{telemetry-Ckn12kyP.js → telemetry-DC0Jw3JD.js} +0 -0
- /package/dist/{theme-Brz9wK0w.js → theme-BuGrQHax.js} +0 -0
- /package/dist/{tier-BneaO4vD.js → tier-C4q8fJ8m.js} +0 -0
- /package/dist/{ui-DXrdVAc-.js → ui-whccLLRv.js} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{mocha as e}from"./theme-
|
|
2
|
-
`).filter(e=>e.trim().startsWith(`{`)||e.trim().startsWith(`[`)).pop();if(e)try{return{ok:!0,value:JSON.parse(e)}}catch{}return{ok:!1,reason:`stdout not JSON (got ${t.length} bytes)`}}}function f(e,t,n){if(n!==0)return{ok:!1,reason:`exit ${n}`};let r=d(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}}function p(e,t,n){if(n!==0){let r=[e,t];for(let e of r)if(e.includes(`tier_insufficient`))return{ok:!0,detail:{gated:!0}};return{ok:!1,reason:`exit ${n} — ${(t||e).slice(0,80)}`}}let r=d(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}}function m(e){if(typeof e!=`object`||!e)return!1;let t=e;if(Array.isArray(t.items)||Array.isArray(t.rows)||Array.isArray(t.data))return!0;if(typeof t.data==`object`&&t.data!==null){let e=t.data;if(Array.isArray(e.items)||Array.isArray(e.rows))return!0}return!1}const h=[{name:`analytics`,category:`ANALYTICS`,command:[`analytics`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.visitors??a.data?.visitors,s=a.pageviews??a.data?.pageviews;return{ok:!0,detail:{visitors:o??null,pageviews:s??null}}},quick:!0},{name:`overview`,category:`ANALYTICS`,command:[`overview`,`--json`],assert:f},{name:`pages`,category:`ANALYTICS`,command:[`pages`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.items??a.data?.items;return{ok:!0,detail:{rows:o?.length??0}}},quick:!0},{name:`sources`,category:`ANALYTICS`,command:[`sources`,`--json`],assert:f,quick:!0},{name:`devices`,category:`ANALYTICS`,command:[`devices`,`--json`],assert:f},{name:`geo`,category:`ANALYTICS`,command:[`geo`,`--json`],assert:f},{name:`live`,category:`ANALYTICS`,command:[`live`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);if(i.ok&&typeof i.value==`object`&&i.value!==null){let e=i.value,t=e.bounceRate??e.data?.bounceRate;if(typeof t==`number`&&(t<0||t>1))return{ok:!1,reason:`bounceRate semantics violated (got ${t}, expected 0..1)`}}return{ok:!0}}},{name:`revenue`,category:`ANALYTICS`,command:[`revenue`,`--json`],assert:f},{name:`funnels`,category:`ANALYTICS`,command:[`funnels`,`--json`],assert:p,requires:{tier:`pro`}},{name:`home`,category:`ANALYTICS`,command:[`home`,`--json`],assert:f},{name:`usage`,category:`ANALYTICS`,command:[`usage`,`--json`],assert:f,quick:!0},{name:`stats`,category:`ANALYTICS`,command:[`stats`,`--json`],assert:f},{name:`retention`,category:`BEHAVIOR`,command:[`retention`,`--json`],assert:p,requires:{tier:`pro`}},{name:`uptime`,category:`BEHAVIOR`,command:[`uptime`,`--json`],assert:p,requires:{tier:`pro`}},{name:`sessions`,category:`BEHAVIOR`,command:[`sessions`,`--json`],assert:p,requires:{tier:`pro`}},{name:`heatmaps`,category:`BEHAVIOR`,command:[`heatmaps`,`--json`],assert:p,requires:{tier:`pro`}},{name:`journeys`,category:`BEHAVIOR`,command:[`journeys`,`--json`],assert:p,requires:{tier:`pro`}},{name:`insights`,category:`INTELLIGENCE`,command:[`insights`,`--json`],assert:p,requires:{tier:`pro`}},{name:`domains list`,category:`MANAGE`,command:[`domains`,`list`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);return!i.ok||!m(i.value)?{ok:!1,reason:`expected list shape ({items|rows|data})`}:{ok:!0}},quick:!0},{name:`api-keys list`,category:`MANAGE`,command:[`api-keys`,`list`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);return!i.ok||!m(i.value)?{ok:!1,reason:`expected list shape`}:{ok:!0}}},{name:`team list`,category:`MANAGE`,command:[`team`,`list`,`--json`],assert:p,requires:{tier:`pro`}},{name:`webhooks list`,category:`MANAGE`,command:[`webhooks`,`list`,`--json`],assert:f},{name:`profile show`,category:`ACCOUNT`,command:[`profile`,`show`,`--json`],assert:f,quick:!0},{name:`plans info`,category:`ACCOUNT`,command:[`plans`,`info`,`--json`],assert:f},{name:`settings get`,category:`ACCOUNT`,command:[`settings`,`get`,`--json`],assert:f},{name:`integrations list`,category:`ACCOUNT`,command:[`integrations`,`list`,`--json`],assert:f},{name:`goals list`,category:`ACCOUNT`,command:[`goals`,`list`,`--json`],assert:p,requires:{tier:`pro`}},{name:`notes list`,category:`ACCOUNT`,command:[`notes`,`list`,`--json`],assert:f},{name:`audit list`,category:`ACCOUNT`,command:[`audit`,`list`,`--json`],assert:p,requires:{tier:`pro`}},{name:`share url`,category:`ACCOUNT`,command:[`share`,`url`,`--json`],assert:(e,t,n)=>n!==0&&n!==1&&n!==2?{ok:!1,reason:`unexpected exit ${n}`}:{ok:!0}},{name:`teams list`,category:`ACCOUNT`,command:[`teams`,`list`,`--json`],assert:f},{name:`health`,category:`OPERATIONS`,command:[`health`,`--json`],assert:(e,t,n)=>{let r=d(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}},quick:!0},{name:`commands`,category:`OPERATIONS`,command:[`commands`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.commands;return!Array.isArray(o)||o.length===0?{ok:!1,reason:`commands tree empty`}:{ok:!0,detail:{commands:o.length}}}},{name:`themes`,category:`OPERATIONS`,command:[`themes`,`--json`],assert:f},{name:`projects`,category:`OPERATIONS`,command:[`projects`,`--json`],assert:f},{name:`idor.cross-team`,category:`SECURITY`,command:[`domains`,`list`,`--site-id`,`00000000-0000-0000-0000-000000000001`,`--json`],assert:(e,t,n)=>{let r=e+t;return/forbidden|not_found|tier_insufficient|auth_required|auth_invalid/.test(r)?{ok:!0,detail:{rejected:!0}}:r.includes(`"items"`)||r.includes(`"rows"`)?{ok:!1,reason:`expected forbidden/not_found, got data`}:{ok:!0,detail:{rejected:`empty`}}},requires:{multipleTeams:!0},dev:!0},{name:`idor.bad-uuid`,category:`SECURITY`,command:[`analytics`,`--site-id`,`00000000-0000-0000-0000-000000000000`,`--json`],assert:(e,t,n)=>{let r=e+t;return/not_found|forbidden|auth_/.test(r)?{ok:!0,detail:{rejected:!0}}:/error|invalid|"code":/i.test(r)?{ok:!0,detail:{rejected:`error-shaped`}}:{ok:!1,reason:`silent zeros — expected not_found`}},quick:!0,dev:!0},{name:`tier-gate.retention`,category:`SECURITY`,command:[`retention`,`--json`],assert:(e,t,n)=>{let r=e+t;return r.includes(`tier_insufficient`)?{ok:!0,detail:{gated:`tier_insufficient`}}:/upgrade_required|tier_required/.test(r)?{ok:!0,detail:{gated:`legacy-or-transitional`}}:/"code":\s*"forbidden"/.test(r)&&/tier|upgrade|plan/i.test(r)?{ok:!0,detail:{gated:`forbidden+tier-message`}}:n===0&&!/"type"\s*:\s*"error"/.test(r)?{ok:!0,detail:{gated:`pass-through (Pro+ access)`}}:{ok:!1,reason:`gate did not behave as expected (no tier envelope and no clean pass-through)`}},dev:!0},{name:`stack-leak.bad-net`,category:`SECURITY`,command:[`analytics`,`--json`],assert:(e,t,n)=>{let r=e+t;return/\/Users\//.test(r)||/node:internal\//.test(r)?{ok:!1,reason:`stack trace leaked filesystem path`}:{ok:!0}},quick:!0},{name:`token-perms`,category:`SECURITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{stat:e}=await import(`node:fs/promises`),t=await import(`node:path`),n=process.env.HOME??process.env.USERPROFILE??``,r=process.env.XDG_CONFIG_HOME??t.join(n,`.config`),i=process.platform===`win32`?t.join(process.env.APPDATA??t.join(n,`AppData`,`Roaming`),`zenovay`,`auth.json`):t.join(r,`zenovay`,`auth.json`);try{let t=await e(i);if(process.platform===`win32`)return{ok:!0,detail:{mode:`win32-skip`}};let n=t.mode&511;return n===384?{ok:!0,detail:{mode:`0600`}}:{ok:!1,reason:`auth.json mode ${n.toString(8)} != 0600`}}catch(e){let t=e.code;return t===`ENOENT`?{ok:!0,detail:{mode:`no-auth-file`}}:{ok:!1,reason:e.message}}},quick:!0},{name:`secret-scrub`,category:`SECURITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{SECRET_PATTERNS:e,scrubSecrets:t}=await import(`./secrets-
|
|
1
|
+
import{mocha as e}from"./theme-BuGrQHax.js";import{spawn as t}from"node:child_process";import n from"chalk";const r=3e4,i=4,a=1e3;function o(e,t){let n=e.requires;if(!n)return null;if(n.auth!==!1&&!t.authenticated)return`not authenticated`;if(n.tier&&t.currentTier){let e={free:0,pro:1,scale:2,enterprise:3},r=e[t.currentTier]??0,i=e[n.tier]??99}return n.multipleTeams&&!t.hasMultipleTeams?`requires 2+ teams`:n.freeTeam&&!t.hasFreeTeam?`requires a Free-tier team`:null}function s(e,n,r,i){return new Promise(a=>{let o=/\.[mc]?js$/.test(e),s=o?`node`:e,c=o?[e,...n]:n,l=t(s,c,{env:{...process.env,ZENOVAY_NO_UPDATE_CHECK:`1`,...i},stdio:[`ignore`,`pipe`,`pipe`]}),u=``,d=``,f=!1,p=setTimeout(()=>{f=!0;try{l.kill(`SIGKILL`)}catch{}},r);l.stdout?.on(`data`,e=>{u+=e.toString(`utf8`),u.length>1048576&&(u=u.slice(0,1048576))}),l.stderr?.on(`data`,e=>{d+=e.toString(`utf8`),d.length>1048576&&(d=d.slice(0,1048576))}),l.on(`error`,e=>{clearTimeout(p),a({stdout:u,stderr:d+`\n[spawn error: ${e.message}]`,exitCode:-1,timedOut:f})}),l.on(`close`,e=>{clearTimeout(p),a({stdout:u,stderr:d,exitCode:e??0,timedOut:f})})})}async function c(e,t){let n=Date.now(),i=o(e,t.env);if(i)return{name:e.name,category:e.category,status:`skip`,durationMs:0,reason:i};if(e.inProcess)try{let t=await e.inProcess(),r=Date.now()-n;return t.ok?{name:e.name,category:e.category,status:`pass`,durationMs:r,...t.detail?{detail:t.detail}:{}}:{name:e.name,category:e.category,status:`fail`,durationMs:r,reason:t.reason}}catch(t){return{name:e.name,category:e.category,status:`fail`,durationMs:Date.now()-n,reason:t.message}}let c=e.name===`stack-leak.bad-net`?{ZENOVAY_API_BASE:`http://127.0.0.1:1`}:void 0,l=t.timeoutMs??r,u=await s(t.binPath,e.command,l,c),d=Date.now()-n;if(u.timedOut)return{name:e.name,category:e.category,status:`fail`,durationMs:d,reason:`timeout (${Math.round(l/1e3)}s)`,...t.verbose?{rawStdout:u.stdout.slice(0,a),rawStderr:u.stderr.slice(0,a)}:{}};let f;try{f=e.assert(u.stdout,u.stderr,u.exitCode)}catch(n){return{name:e.name,category:e.category,status:`fail`,durationMs:d,reason:`assert threw: ${n.message}`,...t.verbose?{rawStdout:u.stdout.slice(0,a),rawStderr:u.stderr.slice(0,a)}:{}}}return f.ok?{name:e.name,category:e.category,status:`pass`,durationMs:d,...f.detail?{detail:f.detail}:{},...t.verbose?{rawStdout:u.stdout.slice(0,a),rawStderr:u.stderr.slice(0,a)}:{}}:{name:e.name,category:e.category,status:`fail`,durationMs:d,reason:f.reason,...t.verbose?{rawStdout:u.stdout.slice(0,a),rawStderr:u.stderr.slice(0,a)}:{}}}async function l(e,t){let n=Date.now(),r=Math.max(1,t.parallel??i),a=Array(e.length).fill(void 0),o=[];for(let n=0;n<e.length;n++){let r=e[n];r&&(t.quick&&!r.quick||o.push(n))}let s=0,l=[],u=async()=>{for(;;){let n=s;if(s+=1,n>=o.length)return;let r=o[n];if(r===void 0)return;let i=e[r];if(!i)continue;let l=await c(i,t);a[r]=l,t.onResult?.(l)}};for(let e=0;e<r;e++)l.push(u());await Promise.all(l);let d=[];for(let e of a)e&&d.push(e);let f=d.filter(e=>e.status===`pass`).length,p=d.filter(e=>e.status===`fail`).length,m=d.filter(e=>e.status===`skip`).length;return{results:d,total:d.length,pass:f,fail:p,skip:m,durationMs:Date.now()-n}}async function u(e){let t={currentTier:null,hasMultipleTeams:!1,hasFreeTeam:!1,authenticated:!1};try{let{readToken:n}=await import(`./token-store-TmBx42nv.js`),{readConfig:r}=await import(`./config-DB3jF5gG.js`),{ApiV2Client:i}=await import(`./api-v2-D9N_2hdW.js`),a=await n({strict:!1}).catch(()=>null);if(!a)return t;t.authenticated=!0;let o=await r(),s=new i({config:o,cliVersion:e,token:a}),c=await s.me();if(c.team?.plan){let e=c.team.plan.toLowerCase();(e===`free`||e===`pro`||e===`scale`||e===`enterprise`)&&(t.currentTier=e)}c.teams&&c.teams.length>=2&&(t.hasMultipleTeams=!0),(c.teams&&c.teams.some(e=>e.plan?.toLowerCase()===`free`)||t.currentTier===`free`)&&(t.hasFreeTeam=!0)}catch{}return t}function d(e){let t=e.trim();if(!t)return{ok:!1,reason:`empty stdout`};try{return{ok:!0,value:JSON.parse(t)}}catch{let e=t.split(`
|
|
2
|
+
`).filter(e=>e.trim().startsWith(`{`)||e.trim().startsWith(`[`)).pop();if(e)try{return{ok:!0,value:JSON.parse(e)}}catch{}return{ok:!1,reason:`stdout not JSON (got ${t.length} bytes)`}}}function f(e,t,n){if(n!==0)return{ok:!1,reason:`exit ${n}`};let r=d(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}}function p(e,t,n){if(n!==0){let r=[e,t];for(let e of r)if(e.includes(`tier_insufficient`))return{ok:!0,detail:{gated:!0}};return{ok:!1,reason:`exit ${n} — ${(t||e).slice(0,80)}`}}let r=d(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}}function m(e){if(typeof e!=`object`||!e)return!1;let t=e;if(Array.isArray(t.items)||Array.isArray(t.rows)||Array.isArray(t.data))return!0;if(typeof t.data==`object`&&t.data!==null){let e=t.data;if(Array.isArray(e.items)||Array.isArray(e.rows))return!0}return!1}const h=[{name:`analytics`,category:`ANALYTICS`,command:[`analytics`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.visitors??a.data?.visitors,s=a.pageviews??a.data?.pageviews;return{ok:!0,detail:{visitors:o??null,pageviews:s??null}}},quick:!0},{name:`overview`,category:`ANALYTICS`,command:[`overview`,`--json`],assert:f},{name:`pages`,category:`ANALYTICS`,command:[`pages`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.items??a.data?.items;return{ok:!0,detail:{rows:o?.length??0}}},quick:!0},{name:`sources`,category:`ANALYTICS`,command:[`sources`,`--json`],assert:f,quick:!0},{name:`devices`,category:`ANALYTICS`,command:[`devices`,`--json`],assert:f},{name:`geo`,category:`ANALYTICS`,command:[`geo`,`--json`],assert:f},{name:`live`,category:`ANALYTICS`,command:[`live`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);if(i.ok&&typeof i.value==`object`&&i.value!==null){let e=i.value,t=e.bounceRate??e.data?.bounceRate;if(typeof t==`number`&&(t<0||t>1))return{ok:!1,reason:`bounceRate semantics violated (got ${t}, expected 0..1)`}}return{ok:!0}}},{name:`revenue`,category:`ANALYTICS`,command:[`revenue`,`--json`],assert:f},{name:`funnels`,category:`ANALYTICS`,command:[`funnels`,`--json`],assert:p,requires:{tier:`pro`}},{name:`home`,category:`ANALYTICS`,command:[`home`,`--json`],assert:f},{name:`usage`,category:`ANALYTICS`,command:[`usage`,`--json`],assert:f,quick:!0},{name:`stats`,category:`ANALYTICS`,command:[`stats`,`--json`],assert:f},{name:`retention`,category:`BEHAVIOR`,command:[`retention`,`--json`],assert:p,requires:{tier:`pro`}},{name:`uptime`,category:`BEHAVIOR`,command:[`uptime`,`--json`],assert:p,requires:{tier:`pro`}},{name:`sessions`,category:`BEHAVIOR`,command:[`sessions`,`--json`],assert:p,requires:{tier:`pro`}},{name:`heatmaps`,category:`BEHAVIOR`,command:[`heatmaps`,`--json`],assert:p,requires:{tier:`pro`}},{name:`journeys`,category:`BEHAVIOR`,command:[`journeys`,`--json`],assert:p,requires:{tier:`pro`}},{name:`insights`,category:`INTELLIGENCE`,command:[`insights`,`--json`],assert:p,requires:{tier:`pro`}},{name:`domains list`,category:`MANAGE`,command:[`domains`,`list`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);return!i.ok||!m(i.value)?{ok:!1,reason:`expected list shape ({items|rows|data})`}:{ok:!0}},quick:!0},{name:`api-keys list`,category:`MANAGE`,command:[`api-keys`,`list`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);return!i.ok||!m(i.value)?{ok:!1,reason:`expected list shape`}:{ok:!0}}},{name:`team list`,category:`MANAGE`,command:[`team`,`list`,`--json`],assert:p,requires:{tier:`pro`}},{name:`webhooks list`,category:`MANAGE`,command:[`webhooks`,`list`,`--json`],assert:f},{name:`profile show`,category:`ACCOUNT`,command:[`profile`,`show`,`--json`],assert:f,quick:!0},{name:`plans info`,category:`ACCOUNT`,command:[`plans`,`info`,`--json`],assert:f},{name:`settings get`,category:`ACCOUNT`,command:[`settings`,`get`,`--json`],assert:f},{name:`integrations list`,category:`ACCOUNT`,command:[`integrations`,`list`,`--json`],assert:f},{name:`goals list`,category:`ACCOUNT`,command:[`goals`,`list`,`--json`],assert:p,requires:{tier:`pro`}},{name:`notes list`,category:`ACCOUNT`,command:[`notes`,`list`,`--json`],assert:f},{name:`audit list`,category:`ACCOUNT`,command:[`audit`,`list`,`--json`],assert:p,requires:{tier:`pro`}},{name:`share url`,category:`ACCOUNT`,command:[`share`,`url`,`--json`],assert:(e,t,n)=>n!==0&&n!==1&&n!==2?{ok:!1,reason:`unexpected exit ${n}`}:{ok:!0}},{name:`teams list`,category:`ACCOUNT`,command:[`teams`,`list`,`--json`],assert:f},{name:`health`,category:`OPERATIONS`,command:[`health`,`--json`],assert:(e,t,n)=>{let r=d(e);return r.ok?{ok:!0}:{ok:!1,reason:r.reason}},quick:!0},{name:`commands`,category:`OPERATIONS`,command:[`commands`,`--json`],assert:(e,t,n)=>{let r=f(e,t,n);if(!r.ok)return r;let i=d(e);if(!i.ok)return{ok:!1,reason:i.reason};let a=i.value,o=a.commands;return!Array.isArray(o)||o.length===0?{ok:!1,reason:`commands tree empty`}:{ok:!0,detail:{commands:o.length}}}},{name:`themes`,category:`OPERATIONS`,command:[`themes`,`--json`],assert:f},{name:`projects`,category:`OPERATIONS`,command:[`projects`,`--json`],assert:f},{name:`idor.cross-team`,category:`SECURITY`,command:[`domains`,`list`,`--site-id`,`00000000-0000-0000-0000-000000000001`,`--json`],assert:(e,t,n)=>{let r=e+t;return/forbidden|not_found|tier_insufficient|auth_required|auth_invalid/.test(r)?{ok:!0,detail:{rejected:!0}}:r.includes(`"items"`)||r.includes(`"rows"`)?{ok:!1,reason:`expected forbidden/not_found, got data`}:{ok:!0,detail:{rejected:`empty`}}},requires:{multipleTeams:!0},dev:!0},{name:`idor.bad-uuid`,category:`SECURITY`,command:[`analytics`,`--site-id`,`00000000-0000-0000-0000-000000000000`,`--json`],assert:(e,t,n)=>{let r=e+t;return/not_found|forbidden|auth_/.test(r)?{ok:!0,detail:{rejected:!0}}:/error|invalid|"code":/i.test(r)?{ok:!0,detail:{rejected:`error-shaped`}}:{ok:!1,reason:`silent zeros — expected not_found`}},quick:!0,dev:!0},{name:`tier-gate.retention`,category:`SECURITY`,command:[`retention`,`--json`],assert:(e,t,n)=>{let r=e+t;return r.includes(`tier_insufficient`)?{ok:!0,detail:{gated:`tier_insufficient`}}:/upgrade_required|tier_required/.test(r)?{ok:!0,detail:{gated:`legacy-or-transitional`}}:/"code":\s*"forbidden"/.test(r)&&/tier|upgrade|plan/i.test(r)?{ok:!0,detail:{gated:`forbidden+tier-message`}}:n===0&&!/"type"\s*:\s*"error"/.test(r)?{ok:!0,detail:{gated:`pass-through (Pro+ access)`}}:{ok:!1,reason:`gate did not behave as expected (no tier envelope and no clean pass-through)`}},dev:!0},{name:`stack-leak.bad-net`,category:`SECURITY`,command:[`analytics`,`--json`],assert:(e,t,n)=>{let r=e+t;return/\/Users\//.test(r)||/node:internal\//.test(r)?{ok:!1,reason:`stack trace leaked filesystem path`}:{ok:!0}},quick:!0},{name:`token-perms`,category:`SECURITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{stat:e}=await import(`node:fs/promises`),t=await import(`node:path`),n=process.env.HOME??process.env.USERPROFILE??``,r=process.env.XDG_CONFIG_HOME??t.join(n,`.config`),i=process.platform===`win32`?t.join(process.env.APPDATA??t.join(n,`AppData`,`Roaming`),`zenovay`,`auth.json`):t.join(r,`zenovay`,`auth.json`);try{let t=await e(i);if(process.platform===`win32`)return{ok:!0,detail:{mode:`win32-skip`}};let n=t.mode&511;return n===384?{ok:!0,detail:{mode:`0600`}}:{ok:!1,reason:`auth.json mode ${n.toString(8)} != 0600`}}catch(e){let t=e.code;return t===`ENOENT`?{ok:!0,detail:{mode:`no-auth-file`}}:{ok:!1,reason:e.message}}},quick:!0},{name:`secret-scrub`,category:`SECURITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{SECRET_PATTERNS:e,scrubSecrets:t}=await import(`./secrets-M60NENIa.js`),n=[{name:`openai-proj`,sample:`sk-proj-abcdefghijklmnopqrstuvwxyz0123456789`},{name:`anthropic`,sample:`sk-ant-abcdefghijklmnopqrstuvwxyz0123456789`},{name:`openai-sk`,sample:`sk-abcdefghijklmnopqrstuvwxyz0123`},{name:`github-pat-new`,sample:`github_pat_`+`a`.repeat(82)},{name:`github-pat`,sample:`ghp_`+`a`.repeat(36)},{name:`github-oauth`,sample:`gho_`+`a`.repeat(36)},{name:`aws-access-key`,sample:`AKIAABCDEFGHIJKLMNOP`},{name:`stripe-live`,sample:`sk_live_`+`a`.repeat(28)},{name:`stripe-test`,sample:`pk_test_`+`a`.repeat(28)},{name:`stripe-restricted`,sample:`rk_live_`+`a`.repeat(28)},{name:`stripe-webhook`,sample:`whsec_`+`a`.repeat(28)},{name:`slack-bot`,sample:`xoxb-1234567890-abcdef`},{name:`google-api`,sample:`AIza`+`a`.repeat(35)},{name:`jwt`,sample:`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTYifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`},{name:`private-key-rsa`,sample:`-----BEGIN RSA PRIVATE KEY-----`},{name:`private-key-pkcs8`,sample:`-----BEGIN PRIVATE KEY-----`},{name:`supabase-jwt`,sample:`eyJhbGciOi`+`a`.repeat(40)},{name:`resend-api`,sample:`re_`+`a`.repeat(20)},{name:`gitlab-pat`,sample:`glpat-`+`a`.repeat(20)},{name:`shopify`,sample:`shpat_`+`a`.repeat(32)},{name:`service-role-key`,sample:`service_role: "`+`a`.repeat(40)+`"`}],r=n.map(e=>`${e.name}=${e.sample}`).join(`
|
|
3
3
|
`),i=t(r),a=n.filter(e=>i.includes(`[REDACTED:${e.name}]`)).length,o=e.length,s=Math.max(18,o-4);return a>=s?{ok:!0,detail:{matched:a,total:o}}:{ok:!1,reason:`${a}/${o} patterns redacted (need >= ${s})`}},quick:!0},{name:`help-line-count`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=e.split(`
|
|
4
|
-
`).length;return r<90?{ok:!0,detail:{lines:r}}:{ok:!1,reason:`${r} lines (target < 90)`}},dev:!0},{name:`help-no-wave-markers`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=/\b(?:Wave\s*\d|W\d|V2\.1)\b/i,i=e.match(r);return i?{ok:!1,reason:`found marker: ${i[0]}`}:{ok:!0}},dev:!0},{name:`help-has-groups`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=[`ANALYTICS`,`BEHAVIOR`,`MANAGE`,`ACCOUNT`,`OPERATIONS`],i=r.filter(t=>!e.includes(t));return i.length===0?{ok:!0,detail:{found:r}}:{ok:!1,reason:`missing groups: ${i.join(`, `)}`}},dev:!0},{name:`examples-coverage`,category:`DISCOVERABILITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{EXAMPLES:e}=await import(`./examples-
|
|
4
|
+
`).length;return r<90?{ok:!0,detail:{lines:r}}:{ok:!1,reason:`${r} lines (target < 90)`}},dev:!0},{name:`help-no-wave-markers`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=/\b(?:Wave\s*\d|W\d|V2\.1)\b/i,i=e.match(r);return i?{ok:!1,reason:`found marker: ${i[0]}`}:{ok:!0}},dev:!0},{name:`help-has-groups`,category:`DISCOVERABILITY`,command:[`--help`],assert:(e,t,n)=>{let r=[`ANALYTICS`,`BEHAVIOR`,`MANAGE`,`ACCOUNT`,`OPERATIONS`],i=r.filter(t=>!e.includes(t));return i.length===0?{ok:!0,detail:{found:r}}:{ok:!1,reason:`missing groups: ${i.join(`, `)}`}},dev:!0},{name:`examples-coverage`,category:`DISCOVERABILITY`,command:[],assert:()=>({ok:!1,reason:`should run in-process`}),inProcess:async()=>{let{EXAMPLES:e}=await import(`./examples-CFatZcPz.js`),t=Object.keys(e).length;return t>=25?{ok:!0,detail:{commands:t}}:{ok:!1,reason:`${t} commands have examples (need >= 25)`}},dev:!0},{name:`envelope-shape`,category:`DISCOVERABILITY`,command:[`commands`,`--json`],assert:(e,t,n)=>{if(n!==0)return{ok:!1,reason:`exit ${n}`};let r=d(e);if(!r.ok)return{ok:!1,reason:r.reason};let i=r.value,a=typeof i.version==`string`&&Array.isArray(i.commands);return a?{ok:!0,detail:{commands:i.commands.length}}:{ok:!1,reason:`commands payload missing version+commands`}},dev:!0}],g=h.length,_={accent:n.hex(e.accent),success:n.hex(e.success),error:n.hex(e.error),muted:n.hex(e.muted)};async function v(e){let t=(process.execPath||``).split(`/`).pop()||``,n=/^node(\.exe)?$/i.test(t),r=n?process.argv[1]??process.execPath:process.execPath,i=!!e.full||process.env.ZENOVAY_SELF_TEST_FULL===`1`,a=h.filter(e=>i||!e.dev);e.quick&&(a=a.filter(e=>e.quick));let o=await u(e.cliVersion);return e.json?y({...e,binPath:r,env:o,catalog:a}):S({...e,binPath:r,env:o,catalog:a})}async function y(e){let t=await l(e.catalog,{binPath:e.binPath,quick:e.quick??!1,verbose:e.verbose??!1,parallel:e.parallel,env:e.env,onResult:e=>{let t={type:`self-test.result`,name:e.name,category:e.category,status:e.status,durationMs:e.durationMs,...e.detail?{detail:e.detail}:{},...e.reason?{reason:e.reason}:{},...e.rawStdout?{rawStdout:e.rawStdout}:{},...e.rawStderr?{rawStderr:e.rawStderr}:{}};process.stdout.write(`${JSON.stringify(t)}\n`)}});return process.stdout.write(`${JSON.stringify({type:`self-test.summary`,total:t.total,pass:t.pass,fail:t.fail,skip:t.skip,durationMs:t.durationMs,cliVersion:e.cliVersion,env:e.env})}\n`),t.fail>0?1:0}const b=26,x=8;async function S(e){w(e.cliVersion,e.quick??!1,e.catalog.length);let t=new Map,n=0,r=null,i=new Map;for(let t of e.catalog)i.set(t.category,(i.get(t.category)??0)+1);let a=await l(e.catalog,{binPath:e.binPath,quick:e.quick??!1,verbose:e.verbose??!1,parallel:e.parallel,env:e.env,onResult:a=>{for(t.set(a.name,a);n<e.catalog.length;){let a=e.catalog[n];if(!a)break;let o=t.get(a.name);if(!o)break;r!==a.category&&(T(a.category,i.get(a.category)??0),r=a.category),E(a,o),t.delete(a.name),n+=1}}});return D(a),a.fail>0?1:0}function C(){return Math.max(60,process.stdout.columns??80)}function w(e,t,n){let r=Math.min(120,C()),i=r-2,a=`ZENOVAY · v${e}`,o=`self-test · ${t?`quick`:`full`} · ${n} test${n===1?``:`s`}`,s=`╭─ `+a+` `+`─`.repeat(Math.max(0,i-a.length-4))+`╮`,c=`│ `+o+` `.repeat(Math.max(0,i-o.length-2))+`│`,l=`╰`+`─`.repeat(i)+`╯`;process.stdout.write(_.accent(s)+`
|
|
5
5
|
`),process.stdout.write(_.accent(c)+`
|
|
6
6
|
`),process.stdout.write(_.accent(l)+`
|
|
7
7
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{requireTier as r}from"./tier-C4q8fJ8m.js";import"./formatter-DDG2TSOz.js";import{emit$1 as i,isHeadless as a}from"./emit-C9vAopcy.js";import{openInBrowser as o}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{Panel as s,useTheme as c}from"./panel-B-XxdP-N.js";import{Banner as l}from"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import{Keybar as u}from"./keybar-QgnmSion.js";import{resolveSiteId as d}from"./resolve-site-DQVcWhjG.js";import{DataTable as f}from"./data-table-DJzT7bAr.js";import{EmptyState as p}from"./empty-state-DbToIL5T.js";import{deepLinkFor as m}from"./keybar-deep-link-DbmPjAEz.js";import{Box as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useState as S}from"react";import C from"ink-spinner";function w(e){if(!e||e<=0)return`—`;let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return`${n}m ${(t%60).toString().padStart(2,`0`)}s`}function T(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.max(0,Math.floor((Date.now()-t)/1e3));return n<60?`${n}s`:n<3600?`${Math.floor(n/60)}m`:n<86400?`${Math.floor(n/3600)}h`:`${Math.floor(n/86400)}d`}async function E(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(l,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let u,f;try{({siteId:u,site:f}=await d(l,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??u;if(a(o)){let e=await l.getSessions(u);return i({type:`sessions.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=_(b.createElement(D,{api:l,siteId:u,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const D=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=v(),{theme:d}=c(),[_,E]=S(null),[D,O]=S(!0),[k,A]=S(null);if(y(e=>{if(e===`o`||e===`O`){o(m(`sessions`,{siteId:t}));return}e===`q`&&(a(),i(0))}),x(()=>{let n=!1;return(async()=>{try{let r=await e.getSessions(t);n||(E(r),O(!1))}catch(e){n||(A(e.message),O(!1))}})(),()=>{n=!0}},[e,t]),D)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`sessions · ${n}`}),b.createElement(s,{title:`Loading`,state:`busy`},b.createElement(h,null,b.createElement(g,{color:d.accent},b.createElement(C,{type:`dots`})),b.createElement(g,null,` Fetching sessions…`))));if(k)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`sessions · ${n}`}),b.createElement(p,{reason:`error`,headline:`Failed to load`,hint:k}));if(!_||_.length===0)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`sessions · ${n}`}),b.createElement(p,{reason:`no-data`,headline:`No replays yet`,hint:`Enable session replay in your site settings`}));let j=[{key:`id`,label:`session id`,width:24},{key:`visitor`,label:`visitor`,width:18},{key:`duration`,label:`duration`,align:`right`,width:9,format:e=>w(e)},{key:`startedAt`,label:`when`,align:`right`,width:6,format:e=>T(String(e))},{key:`pageCount`,label:`events`,align:`right`,width:7},{key:`deviceType`,label:`device`,width:8,format:e=>String(e??`—`)}];return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`sessions · ${n}`}),b.createElement(s,{title:`Recent sessions (${_.length})`},b.createElement(f,{columns:j,data:_,zebra:!0})),b.createElement(h,{marginTop:1},b.createElement(g,{color:d.muted},`Open any session for replay at https://app.zenovay.com/replay`)),b.createElement(u,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{E as sessionsCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";function r(e){try{return JSON.parse(e)}catch{return e}}async function i(i){let a=await e(),o=await t({strict:!1}),s=new n({config:a,cliVersion:i.cliVersion,token:o});try{switch(i.action){case`get`:{let{settings:e}=await s.getSettings();if(i.key){let t=e[i.key];return t===void 0?(process.stderr.write(`Unknown setting: ${i.key}\n`),2):(i.json?process.stdout.write(JSON.stringify({[i.key]:t},null,2)+`
|
|
2
2
|
`):process.stdout.write(`${i.key} = ${t===null?`—`:JSON.stringify(t)}\n`),0)}if(i.json)return process.stdout.write(JSON.stringify({settings:e},null,2)+`
|
|
3
3
|
`),0;for(let[t,n]of Object.entries(e))process.stdout.write(`${t.padEnd(28)} ${n===null?`—`:JSON.stringify(n)}\n`);return 0}case`set`:{if(!i.key||i.value===void 0)return process.stderr.write("Error: usage `zenovay settings set <key> <value>`.\n"),2;let e=r(i.value),t=await s.setSetting(i.key,e);return i.json?(process.stdout.write(JSON.stringify(t,null,2)+`
|
|
4
4
|
`),0):(process.stdout.write(`✔ Set ${i.key} → ${JSON.stringify(e)}\n`),0)}}}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}}export{i as settingsCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{confirmDestructive as r}from"./confirm-CIdxMt7N.js";import"./theme-BuGrQHax.js";import"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import{resolveSiteId as i}from"./resolve-site-DQVcWhjG.js";async function a(a){let o=await e(),s=await t({strict:!1}),c=new n({config:o,cliVersion:a.cliVersion,token:s}),l;try{({siteId:l}=await i(c,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}try{switch(a.action){case`enable`:{let e=await c.enableShare(l);if(a.json)return process.stdout.write(JSON.stringify(e,null,2)+`
|
|
2
2
|
`),0;let t=`═`.repeat(72);return process.stdout.write(`\n${t}\n Public dashboard sharing enabled\n url: ${e.url}\n${t}\n\n Anyone with this link can view your dashboard. Disable with\n \`zenovay share disable\` to invalidate the link immediately.\n\n`),0}case`disable`:{let e=await r({resource:`public share link`,name:l.length>12?`${l.slice(0,8)}…${l.slice(-4)}`:l,yes:a.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
|
|
3
3
|
`),1;let t=await c.disableShare(l);return a.json?(process.stdout.write(JSON.stringify(t)+`
|
|
4
4
|
`),0):(process.stdout.write(`✔ Public sharing disabled. The previous link is no longer valid.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./client-Dm8uGVCy.js";import{openInBrowser as a}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{useTheme as o}from"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import"./chat-panel-ZlKZ0W6J.js";import{resolveSiteId as s}from"./resolve-site-DQVcWhjG.js";import{DataTable as c}from"./data-table-DJzT7bAr.js";import{deepLinkFor as l}from"./keybar-deep-link-DbmPjAEz.js";import{runAnalyticalScreen as u}from"./analytical-screen-B_wWUnT4.js";import{Box as d,Text as f}from"ink";import p from"react";function m(e,t){let n=Math.round(e/100*t);return`█`.repeat(n)+`░`.repeat(Math.max(0,t-n))}function h(e){return e==null?{glyph:`·`,tone:`neutral`}:e>.5?{glyph:`▲`,tone:`up`}:e<-.5?{glyph:`▼`,tone:`down`}:{glyph:`→`,tone:`neutral`}}function g({data:e}){let{theme:t}=o();return p.createElement(f,null,p.createElement(f,{bold:!0},e.totalVisitors.toLocaleString()),` `,p.createElement(f,{color:t.muted},`visitors · `,e.sources.length,` sources`))}function _({data:e}){let{theme:t}=o();if(e.sources.length===0)return p.createElement(f,{color:t.muted},`— no source data —`);let n={up:t.success,down:t.accent2,neutral:t.muted},r=e.totalVisitors||1,i=[...e.sources].sort((e,t)=>t.visitors-e.visitors).slice(0,12);return p.createElement(d,{flexDirection:`column`},i.map((e,i)=>{let a=e.visitors/r*100,o=h(e.delta);return p.createElement(d,{key:`${e.source}-${i}`},p.createElement(f,null,p.createElement(f,{color:t.accent},e.source.padEnd(20).slice(0,20)),` `,p.createElement(f,{color:t.accent},m(a,30)),` `,p.createElement(f,null,e.visitors.toString().padStart(6),` `),p.createElement(f,{color:t.muted},`(`,a.toFixed(1),`%)`),` `,p.createElement(f,{color:n[o.tone]},o.glyph)))}))}function v({data:e,columns:t}){let{theme:n}=o();return e.sources.length===0?p.createElement(f,{color:n.muted},`— —`):p.createElement(c,{data:e.sources.slice(0,20),columns:t,headerStyle:`accent`})}async function y(o){let c=await e(),d=await t({strict:!1}),f=new n({config:c,cliVersion:o.cliVersion,token:d}),m,h;try{({siteId:m,site:h}=await s(f,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(o),b=o.period??`30d`,x=[{key:`source`,label:`source`,width:22},{key:`channel`,label:`channel`,width:10,format:e=>String(e??`—`)},{key:`visitors`,label:`visitors`,width:8,align:`right`},{key:`delta`,label:`Δ`,width:6,align:`right`,format:e=>typeof e==`number`?`${e>0?`+`:``}${(e*100).toFixed(1)}%`:`—`}];return u({cliVersion:o.cliVersion,title:`sources · ${m} · ${b}`,commandName:`sources`,authToken:d?.accessToken??null,refreshIntervalMs:6e4,fetcher:e=>f.getSources(m,b,o.compare,e),format:y,ai:{api:f,siteId:m,siteLabel:h?.url?h.url.replace(/^https?:\/\//,``).replace(/\/$/,``):h?.name??m},keybindings:{o:{label:`open in browser`,handler:()=>{a(l(`sources`,{siteId:m}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
|
|
2
2
|
`);return}process.stdout.write(r(e.sources,[`source`,`channel`,`visitors`,`conversions`,`revenue`,`delta`],t))},panels:[{id:`summary`,title:`Total`,render:e=>p.createElement(g,{data:e})},{id:`channels`,title:`By channel`,render:e=>p.createElement(_,{data:e})},{id:`table`,title:`Detail`,render:e=>p.createElement(v,{data:e,columns:x})}]})}export{y as sourcesCommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./client-Dm8uGVCy.js";import"./theme-BuGrQHax.js";import{useTheme as a}from"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import"./chat-panel-ZlKZ0W6J.js";import{resolveSiteId as o}from"./resolve-site-DQVcWhjG.js";import{DataTable as s}from"./data-table-DJzT7bAr.js";import{runAnalyticalScreen as c}from"./analytical-screen-B_wWUnT4.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e){return`${(e*100).toFixed(1)}%`}function p(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.floor(e/60)}m ${Math.round(e%60)}s`:`${Math.floor(e/3600)}h ${Math.floor(e%3600/60)}m`}const m=({data:e})=>{let{theme:t}=a();return d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},e.visitors.toLocaleString()),d.createElement(u,{color:t.muted},` visitors `),d.createElement(u,{bold:!0},e.pageviews.toLocaleString()),d.createElement(u,{color:t.muted},` pageviews `),d.createElement(u,{bold:!0},e.sessions.toLocaleString()),d.createElement(u,{color:t.muted},` sessions`)),d.createElement(u,{color:t.muted},`bounce `,f(e.bounceRate),` · avg session `,p(e.avgSessionSec)))},h=({label:e})=>{let{theme:t}=a();return d.createElement(u,{color:t.dim},e)};async function g(a){let l=await e(),u=await t({strict:!1}),g=new n({config:l,cliVersion:a.cliVersion,token:u}),_,v;try{({siteId:_,site:v}=await o(g,{explicit:a.siteId,headless:!!(a.json||a.csv||a.tsv||a.ndjson),cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(a),b=a.range??`24h`,x=[{key:`url`,label:`page`,width:40,format:e=>String(e??`—`)},{key:`views`,label:`views`,width:8,align:`right`}],S=[{key:`country`,label:`country`,width:8},{key:`visitors`,label:`visitors`,width:8,align:`right`}];return c({cliVersion:a.cliVersion,title:`stats · ${_} · ${b}`,commandName:`stats`,ai:{api:g,siteId:_,siteLabel:v?.url?v.url.replace(/^https?:\/\//,``).replace(/\/$/,``):v?.name??_},authToken:u?.accessToken??null,refreshIntervalMs:a.watch?6e4:0,fetcher:e=>g.getStats(_,b,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
|
|
2
2
|
`);return}process.stdout.write(r([{range:b,visitors:e.visitors,pageviews:e.pageviews,sessions:e.sessions,bounceRate:f(e.bounceRate),avgSession:p(e.avgSessionSec)}],[`range`,`visitors`,`pageviews`,`sessions`,`bounceRate`,`avgSession`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>d.createElement(m,{data:e})},{id:`pages`,title:`Top pages`,render:e=>e.topPages.length===0?d.createElement(h,{label:`— no pages —`}):d.createElement(s,{data:e.topPages.slice(0,10),columns:x,headerStyle:`accent`})},{id:`countries`,title:`Top countries`,render:e=>e.topCountries.length===0?d.createElement(h,{label:`— no country data —`}):d.createElement(s,{data:e.topCountries.slice(0,10),columns:S,headerStyle:`accent`})}]})}export{g as statsCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{configPath as e,readConfig as t,writeConfig as n}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as r}from"./token-store-BQuGH0z2.js";import{emit as i}from"./telemetry-DRh10SvO.js";import{ApiV2Client as a}from"./api-v2-
|
|
1
|
+
import{configPath as e,readConfig as t,writeConfig as n}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as r}from"./token-store-BQuGH0z2.js";import{emit as i}from"./telemetry-DRh10SvO.js";import{ApiV2Client as a}from"./api-v2-CPUUcP1i.js";import{spawn as o}from"node:child_process";import s from"node:path";import{existsSync as c,mkdirSync as l,readFileSync as u,renameSync as d,unlinkSync as f,writeFileSync as p}from"node:fs";import{homedir as m}from"node:os";const h=6e4;function g(){return s.join(m(),`.zenovay`)}function _(){return s.join(g(),`status-agent.pid`)}function v(){return s.join(g(),`tmux-status`)}function y(){l(g(),{recursive:!0,mode:448})}function b(e){let t=_(),n=`${t}.tmp.${process.pid}`;p(n,String(e),{mode:384}),d(n,t)}function x(e){try{return process.kill(e,0),!0}catch{return!1}}function S(e){if(!e)return[];let t=[];for(let n of e.split(`,`).map(e=>e.trim()).filter(Boolean)){let e=n.match(/^([a-z_]+)\s*(>|<)\s*(-?\d+(?:\.\d+)?)$/i);if(!e)continue;t.push({key:(e[1]??``).toLowerCase(),op:e[2]??`>`,value:Number(e[3]??0)})}return t}function C(e,t,n,r=!1){let i=(t/1e5).toFixed(1),a=[`#[fg=colour141]● ${e} live`,`#[fg=colour114]▲ MRR $${i}k`,`#[fg=colour203]✗ ${n.toFixed(0)} err/s`].join(` `);return r?`#[reverse]${a}#[noreverse]`:a}const w=3e4,T=5*60*1e3,E=new Map;function D(e,t){let n=Math.floor(t/10),r=`${e}:${n}`,i=Date.now(),a=E.get(r);return a&&i-a<T?!1:(E.set(r,i),!0)}async function O(e,t){let n=process.platform;try{if(n===`darwin`){await new Promise((n,r)=>{let i=o(`terminal-notifier`,[`-title`,e,`-message`,t,`-group`,`zenovay`],{stdio:`ignore`});i.on(`error`,r),i.on(`exit`,()=>n())});return}if(n===`linux`){await new Promise((n,r)=>{let i=o(`notify-send`,[e,t],{stdio:`ignore`});i.on(`error`,r),i.on(`exit`,()=>n())});return}}catch{}process.stdout.write(`\x1b]9;${e} — ${t}\x07`)}function k(e,t){let n=[];for(let r of e){let e=t[r.key];if(typeof e!=`number`)continue;r.op===`>`&&e>r.value&&n.push({rule:r,actual:e}),r.op===`<`&&e<r.value&&n.push({rule:r,actual:e})}return n}async function A(e){let n=await t(),o=await r({strict:!1});if(!o)return process.stderr.write(`status-agent: not logged in
|
|
2
2
|
`),2;let s=new a({config:n,cliVersion:e.cliVersion,token:o}),c=e.siteId??n.defaultSiteId??``;if(!c)return process.stderr.write("status-agent: no site selected — pass --site-id or run `zenovay use <site>`\n"),2;y();let l=n.statusAgent?.notifyOn,u=n.statusAgent?.refreshIntervalMs,d=S(e.notifyOn??l),m=e.intervalMs??u??h,g=Date.now(),b=0;i(`status_agent.start`,{properties:{rule_count:d.length,interval_ms:m}});let x=null,T=!1,E=0,A=null,j=()=>{T=!0,A&&A()};for(process.on(`SIGTERM`,j),process.on(`SIGINT`,j);!T;){try{let[e,t,n]=await Promise.all([s.getLive(c).catch(()=>({activeVisitors:0,recentEvents:[]})),s.getErrors(c,{window:`24h`}).catch(()=>({errors:[],total:0})),s.getRevenue(c,`24h`).catch(()=>null)]),r=e.activeVisitors,a=n?.mrr??n?.totalAmount??0,o=t.total/86400,l=x&&x>0?(x-a)/x*100:0,u=k(d,{error_rate:o,revenue_drop:l}),f=!1;for(let e of u){if(!D(e.rule.key,e.actual))continue;f=!0,i(`status_agent.alert_fired`,{properties:{rule_key:e.rule.key,op:e.rule.op}}),await O(`Zenovay alert`,`${e.rule.key} ${e.rule.op} ${e.rule.value} (got ${e.actual.toFixed(2)})`)}f&&(E=Date.now());let m=E>0&&Date.now()-E<w;p(v(),C(r,a,o,m),{mode:420}),b+=1,b%10==0&&i(`status_agent.tick`,{properties:{tick:b,has_revenue:a>0,has_visitors:r>0,had_errors:o>0}}),x=a}catch(e){process.stderr.write(`status-agent tick failed: ${e.message}\n`)}await new Promise(e=>{let t=setTimeout(e,m);A=()=>{clearTimeout(t),e()}}),A=null}i(`status_agent.stop`,{duration_ms:Date.now()-g,properties:{ticks:b}});try{f(_())}catch{}return 0}function j(){return[`# Add to ~/.tmux.conf:`,`set -g status-right "#(cat ~/.zenovay/tmux-status) %H:%M"`,``,`# Then reload:`,`# $ tmux source ~/.tmux.conf`].join(`
|
|
3
3
|
`)}function M(){let e=process.argv[0]??`zenovay`;return[`[Unit]`,`Description=Zenovay status agent`,`After=network.target`,``,`[Service]`,`Type=simple`,`ExecStart=${e} status-agent --child`,`Restart=on-failure`,`RestartSec=10`,``,`[Install]`,`WantedBy=default.target`,``,`# Save as ~/.config/systemd/user/zenovay-status.service`,`# systemctl --user enable --now zenovay-status`].join(`
|
|
4
4
|
`)}function N(){let e=process.argv[0]??`zenovay`;return[`<?xml version="1.0" encoding="UTF-8"?>`,`<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">`,`<plist version="1.0">`,`<dict>`,` <key>Label</key><string>com.zenovay.status-agent</string>`,` <key>ProgramArguments</key>`,` <array>`,` <string>${e}</string>`,` <string>status-agent</string>`,` <string>--child</string>`,` </array>`,` <key>RunAtLoad</key><true/>`,` <key>KeepAlive</key><true/>`,`</dict>`,`</plist>`,``,`<!-- Save as ~/Library/LaunchAgents/com.zenovay.status-agent.plist -->`,`<!-- launchctl load ~/Library/LaunchAgents/com.zenovay.status-agent.plist -->`].join(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{requireTier as r}from"./tier-C4q8fJ8m.js";import{confirmDestructive as i}from"./confirm-CIdxMt7N.js";import{fmtDate as a,formatTable as o,shortId as s}from"./fmt-xxIPQJX-.js";async function c(c){let l=await e(),u=await t({strict:!1}),d=new n({config:l,cliVersion:c.cliVersion,token:u});try{await r(d,`pro`)}catch(e){return process.stderr.write(`✗ ${e.message}\n`),2}try{switch(c.action){case`list`:{let e=await d.listTeam();if(c.json)return process.stdout.write(JSON.stringify(e,null,2)+`
|
|
2
2
|
`),0;let t=[{key:`userId`,header:`user id`,width:14,format:e=>s(String(e))},{key:`email`,header:`email`,width:32,format:e=>String(e??`—`)},{key:`role`,header:`role`,width:8},{key:`joinedAt`,header:`joined`,width:10,format:e=>a(e)}],n=[{key:`id`,header:`invite id`,width:14,format:e=>s(String(e))},{key:`email`,header:`email`,width:32},{key:`role`,header:`role`,width:8},{key:`expiresAt`,header:`expires`,width:10,format:e=>a(e)}];return process.stdout.write(`\nMEMBERS (${e.members.length})\n`),e.members.length===0?process.stdout.write(` — none —
|
|
3
3
|
`):process.stdout.write(o({rows:e.members,cols:t})),process.stdout.write(`\nPENDING INVITES (${e.invites.length})\n`),e.invites.length===0?process.stdout.write(` — none —
|
|
4
4
|
`):process.stdout.write(o({rows:e.invites,cols:n})),process.stdout.write(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as n}from"./token-store-BQuGH0z2.js";import{ApiV2Client as r}from"./api-v2-
|
|
1
|
+
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as n}from"./token-store-BQuGH0z2.js";import{ApiV2Client as r}from"./api-v2-CPUUcP1i.js";function i(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}async function a(a){let o=await e(),s=await n({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new r({config:o,cliVersion:a.cliVersion,token:s});try{switch(a.action){case`reset`:{let e=await t({currentTeamId:void 0,currentTeamName:void 0});return a.json?(process.stdout.write(JSON.stringify({reset:!0,currentTeamId:e.currentTeamId??null})+`
|
|
2
2
|
`),0):(process.stdout.write(`✔ Team override cleared. Future commands use the API key's default team.
|
|
3
3
|
`),0)}case`current`:{let e=await c.me(),t=e.teams?.find(e=>e.isCurrent)??(e.team?{id:e.team.id,name:e.team.name,plan:e.team.plan,role:`?`,siteCount:0,isCurrent:!0}:null);return a.json?(process.stdout.write(JSON.stringify({current:t,override:o.currentTeamId??null},null,2)+`
|
|
4
4
|
`),0):t?(process.stdout.write(`\n current team: ${t.name} (${i(t.id)})\n plan: ${t.plan}\n override? ${o.currentTeamId?"yes — set via `teams switch`":`no — using API key default`}\n\n`),0):(process.stdout.write(`No team currently bound.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./theme-
|
|
1
|
+
import{dracula as e,latte as t,mocha as n,nord as r,tokyoNight as i}from"./theme-BuGrQHax.js";import{useTheme as a}from"./panel-B-XxdP-N.js";import{Banner as o}from"./banner-DdgwXGzt.js";import"./progress-row-5ns2IsFh.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import"./sparkline-CpoBjjlc.js";import"./data-table-DJzT7bAr.js";import"./bar-C1Zrfe9H.js";import"./ui-whccLLRv.js";import{promises as s}from"node:fs";import{Box as c,Text as l,render as u}from"ink";import d from"react";const f=[{name:`mocha`,theme:n,mode:`dark`},{name:`latte`,theme:t,mode:`light`},{name:`dracula`,theme:e,mode:`dark`},{name:`tokyoNight`,theme:i,mode:`dark`},{name:`nord`,theme:r,mode:`dark`}],p=[`name`,`bg`,`fg`,`muted`,`accent`,`accent2`,`success`,`warn`,`error`,`border`,`dim`];function m({name:e,theme:t,mode:n}){let{theme:r}=a(),i=[t.accent,t.accent2,t.success,t.warn,t.error];return d.createElement(c,{flexDirection:`row`},d.createElement(l,{bold:!0},e.padEnd(14)),d.createElement(l,{color:r.muted},n.padEnd(7)),i.map((e,t)=>d.createElement(l,{key:t,color:e},`████`,` `)),d.createElement(l,{color:r.muted},t.bg))}function h({themes:e}){let{theme:t}=a();return d.createElement(c,{flexDirection:`column`},d.createElement(o,{version:`themes`}),d.createElement(c,{marginTop:1,marginBottom:1},d.createElement(l,{color:t.muted},e.length,` themes — pass --theme <name> to any command, or set in your config.`)),d.createElement(c,{flexDirection:`column`},d.createElement(c,null,d.createElement(l,{bold:!0},`name`.padEnd(14)),d.createElement(l,{bold:!0},`mode`.padEnd(7)),d.createElement(l,{bold:!0},`swatch`.padEnd(28)),d.createElement(l,{bold:!0},`bg`)),e.map(({name:e,theme:t,mode:n})=>d.createElement(m,{key:e,name:e,theme:t,mode:n}))))}async function g(e){if(e.validate){let t;try{let n=await s.readFile(e.validate,`utf8`);t=JSON.parse(n)}catch(t){return process.stderr.write(`✗ Failed to read ${e.validate}: ${t.message}\n`),1}let n=p.filter(e=>t[e]==null);return n.length>0?(process.stderr.write(`✗ Missing required tokens: ${n.join(`, `)}\n`),e.json&&process.stdout.write(JSON.stringify({ok:!1,missing:n},null,2)+`
|
|
2
2
|
`),1):(process.stdout.write(`✔ Valid theme (${p.length} tokens present).\n`),e.json&&process.stdout.write(JSON.stringify({ok:!0,theme:t},null,2)+`
|
|
3
3
|
`),0)}if(e.json)return process.stdout.write(JSON.stringify({themes:f.map(({name:e,theme:t,mode:n})=>({name:e,mode:n,background:t.bg,foreground:t.fg,accent:t.accent}))},null,2)+`
|
|
4
4
|
`),0;let{waitUntilExit:t}=u(d.createElement(h,{themes:f}));return await t(),0}export{g as themesCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import"./theme-
|
|
1
|
+
import"./theme-BuGrQHax.js";import{Panel as e,useTheme as t}from"./panel-B-XxdP-N.js";import{Banner as n}from"./banner-DdgwXGzt.js";import{spawn as r}from"node:child_process";import{Box as i,Text as a,render as o,useApp as s,useInput as c}from"ink";import l,{useEffect as u,useState as d}from"react";import f from"ink-spinner";const p=[{title:`Identify`,explainer:"Who you are and which team you’re acting on. CLI uses your saved bearer token from `zenovay login`.",command:`profile show`},{title:`Tracked sites`,explainer:`The websites your account can read.`,command:`domains list`},{title:`Today's analytics`,explainer:`What visitors did on your sites in the last 24 hours.`,command:`analytics`},{title:`Traffic sources`,explainer:`Where visitors come from — direct, organic, referrals.`,command:`sources --period 7d`},{title:`Recent sessions`,explainer:`Replay-style listing of recorded sessions (Pro+).`,command:`sessions`,tierGated:!0},{title:`Alert configs`,explainer:`Threshold-based alerts you’ve set up.`,command:`alerts list`,tierGated:!0},{title:`Export today`,explainer:`Bulk-export analytics data to CSV.`,command:`export analytics --range 7d --format csv`,csvPreview:!0},{title:`Self-test`,explainer:`One-command verification that everything works.`,command:`self-test --quick`,maxLines:24}],m=p.length;async function h(e){let t=process.argv[1]??process.execPath;return e.nonInteractive?g(t,e.cliVersion):new Promise(n=>{let{unmount:r}=o(l.createElement(y,{cliVersion:e.cliVersion,binPath:t,onDone:e=>{r(),n(e)}}))})}async function g(e,t){process.stdout.write(`Zenovay CLI v${t} — tour (non-interactive)\n`),process.stdout.write(`────────────────────────────────────────────────────
|
|
2
2
|
|
|
3
3
|
`);for(let t=0;t<p.length;t++){let n=p[t];process.stdout.write(`[${t+1}/${m}] ${n.title}\n`),process.stdout.write(` ${n.explainer}\n`),process.stdout.write(` $ zenovay ${n.command}\n\n`);let r=await v(e,n);if(r.tierSkipped){process.stdout.write(` → Skipping (requires Pro plan)
|
|
4
4
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import{classifyBump as t,fetchManifest as n}from"./check-D9G0N7NB.js";import{applyUpdate as r}from"./apply-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import{classifyBump as t,fetchManifest as n}from"./check-D9G0N7NB.js";import{applyUpdate as r}from"./apply-B19bFTz0.js";import"./formatter-DDG2TSOz.js";import{emit$1 as i,isHeadless as a}from"./emit-C9vAopcy.js";async function o(o){let s=await e(),c=await n({cliBase:s.cliBase}),l=t(o.cliVersion,c.latest);if(o.check)return a({json:o.json})?i({type:`info`,message:`latest=${c.latest} current=${o.cliVersion} bump=${l}`}):process.stdout.write(`Current: ${o.cliVersion}\nLatest: ${c.latest}\nBump: ${l}\n`),{updated:!1,from:o.cliVersion,to:c.latest};if(l===`none`)return a({json:o.json})||process.stdout.write(`Already on latest (${o.cliVersion}).\n`),{updated:!1,from:o.cliVersion,to:c.latest};if(l===`downgrade`&&!o.forceDowngrade)throw Error(`Refused to downgrade ${o.cliVersion} → ${c.latest}. Pass --force-downgrade if you really want this.`);let u=await r({currentVersion:o.cliVersion,cliBase:s.cliBase,binaryPath:o.binaryPath,forceDowngrade:o.forceDowngrade});return a({json:o.json})?u.updated&&i({type:`update.applied`,from:u.from,to:u.to}):u.updated?process.stdout.write(`Updated ${u.from} → ${u.to}\n`):process.stdout.write(`Not updated (${u.reason??`unknown`}).\n`),u}export{o as updateCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{requireTier as r}from"./tier-C4q8fJ8m.js";import"./formatter-DDG2TSOz.js";import{emit$1 as i,isHeadless as a}from"./emit-C9vAopcy.js";import{openInBrowser as o}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{Panel as s,useTheme as c}from"./panel-B-XxdP-N.js";import{Banner as l}from"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import{Keybar as u}from"./keybar-QgnmSion.js";import{resolveSiteId as d}from"./resolve-site-DQVcWhjG.js";import{DataTable as f}from"./data-table-DJzT7bAr.js";import{EmptyState as p}from"./empty-state-DbToIL5T.js";import{deepLinkFor as m}from"./keybar-deep-link-DbmPjAEz.js";import{Box as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useState as S}from"react";import C from"ink-spinner";function w(e){return e===`up`?{glyph:`● up`,color:`green`}:e===`down`?{glyph:`● down`,color:`red`}:{glyph:`○ unknown`,color:`gray`}}function T(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.round((t-Date.now())/(1e3*60*60*24));return`${n}d`}async function E(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(l,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let u,f;try{({siteId:u,site:f}=await d(l,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??u;if(a(o)){let e=await l.getUptime(u);return i({type:`uptime.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=_(b.createElement(D,{api:l,siteId:u,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const D=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=v(),{theme:d}=c(),[_,E]=S(null),[D,O]=S(!0),[k,A]=S(null);if(y(e=>{if(e===`o`||e===`O`){o(m(`uptime`,{siteId:t}));return}e===`q`&&(a(),i(0))}),x(()=>{let n=!1;return(async()=>{try{let r=await e.getUptime(t);n||(E(r.monitors),O(!1))}catch(e){n||(A(e.message),O(!1))}})(),()=>{n=!0}},[e,t]),D)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(s,{title:`Loading`,state:`busy`},b.createElement(h,null,b.createElement(g,{color:d.accent},b.createElement(C,{type:`dots`})),b.createElement(g,null,` Fetching monitors…`))));if(k)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(p,{reason:`error`,headline:`Failed to load`,hint:k}));if(!_||_.length===0)return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(p,{reason:`no-data`,headline:`No monitors configured`,hint:`Add one at app.zenovay.com/uptime`}));let j=[{key:`url`,label:`monitor`,width:36},{key:`status`,label:`status`,width:12,format:e=>w(String(e)).glyph},{key:`p95ms`,label:`p95 ms`,align:`right`,width:8,format:e=>typeof e==`number`?String(e):`—`},{key:`sslExpiry`,label:`ssl exp`,align:`right`,width:7,format:e=>T(e)}];return b.createElement(h,{flexDirection:`column`},b.createElement(l,{version:r,subtitle:`uptime · ${n}`}),b.createElement(s,{title:`Monitors (${_.length})`},b.createElement(f,{columns:j,data:_,zebra:!0})),b.createElement(u,{items:[{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))};export{E as uptimeCommand};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{fmtDate as r,fmtNumber as i}from"./fmt-xxIPQJX-.js";const a=1e8,o=e=>e<=0||e>=a;function s(e,t,n=24){if(o(t))return`─`.repeat(n);let r=Math.min(1,e/t),i=Math.round(r*n);return`█`.repeat(i)+`░`.repeat(Math.max(0,n-i))}function c(e,t){if(o(t))return`—`;let n=e/t*100;return`${n.toFixed(0)}%`}function l(e,t){if(o(t))return``;let n=e/t;return n>=1?`⚠ over limit`:n>=.8?`⚠ near limit`:``}function u(e,t){return o(e)?`∞`:t(e)}async function d(a){let o=await e(),d=await t({strict:!1});if(!d)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let f=new n({config:o,cliVersion:a.cliVersion,token:d}),p;try{p=await f.getUsage()}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}if(a.json)return process.stdout.write(JSON.stringify(p,null,2)+`
|
|
2
2
|
`),0;let m=[{label:`events this month`,used:p.events.thisMonth,limit:p.events.monthlyLimit,format:i},{label:`events today`,used:p.events.today,limit:p.events.dailyLimit,format:i},{label:`websites`,used:p.websites.used,limit:p.websites.limit},{label:`team members`,used:p.teamMembers.used,limit:p.teamMembers.limit}],h=18,g=8,_=9,v=[];v.push(``),v.push(` plan: ${p.plan}`),v.push(``);for(let e of m){let t=e.format??i,n=t(e.used).padStart(g),r=u(e.limit,t).padStart(_),a=s(e.used,e.limit),o=c(e.used,e.limit).padStart(5),d=l(e.used,e.limit);v.push(` ${e.label.padEnd(h)} ${n} / ${r} ${a} ${o} ${d}`.trimEnd())}return v.push(` ${`api keys`.padEnd(h)} ${i(p.apiKeys.used).padStart(g)} / ${`—`.padStart(_)} ${`─`.repeat(24)} ${`—`.padStart(5)}`),v.push(``),v.push(` data retention: ${p.dataRetentionDays} days`),v.push(` last event: ${r(p.events.lastEventAt,`datetime`)}`),v.push(``),process.stdout.write(v.join(`
|
|
3
3
|
`)),0}export{d as usageCommand};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import{ApiClient as n}from"./api-FCanTxsb.js";import{readToken as r}from"./token-store-BQuGH0z2.js";import"./formatter-
|
|
1
|
+
import{readConfig as e,updateConfig as t}from"./config--JRu_jFq.js";import{ApiClient as n}from"./api-FCanTxsb.js";import{readToken as r}from"./token-store-BQuGH0z2.js";import"./formatter-DDG2TSOz.js";import{emitEnvelope as i,wrapSnapshot as a}from"./emit-C9vAopcy.js";async function o(o){if(o.reset)return await t({defaultSiteId:void 0,defaultSiteName:void 0}),o.json?(i(a({reset:!0,defaultSiteId:null},`use.reset`)),0):(process.stdout.write(`Default site cleared.
|
|
2
2
|
`),0);if(!o.match||!o.match.trim()){let t=await e();if(t.defaultSiteId){let e={siteId:t.defaultSiteId,name:t.defaultSiteName??null,domain:t.defaultSiteName??null};return o.json?(i(a(e,`use.current`,{siteId:t.defaultSiteId})),0):(process.stdout.write(`Default site: ${e.name??e.siteId} (${t.defaultSiteId})\n`),0)}return o.json?(i(a(null,`use.current`,{})),0):(process.stdout.write("No default site set. Run `zenovay use <domain>` to set one.\n"),0)}let c=await e(),l=await r({strict:!1});if(!l&&!process.env.ZENOVAY_API_TOKEN)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:c,cliVersion:o.cliVersion,token:l}),d=o.match.trim().toLowerCase(),f=await u.getSites(),p=f.find(e=>e.id===o.match||e.trackingCode===o.match||e.url===o.match),m=p??f.find(e=>s(e.url).includes(d)||e.name.toLowerCase().includes(d));return m?(await t({defaultSiteId:m.id,defaultSiteName:m.name}),o.json?(i(a({siteId:m.id,name:m.name,domain:s(m.url)},`use.set`,{siteId:m.id})),0):(process.stdout.write(`Default site → ${m.name} (${m.url})\n`),0)):(process.stderr.write(`No site matched "${o.match}". Your sites:\n${f.map(e=>` ${e.name} — ${e.url} — ${e.id}`).join(`
|
|
3
3
|
`)}\n`),2)}function s(e){return e.toLowerCase().replace(/^https?:\/\//,``).replace(/\/.*$/,``)}export{o as useCommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./client-Dm8uGVCy.js";import{openInBrowser as a}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{useTheme as o}from"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import{brailleSpark as s,spark as c}from"./sparkline-CpoBjjlc.js";import"./chat-panel-ZlKZ0W6J.js";import{resolveSiteId as l}from"./resolve-site-DQVcWhjG.js";import{DataTable as u}from"./data-table-DJzT7bAr.js";import{deepLinkFor as d}from"./keybar-deep-link-DbmPjAEz.js";import{runAnalyticalScreen as f}from"./analytical-screen-B_wWUnT4.js";import{Box as p,Text as m}from"ink";import h from"react";function g(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function _(e){let t=e,n=t.events??t.timeseries;return Array.isArray(n)&&n.length>0?c(n,8):`▁▁▁▁▁▁▁▁`}function v(e){let t=e;if(typeof t.sessionDurationSec==`number`)return t.sessionDurationSec;if(typeof t.sessionDurationMs==`number`)return Math.floor(t.sessionDurationMs/1e3);if(typeof t.durationMs==`number`)return Math.floor(t.durationMs/1e3);if(typeof t.duration==`number`)return Math.floor(t.duration/1e3);let n=Date.parse(e.startedAt);return Number.isNaN(n)?0:Math.max(0,Math.floor((Date.now()-n)/1e3))}async function y(o){let s=await e(),c=await t({strict:!1}),u=new n({config:s,cliVersion:o.cliVersion,token:c}),p,m;try{({siteId:p,site:m}=await l(u,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(o),S=o.limit??50,C=typeof o.minDuration==`number`&&o.minDuration>0?o.minDuration:0,w=e=>C<=0?e:e.filter(e=>v(e)>=C),T=6e4,E=e=>{let t=Date.parse(e.startedAt);return Number.isFinite(t)&&Date.now()-t<T},D=[{key:`startedAt`,label:``,width:5,format:(e,t)=>E(t)?`● new`:``},{key:`startedAt`,label:`when`,width:6,format:e=>g(String(e))},{key:`country`,label:`country`,width:7,format:e=>String(e??`—`)},{key:`city`,label:`city`,width:14,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`page`,label:`page`,width:26,format:e=>String(e??`—`)},{key:`id`,label:`24h`,width:8,format:(e,t)=>_(t)}];return f({cliVersion:o.cliVersion,title:`visitors · ${p}`,commandName:`visitors`,ai:{api:u,siteId:p,siteLabel:m?.url?m.url.replace(/^https?:\/\//,``).replace(/\/$/,``):m?.name??p},authToken:c?.accessToken??null,refreshIntervalMs:1e4,fetcher:e=>u.getVisitors(p,{limit:S},e),format:y,keybindings:{o:{label:`open in browser`,handler:()=>{a(d(`visitors`,{siteId:p}))}}},headlessEmit:(e,t)=>{let n={...e,visitors:w(e.visitors)};if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(n,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
|
|
2
2
|
`);return}let i=[`startedAt`,`country`,`city`,`device`,`page`];process.stdout.write(r(n.visitors,i,t))},panels:[{id:`live`,title:`Now`,render:e=>h.createElement(b,{visitors:w(e.visitors)})},{id:`visitors`,title:`Active sessions`,render:e=>h.createElement(x,{visitors:w(e.visitors),limit:S,columns:D})}]})}const b=({visitors:e})=>{let{theme:t}=o(),n=[...e].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)),r=n[0],i=Array(24*6).fill(0),a=Date.now();for(let t of e){let e=a-new Date(t.startedAt).getTime(),n=Math.floor(e/(10*60*1e3));n>=0&&n<i.length&&(i[i.length-1-n]+=1)}return h.createElement(p,{flexDirection:`column`},h.createElement(m,{bold:!0},e.length,` live`),h.createElement(m,{color:t.muted},s(i,40)),r?h.createElement(m,{color:t.muted},`top: `,r.city??r.country??`—`,` · `,r.page??`—`):null)},x=({visitors:e,limit:t,columns:n})=>{let{theme:r}=o(),i=[...e].sort((e,t)=>Date.parse(t.startedAt)-Date.parse(e.startedAt)).slice(0,t);return i.length===0?h.createElement(m,{color:r.dim},`— no visitors yet —`):h.createElement(u,{columns:n,data:i,headerStyle:`accent`})};export{y as visitorsCommand};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import"./error-codes-C5caZH9p.js";import"./telemetry-DRh10SvO.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import{formatTabular as r,selectFormat as i}from"./formatter-DDG2TSOz.js";import"./client-Dm8uGVCy.js";import{openInBrowser as a}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{useTheme as o}from"./panel-B-XxdP-N.js";import"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import"./chat-panel-ZlKZ0W6J.js";import{resolveSiteId as s}from"./resolve-site-DQVcWhjG.js";import{DataTable as c}from"./data-table-DJzT7bAr.js";import{deepLinkFor as l}from"./keybar-deep-link-DbmPjAEz.js";import{runAnalyticalScreen as u}from"./analytical-screen-B_wWUnT4.js";import{Box as d,Text as f}from"ink";import p from"react";const m={lcp:{good:2500,poor:4e3},inp:{good:200,poor:500},cls:{good:.1,poor:.25},ttfb:{good:800,poor:1800},fcp:{good:1800,poor:3e3}};function h(e,t){let n=m[e];return t<=n.good?{label:`good`,tone:`good`}:t<=n.poor?{label:`needs`,tone:`needs`}:{label:`poor`,tone:`poor`}}function g(e,t){return e===`cls`?t.toFixed(3):t<1e3?`${Math.round(t)}ms`:`${(t/1e3).toFixed(2)}s`}function _({data:e}){let{theme:t}=o(),n={good:t.success,needs:t.warn,poor:t.error},r=t=>{let n=0,r=0;for(let i of e.vitals){let e=i[t]?.p75;typeof e==`number`&&(n+=e*i.samples,r+=i.samples)}return r>0?n/r:0},i=[`lcp`,`inp`,`cls`,`ttfb`,`fcp`];return p.createElement(d,{flexDirection:`column`},i.map(e=>{let t=r(e),i=h(e,t);return p.createElement(f,{key:e},p.createElement(f,{color:n[i.tone]},`● `),p.createElement(f,{bold:!0},e.toUpperCase().padEnd(5)),` `,p.createElement(f,null,g(e,t).padStart(8)),` `,p.createElement(f,{color:n[i.tone]},i.label))}))}function v({data:e,columns:t}){let{theme:n}=o();return e.vitals.length===0?p.createElement(f,{color:n.muted},`— no vitals data yet —`):p.createElement(c,{data:e.vitals.slice(0,15),columns:t,headerStyle:`accent`})}async function y(o){let c=await e(),d=await t({strict:!1}),f=new n({config:c,cliVersion:o.cliVersion,token:d}),m,h;try{({siteId:m,site:h}=await s(f,{explicit:o.siteId,headless:!!(o.json||o.csv||o.tsv||o.ndjson),cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(o),b=[{key:`url`,label:`url`,width:32},{key:`device`,label:`device`,width:7,format:e=>String(e??`—`)},{key:`lcp`,label:`LCP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?g(`lcp`,e.p75):`—`},{key:`inp`,label:`INP p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?g(`inp`,e.p75):`—`},{key:`cls`,label:`CLS p75`,width:9,align:`right`,format:e=>e&&typeof e==`object`&&`p75`in e?g(`cls`,e.p75):`—`},{key:`samples`,label:`n`,width:6,align:`right`}];return u({cliVersion:o.cliVersion,title:`vitals · ${m}`,commandName:`vitals`,ai:{api:f,siteId:m,siteLabel:h?.url?h.url.replace(/^https?:\/\//,``).replace(/\/$/,``):h?.name??m},authToken:d?.accessToken??null,refreshIntervalMs:o.watch?5*6e4:0,fetcher:e=>f.getVitals(m,{url:o.url,device:o.device,window:o.window},e),format:y,keybindings:{o:{label:`open in browser`,handler:()=>{a(l(`vitals`,{siteId:m}))}}},headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
|
|
2
2
|
`);return}process.stdout.write(r(e.vitals,[`url`,`device`,`samples`],t))},panels:[{id:`summary`,title:`Site-wide p75`,render:e=>p.createElement(_,{data:e})},{id:`pages`,title:`Per-page`,render:e=>p.createElement(v,{data:e,columns:b})}]})}export{y as vitalsCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CI5hxW-O.js";import"./formatter-C4YSOKuq.js";import{emit$1 as r,isHeadless as i}from"./emit-D4YlMlzk.js";import{parseSseStream as a}from"./client-I4GTcUcm.js";import{openInBrowser as o}from"./open-url-dPoDcwsm.js";import"./theme-Brz9wK0w.js";import{Panel as s,useTheme as c}from"./panel-DB1HLxAw.js";import{Banner as l}from"./banner-MAYlzjcP.js";import"./prompt-D7Ek9MYk.js";import{Keybar as u}from"./keybar-BcHUm3hI.js";import{spark as d}from"./sparkline-8ucKVUV7.js";import{resolveSiteId as f}from"./resolve-site-DYBsBK4c.js";import{EmptyState as p}from"./empty-state-DdLBcz4h.js";import{deepLinkFor as m}from"./keybar-deep-link-Dagnpllp.js";import{z as h}from"zod";import{Box as g,Text as _,render as v,useApp as y,useInput as b}from"ink";import x,{useEffect as S,useState as C}from"react";import w from"ink-spinner";import T from"ink-text-input";const E=Math.PI*2;function D(e){let t=e,n=Math.PI*Math.sin(e);for(let e=0;e<6;e++){let e=2*t+Math.sin(2*t)-n,r=2+2*Math.cos(2*t);if(r===0)break;t-=e/r}return t}function O(e,t){if(e<-90||e>90||t<-180||t>180)return null;let n=e*Math.PI/180,r=t*Math.PI/180,i=D(n),a=r*Math.cos(i)/Math.PI,o=Math.sin(i);return{x:a,y:o}}function k(e){if(e)return!0;let t=process.env;if(t.NO_COLOR||t.ZENOVAY_GLOBE===`ascii`)return!0;let n=(t.LANG||t.LC_ALL||t.LC_CTYPE||``).toLowerCase();return!!(n&&!n.includes(`utf`))}function A(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function j(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function M(e){let t=e.dw/2,n=e.dh/2,r=e.dw/2-1,i=e.dh/2-1,a=Math.max(e.dw,e.dh)*2;for(let o=0;o<a;o++){let s=o/a*E,c=Math.round(t+r*Math.cos(s)),l=Math.round(n+i*Math.sin(s));j(e,c,l)}}function N(e){let t=Math.floor(e.dh/2);for(let n=0;n<e.dw;n+=4)j(e,n,t)}function P(e,t){let n=e.dw/2,r=e.dh/2,i=e.dw/2-1,a=e.dh/2-1;for(let o of t){let t=O(o.lat,o.lng);if(!t)continue;let s=Math.round(n+t.x*i),c=Math.round(r-t.y*a);j(e,s,c),j(e,s+1,c),j(e,s,c+1),j(e,s+1,c+1)}}const F=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function I(e,t,n){let r=0;for(let i=0;i<F.length;i++){let[a,o]=F[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function L(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`.`:r<=4?`:`:r<=6?`*`:`#`}function R({data:e,width:t=80,height:n=20,asciiOnly:r}){let{theme:i}=c(),a=k(r),o=A(t,n);M(o),N(o),P(o,e);let s=[];for(let e=0;e<n;e++){let n=``;for(let r=0;r<t;r++)n+=a?L(o,r,e):I(o,r,e);s.push(n)}return x.createElement(g,{flexDirection:`column`},s.map((e,t)=>x.createElement(_,{key:t,color:i.accent},e)),x.createElement(_,{color:i.muted},e.length,` live · `,a?`ascii mode`:`braille mode`))}const z=h.object({siteId:h.string().optional(),window:h.string().optional(),totalVisitors:h.number().optional(),visitors:h.object({count:h.number().optional(),series:h.array(h.number()).optional()}).optional(),topPages:h.array(h.object({path:h.string(),views:h.number().optional(),count:h.number().optional()})).optional(),sources:h.array(h.object({source:h.string(),visitors:h.number()})).optional()}).passthrough();async function B(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:a.cliVersion,token:s}),l;try{({siteId:l}=await f(c,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(i(a)){let e=await c.getDashboardSnapshot(l);return r({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=v(x.createElement(V,{api:c,siteId:l,intervalMs:a.intervalMs??15e3,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const V=({api:e,siteId:t,intervalMs:n,cliVersion:r,onExit:i})=>{let{theme:d}=c(),{exit:f}=y(),[h,v]=C(null),[T,E]=C(null),[D,O]=C(null),[k,A]=C([]),[j,M]=C(!0),[N,P]=C(null),[F,I]=C(1),[L,B]=C(!1),[V,Y]=C(!1);b((e,n)=>{if(e===`o`||e===`O`){o(m(`watch`,{siteId:t}));return}if(e===`q`){f(),i(0);return}if(e===`?`||e===`/`){Y(e=>!e);return}if(e===`g`){B(e=>!e);return}if(n.tab){I(e=>{let t=n.shift?(e+4)%6+1:e%6+1;return t});return}(e===`1`||e===`2`||e===`3`||e===`4`||e===`5`||e===`6`)&&I(Number(e))});let[X,Z]=C(!1);if(S(()=>{let r=!1,i=async()=>{try{let n=await e.getDashboardSnapshot(t);if(r)return;let i=z.safeParse(n);if(!i.success){Z(!0),M(!1);return}Z(!1);let a=i.data,o={visitors:a.visitors??(typeof a.totalVisitors==`number`?{count:a.totalVisitors}:void 0),topPages:a.topPages?.map(e=>({path:e.path,views:e.views??e.count??0})),sources:a.sources};v(o),e.getVitals(t).then(e=>{r||E(e)},()=>{}),e.getGoals(t).then(e=>{r||O(e)},()=>{}),M(!1),P(null)}catch(e){r||P(e.message)}};i();let a=setInterval(i,n);return()=>{r=!0,clearInterval(a)}},[e,t,n]),S(()=>{let n=new AbortController;return(async()=>{try{let r=await e.openEventsStream(t,n.signal);for await(let e of a(r))e.type===`error`&&A(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>n.abort()},[e,t]),j)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(s,{title:`Loading`,state:`busy`},x.createElement(g,null,x.createElement(_,{color:d.accent},x.createElement(w,{type:`dots`})),x.createElement(_,null,` Fetching snapshot…`))));if(N&&!h)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(s,{title:`Error`,state:`err`},x.createElement(_,{color:d.error},N)));if(X&&!h)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(p,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let Q=process.stdout.columns??80,$=Math.max(20,Math.floor(Q/3)-1),ee=[];return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}${L?` · globe`:``}`}),x.createElement(g,{flexDirection:`row`},x.createElement(g,{flexDirection:`column`},L?x.createElement(s,{title:`Live globe`,focused:F===1,width:$},x.createElement(R,{data:ee,width:Math.max(40,$-4),height:12})):x.createElement(U,{snapshot:h,focused:F===1,width:$}),x.createElement(K,{events:k,focused:F===4,width:$})),x.createElement(g,{flexDirection:`column`},x.createElement(W,{snapshot:h,focused:F===2,width:$}),x.createElement(q,{vitals:T,focused:F===5,width:$})),x.createElement(g,{flexDirection:`column`},x.createElement(G,{snapshot:h,focused:F===3,width:$}),x.createElement(J,{goals:D,focused:F===6,width:$}))),V?x.createElement(H,{api:e,siteId:t,width:Q-2}):null,x.createElement(u,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:L?`panels`:`globe`},{key:`?/`,label:V?`close chat`:`ai chat`},{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))},H=({api:e,siteId:t,width:n})=>{let{theme:r}=c(),[i,o]=C(``),[l,u]=C([]),[d,f]=C(!1),[p,m]=C(``),[h,v]=C(null),y=async n=>{let r=n.trim();if(!r||d)return;v(null),o(``);let i=[...l,{role:`user`,content:r}];u(i),f(!0),m(``);try{let n=i.map(e=>({role:e.role,content:e.content})),r=await e.openAiStream(`chat`,{messages:n,siteId:t},void 0),o=``;for await(let e of a(r))if(e.type===`delta`)o+=e.content,m(o);else if(e.type===`error`)v(`${e.code}: ${e.message}`);else if(e.type===`done`)break;u([...i,{role:`assistant`,content:o}]),m(``)}catch(e){v(e instanceof Error?e.message:`chat failed`)}finally{f(!1)}};return x.createElement(g,{marginTop:1},x.createElement(s,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:n},x.createElement(g,{flexDirection:`column`},l.slice(-6).map((e,t)=>x.createElement(g,{key:t,flexDirection:`column`,marginBottom:1},x.createElement(_,{color:e.role===`user`?r.accent:r.info,bold:!0},e.role===`user`?`you`:`zenovay`),x.createElement(_,null,e.content))),d&&p?x.createElement(g,{flexDirection:`column`,marginBottom:1},x.createElement(_,{color:r.info,bold:!0},`zenovay`),x.createElement(_,null,p)):null,h?x.createElement(_,{color:r.error},`✗ `,h):null,x.createElement(g,null,x.createElement(_,{color:r.accent},d?`⠋ `:`▸ `),x.createElement(T,{value:i,onChange:o,onSubmit:y,placeholder:d?`streaming…`:`ask anything about your analytics`})))))},U=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.visitors?.count??0,a=e?.visitors?.series??[];return x.createElement(s,{title:`Visitors`,focused:t,width:n},x.createElement(_,{bold:!0},i.toString()),x.createElement(_,{color:r.muted},a.length>0?d(a,Math.max(8,n-6)):`— no data —`))},W=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.topPages?.slice(0,5)??[];return x.createElement(s,{title:`Top pages`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.path},x.createElement(_,null,e.path.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.views))))},G=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.sources?.slice(0,5)??[];return x.createElement(s,{title:`Sources`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.source},x.createElement(_,null,e.source.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.visitors))))},K=({events:e,focused:t,width:n})=>{let{theme:r}=c();return x.createElement(s,{title:`Events`,focused:t,width:n},e.length===0?x.createElement(_,{color:r.muted},`— waiting —`):e.slice(-10).map((e,t)=>x.createElement(_,{key:t},e.slice(0,n-4))))},q=({vitals:e,focused:t,width:n})=>{let{theme:r}=c(),i=(e,t,n)=>x.createElement(g,{key:e},x.createElement(_,{bold:!0},e.padEnd(6)),x.createElement(_,{color:r.muted},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return x.createElement(s,{title:`Vitals`,focused:t,width:n},i(`LCP`,e?.lcpP75,`ms`),i(`INP`,e?.inpP75,`ms`),i(`CLS`,e?.clsP75?e.clsP75*1e3:void 0,`/1k`),i(`TTFB`,e?.ttfbP75,`ms`),i(`FCP`,e?.fcpP75,`ms`))},J=({goals:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.goals?.slice(0,5)??[];return x.createElement(s,{title:`Goals`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.name},x.createElement(_,null,e.name.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.completions))))};export{B as watchCommand};
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import"./formatter-DDG2TSOz.js";import{emit$1 as r,isHeadless as i}from"./emit-C9vAopcy.js";import{parseSseStream as a}from"./client-Dm8uGVCy.js";import{openInBrowser as o}from"./open-url-BxXbZzWS.js";import"./theme-BuGrQHax.js";import{Panel as s,useTheme as c}from"./panel-B-XxdP-N.js";import{Banner as l}from"./banner-DdgwXGzt.js";import"./prompt-B4s3o9G7.js";import{Keybar as u}from"./keybar-QgnmSion.js";import{spark as d}from"./sparkline-CpoBjjlc.js";import{resolveSiteId as f}from"./resolve-site-DQVcWhjG.js";import{EmptyState as p}from"./empty-state-DbToIL5T.js";import{deepLinkFor as m}from"./keybar-deep-link-DbmPjAEz.js";import{z as h}from"zod";import{Box as g,Text as _,render as v,useApp as y,useInput as b}from"ink";import x,{useEffect as S,useState as C}from"react";import w from"ink-spinner";import T from"ink-text-input";const E=Math.PI*2;function D(e){let t=e,n=Math.PI*Math.sin(e);for(let e=0;e<6;e++){let e=2*t+Math.sin(2*t)-n,r=2+2*Math.cos(2*t);if(r===0)break;t-=e/r}return t}function O(e,t){if(e<-90||e>90||t<-180||t>180)return null;let n=e*Math.PI/180,r=t*Math.PI/180,i=D(n),a=r*Math.cos(i)/Math.PI,o=Math.sin(i);return{x:a,y:o}}function k(e){if(e)return!0;let t=process.env;if(t.NO_COLOR||t.ZENOVAY_GLOBE===`ascii`)return!0;let n=(t.LANG||t.LC_ALL||t.LC_CTYPE||``).toLowerCase();return!!(n&&!n.includes(`utf`))}function A(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function j(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function M(e){let t=e.dw/2,n=e.dh/2,r=e.dw/2-1,i=e.dh/2-1,a=Math.max(e.dw,e.dh)*2;for(let o=0;o<a;o++){let s=o/a*E,c=Math.round(t+r*Math.cos(s)),l=Math.round(n+i*Math.sin(s));j(e,c,l)}}function N(e){let t=Math.floor(e.dh/2);for(let n=0;n<e.dw;n+=4)j(e,n,t)}function P(e,t){let n=e.dw/2,r=e.dh/2,i=e.dw/2-1,a=e.dh/2-1;for(let o of t){let t=O(o.lat,o.lng);if(!t)continue;let s=Math.round(n+t.x*i),c=Math.round(r-t.y*a);j(e,s,c),j(e,s+1,c),j(e,s,c+1),j(e,s+1,c+1)}}const F=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function I(e,t,n){let r=0;for(let i=0;i<F.length;i++){let[a,o]=F[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function L(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`.`:r<=4?`:`:r<=6?`*`:`#`}function R({data:e,width:t=80,height:n=20,asciiOnly:r}){let{theme:i}=c(),a=k(r),o=A(t,n);M(o),N(o),P(o,e);let s=[];for(let e=0;e<n;e++){let n=``;for(let r=0;r<t;r++)n+=a?L(o,r,e):I(o,r,e);s.push(n)}return x.createElement(g,{flexDirection:`column`},s.map((e,t)=>x.createElement(_,{key:t,color:i.accent},e)),x.createElement(_,{color:i.muted},e.length,` live · `,a?`ascii mode`:`braille mode`))}const z=h.object({siteId:h.string().optional(),window:h.string().optional(),totalVisitors:h.number().optional(),visitors:h.object({count:h.number().optional(),series:h.array(h.number()).optional()}).optional(),topPages:h.array(h.object({path:h.string(),views:h.number().optional(),count:h.number().optional()})).optional(),sources:h.array(h.object({source:h.string(),visitors:h.number()})).optional()}).passthrough();async function B(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:a.cliVersion,token:s}),l;try{({siteId:l}=await f(c,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}if(i(a)){let e=await c.getDashboardSnapshot(l);return r({type:`watch.tick`,snapshot:e}),0}return new Promise(e=>{let{unmount:t}=v(x.createElement(V,{api:c,siteId:l,intervalMs:a.intervalMs??15e3,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const V=({api:e,siteId:t,intervalMs:n,cliVersion:r,onExit:i})=>{let{theme:d}=c(),{exit:f}=y(),[h,v]=C(null),[T,E]=C(null),[D,O]=C(null),[k,A]=C([]),[j,M]=C(!0),[N,P]=C(null),[F,I]=C(1),[L,B]=C(!1),[V,Y]=C(!1);b((e,n)=>{if(e===`o`||e===`O`){o(m(`watch`,{siteId:t}));return}if(e===`q`){f(),i(0);return}if(e===`?`||e===`/`){Y(e=>!e);return}if(e===`g`){B(e=>!e);return}if(n.tab){I(e=>{let t=n.shift?(e+4)%6+1:e%6+1;return t});return}(e===`1`||e===`2`||e===`3`||e===`4`||e===`5`||e===`6`)&&I(Number(e))});let[X,Z]=C(!1);if(S(()=>{let r=!1,i=async()=>{try{let n=await e.getDashboardSnapshot(t);if(r)return;let i=z.safeParse(n);if(!i.success){Z(!0),M(!1);return}Z(!1);let a=i.data,o={visitors:a.visitors??(typeof a.totalVisitors==`number`?{count:a.totalVisitors}:void 0),topPages:a.topPages?.map(e=>({path:e.path,views:e.views??e.count??0})),sources:a.sources};v(o),e.getVitals(t).then(e=>{r||E(e)},()=>{}),e.getGoals(t).then(e=>{r||O(e)},()=>{}),M(!1),P(null)}catch(e){r||P(e.message)}};i();let a=setInterval(i,n);return()=>{r=!0,clearInterval(a)}},[e,t,n]),S(()=>{let n=new AbortController;return(async()=>{try{let r=await e.openEventsStream(t,n.signal);for await(let e of a(r))e.type===`error`&&A(t=>[...t,`[ERR ${e.code}] ${e.message}`].slice(-10))}catch{}})(),()=>n.abort()},[e,t]),j)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(s,{title:`Loading`,state:`busy`},x.createElement(g,null,x.createElement(_,{color:d.accent},x.createElement(w,{type:`dots`})),x.createElement(_,null,` Fetching snapshot…`))));if(N&&!h)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(s,{title:`Error`,state:`err`},x.createElement(_,{color:d.error},N)));if(X&&!h)return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}`}),x.createElement(p,{reason:`error`,headline:`Couldn't load dashboard`,hint:"The server returned an unexpected shape. Try `zenovay update` to refresh the CLI."}));let Q=process.stdout.columns??80,$=Math.max(20,Math.floor(Q/3)-1),ee=[];return x.createElement(g,{flexDirection:`column`},x.createElement(l,{version:r,subtitle:`watch · ${t}${L?` · globe`:``}`}),x.createElement(g,{flexDirection:`row`},x.createElement(g,{flexDirection:`column`},L?x.createElement(s,{title:`Live globe`,focused:F===1,width:$},x.createElement(R,{data:ee,width:Math.max(40,$-4),height:12})):x.createElement(U,{snapshot:h,focused:F===1,width:$}),x.createElement(K,{events:k,focused:F===4,width:$})),x.createElement(g,{flexDirection:`column`},x.createElement(W,{snapshot:h,focused:F===2,width:$}),x.createElement(q,{vitals:T,focused:F===5,width:$})),x.createElement(g,{flexDirection:`column`},x.createElement(G,{snapshot:h,focused:F===3,width:$}),x.createElement(J,{goals:D,focused:F===6,width:$}))),V?x.createElement(H,{api:e,siteId:t,width:Q-2}):null,x.createElement(u,{items:[{key:`tab`,label:`next`},{key:`1-6`,label:`jump`},{key:`g`,label:L?`panels`:`globe`},{key:`?/`,label:V?`close chat`:`ai chat`},{key:`o`,label:`open in browser`},{key:`q`,label:`quit`}]}))},H=({api:e,siteId:t,width:n})=>{let{theme:r}=c(),[i,o]=C(``),[l,u]=C([]),[d,f]=C(!1),[p,m]=C(``),[h,v]=C(null),y=async n=>{let r=n.trim();if(!r||d)return;v(null),o(``);let i=[...l,{role:`user`,content:r}];u(i),f(!0),m(``);try{let n=i.map(e=>({role:e.role,content:e.content})),r=await e.openAiStream(`chat`,{messages:n,siteId:t},void 0),o=``;for await(let e of a(r))if(e.type===`delta`)o+=e.content,m(o);else if(e.type===`error`)v(`${e.code}: ${e.message}`);else if(e.type===`done`)break;u([...i,{role:`assistant`,content:o}]),m(``)}catch(e){v(e instanceof Error?e.message:`chat failed`)}finally{f(!1)}};return x.createElement(g,{marginTop:1},x.createElement(s,{title:`AI chat (esc / ?/ to close)`,focused:!0,width:n},x.createElement(g,{flexDirection:`column`},l.slice(-6).map((e,t)=>x.createElement(g,{key:t,flexDirection:`column`,marginBottom:1},x.createElement(_,{color:e.role===`user`?r.accent:r.info,bold:!0},e.role===`user`?`you`:`zenovay`),x.createElement(_,null,e.content))),d&&p?x.createElement(g,{flexDirection:`column`,marginBottom:1},x.createElement(_,{color:r.info,bold:!0},`zenovay`),x.createElement(_,null,p)):null,h?x.createElement(_,{color:r.error},`✗ `,h):null,x.createElement(g,null,x.createElement(_,{color:r.accent},d?`⠋ `:`▸ `),x.createElement(T,{value:i,onChange:o,onSubmit:y,placeholder:d?`streaming…`:`ask anything about your analytics`})))))},U=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.visitors?.count??0,a=e?.visitors?.series??[];return x.createElement(s,{title:`Visitors`,focused:t,width:n},x.createElement(_,{bold:!0},i.toString()),x.createElement(_,{color:r.muted},a.length>0?d(a,Math.max(8,n-6)):`— no data —`))},W=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.topPages?.slice(0,5)??[];return x.createElement(s,{title:`Top pages`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.path},x.createElement(_,null,e.path.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.views))))},G=({snapshot:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.sources?.slice(0,5)??[];return x.createElement(s,{title:`Sources`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.source},x.createElement(_,null,e.source.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.visitors))))},K=({events:e,focused:t,width:n})=>{let{theme:r}=c();return x.createElement(s,{title:`Events`,focused:t,width:n},e.length===0?x.createElement(_,{color:r.muted},`— waiting —`):e.slice(-10).map((e,t)=>x.createElement(_,{key:t},e.slice(0,n-4))))},q=({vitals:e,focused:t,width:n})=>{let{theme:r}=c(),i=(e,t,n)=>x.createElement(g,{key:e},x.createElement(_,{bold:!0},e.padEnd(6)),x.createElement(_,{color:r.muted},typeof t==`number`?`${t.toFixed(0)}${n}`:`—`));return x.createElement(s,{title:`Vitals`,focused:t,width:n},i(`LCP`,e?.lcpP75,`ms`),i(`INP`,e?.inpP75,`ms`),i(`CLS`,e?.clsP75?e.clsP75*1e3:void 0,`/1k`),i(`TTFB`,e?.ttfbP75,`ms`),i(`FCP`,e?.fcpP75,`ms`))},J=({goals:e,focused:t,width:n})=>{let{theme:r}=c(),i=e?.goals?.slice(0,5)??[];return x.createElement(s,{title:`Goals`,focused:t,width:n},i.length===0?x.createElement(_,{color:r.muted},`— no data —`):i.map(e=>x.createElement(g,{key:e.name},x.createElement(_,null,e.name.padEnd(n-10).slice(0,n-10)),x.createElement(_,{color:r.muted},` `,e.completions))))};export{B as watchCommand};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{emitErrorEnvelope as n}from"./error-codes-C5caZH9p.js";import{ApiV2Client as r}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{emitErrorEnvelope as n}from"./error-codes-C5caZH9p.js";import{ApiV2Client as r}from"./api-v2-CPUUcP1i.js";import{confirmDestructive as i}from"./confirm-CIdxMt7N.js";import"./formatter-DDG2TSOz.js";import{emitEnvelope as a,wrapItem as o,wrapList as s}from"./emit-C9vAopcy.js";function c(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}function l(e){return e?new Date(e).toISOString().slice(0,10):`—`}async function u(u){let d=await e(),f=await t({strict:!1}),p=new r({config:d,cliVersion:u.cliVersion,token:f});try{switch(u.action){case`list`:{let{webhooks:e}=await p.listWebhooks();if(u.json)return a(s(e,`webhooks.list`),{legacyKey:`webhooks`,legacyValue:e}),0;if(e.length===0)return process.stdout.write("No webhooks yet. Add one with `zenovay webhooks add <https-url> --events <e1,e2>`.\n"),0;let t=[``,`id`,`url`,`events`,`created`],n=[1,14,40,28,10],r=e=>e.map((e,t)=>(e??``).padEnd(n[t])).join(` `);process.stdout.write(r(t)+`
|
|
2
2
|
`),process.stdout.write(r(n.map(e=>`─`.repeat(e)))+`
|
|
3
3
|
`);for(let t of e){let e=t.status===`disabled`?`○`:`●`,i=t.url.length>n[2]?`${t.url.slice(0,n[2]-1)}…`:t.url,a=t.events.join(`,`),o=a.length>n[3]?`${a.slice(0,n[3]-1)}…`:a;process.stdout.write(r([e,c(t.id),i,o,l(t.createdAt)])+`
|
|
4
4
|
`)}return process.stdout.write(`
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-
|
|
1
|
+
import{readConfig as e}from"./config--JRu_jFq.js";import"./api-FCanTxsb.js";import{readToken as t}from"./token-store-BQuGH0z2.js";import{ApiV2Client as n}from"./api-v2-CPUUcP1i.js";import"./theme-BuGrQHax.js";import{Panel as r,useTheme as i}from"./panel-B-XxdP-N.js";import{Banner as a}from"./banner-DdgwXGzt.js";import"./progress-row-5ns2IsFh.js";import"./prompt-B4s3o9G7.js";import"./keybar-QgnmSion.js";import"./sparkline-CpoBjjlc.js";import"./data-table-DJzT7bAr.js";import"./bar-C1Zrfe9H.js";import"./ui-whccLLRv.js";import{Box as o,Text as s,render as c,useApp as l,useInput as u}from"ink";import d,{useEffect as f,useState as p}from"react";async function m(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]),i=await crypto.subtle.sign(`HMAC`,r,n.encode(t));return Array.from(new Uint8Array(i),e=>e.toString(16).padStart(2,`0`)).join(``)}function h({stats:e}){let{theme:t}=i();return d.createElement(r,{title:`webhooks forward`,state:e.connected?`ok`:`busy`},d.createElement(o,{flexDirection:`column`},d.createElement(s,null,d.createElement(s,{color:t.muted},`public URL `),d.createElement(s,{color:t.accent},e.publicUrl)),d.createElement(s,null,d.createElement(s,{color:t.muted},`→ forwarding to `),d.createElement(s,{color:t.accent},e.wsUrl)),d.createElement(s,null,e.connected?d.createElement(s,{color:t.success},`● connected`):d.createElement(s,{color:t.warn},`○ connecting…`),d.createElement(s,{color:t.muted},` · `,e.total,` requests · `,e.ok,` ok · `),d.createElement(s,{color:e.err>0?t.error:t.muted},e.err,` err`),e.lastStatus===null?null:d.createElement(s,{color:t.muted},` · last: HTTP `,e.lastStatus)),e.lastError?d.createElement(s,{color:t.error},`last error: `,e.lastError.slice(0,80)):null))}async function g(r){let g=await e(),_=await t({strict:!1});if(!_?.accessToken)return process.stderr.write("Not authenticated. Run `zenovay login` first.\n"),2;let v=r.siteId??_.teamId??``;if(!v)return process.stderr.write(`No site selected — pass --site-id or set ZENOVAY_SITE.
|
|
2
2
|
`),2;if(!r.to)return process.stderr.write(`Missing --to <url> (e.g. --to localhost:3000/webhook).
|
|
3
3
|
`),2;let y=r.to.match(/^https?:\/\//)?r.to:`http://${r.to}`,b=new n({config:g,cliVersion:r.cliVersion,token:_}),x;try{x=await b.createTunnel(v,r.to)}catch(e){return process.stderr.write(`Failed to register tunnel: ${e.message}\n`),1}let S=r.sign?r.secret??x.tunnelKey:null,C=()=>{let{theme:e}=i(),{exit:t}=l(),[n,c]=p({total:0,ok:0,err:0,lastStatus:null,lastError:null,publicUrl:x.publicUrl,wsUrl:x.wsUrl,connected:!1});return u((e,n)=>{(e===`q`||n.escape)&&t()}),f(()=>{let e=new AbortController,t=async e=>{try{let t={...e.headers};delete t.host,delete t[`content-length`],S&&(t[`X-Zenovay-Signature`]=`sha256=${await m(S,e.body)}`);let n=await fetch(y,{method:e.method,headers:t,body:e.method===`GET`||e.method===`HEAD`?void 0:e.body}),r=await n.text(),i={};return n.headers.forEach((e,t)=>{i[t]=e}),c(e=>({...e,total:e.total+1,ok:e.ok+(n.ok?1:0),err:e.err+(n.ok?0:1),lastStatus:n.status,lastError:n.ok?null:`HTTP ${n.status}`})),{status:n.status,headers:i,body:r}}catch(e){let t=e instanceof Error?e.message:String(e);return c(e=>({...e,total:e.total+1,err:e.err+1,lastError:t})),{status:502,body:JSON.stringify({error:`cli_local_failed`,detail:t})}}};return(async()=>{let n=b.tunnelClient(x.wsUrl);c(e=>({...e,connected:!0}));try{await n.start(t,e.signal)}catch(e){c(t=>({...t,connected:!1,lastError:e.message}))}})(),()=>{e.abort()}},[]),d.createElement(o,{flexDirection:`column`},d.createElement(a,{version:`webhooks forward`}),d.createElement(h,{stats:n}),d.createElement(s,{color:e.muted},`target: `,y,` `,r.sign?`· HMAC-signed`:``),d.createElement(s,{color:e.muted},`[q | Esc] quit`))},{waitUntilExit:w}=c(d.createElement(C,null));return await w(),0}export{g as webhooksForwardCommand};
|
package/dist/wizard-bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import(`./init-
|
|
2
|
+
import(`./init-WmEUW4Em.js`).then(async({initCommand:e})=>{let{readFileSync:t}=await import(`node:fs`),n=await import(`node:path`),{fileURLToPath:r}=await import(`node:url`),i=n.dirname(r(import.meta.url)),a=JSON.parse(t(n.join(i,`..`,`package.json`),`utf8`)),o=process.argv.slice(2),s=o.includes(`--json`),c=o.includes(`--yes`),l=o.includes(`--skip-mcp`),u=o.includes(`--skip-verify`),d=await e({cliVersion:a.version,cwd:process.cwd(),json:s,yes:c,skipMcp:l,skipVerify:u});process.exit(d)});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=[500,1e3,2e3,4e3,8e3,16e3,32e3,6e4];let t=null;async function n(){if(t)return t;let e=globalThis.WebSocket;if(typeof e==`function`)return t=e,e;try{let e=await import(`ws`),n=e.default??e.WebSocket;if(!n)throw Error(`ws package missing default export`);return t=n,n}catch(e){throw Error(`WebSocket unavailable: install Node 22+ or add the 'ws' dependency (${e.message})`)}}function r(e,t){return new Promise((n,r)=>{if(t?.aborted){r(t.reason??Error(`aborted`));return}let i=setTimeout(()=>{t?.removeEventListener(`abort`,a),n()},e),a=()=>{clearTimeout(i),r(t?.reason??Error(`aborted`))};t?.addEventListener(`abort`,a,{once:!0})})}function i(t){return e[Math.min(t-1,e.length-1)]??6e4}function a(e,t){if(!t)return e;let n=e.includes(`?`)?`&`:`?`;return`${e}${n}access_token=${encodeURIComponent(t)}`}async function o(e,t,n,r){let i=a(e,n),o;try{o=n?new t(i,{headers:{Authorization:`Bearer ${n}`}}):new t(i)}catch(e){throw Error(`ws connect failed: ${e.message}`)}return await new Promise((e,t)=>{let n=!1,i=()=>{n||(n=!0,c(),e({socket:o,open:!0}))},a=e=>{if(n)return;n=!0,c();let r=e?.message??(typeof e==`string`?e:`ws connection error`);t(Error(r))},s=()=>{if(!n){n=!0,c();try{o.close()}catch{}t(r?.reason??Error(`aborted`))}},c=()=>{o.onopen=null,o.onerror=null,r?.removeEventListener(`abort`,s)};o.onopen=i,o.onerror=a,r?.addEventListener(`abort`,s,{once:!0})})}async function*s(e){let t=e.webSocketImpl??await n(),a=e.pingIntervalMs??3e4,s=e.maxReconnectAttempts??10,c=0;for(;;){if(e.signal?.aborted)return;let n;try{n=await o(e.url,t,e.bearer,e.signal)}catch(t){if(e.signal?.aborted)return;if(c++,c>s)throw t;let n=i(c);e.onReconnect?.(c,n);try{await r(n,e.signal)}catch{return}continue}yield{type:`open`};let l=[],u=[],d=!1,f=Date.now(),p=!1,m=e=>{f=Date.now();let t=u.shift();t?t(e):l.push(e)},h=()=>{if(!d)for(d=!0;u.length;)u.shift()(null)};n.socket.onmessage=e=>{m({type:`message`,data:e.data})},n.socket.onclose=()=>{m({type:`close`}),h()},n.socket.onerror=e=>{let t=e?.message??`ws error`;m({type:`error`,data:t})};let g=()=>{try{n.socket.close()}catch{}h()};e.signal?.addEventListener(`abort`,g,{once:!0});let _=null;a>0&&(_=setInterval(()=>{if(Date.now()-f>a*1.5){try{n.socket.close()}catch{}h()}},Math.max(1e3,Math.floor(a/2))));try{for(;;){if(e.signal?.aborted)return;let t;if(t=l.length>0?l.shift():d?null:await new Promise(e=>u.push(e)),t===null||(t.type===`message`&&(p=!0),yield t,t.type===`close`))break}}finally{_&&clearInterval(_),e.signal?.removeEventListener(`abort`,g);try{n.socket.close()}catch{}}if(e.signal?.aborted)return;if(p&&(c=0),c++,c>s)throw Error(`ws connection exceeded reconnect cap`);let v=i(c);e.onReconnect?.(c,v);try{await r(v,e.signal)}catch{return}}}var c=class{opts;ac=null;socket=null;running=!1;constructor(e){this.opts=e}async start(e){this.running=!0,this.ac=new AbortController;let t=l(this.ac.signal,this.opts.signal),a=this.opts.webSocketImpl??await n(),s=this.opts.maxReconnectAttempts??10,c=0;for(;this.running;){if(t.aborted)return;let n;try{n=await o(this.opts.url,a,this.opts.bearer,t)}catch(e){if(t.aborted)return;if(c++,c>s)throw e;let n=i(c);this.opts.onReconnect?.(c,n);try{await r(n,t)}catch{return}continue}this.socket=n.socket;let l=!1;if(await new Promise(r=>{n.socket.onmessage=t=>{l=!0;let r=typeof t.data==`string`?t.data:String(t.data),i=null;try{i=JSON.parse(r)}catch{return}!i||typeof i.correlationId!=`string`||e(i).then(e=>{let t={correlationId:i.correlationId,status:e.status,headers:e.headers,body:e.body};try{n.socket.send(JSON.stringify(t))}catch{}}).catch(e=>{let t={correlationId:i.correlationId,status:502,body:JSON.stringify({error:e.message})};try{n.socket.send(JSON.stringify(t))}catch{}})},n.socket.onclose=()=>r(),n.socket.onerror=()=>r(),t.addEventListener(`abort`,()=>{try{n.socket.close()}catch{}r()},{once:!0})}),this.socket=null,t.aborted||!this.running)return;if(l&&(c=0),c++,c>s)throw Error(`ws tunnel exceeded reconnect cap`);let u=i(c);this.opts.onReconnect?.(c,u);try{await r(u,t)}catch{return}}}async stop(){this.running=!1,this.ac?.abort();try{this.socket?.close()}catch{}this.socket=null}};function l(e,t){if(!t)return e;let n=new AbortController,r=()=>n.abort(e.reason),i=()=>n.abort(t.reason);return e.aborted?n.abort(e.reason):e.addEventListener(`abort`,r,{once:!0}),t.aborted?n.abort(t.reason):t.addEventListener(`abort`,i,{once:!0}),n.signal}export{c as WsTunnelClient,s as connectWs};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenovay/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.67",
|
|
4
4
|
"description": "Zenovay CLI — AI install wizard + full terminal analytics dashboard",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"eslint": "^9.16.0",
|
|
61
61
|
"husky": "^9.1.7",
|
|
62
62
|
"ink-testing-library": "^4.0.0",
|
|
63
|
+
"react-devtools-core": "^4.19.1",
|
|
63
64
|
"tsdown": "^0.9.0",
|
|
64
65
|
"tsx": "^4.19.2",
|
|
65
66
|
"typescript": "^5.7.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{formatTabular as e}from"./formatter-C4YSOKuq.js";function t(t,n,r){return e(t,n,r)}function n(e,n,r){return process.stdout.write(t(e,n,r)),0}export{t as toCsv,n as writeCsv};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./formatter-C4YSOKuq.js";import{toCsv as e,writeCsv as t}from"./csv-emit-DYTuKBke.js";export{t as writeCsv};
|