@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.
Files changed (107) hide show
  1. package/dist/{agency-C69JHza5.js → agency-BxYMejNb.js} +1 -1
  2. package/dist/{ai-eSlGP6ay.js → ai-DbtIo6k2.js} +1 -1
  3. package/dist/{alerts-CcKnqwmm.js → alerts-DKQa_K77.js} +1 -1
  4. package/dist/{analytical-screen-BrOFDrQ_.js → analytical-screen-B_wWUnT4.js} +1 -1
  5. package/dist/{analytics-B8yy7gjr.js → analytics-BO22Zeas.js} +1 -1
  6. package/dist/{annotation-BiviGSmz.js → annotation-CL1q8mjr.js} +1 -1
  7. package/dist/{api-keys-DQob1q69.js → api-keys-lfjOVUIe.js} +1 -1
  8. package/dist/{api-v2-CI5hxW-O.js → api-v2-CPUUcP1i.js} +1 -1
  9. package/dist/{api-v2-CTc_U2Gw.js → api-v2-D9N_2hdW.js} +1 -1
  10. package/dist/{apply-oUMOH7u2.js → apply-B19bFTz0.js} +1 -1
  11. package/dist/{audit-B4a5u54T.js → audit-DfKQdrug.js} +1 -1
  12. package/dist/{banner-MAYlzjcP.js → banner-DdgwXGzt.js} +1 -1
  13. package/dist/{bar-DG-MqgGx.js → bar-C1Zrfe9H.js} +1 -1
  14. package/dist/bin.js +6 -6
  15. package/dist/{chat-panel-dXLm3hUn.js → chat-panel-ZlKZ0W6J.js} +1 -1
  16. package/dist/{commands-B-NMyq2s.js → commands-NsH5CS-H.js} +1 -1
  17. package/dist/{companies-CpDnB5NR.js → companies-CtZ2vGQs.js} +1 -1
  18. package/dist/{completions-Cy6kF9kp.js → completions-Bem7-lcb.js} +1 -1
  19. package/dist/csv-emit-BWWv60mT.js +1 -0
  20. package/dist/csv-emit-CVO5kebZ.js +1 -0
  21. package/dist/{data-table-BvnWCG-w.js → data-table-DJzT7bAr.js} +1 -1
  22. package/dist/{deploys-CI88FRFO.js → deploys-CUbSa8S5.js} +1 -1
  23. package/dist/{devices-DNkzamfH.js → devices-CrkIxfde.js} +1 -1
  24. package/dist/{doctor-DJbNKwdF.js → doctor-D5HWdhgv.js} +1 -1
  25. package/dist/{domains-BoRRxWzR.js → domains-V4sD09io.js} +1 -1
  26. package/dist/{emit-D4YlMlzk.js → emit-C9vAopcy.js} +1 -1
  27. package/dist/{empty-state-DdLBcz4h.js → empty-state-DbToIL5T.js} +1 -1
  28. package/dist/{errors-BtGhPNBy.js → errors-D3fS1kYu.js} +1 -1
  29. package/dist/{events-tail-ig5nAsbQ.js → events-tail-DGRZewwc.js} +1 -1
  30. package/dist/{export-CTI3xHqF.js → export-FjEyji8r.js} +1 -1
  31. package/dist/{funnel-DkcJHeX6.js → funnel-C7DmrdUC.js} +1 -1
  32. package/dist/{geo-UBu3aUHh.js → geo-C9OcRStg.js} +1 -1
  33. package/dist/{globe-GU2r8P23.js → globe-PiPL3Bei.js} +1 -1
  34. package/dist/{goals-CcA4qOM5.js → goals-CVRryIri.js} +1 -1
  35. package/dist/{health-am28BgPf.js → health-DMiTjQ9Z.js} +1 -1
  36. package/dist/{health-C-efHHs0.js → health-vxoiMF8G.js} +1 -1
  37. package/dist/{heatmaps-C6ynBgMW.js → heatmaps-G3Nf95tV.js} +1 -1
  38. package/dist/{home-B0miYclo.js → home-CXwRtMge.js} +1 -1
  39. package/dist/init-BuyESMBj.js +79 -0
  40. package/dist/init-WmEUW4Em.js +1 -0
  41. package/dist/{insights-C8PBisLR.js → insights-J99-8Rcu.js} +1 -1
  42. package/dist/{integrations-CS16nG51.js → integrations-CWPrMJfZ.js} +1 -1
  43. package/dist/{journeys-DaqlziL4.js → journeys-BLxqoeFu.js} +1 -1
  44. package/dist/{keybar-BcHUm3hI.js → keybar-QgnmSion.js} +1 -1
  45. package/dist/{live-cIPlpoWN.js → live-CWSLgkC2.js} +1 -1
  46. package/dist/login-CaDs2Peq.js +2 -0
  47. package/dist/login-wpGuU_Zm.js +1 -0
  48. package/dist/{logout-BSSOsDr7.js → logout-BkeT6Hke.js} +1 -1
  49. package/dist/{metric-card-CaFIymSQ.js → metric-card-bQ-j_G6l.js} +1 -1
  50. package/dist/{notes-ZXJfqA4H.js → notes-C8cba6QA.js} +1 -1
  51. package/dist/{pages-3tis8juF.js → pages-CKs5X38q.js} +1 -1
  52. package/dist/{panel-DB1HLxAw.js → panel-B-XxdP-N.js} +1 -1
  53. package/dist/{plans-DCon6c8N.js → plans-oxxMSOdB.js} +1 -1
  54. package/dist/{profile-CY1_dG5d.js → profile-CD9QVZ2I.js} +1 -1
  55. package/dist/{progress-row-BS7fwhn_.js → progress-row-5ns2IsFh.js} +1 -1
  56. package/dist/{projects-B7xPHSK2.js → projects-hIQqeDYq.js} +1 -1
  57. package/dist/{prompt-D7Ek9MYk.js → prompt-B4s3o9G7.js} +1 -1
  58. package/dist/{query-CC7wPhmz.js → query-BLHvu1IF.js} +1 -1
  59. package/dist/{resolve-site-DYBsBK4c.js → resolve-site-DQVcWhjG.js} +1 -1
  60. package/dist/{retention-DeG_P1-s.js → retention-B8bgiVux.js} +1 -1
  61. package/dist/{revenue-Dobs3EQH.js → revenue-BiViSloE.js} +1 -1
  62. package/dist/secrets-M60NENIa.js +1 -0
  63. package/dist/{self-test-DKOYwgHD.js → self-test-CSST_zHj.js} +3 -3
  64. package/dist/{sessions-DM4XGC2N.js → sessions-lUUiiNYc.js} +1 -1
  65. package/dist/{settings-C_st_Aqq.js → settings-CFFiWmGO.js} +1 -1
  66. package/dist/{share-6Dt695rC.js → share-Cx62AEP-.js} +1 -1
  67. package/dist/{sources-BofnMkYR.js → sources-D-KqX0Sg.js} +1 -1
  68. package/dist/{stats-DkrgaDDP.js → stats-BzTqFpJL.js} +1 -1
  69. package/dist/{status-agent-CQ955HRn.js → status-agent-TIyEIKOj.js} +1 -1
  70. package/dist/{team-N-Ycc7Mh.js → team-BRebgNMO.js} +1 -1
  71. package/dist/{teams-BmzDAiAn.js → teams-DhrkUkt8.js} +1 -1
  72. package/dist/{themes-lGJ4GHVu.js → themes-gluHmb6E.js} +1 -1
  73. package/dist/{tour-BA4g04Qt.js → tour-STZ66G7K.js} +1 -1
  74. package/dist/{update-CYLXsiSE.js → update-BCgHj5O4.js} +1 -1
  75. package/dist/{uptime-I3klxuzW.js → uptime-CwG6bqir.js} +1 -1
  76. package/dist/{usage-DIzd9nzk.js → usage-BFCTeA8E.js} +1 -1
  77. package/dist/{use-DlyoJe6I.js → use-baQFldqI.js} +1 -1
  78. package/dist/{visitors-BFBitwBV.js → visitors-BtriXh9k.js} +1 -1
  79. package/dist/{vitals-Bq1y2LBt.js → vitals-BgAwONID.js} +1 -1
  80. package/dist/{watch-BYIKjsGC.js → watch-Cv4FtwSJ.js} +1 -1
  81. package/dist/{webhooks-DKBhl3fL.js → webhooks-PRWhMVgS.js} +1 -1
  82. package/dist/{webhooks-forward-Cfzd9veV.js → webhooks-forward-BDxi2TcF.js} +1 -1
  83. package/dist/wizard-bin.js +1 -1
  84. package/dist/ws-client-BZMMGeRe.js +1 -0
  85. package/package.json +2 -1
  86. package/dist/csv-emit-DYTuKBke.js +0 -1
  87. package/dist/csv-emit-XJfJC5e2.js +0 -1
  88. package/dist/init-CqcqX8o5.js +0 -79
  89. package/dist/init-awEnG3zC.js +0 -1
  90. package/dist/login-CiJG9-gq.js +0 -1
  91. package/dist/login-RVU9FkAl.js +0 -2
  92. package/dist/secrets-BBaEWu03.js +0 -1
  93. package/dist/wrapper-Dl9i0Nh7.js +0 -6
  94. package/dist/ws-client-MoEdfqAO.js +0 -1
  95. /package/dist/{client-I4GTcUcm.js → client-Dm8uGVCy.js} +0 -0
  96. /package/dist/{confirm-DS5wux0g.js → confirm-CIdxMt7N.js} +0 -0
  97. /package/dist/{examples-C0LrZPUl.js → examples-CFatZcPz.js} +0 -0
  98. /package/dist/{fmt-iR2sYwsO.js → fmt-xxIPQJX-.js} +0 -0
  99. /package/dist/{formatter-C4YSOKuq.js → formatter-DDG2TSOz.js} +0 -0
  100. /package/dist/{keybar-deep-link-Dagnpllp.js → keybar-deep-link-DbmPjAEz.js} +0 -0
  101. /package/dist/{open-url-dPoDcwsm.js → open-url-BxXbZzWS.js} +0 -0
  102. /package/dist/{secrets-DzueUVGL.js → secrets-DPf_7SkN.js} +0 -0
  103. /package/dist/{sparkline-8ucKVUV7.js → sparkline-CpoBjjlc.js} +0 -0
  104. /package/dist/{telemetry-Ckn12kyP.js → telemetry-DC0Jw3JD.js} +0 -0
  105. /package/dist/{theme-Brz9wK0w.js → theme-BuGrQHax.js} +0 -0
  106. /package/dist/{tier-BneaO4vD.js → tier-C4q8fJ8m.js} +0 -0
  107. /package/dist/{ui-DXrdVAc-.js → ui-whccLLRv.js} +0 -0
@@ -1,7 +1,7 @@
1
- import{mocha as e}from"./theme-Brz9wK0w.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-CTc_U2Gw.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-BBaEWu03.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(`
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-C0LrZPUl.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)+`
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-CI5hxW-O.js";import{requireTier as r}from"./tier-BneaO4vD.js";import"./formatter-C4YSOKuq.js";import{emit$1 as i,isHeadless as a}from"./emit-D4YlMlzk.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{resolveSiteId as d}from"./resolve-site-DYBsBK4c.js";import{DataTable as f}from"./data-table-BvnWCG-w.js";import{EmptyState as p}from"./empty-state-DdLBcz4h.js";import{deepLinkFor as m}from"./keybar-deep-link-Dagnpllp.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
+ 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-CI5hxW-O.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)+`
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-CI5hxW-O.js";import{confirmDestructive as r}from"./confirm-DS5wux0g.js";import"./theme-Brz9wK0w.js";import"./panel-DB1HLxAw.js";import"./banner-MAYlzjcP.js";import"./prompt-D7Ek9MYk.js";import{resolveSiteId as i}from"./resolve-site-DYBsBK4c.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)+`
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-CI5hxW-O.js";import{formatTabular as r,selectFormat as i}from"./formatter-C4YSOKuq.js";import"./client-I4GTcUcm.js";import{openInBrowser as a}from"./open-url-dPoDcwsm.js";import"./theme-Brz9wK0w.js";import{useTheme as o}from"./panel-DB1HLxAw.js";import"./banner-MAYlzjcP.js";import"./prompt-D7Ek9MYk.js";import"./keybar-BcHUm3hI.js";import"./chat-panel-dXLm3hUn.js";import{resolveSiteId as s}from"./resolve-site-DYBsBK4c.js";import{DataTable as c}from"./data-table-BvnWCG-w.js";import{deepLinkFor as l}from"./keybar-deep-link-Dagnpllp.js";import{runAnalyticalScreen as u}from"./analytical-screen-BrOFDrQ_.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(`
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-CI5hxW-O.js";import{formatTabular as r,selectFormat as i}from"./formatter-C4YSOKuq.js";import"./client-I4GTcUcm.js";import"./theme-Brz9wK0w.js";import{useTheme as a}from"./panel-DB1HLxAw.js";import"./banner-MAYlzjcP.js";import"./prompt-D7Ek9MYk.js";import"./keybar-BcHUm3hI.js";import"./chat-panel-dXLm3hUn.js";import{resolveSiteId as o}from"./resolve-site-DYBsBK4c.js";import{DataTable as s}from"./data-table-BvnWCG-w.js";import{runAnalyticalScreen as c}from"./analytical-screen-BrOFDrQ_.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(`
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-CI5hxW-O.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
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-CI5hxW-O.js";import{requireTier as r}from"./tier-BneaO4vD.js";import{confirmDestructive as i}from"./confirm-DS5wux0g.js";import{fmtDate as a,formatTable as o,shortId as s}from"./fmt-iR2sYwsO.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)+`
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-CI5hxW-O.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})+`
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-Brz9wK0w.js";import{useTheme as a}from"./panel-DB1HLxAw.js";import{Banner as o}from"./banner-MAYlzjcP.js";import"./progress-row-BS7fwhn_.js";import"./prompt-D7Ek9MYk.js";import"./keybar-BcHUm3hI.js";import"./sparkline-8ucKVUV7.js";import"./data-table-BvnWCG-w.js";import"./bar-DG-MqgGx.js";import"./ui-DXrdVAc-.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)+`
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-Brz9wK0w.js";import{Panel as e,useTheme as t}from"./panel-DB1HLxAw.js";import{Banner as n}from"./banner-MAYlzjcP.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(`────────────────────────────────────────────────────
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-oUMOH7u2.js";import"./formatter-C4YSOKuq.js";import{emit$1 as i,isHeadless as a}from"./emit-D4YlMlzk.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
+ 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-CI5hxW-O.js";import{requireTier as r}from"./tier-BneaO4vD.js";import"./formatter-C4YSOKuq.js";import{emit$1 as i,isHeadless as a}from"./emit-D4YlMlzk.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{resolveSiteId as d}from"./resolve-site-DYBsBK4c.js";import{DataTable as f}from"./data-table-BvnWCG-w.js";import{EmptyState as p}from"./empty-state-DdLBcz4h.js";import{deepLinkFor as m}from"./keybar-deep-link-Dagnpllp.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
+ 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-CI5hxW-O.js";import{fmtDate as r,fmtNumber as i}from"./fmt-iR2sYwsO.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)+`
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-C4YSOKuq.js";import{emitEnvelope as i,wrapSnapshot as a}from"./emit-D4YlMlzk.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.
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-CI5hxW-O.js";import{formatTabular as r,selectFormat as i}from"./formatter-C4YSOKuq.js";import"./client-I4GTcUcm.js";import{openInBrowser as a}from"./open-url-dPoDcwsm.js";import"./theme-Brz9wK0w.js";import{useTheme as o}from"./panel-DB1HLxAw.js";import"./banner-MAYlzjcP.js";import"./prompt-D7Ek9MYk.js";import"./keybar-BcHUm3hI.js";import{brailleSpark as s,spark as c}from"./sparkline-8ucKVUV7.js";import"./chat-panel-dXLm3hUn.js";import{resolveSiteId as l}from"./resolve-site-DYBsBK4c.js";import{DataTable as u}from"./data-table-BvnWCG-w.js";import{deepLinkFor as d}from"./keybar-deep-link-Dagnpllp.js";import{runAnalyticalScreen as f}from"./analytical-screen-BrOFDrQ_.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(`
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-CI5hxW-O.js";import{formatTabular as r,selectFormat as i}from"./formatter-C4YSOKuq.js";import"./client-I4GTcUcm.js";import{openInBrowser as a}from"./open-url-dPoDcwsm.js";import"./theme-Brz9wK0w.js";import{useTheme as o}from"./panel-DB1HLxAw.js";import"./banner-MAYlzjcP.js";import"./prompt-D7Ek9MYk.js";import"./keybar-BcHUm3hI.js";import"./chat-panel-dXLm3hUn.js";import{resolveSiteId as s}from"./resolve-site-DYBsBK4c.js";import{DataTable as c}from"./data-table-BvnWCG-w.js";import{deepLinkFor as l}from"./keybar-deep-link-Dagnpllp.js";import{runAnalyticalScreen as u}from"./analytical-screen-BrOFDrQ_.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(`
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-CI5hxW-O.js";import{confirmDestructive as i}from"./confirm-DS5wux0g.js";import"./formatter-C4YSOKuq.js";import{emitEnvelope as a,wrapItem as o,wrapList as s}from"./emit-D4YlMlzk.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)+`
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-CI5hxW-O.js";import"./theme-Brz9wK0w.js";import{Panel as r,useTheme as i}from"./panel-DB1HLxAw.js";import{Banner as a}from"./banner-MAYlzjcP.js";import"./progress-row-BS7fwhn_.js";import"./prompt-D7Ek9MYk.js";import"./keybar-BcHUm3hI.js";import"./sparkline-8ucKVUV7.js";import"./data-table-BvnWCG-w.js";import"./bar-DG-MqgGx.js";import"./ui-DXrdVAc-.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.
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};
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import(`./init-awEnG3zC.js`).then(async({initCommand:e})=>{let{readFileSync:t}=await import(`node:fs`),n=await import(`node:path`),{fileURLToPath:r}=await import(`node:url`),i=n.dirname(r(import.meta.url)),a=JSON.parse(t(n.join(i,`..`,`package.json`),`utf8`)),o=process.argv.slice(2),s=o.includes(`--json`),c=o.includes(`--yes`),l=o.includes(`--skip-mcp`),u=o.includes(`--skip-verify`),d=await e({cliVersion:a.version,cwd:process.cwd(),json:s,yes:c,skipMcp:l,skipVerify:u});process.exit(d)});
2
+ import(`./init-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.65",
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};