@zenovay/cli 0.1.34 → 0.1.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -0
- package/dist/{agency-DEixFVRT.js → agency-Ba8f5PMP.js} +1 -1
- package/dist/ai-Dz_MAHHV.js +11 -0
- package/dist/alerts-qoMz5CX-.js +3 -0
- package/dist/{analytical-screen-BpTK5dCY.js → analytical-screen-BGMW3z_2.js} +1 -1
- package/dist/analytics-5ztZSLLH.js +1 -0
- package/dist/api-CJnD6Auw.js +1 -0
- package/dist/api-keys-D85DV2qg.js +4 -0
- package/dist/api-v2-CfYUL93L.js +1 -0
- package/dist/{api-v2-B_kZhVxd.js → api-v2-UJJ6ube8.js} +1 -1
- package/dist/{apply-D2xZJdvQ.js → apply-oUMOH7u2.js} +1 -1
- package/dist/{audit-CfOJ3rNW.js → audit-DqPlGP-B.js} +1 -1
- package/dist/{banner-BPQh2F8l.js → banner-gVm7GaJF.js} +1 -1
- package/dist/{bar-BNmNGwlD.js → bar-BPHTpgfb.js} +1 -1
- package/dist/bin.js +5 -3
- package/dist/{commands-DbkdKFGz.js → commands-BrU-VT7M.js} +1 -1
- package/dist/companies-CH3F-hmU.js +2 -0
- package/dist/completions-Ba0Zr-G3.js +135 -0
- package/dist/{config-Cmi_f_SY.js → config-CG7B8fR0.js} +1 -1
- package/dist/config-CUWIr4Qh.js +1 -0
- package/dist/{data-table-BUyOP6Nc.js → data-table-BnWXIW9M.js} +1 -1
- package/dist/deploys-B79-S9yT.js +2 -0
- package/dist/devices-BQnWRrD3.js +1 -0
- package/dist/{doctor-K37xh3M7.js → doctor-DjmsSn5Z.js} +1 -1
- package/dist/domains-Bg3Tt8bm.js +8 -0
- package/dist/emit-B8RbnBJe.js +2 -0
- package/dist/{empty-state-Dkho-_3J.js → empty-state-BkS6DKWZ.js} +1 -1
- package/dist/error-codes-CCK850J9.js +2 -0
- package/dist/errors-CmbIkaPX.js +2 -0
- package/dist/{events-tail-CXJUK5ka.js → events-tail-CE5QxNmF.js} +1 -1
- package/dist/examples-B8b7EpXo.js +1 -0
- package/dist/export-CNhqB2nk.js +4 -0
- package/dist/{funnel-nm9X3Od7.js → funnel-4A9Q_ZCD.js} +1 -1
- package/dist/geo-BAXdGLKJ.js +1 -0
- package/dist/globe-DMOyP2MN.js +2 -0
- package/dist/goals-B32fvItX.js +7 -0
- package/dist/health-CAnAYv9x.js +1 -0
- package/dist/health-DAyE161Z.js +1 -0
- package/dist/heatmaps-DkY7BW0E.js +1 -0
- package/dist/home-DL_Ty0eK.js +2 -0
- package/dist/init-C13-OX68.js +79 -0
- package/dist/init-C8KOSKzO.js +1 -0
- package/dist/insights-BDxlGN5s.js +1 -0
- package/dist/{integrations-B6IO1dM0.js → integrations-Eu2LbV95.js} +1 -1
- package/dist/journeys-CQMP6cvE.js +1 -0
- package/dist/{keybar-C7YkmK1U.js → keybar-BYQ2Bam1.js} +1 -1
- package/dist/live-BO8Wl0Q3.js +1 -0
- package/dist/login-CYaCSVUe.js +1 -0
- package/dist/login-D2ll-nBp.js +2 -0
- package/dist/logout-Cp7T5T1Y.js +2 -0
- package/dist/{metric-card-BRHv93Un.js → metric-card-DHIjVzNg.js} +1 -1
- package/dist/{notes-Cepz-K00.js → notes-BsegG0Q-.js} +1 -1
- package/dist/pages-Bi57FO27.js +1 -0
- package/dist/{plans-D8aqF_lo.js → plans-BXm8QsVF.js} +1 -1
- package/dist/{profile-DQJdZ-s_.js → profile-GGQyYHdV.js} +1 -1
- package/dist/{progress-row-DFOvHAc5.js → progress-row-C7gQLX4T.js} +1 -1
- package/dist/projects-t5f3WFmw.js +2 -0
- package/dist/{prompt-BURfUNxp.js → prompt-Db9Y7CVt.js} +1 -1
- package/dist/query-BmeQkD1w.js +8 -0
- package/dist/resolve-site-CZEwJoBj.js +2 -0
- package/dist/retention-6HhdWwsd.js +1 -0
- package/dist/revenue-CdXv5fdi.js +2 -0
- package/dist/secrets-A956dF9B.js +1 -0
- package/dist/secrets-BszMfkn1.js +1 -0
- package/dist/self-test-BSSwSeXl.js +4 -0
- package/dist/sessions-CvSKjWsw.js +1 -0
- package/dist/{settings-BsczzB3M.js → settings-CtEE3MFe.js} +1 -1
- package/dist/{share-BQjP_Anq.js → share-5a0qKu3z.js} +1 -1
- package/dist/sources-Dtp05gd2.js +2 -0
- package/dist/sparkline-BlAQSlYZ.js +1 -0
- package/dist/stats-DRRgb-C3.js +2 -0
- package/dist/{team-Bg-ggtky.js → team-q747Nwe6.js} +1 -1
- package/dist/{teams-Dvh7_Gkg.js → teams-nDIrOaly.js} +1 -1
- package/dist/{themes-CRvhjrRx.js → themes-DVChFf6Y.js} +1 -1
- package/dist/{tier-DyX4EObq.js → tier-uaU5pkTz.js} +1 -1
- package/dist/token-store-C1AqhmDP.js +1 -0
- package/dist/token-store-DpyCOgNw.js +1 -0
- package/dist/tour-Dp2WmQUO.js +8 -0
- package/dist/{update-DWBRR_PD.js → update-DrsZLYAQ.js} +1 -1
- package/dist/uptime-Bmg-epd-.js +1 -0
- package/dist/usage-ZJK4hekT.js +3 -0
- package/dist/use-SGwWI1Rq.js +3 -0
- package/dist/visitors-D7FmGVz1.js +2 -0
- package/dist/vitals-CRE0nVgp.js +2 -0
- package/dist/watch-DeWYzdo4.js +1 -0
- package/dist/webhooks-Ck6zBgz3.js +10 -0
- package/dist/webhooks-forward-X4iUnLrU.js +3 -0
- package/dist/wizard-bin.js +1 -1
- package/dist/{ws-client-_BBjvKCb.js → ws-client-Cp_nIj_N.js} +1 -1
- package/package.json +2 -2
- package/dist/ai-B8r28ZBm.js +0 -11
- package/dist/analytics-DZpf8Q9f.js +0 -1
- package/dist/api-CeB_9iPg.js +0 -1
- package/dist/api-keys-DsQR075b.js +0 -7
- package/dist/companies-BToqUnFi.js +0 -2
- package/dist/completions-CXAOfyWo.js +0 -113
- package/dist/deploys-CgNr5r7M.js +0 -2
- package/dist/devices-C8xVqaBs.js +0 -1
- package/dist/domains-Bfx2vdwv.js +0 -11
- package/dist/emit-DBbMG9mK.js +0 -1
- package/dist/errors-BXwphY11.js +0 -2
- package/dist/geo-BaCNZ7-S.js +0 -1
- package/dist/globe-B4iKPH4T.js +0 -2
- package/dist/goals-D1qL286b.js +0 -10
- package/dist/health-ChZuTNP2.js +0 -1
- package/dist/health-DfgPNC1A.js +0 -1
- package/dist/heatmaps-e1Q72VWJ.js +0 -1
- package/dist/home-CtsY-gj0.js +0 -2
- package/dist/init-BVUEPvVr.js +0 -62
- package/dist/init-CJ1Py9a8.js +0 -1
- package/dist/insights-wx3wIgGV.js +0 -1
- package/dist/journeys-zPmCha98.js +0 -1
- package/dist/live-k32y1phk.js +0 -1
- package/dist/login-BSDS_gNS.js +0 -1
- package/dist/login-B_CW06vS.js +0 -1
- package/dist/logout-1ohk4uie.js +0 -2
- package/dist/pages-CAYP4Abn.js +0 -1
- package/dist/projects-BC8pmo7u.js +0 -2
- package/dist/query-X38xyHCI.js +0 -8
- package/dist/resolve-site-BUpzvcMz.js +0 -2
- package/dist/retention-DQPI6wVN.js +0 -1
- package/dist/revenue-CD1YwoZj.js +0 -2
- package/dist/sessions-Dv-Z29cQ.js +0 -1
- package/dist/sources-DL_o-kkA.js +0 -2
- package/dist/sparkline-Bkfzqe4x.js +0 -1
- package/dist/stats-DRy2d3At.js +0 -2
- package/dist/uptime-DACm8Hdh.js +0 -1
- package/dist/usage-BhLXHEkY.js +0 -3
- package/dist/use-DJ0b_xNo.js +0 -5
- package/dist/visitors-CrF-_BuG.js +0 -2
- package/dist/vitals-lpeK0mbA.js +0 -2
- package/dist/watch-BMrHdnHX.js +0 -1
- package/dist/webhooks-Ddhz2P7n.js +0 -15
- package/dist/webhooks-forward-BUoKx2Dz.js +0 -3
- /package/dist/{check-Comj8AkL.js → check-D9G0N7NB.js} +0 -0
- /package/dist/{client-WzSy90dG.js → client-CN2wyAL7.js} +0 -0
- /package/dist/{confirm-D_aKHknn.js → confirm-Dk3CEdpn.js} +0 -0
- /package/dist/{fmt-DSJbiH8w.js → fmt-CdJ3NqAG.js} +0 -0
- /package/dist/{formatter-mW0Yk3Nt.js → formatter-KOe_hjhc.js} +0 -0
- /package/dist/{globe-BrlflaZ1.js → globe-WYN8kVDK.js} +0 -0
- /package/dist/{panel-uygscwY5.js → panel-jycoT562.js} +0 -0
- /package/dist/{ui-BRls3_H3.js → ui-hZ5oXnwY.js} +0 -0
- /package/dist/{wrapper-BgssVzXH.js → wrapper-Ce_PZUZ9.js} +0 -0
package/README.md
CHANGED
|
@@ -39,6 +39,41 @@ Every command supports `--json` / `--ndjson` for piping. Auto-detects `CI=true`
|
|
|
39
39
|
- Changelog: https://cli.zenovay.com/changelog
|
|
40
40
|
- Feedback: https://cli.zenovay.com/feedback
|
|
41
41
|
|
|
42
|
+
## Local Development
|
|
43
|
+
|
|
44
|
+
### Prerequisites
|
|
45
|
+
|
|
46
|
+
- Node.js 20 or 22 (CI matrix runs on both)
|
|
47
|
+
- npm 10+
|
|
48
|
+
- A Zenovay account is **not** required for most work — local dev runs against test fixtures, and `zenovay login` only matters when you exercise the device-flow OAuth against the real api.
|
|
49
|
+
|
|
50
|
+
### Quick start
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
git clone git@github.com:zenovay/cli-zenovay.git
|
|
54
|
+
cd cli-zenovay
|
|
55
|
+
npm install
|
|
56
|
+
npm run dev # tsx src/bin.ts — runs the CLI from source
|
|
57
|
+
npm run dev -- health
|
|
58
|
+
npm run dev -- watch
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Common commands
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm run dev # Run CLI from source via tsx
|
|
65
|
+
npm run typecheck # Strict TypeScript
|
|
66
|
+
npm run lint # ESLint
|
|
67
|
+
npm run build # tsdown bundle
|
|
68
|
+
npm test # Vitest unit tests
|
|
69
|
+
npm run test:all # unit + integration + security corpus
|
|
70
|
+
npm run smoke # End-to-end smoke against a built binary
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Releases
|
|
74
|
+
|
|
75
|
+
cli-zenovay ships actual versioned npm releases via the gold-standard `release.yml` workflow (semver, signed binaries, multi-stage approval, post-deploy smoke). Releases are triggered by tagging `v*.*.*`. **Read `CLAUDE.md` §"PUBLISH SAFETY"** before any `npm publish` — the dry-run-then-publish protocol is mandatory.
|
|
76
|
+
|
|
42
77
|
## Status
|
|
43
78
|
|
|
44
79
|
**Private repository.** Compiled binaries are public; source is not.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-UJJ6ube8.js";import{requireTier as r}from"./tier-uaU5pkTz.js";import{confirmDestructive as i}from"./confirm-Dk3CEdpn.js";function a(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}function o(e){return e?new Date(e).toISOString().slice(0,10):`—`}async function s(s){let c=await e(),l=await t({strict:!1}),u=new n({config:c,cliVersion:s.cliVersion,token:l});try{await r(u,`scale`)}catch(e){return process.stderr.write(`✗ ${e.message}\n`),2}try{switch(s.action){case`clients-list`:{let{clients:e}=await u.listAgencyClients();if(s.json)return process.stdout.write(JSON.stringify({clients:e},null,2)+`
|
|
2
2
|
`),0;if(e.length===0)return process.stdout.write("No clients yet. Add one with `zenovay agency clients add --name <n> --email <e>`.\n"),0;let t=[14,30,30,12],n=e=>e.map((e,n)=>(e??``).padEnd(t[n])).join(` `);process.stdout.write(`
|
|
3
3
|
`+n([`id`,`name`,`domain`,`created`])+`
|
|
4
4
|
`),process.stdout.write(n(t.map(e=>`─`.repeat(e)))+`
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import{ApiClient as t}from"./api-CJnD6Auw.js";import{readToken as n}from"./token-store-C1AqhmDP.js";import{detectInstalled as r,initCommand as i}from"./init-C13-OX68.js";import{parseSseStream as a}from"./client-CN2wyAL7.js";import"./formatter-KOe_hjhc.js";import{emit as o,isHeadless as s}from"./emit-B8RbnBJe.js";import"./secrets-BszMfkn1.js";import"./login-D2ll-nBp.js";import{Panel as c}from"./panel-jycoT562.js";import"./banner-gVm7GaJF.js";import"./progress-row-C7gQLX4T.js";import{Select as l}from"./prompt-Db9Y7CVt.js";import"./keybar-BYQ2Bam1.js";import"./sparkline-BlAQSlYZ.js";import{Box as u,Text as d,render as f}from"ink";import p from"react";async function m(e){let t=await r(e.cwd),n;if(e.mode)n=e.mode;else if(!t.installed)n=`install`;else if(s(e))return o({type:`error`,code:`no_mode`,message:`Headless mode requires --mode chat|mcp|install`}),2;else n=await h(t);return n===`install`?i({cliVersion:e.cliVersion,cwd:e.cwd,json:e.json}):n===`chat`?g(e):_(e)}async function h(e){return new Promise(t=>{let n=[{label:`Chat with your analytics`,value:`chat`,description:`Ask natural-language questions about your data`},{label:`Manage via MCP`,value:`mcp`,description:`Create goals, funnels, sites, etc. in plain English`},{label:`Re-run install / repair`,value:`install`,description:`Run the install wizard again`}],{unmount:r}=f(p.createElement(u,{flexDirection:`column`},p.createElement(c,{title:`Zenovay detected${e.packageMarker?` (${e.packageMarker})`:``}`,state:`idle`},p.createElement(d,null,`What do you want to do?`)),p.createElement(l,{items:n,onSelect:e=>{r(),t(e)}})))})}async function g(r){let i=await e(),o=await n({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new t({config:i,cliVersion:r.cliVersion,token:o});process.stdout.write(`
|
|
2
|
+
Zenovay · chat mode — type your question then press Enter. Ctrl-C to exit.
|
|
3
|
+
|
|
4
|
+
> `);let c=await v();if(!c)return 0;let l=await s.openAiStream(`chat`,{messages:[{role:`user`,content:c}]});for await(let e of a(l)){if(e.type===`delta`&&process.stdout.write(e.content),e.type===`done`){process.stdout.write(`
|
|
5
|
+
`);break}if(e.type===`error`)return process.stderr.write(`\n[${e.code}] ${e.message}\n`),1}return 0}async function _(r){let i=await e(),o=await n({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new t({config:i,cliVersion:r.cliVersion,token:o});process.stdout.write(`
|
|
6
|
+
Zenovay · MCP mode — describe what you want to create or change. Ctrl-C to exit.
|
|
7
|
+
|
|
8
|
+
> `);let c=await v();if(!c)return 0;let l=await s.openAiStream(`mcp`,{messages:[{role:`user`,content:c}]});for await(let e of a(l)){if(e.type===`delta`&&process.stdout.write(e.content),e.type===`tool_start`&&process.stdout.write(`\n[tool: ${e.name}] `),e.type===`tool_result`&&process.stdout.write(`
|
|
9
|
+
[result]`),e.type===`done`){process.stdout.write(`
|
|
10
|
+
`);break}if(e.type===`error`)return process.stderr.write(`\n[${e.code}] ${e.message}\n`),1}return 0}function v(){return new Promise(e=>{let t=``,n=r=>{let i=r.toString(`utf8`);i.includes(`
|
|
11
|
+
`)||i.includes(`\r`)?(t+=i.replace(/[\r\n]/g,``),process.stdin.off(`data`,n),process.stdin.pause(),e(t)):t+=i};process.stdin.resume(),process.stdin.on(`data`,n)})}export{m as aiCommand};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{emitErrorEnvelope as n}from"./error-codes-CCK850J9.js";import{ApiV2Client as r}from"./api-v2-UJJ6ube8.js";import{confirmDestructive as i}from"./confirm-Dk3CEdpn.js";import"./formatter-KOe_hjhc.js";import{emitEnvelope as a,wrapItem as o,wrapList as s}from"./emit-B8RbnBJe.js";import{Panel as c}from"./panel-jycoT562.js";import{Banner as l}from"./banner-gVm7GaJF.js";import"./prompt-Db9Y7CVt.js";import{resolveSiteId as u}from"./resolve-site-CZEwJoBj.js";import{fmtDate as d,shortId as f}from"./fmt-CdJ3NqAG.js";import{DataTable as p}from"./data-table-BnWXIW9M.js";import{Box as m,Text as h,render as g}from"ink";import _ from"react";const v=new Set([`visitors`,`pageviews`,`bounce_rate`,`avg_session_duration`,`errors`,`lcp`,`inp`,`cls`,`uptime`,`revenue`]),y=/^\d+(m|h|d)$/;function b(e){let t=e.metric;if(!t)return{errorMessage:"--metric is required for `alerts create`."};if(!v.has(t))return{errorMessage:`--metric must be one of: ${[...v].join(`, `)}. Got: ${t}.`};let n=e.op;if(n!==`gt`&&n!==`lt`)return{errorMessage:"--op must be `gt` or `lt`."};let r=e.threshold,i=typeof r==`number`?r:Number(r);if(!Number.isFinite(i))return{errorMessage:`--threshold must be a number.`};let a=e.window;return!a||!y.test(a)?{errorMessage:"--window must match `<n>m|h|d` (e.g. 5m, 1h, 7d)."}:{body:{metric:t,op:n,threshold:i,window:a}}}async function x(c){let l=await e(),d=await t({strict:!1}),p=new r({config:l,cliVersion:c.cliVersion,token:d}),m;try{({siteId:m}=await u(p,{explicit:c.siteId,headless:!!c.json,cliVersion:c.cliVersion}))}catch(e){return c.json?n(e,{command:`alerts`,cliVersion:c.cliVersion}):(process.stderr.write(`${e.message}\n`),2)}try{switch(c.action){case`list`:{let e=await p.listAlerts(m);return c.json?(a(s(e,`alerts.list`,{siteId:m,cliVersion:c.cliVersion,command:`alerts list`})),0):e.length===0?(process.stdout.write("No alerts yet. Create one with `zenovay alerts create --metric <m> --op <gt|lt> --threshold <n> --window <1h>`.\n"),0):w(e,m,c.cliVersion)}case`create`:{let e=b(c);if(`errorMessage`in e)return c.json?n(new S(e.errorMessage),{command:`alerts create`,cliVersion:c.cliVersion}):(process.stderr.write(`Error: ${e.errorMessage}\n`),2);let t=await p.createAlert(m,e.body);return c.json?(a(o(t,`alerts.created`,{siteId:m,cliVersion:c.cliVersion,command:`alerts create`})),0):(process.stdout.write(`\n ✓ Alert created: ${t.metric} ${t.op} ${t.threshold} over ${t.window}\n id: ${t.id}\n\n`),0)}case`delete`:{if(!c.id){let e="alert id is required for `alerts delete`.";return c.json?n(new S(e),{command:`alerts delete`,cliVersion:c.cliVersion}):(process.stderr.write(`Error: ${e}\n`),2)}let e;try{let t=await p.listAlerts(m);e=t.find(e=>e.id===c.id)}catch{}let t=e?`${e.metric} ${e.op} ${e.threshold} (${f(c.id)})`:f(c.id),r=await i({resource:`alert`,name:t,yes:c.yes,destructive:!0});return r?(await p.deleteAlert(m,c.id),c.json?(a(o({deleted:!0,id:c.id},`alerts.deleted`,{siteId:m,cliVersion:c.cliVersion,command:`alerts delete`})),0):(process.stdout.write(`✓ Alert deleted (${f(c.id)}). Notifications stopped immediately.\n`),0)):c.json?(process.stdout.write(JSON.stringify({cancelled:!0})+`
|
|
2
|
+
`),1):(process.stdout.write(`Cancelled.
|
|
3
|
+
`),1)}}}catch(e){return c.json?n(e,{command:`alerts ${c.action}`,cliVersion:c.cliVersion}):(process.stderr.write(`✗ ${e.message}\n`),1)}}var S=class extends Error{constructor(e){super(e),this.name=`ValidationError`}};const C=({items:e,siteId:t,cliVersion:n})=>{let r=[{key:`id`,label:`id`,width:14,format:e=>f(String(e))},{key:`metric`,label:`metric`,width:18},{key:`op`,label:`op`,width:3},{key:`threshold`,label:`threshold`,width:10,align:`right`,format:e=>String(e??``)},{key:`window`,label:`window`,width:7},{key:`createdAt`,label:`created`,width:10,format:e=>d(e)}];return _.createElement(m,{flexDirection:`column`},_.createElement(l,{version:n,subtitle:`alerts · ${t}`}),_.createElement(c,{title:`${e.length} alert${e.length===1?``:`s`}`,state:`idle`},_.createElement(p,{columns:r,data:e,headerStyle:`accent`}),_.createElement(m,{marginTop:1},_.createElement(h,{color:`gray`},`Create: zenovay alerts create --metric <m> --op <gt|lt> --threshold <n> --window <1h>`))))};function w(e,t,n){return new Promise(r=>{let i=g(_.createElement(C,{items:e,siteId:t,cliVersion:n}));setTimeout(()=>{i.unmount(),r(0)},50)})}export{x as alertsCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ApiError as e}from"./api-
|
|
1
|
+
import{ApiError as e}from"./api-CJnD6Auw.js";import{formatEvent as t}from"./formatter-KOe_hjhc.js";import{Panel as n}from"./panel-jycoT562.js";import{Banner as r}from"./banner-gVm7GaJF.js";import{Keybar as i}from"./keybar-BYQ2Bam1.js";import{Box as a,Text as o,render as s,useApp as c,useInput as l}from"ink";import u,{useEffect as d,useMemo as f,useReducer as p,useRef as m}from"react";import h from"ink-spinner";function g(e,t){switch(t.type){case`set`:return{...e,data:t.data,status:`ready`,error:null};case`merge`:{let n=e.data?{...e.data,...t.partial}:t.partial;return{...e,data:n,status:`ready`,error:null}}case`error`:return{...e,status:`error`,error:{message:t.message,status:t.status,upgradeUrl:t.upgradeUrl}};case`refresh`:return{...e,refreshTick:e.refreshTick+1};case`focus`:return{...e,focusIndex:t.index};case`help-toggle`:return{...e,showHelp:!e.showHelp};default:return e}}async function _(e,n){let r=new AbortController,i=()=>r.abort();process.on(`SIGINT`,i);try{let i=await e.fetcher(r.signal);if(e.headlessEmit?e.headlessEmit(i,n):process.stdout.write(t(i,n)),e.streamer)for await(let i of e.streamer(r.signal))process.stdout.write(t(i,n));return 0}catch(e){if(e.name===`AbortError`)return 0;let t=e.message;return process.stderr.write(`${t}\n`),1}finally{process.off(`SIGINT`,i)}}const v=({cliVersion:e})=>u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:e,subtitle:`login required`}),u.createElement(n,{title:`Not logged in`,state:`warn`},u.createElement(o,null,`You need to authenticate before running this command.`),u.createElement(o,null,` `),u.createElement(o,{color:`gray`},`Run `),u.createElement(o,{color:`cyan`},`zenovay login`),u.createElement(o,{color:`gray`},` to start the device-flow.`)));function y(t){let{exit:s}=c(),[_,v]=p(g,{data:null,status:`loading`,error:null,refreshTick:0,focusIndex:0,showHelp:!1}),y=m(v);y.current=v;let b=f(()=>({q:{label:`quit`,handler:()=>{s(),t.onExit(0)}},r:{label:`refresh`,handler:()=>y.current({type:`refresh`})},"?":{label:`help`,handler:()=>y.current({type:`help-toggle`})}}),[s,t]),x=f(()=>({...t.keybindings??{},...b}),[t.keybindings,b]);if(l((e,n)=>{if(n.tab&&n.shift){v({type:`focus`,index:(_.focusIndex-1+t.panels.length)%t.panels.length});return}if(n.tab){v({type:`focus`,index:(_.focusIndex+1)%t.panels.length});return}if(e>=`1`&&e<=`9`){let n=Number(e)-1;n<t.panels.length&&v({type:`focus`,index:n});return}let r=x[e];r&&r.handler()}),d(()=>{let n=new AbortController,r=!1,i=async()=>{try{let e=await t.fetcher(n.signal);r||y.current({type:`set`,data:e})}catch(t){if(r)return;if(t instanceof e){if(t.status===402){let e=t.body,n=typeof e==`object`&&e&&`upgradeUrl`in e?e.upgradeUrl:void 0;y.current({type:`error`,message:`This command requires a higher plan.`,status:402,upgradeUrl:n});return}y.current({type:`error`,message:t.message,status:t.status});return}if(t.name===`AbortError`)return;y.current({type:`error`,message:t.message})}};i();let a=null,o=t.refreshIntervalMs??15e3;return o>0&&!t.streamer&&(a=setInterval(i,o)),()=>{r=!0,n.abort(),a&&clearInterval(a)}},[t.fetcher,t.refreshIntervalMs,t.streamer,_.refreshTick]),d(()=>{if(!t.streamer)return;let e=new AbortController,n=!1;return(async()=>{try{for await(let r of t.streamer(e.signal)){if(n)return;y.current({type:`merge`,partial:r})}}catch(e){if(n||e.name===`AbortError`)return;y.current({type:`error`,message:e.message})}})(),()=>{n=!0,e.abort()}},[t.streamer]),_.status===`loading`&&_.data===null)return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(n,{title:`Loading`,state:`busy`},u.createElement(a,null,u.createElement(o,{color:`magenta`},u.createElement(h,{type:`dots`})),u.createElement(o,null,` Fetching `,t.commandName,`…`))),u.createElement(i,{items:[{key:`q`,label:`quit`}]}));if(_.status===`error`&&_.error){let e=_.error.status===402;return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(n,{title:e?`Upgrade required`:`Error`,state:e?`warn`:`err`},u.createElement(o,{color:e?`yellow`:`red`},_.error.message),e&&_.error.upgradeUrl?u.createElement(u.Fragment,null,u.createElement(o,null,` `),u.createElement(o,{color:`gray`},`Upgrade: `),u.createElement(o,{color:`cyan`},_.error.upgradeUrl)):null),u.createElement(i,{items:[{key:`r`,label:`retry`},{key:`q`,label:`quit`}]}))}let S=_.data,C=Object.entries(x).map(([e,t])=>({key:e,label:t.label})),w=Math.ceil(t.panels.length/2),T=t.panels.slice(0,w),E=t.panels.slice(w);return u.createElement(a,{flexDirection:`column`},u.createElement(r,{version:t.cliVersion,subtitle:t.title}),u.createElement(a,{flexDirection:`row`},T.map((e,t)=>{let r=_.focusIndex===t;return u.createElement(a,{key:e.id,flexDirection:`column`,marginRight:1,flexGrow:1},u.createElement(n,{title:e.title,state:r?`busy`:`idle`},e.render(S,r)))})),E.length>0?u.createElement(a,{flexDirection:`row`},E.map((e,t)=>{let r=t+w,i=_.focusIndex===r;return u.createElement(a,{key:e.id,flexDirection:`column`,marginRight:1,flexGrow:1},u.createElement(n,{title:e.title,state:i?`busy`:`idle`},e.render(S,i)))})):null,_.showHelp?u.createElement(n,{title:`Help`,state:`idle`},Object.entries(x).map(([e,t])=>u.createElement(o,{key:e},`[`,e,`] `,t.label)),u.createElement(o,{color:`gray`},`[tab/shift+tab] cycle focus [1-9] focus panel`)):null,u.createElement(i,{items:C}))}async function b(e){return e.authToken===null?e.format?(process.stderr.write("Not logged in — run `zenovay login` first.\n"),2):new Promise(t=>{let{unmount:n}=s(u.createElement(v,{cliVersion:e.cliVersion}));setTimeout(()=>{n(),t(2)},50)}):e.format?_(e,e.format):new Promise(t=>{let{unmount:n}=s(u.createElement(y,{...e,onExit:e=>{n(),t(e)}}))})}export{b as runAnalyticalScreen};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-UJJ6ube8.js";import"./formatter-KOe_hjhc.js";import{emit as r,isHeadless as i}from"./emit-B8RbnBJe.js";import{Panel as a}from"./panel-jycoT562.js";import{Banner as o}from"./banner-gVm7GaJF.js";import"./prompt-Db9Y7CVt.js";import{Keybar as s}from"./keybar-BYQ2Bam1.js";import"./sparkline-BlAQSlYZ.js";import{resolveSiteId as c}from"./resolve-site-CZEwJoBj.js";import{stripUrlPrefix as l}from"./fmt-CdJ3NqAG.js";import{DataTable as u}from"./data-table-BnWXIW9M.js";import{EmptyState as d}from"./empty-state-BkS6DKWZ.js";import{MetricCard as f}from"./metric-card-DHIjVzNg.js";import{Bar as p}from"./bar-BPHTpgfb.js";import{Box as m,Text as h,render as g,useApp as _,useInput as v}from"ink";import y,{useEffect as b,useState as x}from"react";import S from"ink-spinner";async function C(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await T(l,u,`24h`);return r({type:`overview.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=g(y.createElement(E,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}function w(e){return e===`24h`?`7d`:e}async function T(e,t,n){let[r,i,a,o,s]=await Promise.all([e.getStats(t,n).catch(()=>null),e.getPages(t).catch(()=>[]),e.getSources(t,w(n),`prev`).catch(()=>null),e.getGeo(t).catch(()=>null),e.getDevices(t).catch(()=>null)]),c=i.reduce((e,t)=>e+t.views,0),l=(r?.daily??[]).map(e=>e.visitors),u=(r?.daily??[]).map(e=>e.pageviews),d=Math.floor(l.length/2),f=l.slice(0,d).reduce((e,t)=>e+t,0),p=u.slice(0,d).reduce((e,t)=>e+t,0),m=(a?.sources??[]).filter(e=>e.channel!==`other`||!e.source.includes(`/`)).slice(0,6).map(e=>({name:e.source,visitors:e.visitors,delta:e.delta??null}));return{visitors:r?.visitors??0,pageviews:r?.pageviews??c,bounceRate:r?.bounceRate??null,avgSession:r?.avgSessionSec??null,series:l,pageviewsSeries:u,prevVisitors:f,prevPageviews:p,topPages:i.slice(0,10),channels:m,countries:(o?.countries??[]).slice(0,8),browsers:(s?.browsers??[]).slice(0,5),devices:(s?.devices??[]).slice(0,5)}}const E=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=_(),[g,C]=x(null),[w,E]=x(!0),[D,O]=x(null),[k,A]=x(`24h`),[j,M]=x(t),[N,P]=x(n),[F,I]=x(!1),[L,R]=x([]);v(async t=>{if(t===`q`){c(),i(0);return}if(t===`1`){A(`24h`);return}if(t===`2`){A(`7d`);return}if(t===`3`){A(`30d`);return}if(t===`4`){A(`90d`);return}if(t===`s`){if(L.length===0)try{let t=await e.getSites();R(t)}catch{}I(e=>!e);return}}),b(()=>{let t=!1;return E(!0),(async()=>{try{let n=await T(e,j,k);t||(C(n),E(!1))}catch(e){t||(O(e.message),E(!1))}})(),()=>{t=!0}},[e,j,k]);let z=()=>y.createElement(a,{title:`Switch site`,state:`idle`},L.length===0?y.createElement(h,{color:`gray`},`Loading your sites…`):L.map(e=>y.createElement(m,{key:e.id},y.createElement(h,{color:e.id===j?`cyan`:`gray`},e.id===j?`› `:` `),y.createElement(h,{bold:e.id===j},e.name),y.createElement(h,{color:`gray`},` (`,e.url.replace(/^https?:\/\//,``).replace(/\/$/,``),`)`))),y.createElement(m,{marginTop:1},y.createElement(h,{color:`gray`},`Press `),y.createElement(h,{color:`cyan`},`[number]`),y.createElement(h,{color:`gray`},` to pick, `),y.createElement(h,{color:`cyan`},`[s]`),y.createElement(h,{color:`gray`},` to close.`)));v(e=>{if(!F)return;let t=Number(e);if(Number.isInteger(t)&&t>=1&&t<=L.length){let e=L[t-1];M(e.id),P(e.url.replace(/^https?:\/\//,``).replace(/\/$/,``)),I(!1)}},{isActive:F});let B=`overview · ${N} · ${k}`,V=[{key:`q`,label:`quit`},{key:`s`,label:`site`},{key:`1-4`,label:`range (24h/7d/30d/90d)`}];if(w)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:B}),y.createElement(a,{title:`Loading`,state:`busy`},y.createElement(m,null,y.createElement(h,{color:`cyan`},y.createElement(S,{type:`dots`})),y.createElement(h,null,` Fetching dashboard…`))),F?z():null);if(D)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:B}),y.createElement(d,{reason:`error`,headline:`Failed to load`,hint:D}),F?z():null,y.createElement(s,{items:V}));if(!g||g.visitors===0&&g.pageviews===0&&g.topPages.length===0)return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:B}),y.createElement(d,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event — or press [s] to switch to a different site, or [1-4] to widen the time range.`}),F?z():null,y.createElement(s,{items:V}));let H=process.stdout.columns??80,U=Math.max(18,Math.floor(H/4)-1),W=Math.max(28,Math.floor(H/2)-2),G=[{key:`path`,label:`path`,width:32,format:e=>l(String(e??``))},{key:`views`,label:`views`,align:`right`,width:8},{key:`uniqueVisitors`,label:`visitors`,align:`right`,width:8},{key:`avgTime`,label:`avg time`,align:`right`,width:9,format:e=>typeof e==`number`?`${Math.round(e/1e3)}s`:`—`},{key:`bounceRate`,label:`bounce`,align:`right`,width:7,format:e=>typeof e==`number`?`${(e*100).toFixed(0)}%`:`—`}],K=g.prevVisitors>0?(g.visitors-g.prevVisitors)/g.prevVisitors:void 0,q=g.prevPageviews>0?(g.pageviews-g.prevPageviews)/g.prevPageviews:void 0,J=Math.max(1,...g.channels.map(e=>e.visitors)),Y=Math.max(1,...g.countries.map(e=>e.visitors)),X=Math.max(1,...g.browsers.map(e=>e.visitors)),Z=Math.max(1,...g.devices.map(e=>e.visitors)),Q=Math.max(8,Math.floor(W/3));return y.createElement(m,{flexDirection:`column`},y.createElement(o,{version:r,subtitle:B}),y.createElement(m,{flexDirection:`row`},y.createElement(f,{title:`Visitors`,value:g.visitors,format:`number`,width:U,series:g.series,...typeof K==`number`?{delta:K}:{}}),y.createElement(f,{title:`Pageviews`,value:g.pageviews,format:`number`,width:U,series:g.pageviewsSeries,...typeof q==`number`?{delta:q}:{}}),y.createElement(f,{title:`Bounce rate`,value:g.bounceRate??``,emptyHint:`—`,format:`percent`,width:U}),y.createElement(f,{title:`Avg session`,value:g.avgSession??``,emptyHint:`—`,format:`duration`,width:U})),y.createElement(m,{flexDirection:`row`,flexWrap:`wrap`},y.createElement(m,{width:W,flexDirection:`column`},y.createElement(a,{title:`Channels`},g.channels.length===0?y.createElement(h,{color:`gray`},`No channel data yet.`):g.channels.map(e=>y.createElement(m,{key:e.name,flexDirection:`row`},y.createElement(m,{width:12},y.createElement(h,null,e.name)),y.createElement(p,{value:e.visitors,max:J,width:Q,showPercent:!1,...typeof e.delta==`number`?{delta:e.delta}:{}}),y.createElement(h,{color:`gray`},` `,e.visitors))))),y.createElement(m,{width:W,flexDirection:`column`},y.createElement(a,{title:`Top countries`},g.countries.length===0?y.createElement(h,{color:`gray`},`No geo data yet.`):g.countries.map(e=>y.createElement(m,{key:e.country,flexDirection:`row`},y.createElement(m,{width:5},y.createElement(h,null,e.country)),y.createElement(p,{value:e.visitors,max:Y,width:Q,showPercent:!1}),y.createElement(h,{color:`gray`},` `,e.visitors)))))),y.createElement(m,{flexDirection:`row`,flexWrap:`wrap`},y.createElement(m,{width:W,flexDirection:`column`},y.createElement(a,{title:`Top browsers`},g.browsers.length===0?y.createElement(h,{color:`gray`},`No browser data yet.`):g.browsers.map(e=>y.createElement(m,{key:e.name,flexDirection:`row`},y.createElement(m,{width:12},y.createElement(h,null,e.name)),y.createElement(p,{value:e.visitors,max:X,width:Q,showPercent:!1}),y.createElement(h,{color:`gray`},` `,e.visitors))))),y.createElement(m,{width:W,flexDirection:`column`},y.createElement(a,{title:`Top devices`},g.devices.length===0?y.createElement(h,{color:`gray`},`No device data yet.`):g.devices.map(e=>y.createElement(m,{key:e.name,flexDirection:`row`},y.createElement(m,{width:12},y.createElement(h,null,e.name)),y.createElement(p,{value:e.visitors,max:Z,width:Q,showPercent:!1}),y.createElement(h,{color:`gray`},` `,e.visitors)))))),y.createElement(a,{title:`Top pages (${k})`},g.topPages.length===0?y.createElement(h,{color:`gray`},`No pages with data in this window yet.`):y.createElement(u,{columns:G,data:g.topPages,zebra:!0})),F?z():null,y.createElement(s,{items:V}))};async function D(e){return C(e)}export{D as analyticsCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{clearToken as e,isExpired as t,readToken as n,writeToken as r}from"./token-store-C1AqhmDP.js";import{z as i}from"zod";const a=i.object({device_code:i.string(),user_code:i.string(),verification_uri:i.string().url(),verification_uri_complete:i.string().url().optional(),expires_in:i.number().int().positive(),interval:i.number().int().positive().default(5)}),o=i.object({access_token:i.string(),refresh_token:i.string(),token_type:i.literal(`Bearer`).default(`Bearer`),expires_in:i.number().int().positive(),scope:i.string().optional()}),s=i.object({error:i.enum([`authorization_pending`,`slow_down`,`access_denied`,`expired_token`,`invalid_client`,`invalid_grant`,`invalid_scope`]),error_description:i.string().optional()});async function c(e){let{apiBase:t,clientId:n=`cli-zenovay`,scope:r=`cli:full`}=e,i=e.fetchImpl??fetch,o=new URLSearchParams({client_id:n,scope:r}),s=await i(`${t}/oauth/device_authorization`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:o.toString()});if(!s.ok){let e=await s.text();throw Error(`Device authorization failed: ${s.status} ${e}`)}let c=await s.json();return a.parse(c)}async function l(e){let{apiBase:t,deviceCode:n,clientId:r=`cli-zenovay`,expiresIn:i}=e,a=e.fetchImpl??fetch,c=e.sleep??(e=>new Promise(t=>setTimeout(t,e))),l=e.interval,u=Date.now(),d=u+i*1e3;for(;Date.now()<d;){if(e.signal?.aborted)throw Error(`Polling aborted`);await c(l*1e3),e.onTick?.(Date.now()-u);let i=new URLSearchParams({grant_type:`urn:ietf:params:oauth:grant-type:device_code`,device_code:n,client_id:r}),d=await a(`${t}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:i.toString()}),f=await d.json().catch(()=>({}));if(d.ok){let e=o.parse(f);return{accessToken:e.access_token,refreshToken:e.refresh_token,expiresAt:Date.now()+e.expires_in*1e3,tokenType:`Bearer`,scope:e.scope}}let p=s.safeParse(f);if(!p.success)throw Error(`Token poll failed (${d.status}): ${JSON.stringify(f)}`);let{error:m}=p.data;if(m!==`authorization_pending`){if(m===`slow_down`){l=Math.min(l*2,30);continue}throw m===`access_denied`?Error(`Device authorization denied by user.`):m===`expired_token`?Error("Device code expired — run `zenovay login` again."):Error(`Device token error: ${m}`)}}throw Error("Device code expired — run `zenovay login` again.")}async function u(e){let r=await n({strict:!0});return r?t(r)?d(r,e):r:null}async function d(t,n){let{apiBase:i,clientId:a=`cli-zenovay`}=n,s=n.fetchImpl??fetch,c=new URLSearchParams({grant_type:`refresh_token`,refresh_token:t.refreshToken,client_id:a}),l=await s(`${i}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:c.toString()}),u=await l.json().catch(()=>({}));if(!l.ok){let t=u&&typeof u==`object`&&`error`in u?u.error:String(u);throw t===`invalid_grant`?(await e(),Error("Refresh token rejected by server — your session has been revoked. Run `zenovay login` again.")):Error(`Token refresh failed (${l.status}): ${JSON.stringify(u)}`)}let d=o.parse(u),f={...t,accessToken:d.access_token,refreshToken:d.refresh_token,expiresAt:Date.now()+d.expires_in*1e3,tokenType:`Bearer`,scope:d.scope??t.scope};return await r(f),f}const f=i.object({id:i.string(),name:i.string(),url:i.string().url(),trackingCode:i.string().optional(),lastActiveAt:i.string().nullable().optional()}),p=i.object({user:i.object({id:i.string(),email:i.string().email(),name:i.string().optional().nullable()}),team:i.object({id:i.string(),name:i.string(),plan:i.string()}).optional().nullable(),teams:i.array(i.object({id:i.string(),name:i.string(),plan:i.string(),role:i.string(),siteCount:i.number().int(),isCurrent:i.boolean()})).optional()});var m=class extends Error{constructor(e,t,n){super(n),this.status=e,this.body=t,this.name=`ApiError`}},h=class{fetchImpl;token;constructor(e){this.opts=e,this.fetchImpl=e.fetchImpl??fetch,this.token=e.token??null}get apiBase(){return this.opts.config.apiBase}async authedHeaders(e={}){let t=process.env.ZENOVAY_TEAM_ID,n=t&&t.trim()?{"X-Zenovay-Team-Id":t.trim()}:{},r=process.env.ZENOVAY_API_TOKEN;if(r&&r.trim())return{Accept:`application/json`,"User-Agent":`zenovay-cli/${this.opts.cliVersion}`,"X-Zenovay-CLI-Version":this.opts.cliVersion,Authorization:`Bearer ${r.trim()}`,...n,...e};this.token||=await u({apiBase:this.apiBase});let i={Accept:`application/json`,"User-Agent":`zenovay-cli/${this.opts.cliVersion}`,"X-Zenovay-CLI-Version":this.opts.cliVersion,...n,...e};return this.token&&(i.Authorization=`${this.token.tokenType} ${this.token.accessToken}`),i}async request(e,t){let n=`${this.apiBase}${e}`,r=await this.fetchImpl(n,{...t,headers:{...await this.authedHeaders(),...t.headers}});if(r.status===401&&this.token&&(this.token=null,r=await this.fetchImpl(n,{...t,headers:{...await this.authedHeaders(),...t.headers}})),!r.ok){let n=await r.text().catch(()=>``);throw new m(r.status,n,`${t.method??`GET`} ${e} → ${r.status}`)}let i=await r.json();return t.schema.parse(i)}async getSites(){return this.request(`/v1/cli/sites`,{schema:i.array(f)})}async createSite(e){return this.request(`/v1/cli/sites`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),schema:i.object({id:i.string()})})}async getFirstEvent(e){let t=new URLSearchParams({site_id:e.siteId,since:String(e.since)});return this.request(`/v1/cli/first-event?${t.toString()}`,{schema:i.object({received:i.boolean(),event:i.unknown().optional()})})}async me(){return this.request(`/v1/cli/me`,{schema:p})}async revokeCurrentToken(){this.token&&await this.fetchImpl(`${this.apiBase}/oauth/revoke`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`,...await this.authedHeaders()},body:new URLSearchParams({token:this.token.refreshToken,token_type_hint:`refresh_token`,client_id:`cli-zenovay`}).toString()})}async openAiStream(e,t,n){let r=await this.authedHeaders({"Content-Type":`application/json`,Accept:`text/event-stream`}),i=await this.fetchImpl(`${this.apiBase}/ai/cli/${e}`,{method:`POST`,headers:r,body:JSON.stringify(t),signal:n});if(!i.ok){let t=await i.text().catch(()=>``);throw new m(i.status,t,`POST /ai/cli/${e} → ${i.status}`)}return i}async openEventsStream(e,t){let n=await this.authedHeaders({Accept:`text/event-stream`}),r=await this.fetchImpl(`${this.apiBase}/v1/cli/events/tail?site_id=${e}`,{method:`GET`,headers:n,signal:t});if(!r.ok){let e=await r.text().catch(()=>``);throw new m(r.status,e,`GET events tail → ${r.status}`)}return r}async getDashboardSnapshot(e){return this.request(`/v1/cli/dashboard?site_id=${e}`,{schema:i.unknown()})}async ping(){let e=Date.now(),t=await this.fetchImpl(`${this.apiBase}/v1/cli/ping`,{headers:await this.authedHeaders()});if(!t.ok)throw new m(t.status,await t.text().catch(()=>``),`ping failed`);return{ok:!0,latencyMs:Date.now()-e}}};export{h as ApiClient,m as ApiError,u as ensureFreshToken,l as pollDeviceToken,c as startDeviceAuthorization};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{emitErrorEnvelope as n}from"./error-codes-CCK850J9.js";import{ApiV2Client as r}from"./api-v2-UJJ6ube8.js";import{confirmDestructive as i}from"./confirm-Dk3CEdpn.js";import"./formatter-KOe_hjhc.js";import{emitEnvelope as a,wrapItem as o,wrapList as s}from"./emit-B8RbnBJe.js";import{fmtDate as c,formatTable as l,shortId as u}from"./fmt-CdJ3NqAG.js";async function d(d){let f=await e(),p=await t({strict:!1}),m=new r({config:f,cliVersion:d.cliVersion,token:p});try{switch(d.action){case`list`:{let{keys:e}=await m.listApiKeys();if(d.json)return a(s(e,`api-keys.list`),{legacyKey:`keys`,legacyValue:e}),0;if(e.length===0)return process.stdout.write("No API keys yet. Create one with `zenovay api-keys create --name <n>`.\n"),0;let t=[{key:`isCurrent`,header:``,width:1,format:e=>e?`*`:` `},{key:`id`,header:`id`,width:14,format:e=>u(String(e))},{key:`name`,header:`name`,width:24,format:e=>String(e??``)},{key:`scope`,header:`scope`,width:6},{key:`createdAt`,header:`created`,width:10,format:e=>c(e)},{key:`lastUsedAt`,header:`last used`,width:19,format:e=>c(e,`datetime`)}];return process.stdout.write(l({rows:e,cols:t})),process.stdout.write(`
|
|
2
|
+
* = current CLI key
|
|
3
|
+
`),0}case`create`:{if(!d.name)return process.stderr.write("Error: --name is required for `api-keys create`.\n"),2;let e=d.scope===`write`?`write`:`read`,t=await m.createApiKey({name:d.name,scope:e});if(d.json)return a(o(t,`api-keys.item`)),0;let n=`═`.repeat(64);return process.stdout.write(`\n${n}\n API key created: ${t.name} (${t.scope})\n id: ${t.id}\n token: ${t.token}\n${n}\n\n ⚠ Save this token NOW — it will not be shown again.\n Use it via the Authorization header: "Bearer ${t.token}"\n\n`),0}case`delete`:{if(!d.id)return process.stderr.write("Error: api-key id is required for `api-keys delete`.\n"),2;let e=await i({resource:`API key`,name:u(d.id),yes:d.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
|
|
4
|
+
`),1;let t=await m.deleteApiKey(d.id);return d.json?(a(o(t,`api-keys.deleted`)),0):(process.stdout.write(`✔ Deleted API key ${u(d.id)}.\n`),0)}}}catch(e){return n(e,{command:`api-keys ${d.action}`})}}export{d as apiKeysCommand};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./config-CG7B8fR0.js";import{ApiError as e}from"./api-CJnD6Auw.js";import"./token-store-C1AqhmDP.js";import{ApiV2Client as t}from"./api-v2-UJJ6ube8.js";export{t as ApiV2Client};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ApiClient as e,ApiError as t,ensureFreshToken as n}from"./api-CeB_9iPg.js";import{z as r}from"zod";const i=r.object({id:r.string(),startedAt:r.string(),country:r.string().nullable().optional(),city:r.string().nullable().optional(),device:r.enum([`mobile`,`desktop`,`tablet`,`unknown`]).optional(),os:r.string().nullable().optional(),browser:r.string().nullable().optional(),page:r.string().optional(),referrer:r.string().nullable().optional(),utmSource:r.string().nullable().optional(),utmMedium:r.string().nullable().optional(),utmCampaign:r.string().nullable().optional(),aiScore:r.number().min(0).max(100).nullable().optional()}),a=r.object({visitors:r.array(i),total:r.number().int(),windowStart:r.string(),windowEnd:r.string()}),o=r.object({type:r.enum([`visitor.started`,`visitor.ended`,`visitor.heartbeat`]),visitor:i}),s=r.object({source:r.string(),channel:r.enum([`direct`,`organic`,`paid`,`social`,`referral`,`email`,`other`]).optional(),visitors:r.number().int(),conversions:r.number().int().optional(),revenue:r.number().int().optional(),delta:r.number().nullable().optional()}),c=r.object({sources:r.array(s),totalVisitors:r.number().int(),windowStart:r.string(),windowEnd:r.string()}),l=r.object({bucket:r.string(),amount:r.number().int(),currency:r.string(),transactions:r.number().int()}),u=r.object({series:r.array(l),totalAmount:r.number().int(),currency:r.string(),totalTransactions:r.number().int(),mrr:r.number().int().optional(),arpu:r.number().int().optional(),windowStart:r.string(),windowEnd:r.string()}),d=r.object({url:r.string(),device:r.enum([`mobile`,`desktop`]).optional(),lcp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),inp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),cls:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),ttfb:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),fcp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),samples:r.number().int()}),f=r.object({vitals:r.array(d),windowStart:r.string(),windowEnd:r.string()}),p=r.object({id:r.string(),name:r.string(),visitors:r.number().int(),conversions:r.number().int(),dropOff:r.number().min(0).max(1).optional()}),m=r.object({funnelId:r.string(),name:r.string(),steps:r.array(p),totalEntries:r.number().int(),totalCompletions:r.number().int(),conversionRate:r.number().min(0).max(1),windowStart:r.string(),windowEnd:r.string()}),h=r.object({id:r.string(),name:r.string(),stepCount:r.number().int(),lastEvaluatedAt:r.string().nullable().optional()}),g=r.object({funnels:r.array(h)}),_=r.object({visitors:r.number().int(),pageviews:r.number().int(),sessions:r.number().int(),bounceRate:r.number().min(0).max(1),avgSessionSec:r.number(),topPages:r.array(r.object({url:r.string(),views:r.number().int()})),topCountries:r.array(r.object({country:r.string(),visitors:r.number().int()})),windowStart:r.string(),windowEnd:r.string(),daily:r.array(r.object({date:r.string(),visitors:r.number().int(),pageviews:r.number().int()})).optional()}),v=r.object({id:r.string(),name:r.string(),type:r.enum([`event`,`pageview`,`revenue`]),conversions24h:r.number().int(),conversions7d:r.number().int()}),y=r.object({goals:r.array(v)}),b=r.object({id:r.string(),name:r.string(),domain:r.string().nullable().optional(),industry:r.string().nullable().optional(),employeeCount:r.number().int().nullable().optional(),visitorCount:r.number().int(),firstSeenAt:r.string(),lastSeenAt:r.string()}),x=r.object({type:r.enum([`company.identified`,`company.returning`]),company:b}),S=r.object({companies:r.array(b),total:r.number().int()}),C=r.object({type:r.literal(`error.captured`),id:r.string(),message:r.string(),stack:r.string().optional(),url:r.string().optional(),occurredAt:r.string(),count:r.number().int().optional(),spike:r.number().optional()}),w=r.object({id:r.string(),ts:r.string(),class:r.string(),message:r.string(),page:r.string().nullable(),device:r.string().nullable(),fingerprint:r.string().nullable()}),T=r.object({errors:r.array(w),total:r.number().int()}),E=r.object({id:r.string(),name:r.string(),domain:r.string().nullable(),industry:r.string().nullable(),employeeCount:r.number().int().nullable(),visitCount:r.number().int(),firstSeenAt:r.string(),lastSeenAt:r.string(),isNew:r.boolean()}),D=r.object({companies:r.array(E),total:r.number().int()}),O=r.object({columns:r.array(r.string()),rows:r.array(r.record(r.unknown())),row_count:r.number(),duration_ms:r.number(),truncated:r.boolean()}),k=r.object({id:r.string(),provider:r.literal(`github`),commit_sha:r.string(),commit_message:r.string().nullable(),commit_author:r.string().nullable(),branch:r.string().nullable(),repository:r.string().nullable(),commit_url:r.string().nullable(),pushed_at:r.string(),show_on_chart:r.boolean()}),A=r.object({deploys:r.array(k),total:r.number().int()}),j=r.object({id:r.string(),name:r.string(),domain:r.string().nullable(),tier:r.string(),pageviews24h:r.number().int(),isCurrent:r.boolean()}),M=r.object({projects:r.array(j)}),N=r.object({type:r.string(),bucket:r.string(),count:r.number().int()}),P=r.object({events:r.array(N),windowStart:r.string(),windowEnd:r.string()}),F=r.object({id:r.string(),receivedAt:r.string(),url:r.string(),method:r.string(),headers:r.record(r.string(),r.string()),body:r.string()}),I=r.object({columns:r.array(r.string()),rows:r.array(r.array(r.unknown())),rowCount:r.number().int(),durationMs:r.number(),truncated:r.boolean().optional()}),L=r.object({resource:r.string(),values:r.array(r.string()),cachedAt:r.string().optional()});function R(e,t){throw Error(`api-v2: ${e} not yet implemented; awaiting backend Wave ${t}`)}async function*z(e,t){R(e,t)}function B(e){switch(e){case`24h`:return 1;case`7d`:return 7;case`30d`:return 30;case`90d`:return 90;case`1y`:return 365;default:return 7}}var V=class extends e{v2Opts;v2Fetch;v2Token;constructor(e){super(e),this.v2Opts=e,this.v2Fetch=e.fetchImpl??fetch,this.v2Token=e.token??null}get v2ApiBase(){return this.v2Opts.config.apiBase}async v2Headers(e={}){let t=process.env.ZENOVAY_TEAM_ID,r=t&&t.trim()?{"X-Zenovay-Team-Id":t.trim()}:{},i=process.env.ZENOVAY_API_TOKEN;if(i&&i.trim())return{Accept:`application/json`,"User-Agent":`zenovay-cli/${this.v2Opts.cliVersion}`,"X-Zenovay-CLI-Version":this.v2Opts.cliVersion,Authorization:`Bearer ${i.trim()}`,...r,...e};this.v2Token||=await n({apiBase:this.v2ApiBase});let a={Accept:`application/json`,"User-Agent":`zenovay-cli/${this.v2Opts.cliVersion}`,"X-Zenovay-CLI-Version":this.v2Opts.cliVersion,...r,...e};return this.v2Token&&(a.Authorization=`${this.v2Token.tokenType} ${this.v2Token.accessToken}`),a}async v2Request(e,n,r={},i){let a=`${this.v2ApiBase}${e}`,o=await this.v2Headers(r.headers??{}),s=await this.v2Fetch(a,{...r,headers:o,signal:i});if(s.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers(r.headers??{});s=await this.v2Fetch(a,{...r,headers:e,signal:i})}if(!s.ok){let n=await s.text().catch(()=>``),i=n;try{i=JSON.parse(n)}catch{}throw new t(s.status,i,`${r.method??`GET`} ${e} → ${s.status}`)}let c=await s.json();return n.parse(c)}async v2RequestRaw(e,n={},r){let i=`${this.v2ApiBase}${e}`,a=await this.v2Headers(n.headers??{}),o=await this.v2Fetch(i,{...n,headers:a,signal:r});if(o.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers(n.headers??{});o=await this.v2Fetch(i,{...n,headers:e,signal:r})}if(!o.ok){let r=await o.text().catch(()=>``),i=r;try{i=JSON.parse(r)}catch{}throw new t(o.status,i,`${n.method??`GET`} ${e} → ${o.status}`)}let s=await o.json();return s?.data??s}async getVisitors(e,t,n){let r=new URLSearchParams({site_id:e});t?.since&&r.set(`since`,t.since),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/visitors?${r.toString()}`,{},n),o=new Date,s=new Date(Date.now()-24*3600*1e3),c=e=>{if(!e)return`unknown`;let t=e.toLowerCase();return t.includes(`mobile`)?`mobile`:t.includes(`tablet`)?`tablet`:t.includes(`desktop`)?`desktop`:`unknown`};return a.parse({total:i.liveCount??i.visitors?.length??0,visitors:(i.visitors??[]).map(e=>({id:e.sessionId,startedAt:e.lastSeen,country:e.country,city:null,device:c(e.device??null),page:e.currentPath??void 0,aiScore:typeof e.valueScore==`number`?Math.max(0,Math.min(100,e.valueScore)):null})),windowStart:s.toISOString(),windowEnd:o.toISOString()})}streamVisitors(e,t){return this.streamChannel(e,`visitors`,t)}async getSources(e,t=`30d`,n,r){let i=new URLSearchParams({site_id:e,period:t});n&&i.set(`compare`,n);let a=await this.v2RequestRaw(`/v1/cli/sources?${i.toString()}`,{},r),o=a.channels??[],s=a.top_utm_sources??[],l=o.reduce((e,t)=>e+t.visitors,0),u=new Set([`direct`,`organic`,`paid`,`social`,`referral`,`email`]),d=[...o.map(e=>({source:e.name,channel:u.has(e.name)?e.name:`other`,visitors:e.visitors,delta:typeof e.delta==`number`?e.delta/100:null})),...s.map(e=>({source:e.medium?`${e.source}/${e.medium}`:e.source,channel:`other`,visitors:e.visitors}))],f=new Date,p=new Date(Date.now()-B(t)*24*3600*1e3);return c.parse({sources:d,totalVisitors:l,windowStart:p.toISOString(),windowEnd:f.toISOString()})}async getRevenue(e,t=`30d`,n){let r=new URLSearchParams({site_id:e,window:t}),i=await this.v2RequestRaw(`/v1/cli/revenue?${r.toString()}`,{},n),a=(i.daily??[]).map(e=>({bucket:e.date,amount:e.cents,currency:i.currency??`USD`,transactions:e.transactions})),o=a.reduce((e,t)=>e+t.amount,0),s=a.reduce((e,t)=>e+t.transactions,0),c=new Date,l=new Date(Date.now()-B(t)*24*3600*1e3),d={series:a,totalAmount:o,currency:i.currency??`USD`,totalTransactions:s,windowStart:l.toISOString(),windowEnd:c.toISOString()};return typeof i.mrr_cents==`number`&&(d.mrr=i.mrr_cents),u.parse(d)}async getVitals(e,t,n){let r=new URLSearchParams({site_id:e});t?.url&&r.set(`url`,t.url),t?.device&&r.set(`device`,t.device),t?.window&&r.set(`window`,t.window);let i=await this.v2RequestRaw(`/v1/cli/vitals?${r.toString()}`,{},n),a=[];if(i.p75&&(i.sample_count??0)>0){let e=i.p75,n={url:`— site-wide aggregate —`,device:t?.device??void 0,samples:i.sample_count??0,...typeof e.lcp==`number`?{lcp:{p50:e.lcp,p75:e.lcp,p90:e.lcp}}:{},...typeof e.inp==`number`?{inp:{p50:e.inp,p75:e.inp,p90:e.inp}}:{},...typeof e.cls==`number`?{cls:{p50:e.cls,p75:e.cls,p90:e.cls}}:{},...typeof e.fcp==`number`?{fcp:{p50:e.fcp,p75:e.fcp,p90:e.fcp}}:{},...typeof e.ttfb==`number`?{ttfb:{p50:e.ttfb,p75:e.ttfb,p90:e.ttfb}}:{}};a.push(n)}for(let e of i.worst_pages??[])a.push({url:e.path,device:t?.device??void 0,samples:e.sample_count,lcp:{p50:e.lcp_p75,p75:e.lcp_p75,p90:e.lcp_p75}});let o=new Date,s=new Date(Date.now()-B(t?.window??`7d`)*24*3600*1e3);return f.parse({vitals:a,windowStart:s.toISOString(),windowEnd:o.toISOString()})}async getFunnel(e,t,n=`30d`,r){let i=new URLSearchParams({site_id:e,window:n}),a=await this.v2RequestRaw(`/v1/cli/funnels/${encodeURIComponent(t)}?${i.toString()}`,{},r),o=a.total_entries??0,s=(a.steps??[]).map(e=>({id:`step-${e.order}`,name:e.name,visitors:e.visitors,conversions:e.visitors,dropOff:Math.max(0,Math.min(1,e.dropoffPct/100))})),c=s[s.length-1],l=c?.visitors??0,u=o>0?Math.min(1,l/o):0,d=new Date,f=new Date(Date.now()-B(n)*24*3600*1e3);return m.parse({funnelId:a.id??t,name:a.name??t,steps:s,totalEntries:o,totalCompletions:l,conversionRate:u,windowStart:f.toISOString(),windowEnd:d.toISOString()})}async listFunnels(e,t){let n=new URLSearchParams({site_id:e}),r=await this.v2RequestRaw(`/v1/cli/funnels?${n.toString()}`,{},t);return g.parse({funnels:(r.funnels??[]).map(e=>({id:e.id,name:e.name,stepCount:e.step_count}))})}async getStats(e,t=`24h`,n){let r=new URLSearchParams({site_id:e,range:t}),i=await this.v2RequestRaw(`/v1/cli/stats?${r.toString()}`,{},n),a=i.visitors??0,o=i.pageviews??0,s=a,c=s>0?o/s:0,l=c>0?Math.max(0,Math.min(1,1/Math.max(1,c))):0,u=i.avgSessionSec??0,d=new Date,f=new Date(Date.now()-B(t)*24*3600*1e3);return _.parse({visitors:a,pageviews:o,sessions:s,bounceRate:l,avgSessionSec:u,topPages:i.topPage?[{url:i.topPage.path,views:i.topPage.views}]:[],topCountries:i.topSource?[{country:i.topSource.channel,visitors:i.topSource.visitors}]:[],windowStart:f.toISOString(),windowEnd:d.toISOString(),daily:i.daily})}async getGoals(e,t){let n=new URLSearchParams({site_id:e});return this.v2Request(`/v1/cli/goals?${n.toString()}`,y,{},t)}async getLive(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/live?${n.toString()}`,t)}async getPages(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/pages?${n.toString()}`,t)}async getDevices(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/devices?${n.toString()}`,t)}async getGeo(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/geo?${n.toString()}`,t)}async getRetention(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/retention?${n.toString()}`,t)}async getUptime(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/uptime?${n.toString()}`,t)}async getSessions(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/sessions?${n.toString()}`,t)}async getHeatmaps(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/heatmaps?${n.toString()}`,t)}async getJourneys(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/journeys?${n.toString()}`,t)}async getInsights(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/insights?${n.toString()}`,t)}async v2RawJson(e,n){let r=`${this.v2ApiBase}${e}`,i=await this.v2Headers(),a=await this.v2Fetch(r,{headers:i,signal:n});if(a.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers();a=await this.v2Fetch(r,{headers:e,signal:n})}if(!a.ok){let n=await a.text().catch(()=>``),r=n;try{r=JSON.parse(n)}catch{}throw new t(a.status,r,`GET ${e} → ${a.status}`)}return a.json()}streamCompaniesV2(e,t){return this.streamChannel(e,`companies`,t)}streamCompanies(e,t){return z(`streamCompanies`,2)}async getCompanies(e){R(`getCompanies`,2)}async getCompaniesSnapshot(e,t,n){let r=new URLSearchParams({site_id:e});t?.window&&r.set(`window`,t.window),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/companies?${r.toString()}`,{},n);return D.parse(i)}async runSqlQuery(e,n,r,i){let a=`${this.v2ApiBase}/v1/cli/query`,o=await this.v2Headers({"Content-Type":`application/json`}),s=await this.v2Fetch(a,{method:`POST`,headers:o,signal:i,body:JSON.stringify({site_id:e,sql:n,...r?.maxRows?{max_rows:r.maxRows}:{}})});if(!s.ok){let e=await s.text().catch(()=>``),n=e;try{n=JSON.parse(e)}catch{}throw new t(s.status,n,`POST /v1/cli/query → ${s.status}`)}let c=await s.json();return O.parse(c.data??c)}async getDeploys(e,t,n){let r=new URLSearchParams({site_id:e});t?.since&&r.set(`since`,t.since),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit)),t?.branch&&r.set(`branch`,t.branch),t?.onChartOnly&&r.set(`on_chart_only`,`true`);let i=await this.v2RequestRaw(`/v1/cli/deploys?${r.toString()}`,{},n);return A.parse(i)}async getProjects(e,t){let n=new URLSearchParams({site_id:e}),r=await this.v2RequestRaw(`/v1/cli/projects?${n.toString()}`,{},t);return M.parse(r)}async getErrors(e,t,n){let r=new URLSearchParams({site_id:e});t?.window&&r.set(`window`,t.window),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/errors?${r.toString()}`,{},n);return T.parse(i)}streamErrorsV2(e,t){return this.streamChannel(e,`errors`,t)}streamErrors(e,t){return z(`streamErrors`,2)}async getEventsHistory(e,t){R(`getEventsHistory`,2)}forwardWebhook(e,t){return z(`forwardWebhook`,2)}async registerTunnel(e,t){R(`registerTunnel`,2)}async queryRaw(e,t,n){R(`queryRaw`,3)}async getCompletions(e,t){R(`getCompletions`,3)}async listApiKeys(e){return await this.v2RawJson(`/v1/cli/mutate/keys`,e)}async createApiKey(e,t){return await this.v2Mutate(`/v1/cli/mutate/keys`,`POST`,e,t)}async deleteApiKey(e,t){return await this.v2Mutate(`/v1/cli/mutate/keys/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async addDomain(e,t){return await this.v2Mutate(`/v1/cli/mutate/domains`,`POST`,e,t)}async deleteDomain(e,t){return await this.v2Mutate(`/v1/cli/mutate/domains/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async listTeam(e){return await this.v2RawJson(`/v1/cli/mutate/team`,e)}async inviteTeamMember(e,t){return await this.v2Mutate(`/v1/cli/mutate/team/invite`,`POST`,e,t)}async removeTeamMember(e,t){return await this.v2Mutate(`/v1/cli/mutate/team/members/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async updateTeamMemberRole(e,t,n){return await this.v2Mutate(`/v1/cli/mutate/team/members/${encodeURIComponent(e)}/role`,`PATCH`,{role:t},n)}async updateProfile(e,t){return await this.v2Mutate(`/v1/cli/mutate/profile`,`POST`,e,t)}async getPlanInfo(e){return await this.v2RawJson(`/v1/cli/mutate/plans/info`,e)}async upgradePlan(e,t){return await this.v2Mutate(`/v1/cli/mutate/plans/upgrade`,`POST`,{targetPlan:e},t)}async cancelPlan(e){return await this.v2Mutate(`/v1/cli/mutate/plans/cancel`,`POST`,{},e)}async getSettings(e){return await this.v2RawJson(`/v1/cli/mutate/settings`,e)}async getUsage(e){return await this.v2RawJson(`/v1/cli/mutate/usage`,e)}async setSetting(e,t,n){return await this.v2Mutate(`/v1/cli/mutate/settings`,`POST`,{key:e,value:t},n)}async listIntegrations(e){return await this.v2RawJson(`/v1/cli/mutate/integrations`,e)}async disconnectIntegration(e,t){return await this.v2Mutate(`/v1/cli/mutate/integrations/disconnect`,`POST`,{name:e},t)}async listGoals(e){return await this.v2RawJson(`/v1/cli/mutate/goals`,e)}async createGoal(e,t){return await this.v2Mutate(`/v1/cli/mutate/goals`,`POST`,e,t)}async deleteGoal(e,t){return await this.v2Mutate(`/v1/cli/mutate/goals/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async listNotes(e){return await this.v2RawJson(`/v1/cli/mutate/notes`,e)}async createNote(e,t){return await this.v2Mutate(`/v1/cli/mutate/notes`,`POST`,e,t)}async deleteNote(e,t){return await this.v2Mutate(`/v1/cli/mutate/notes/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async listAgencyClients(e){return await this.v2RawJson(`/v1/cli/mutate/agency/clients`,e)}async addAgencyClient(e,t){return await this.v2Mutate(`/v1/cli/mutate/agency/clients`,`POST`,e,t)}async removeAgencyClient(e,t){return await this.v2Mutate(`/v1/cli/mutate/agency/clients/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async sendAgencyReport(e,t){return await this.v2Mutate(`/v1/cli/mutate/agency/report/${encodeURIComponent(e)}`,`POST`,{},t)}async listWebhooks(e){return await this.v2RawJson(`/v1/cli/mutate/webhooks`,e)}async createWebhook(e,t){return await this.v2Mutate(`/v1/cli/mutate/webhooks`,`POST`,e,t)}async deleteWebhook(e,t){return await this.v2Mutate(`/v1/cli/mutate/webhooks/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async rotateWebhookSecret(e,t){return await this.v2Mutate(`/v1/cli/mutate/webhooks/${encodeURIComponent(e)}/rotate`,`POST`,{},t)}async testWebhook(e,t){return await this.v2Mutate(`/v1/cli/mutate/webhooks/${encodeURIComponent(e)}/test`,`POST`,{},t)}async getAuditLogs(e,t){let n=new URLSearchParams;e.since&&n.set(`since`,e.since),e.action&&n.set(`action`,e.action),e.actor&&n.set(`actor`,e.actor);let r=n.toString()?`/v1/cli/mutate/audit/logs?${n.toString()}`:`/v1/cli/mutate/audit/logs`;return await this.v2RawJson(r,t)}async exportAudit(e,n){let r=`${this.v2ApiBase}/v1/cli/mutate/audit/export?format=${encodeURIComponent(e.format)}`,i=await this.v2Headers(),a=await this.v2Fetch(r,{headers:i,signal:n});if(a.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers();a=await this.v2Fetch(r,{headers:e,signal:n})}if(!a.ok){let e=await a.text().catch(()=>``),n=e;try{n=JSON.parse(e)}catch{}throw new t(a.status,n,`GET /v1/cli/mutate/audit/export → ${a.status}`)}return a.text()}async getShare(e,t){let n=new URLSearchParams({siteId:e});return await this.v2RawJson(`/v1/cli/mutate/share?${n.toString()}`,t)}async enableShare(e,t){return await this.v2Mutate(`/v1/cli/mutate/share/enable`,`POST`,{siteId:e},t)}async disableShare(e,t){return await this.v2Mutate(`/v1/cli/mutate/share/disable`,`POST`,{siteId:e},t)}async v2Mutate(e,n,r,i){let a=`${this.v2ApiBase}${e}`,o=await this.v2Headers(r===void 0?{}:{"Content-Type":`application/json`}),s={method:n,headers:o,signal:i};r!==void 0&&(s.body=JSON.stringify(r));let c=await this.v2Fetch(a,s);if(c.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers(r===void 0?{}:{"Content-Type":`application/json`});c=await this.v2Fetch(a,{...s,headers:e})}if(!c.ok){let r=await c.text().catch(()=>``),i=r;try{i=JSON.parse(r)}catch{}throw new t(c.status,i,`${n} ${e} → ${c.status}`)}let l=c.headers.get(`content-type`)??``;return l.includes(`application/json`)?c.json():{}}async*streamChannel(e,t,n){let{connectWs:r}=await import(`./ws-client-_BBjvKCb.js`),i=this.v2ApiBase.replace(/^https:\/\//,`wss://`).replace(/^http:\/\//,`ws://`),a=`${i}/v1/cli/stream/${encodeURIComponent(e)}?channels=${t}`,o=this.v2Token?.accessToken;for await(let e of r({url:a,bearer:o,signal:n})){if(e.type!==`message`)continue;let t=e.data;if(t&&typeof t==`object`){let e=t;yield e.event??t}}}async createTunnel(e,n,r){let i=`${this.v2ApiBase}/v1/cli/tunnels`,a=await this.v2Headers({"Content-Type":`application/json`}),o=await this.v2Fetch(i,{method:`POST`,headers:a,signal:r,body:JSON.stringify({site_id:e,target_pattern:n})});if(!o.ok){let e=await o.text().catch(()=>``);throw new t(o.status,e,`POST /v1/cli/tunnels → ${o.status}`)}let s=await o.json(),c=s.data??{};if(!c.tunnel_key||!c.public_url||!c.ws_url)throw new t(500,s,`createTunnel: malformed response`);return{tunnelKey:c.tunnel_key,publicUrl:c.public_url,wsUrl:c.ws_url,siteId:c.site_id??e}}tunnelClient(e){let t=this.v2Token?.accessToken;return{start:async(n,r)=>{let{WsTunnelClient:i}=await import(`./ws-client-_BBjvKCb.js`),a=new i({url:e,bearer:t,signal:r});await a.start(n)}}}};export{V as ApiV2Client};
|
|
1
|
+
import{ApiClient as e,ApiError as t,ensureFreshToken as n}from"./api-CJnD6Auw.js";import{z as r}from"zod";const i=r.object({id:r.string(),startedAt:r.string(),country:r.string().nullable().optional(),city:r.string().nullable().optional(),device:r.enum([`mobile`,`desktop`,`tablet`,`unknown`]).optional(),os:r.string().nullable().optional(),browser:r.string().nullable().optional(),page:r.string().optional(),referrer:r.string().nullable().optional(),utmSource:r.string().nullable().optional(),utmMedium:r.string().nullable().optional(),utmCampaign:r.string().nullable().optional(),aiScore:r.number().min(0).max(100).nullable().optional()}),a=r.object({visitors:r.array(i),total:r.number().int(),windowStart:r.string(),windowEnd:r.string()}),o=r.object({type:r.enum([`visitor.started`,`visitor.ended`,`visitor.heartbeat`]),visitor:i}),s=r.object({source:r.string(),channel:r.enum([`direct`,`organic`,`paid`,`social`,`referral`,`email`,`other`]).optional(),visitors:r.number().int(),conversions:r.number().int().optional(),revenue:r.number().int().optional(),delta:r.number().nullable().optional()}),c=r.object({sources:r.array(s),totalVisitors:r.number().int(),windowStart:r.string(),windowEnd:r.string()}),l=r.object({bucket:r.string(),amount:r.number().int(),currency:r.string(),transactions:r.number().int()}),u=r.object({series:r.array(l),totalAmount:r.number().int(),currency:r.string(),totalTransactions:r.number().int(),mrr:r.number().int().optional(),arpu:r.number().int().optional(),windowStart:r.string(),windowEnd:r.string()}),d=r.object({url:r.string(),device:r.enum([`mobile`,`desktop`]).optional(),lcp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),inp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),cls:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),ttfb:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),fcp:r.object({p50:r.number(),p75:r.number(),p90:r.number()}).optional(),samples:r.number().int()}),f=r.object({vitals:r.array(d),windowStart:r.string(),windowEnd:r.string()}),p=r.object({id:r.string(),name:r.string(),visitors:r.number().int(),conversions:r.number().int(),dropOff:r.number().min(0).max(1).optional()}),m=r.object({funnelId:r.string(),name:r.string(),steps:r.array(p),totalEntries:r.number().int(),totalCompletions:r.number().int(),conversionRate:r.number().min(0).max(1),windowStart:r.string(),windowEnd:r.string()}),h=r.object({id:r.string(),name:r.string(),stepCount:r.number().int(),lastEvaluatedAt:r.string().nullable().optional()}),g=r.object({funnels:r.array(h)}),_=r.object({visitors:r.number().int(),pageviews:r.number().int(),sessions:r.number().int(),bounceRate:r.number().min(0).max(1),avgSessionSec:r.number(),topPages:r.array(r.object({url:r.string(),views:r.number().int()})),topCountries:r.array(r.object({country:r.string(),visitors:r.number().int()})),windowStart:r.string(),windowEnd:r.string(),daily:r.array(r.object({date:r.string(),visitors:r.number().int(),pageviews:r.number().int()})).optional()}),v=r.object({id:r.string(),name:r.string(),type:r.enum([`event`,`pageview`,`revenue`]),conversions24h:r.number().int(),conversions7d:r.number().int()}),y=r.object({goals:r.array(v)}),b=r.object({id:r.string(),name:r.string(),domain:r.string().nullable().optional(),industry:r.string().nullable().optional(),employeeCount:r.number().int().nullable().optional(),visitorCount:r.number().int(),firstSeenAt:r.string(),lastSeenAt:r.string()}),x=r.object({type:r.enum([`company.identified`,`company.returning`]),company:b}),S=r.object({companies:r.array(b),total:r.number().int()}),C=r.object({type:r.literal(`error.captured`),id:r.string(),message:r.string(),stack:r.string().optional(),url:r.string().optional(),occurredAt:r.string(),count:r.number().int().optional(),spike:r.number().optional()}),w=r.object({id:r.string(),ts:r.string(),class:r.string(),message:r.string(),page:r.string().nullable(),device:r.string().nullable(),fingerprint:r.string().nullable()}),T=r.object({errors:r.array(w),total:r.number().int()}),E=r.object({id:r.string(),name:r.string(),domain:r.string().nullable(),industry:r.string().nullable(),employeeCount:r.number().int().nullable(),visitCount:r.number().int(),firstSeenAt:r.string(),lastSeenAt:r.string(),isNew:r.boolean()}),D=r.object({companies:r.array(E),total:r.number().int()}),O=r.object({columns:r.array(r.string()),rows:r.array(r.record(r.unknown())),row_count:r.number(),duration_ms:r.number(),truncated:r.boolean()}),k=r.object({id:r.string(),provider:r.literal(`github`),commit_sha:r.string(),commit_message:r.string().nullable(),commit_author:r.string().nullable(),branch:r.string().nullable(),repository:r.string().nullable(),commit_url:r.string().nullable(),pushed_at:r.string(),show_on_chart:r.boolean()}),A=r.object({deploys:r.array(k),total:r.number().int()}),j=r.object({id:r.string(),name:r.string(),domain:r.string().nullable(),tier:r.string(),pageviews24h:r.number().int(),isCurrent:r.boolean()}),M=r.object({projects:r.array(j)}),N=r.object({type:r.string(),bucket:r.string(),count:r.number().int()}),P=r.object({events:r.array(N),windowStart:r.string(),windowEnd:r.string()}),F=r.object({id:r.string(),receivedAt:r.string(),url:r.string(),method:r.string(),headers:r.record(r.string(),r.string()),body:r.string()}),I=r.object({columns:r.array(r.string()),rows:r.array(r.array(r.unknown())),rowCount:r.number().int(),durationMs:r.number(),truncated:r.boolean().optional()}),L=r.object({resource:r.string(),values:r.array(r.string()),cachedAt:r.string().optional()});function R(e,t){throw Error(`api-v2: ${e} not yet implemented; awaiting backend Wave ${t}`)}async function*z(e,t){R(e,t)}function B(e){switch(e){case`24h`:return 1;case`7d`:return 7;case`30d`:return 30;case`90d`:return 90;case`1y`:return 365;default:return 7}}var V=class extends e{v2Opts;v2Fetch;v2Token;constructor(e){super(e),this.v2Opts=e,this.v2Fetch=e.fetchImpl??fetch,this.v2Token=e.token??null}get v2ApiBase(){return this.v2Opts.config.apiBase}async v2Headers(e={}){let t=process.env.ZENOVAY_TEAM_ID,r=t&&t.trim()?{"X-Zenovay-Team-Id":t.trim()}:{},i=process.env.ZENOVAY_API_TOKEN;if(i&&i.trim())return{Accept:`application/json`,"User-Agent":`zenovay-cli/${this.v2Opts.cliVersion}`,"X-Zenovay-CLI-Version":this.v2Opts.cliVersion,Authorization:`Bearer ${i.trim()}`,...r,...e};this.v2Token||=await n({apiBase:this.v2ApiBase});let a={Accept:`application/json`,"User-Agent":`zenovay-cli/${this.v2Opts.cliVersion}`,"X-Zenovay-CLI-Version":this.v2Opts.cliVersion,...r,...e};return this.v2Token&&(a.Authorization=`${this.v2Token.tokenType} ${this.v2Token.accessToken}`),a}async v2Request(e,n,r={},i){let a=`${this.v2ApiBase}${e}`,o=await this.v2Headers(r.headers??{}),s=await this.v2Fetch(a,{...r,headers:o,signal:i});if(s.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers(r.headers??{});s=await this.v2Fetch(a,{...r,headers:e,signal:i})}if(!s.ok){let n=await s.text().catch(()=>``),i=n;try{i=JSON.parse(n)}catch{}throw new t(s.status,i,`${r.method??`GET`} ${e} → ${s.status}`)}let c=await s.json();return n.parse(c)}async v2RequestRaw(e,n={},r){let i=`${this.v2ApiBase}${e}`,a=await this.v2Headers(n.headers??{}),o=await this.v2Fetch(i,{...n,headers:a,signal:r});if(o.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers(n.headers??{});o=await this.v2Fetch(i,{...n,headers:e,signal:r})}if(!o.ok){let r=await o.text().catch(()=>``),i=r;try{i=JSON.parse(r)}catch{}throw new t(o.status,i,`${n.method??`GET`} ${e} → ${o.status}`)}let s=await o.json();return s?.data??s}async getVisitors(e,t,n){let r=new URLSearchParams({site_id:e});t?.since&&r.set(`since`,t.since),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/visitors?${r.toString()}`,{},n),o=new Date,s=new Date(Date.now()-24*3600*1e3),c=e=>{if(!e)return`unknown`;let t=e.toLowerCase();return t.includes(`mobile`)?`mobile`:t.includes(`tablet`)?`tablet`:t.includes(`desktop`)?`desktop`:`unknown`};return a.parse({total:i.liveCount??i.visitors?.length??0,visitors:(i.visitors??[]).map(e=>({id:e.sessionId,startedAt:e.lastSeen,country:e.country,city:null,device:c(e.device??null),page:e.currentPath??void 0,aiScore:typeof e.valueScore==`number`?Math.max(0,Math.min(100,e.valueScore)):null})),windowStart:s.toISOString(),windowEnd:o.toISOString()})}streamVisitors(e,t){return this.streamChannel(e,`visitors`,t)}async getSources(e,t=`30d`,n,r){let i=new URLSearchParams({site_id:e,period:t});n&&i.set(`compare`,n);let a=await this.v2RequestRaw(`/v1/cli/sources?${i.toString()}`,{},r),o=a.channels??[],s=a.top_utm_sources??[],l=o.reduce((e,t)=>e+t.visitors,0),u=new Set([`direct`,`organic`,`paid`,`social`,`referral`,`email`]),d=[...o.map(e=>({source:e.name,channel:u.has(e.name)?e.name:`other`,visitors:e.visitors,delta:typeof e.delta==`number`?e.delta/100:null})),...s.map(e=>({source:e.medium?`${e.source}/${e.medium}`:e.source,channel:`other`,visitors:e.visitors}))],f=new Date,p=new Date(Date.now()-B(t)*24*3600*1e3);return c.parse({sources:d,totalVisitors:l,windowStart:p.toISOString(),windowEnd:f.toISOString()})}async getRevenue(e,t=`30d`,n){let r=new URLSearchParams({site_id:e,window:t}),i=await this.v2RequestRaw(`/v1/cli/revenue?${r.toString()}`,{},n),a=(i.daily??[]).map(e=>({bucket:e.date,amount:e.cents,currency:i.currency??`USD`,transactions:e.transactions})),o=a.reduce((e,t)=>e+t.amount,0),s=a.reduce((e,t)=>e+t.transactions,0),c=new Date,l=new Date(Date.now()-B(t)*24*3600*1e3),d={series:a,totalAmount:o,currency:i.currency??`USD`,totalTransactions:s,windowStart:l.toISOString(),windowEnd:c.toISOString()};return typeof i.mrr_cents==`number`&&(d.mrr=i.mrr_cents),u.parse(d)}async getVitals(e,t,n){let r=new URLSearchParams({site_id:e});t?.url&&r.set(`url`,t.url),t?.device&&r.set(`device`,t.device),t?.window&&r.set(`window`,t.window);let i=await this.v2RequestRaw(`/v1/cli/vitals?${r.toString()}`,{},n),a=[];if(i.p75&&(i.sample_count??0)>0){let e=i.p75,n={url:`— site-wide aggregate —`,device:t?.device??void 0,samples:i.sample_count??0,...typeof e.lcp==`number`?{lcp:{p50:e.lcp,p75:e.lcp,p90:e.lcp}}:{},...typeof e.inp==`number`?{inp:{p50:e.inp,p75:e.inp,p90:e.inp}}:{},...typeof e.cls==`number`?{cls:{p50:e.cls,p75:e.cls,p90:e.cls}}:{},...typeof e.fcp==`number`?{fcp:{p50:e.fcp,p75:e.fcp,p90:e.fcp}}:{},...typeof e.ttfb==`number`?{ttfb:{p50:e.ttfb,p75:e.ttfb,p90:e.ttfb}}:{}};a.push(n)}for(let e of i.worst_pages??[])a.push({url:e.path,device:t?.device??void 0,samples:e.sample_count,lcp:{p50:e.lcp_p75,p75:e.lcp_p75,p90:e.lcp_p75}});let o=new Date,s=new Date(Date.now()-B(t?.window??`7d`)*24*3600*1e3);return f.parse({vitals:a,windowStart:s.toISOString(),windowEnd:o.toISOString()})}async getFunnel(e,t,n=`30d`,r){let i=new URLSearchParams({site_id:e,window:n}),a=await this.v2RequestRaw(`/v1/cli/funnels/${encodeURIComponent(t)}?${i.toString()}`,{},r),o=a.total_entries??0,s=(a.steps??[]).map(e=>({id:`step-${e.order}`,name:e.name,visitors:e.visitors,conversions:e.visitors,dropOff:Math.max(0,Math.min(1,e.dropoffPct/100))})),c=s[s.length-1],l=c?.visitors??0,u=o>0?Math.min(1,l/o):0,d=new Date,f=new Date(Date.now()-B(n)*24*3600*1e3);return m.parse({funnelId:a.id??t,name:a.name??t,steps:s,totalEntries:o,totalCompletions:l,conversionRate:u,windowStart:f.toISOString(),windowEnd:d.toISOString()})}async listFunnels(e,t){let n=new URLSearchParams({site_id:e}),r=await this.v2RequestRaw(`/v1/cli/funnels?${n.toString()}`,{},t);return g.parse({funnels:(r.funnels??[]).map(e=>({id:e.id,name:e.name,stepCount:e.step_count}))})}async getStats(e,t=`24h`,n){let r=new URLSearchParams({site_id:e,range:t}),i=await this.v2RequestRaw(`/v1/cli/stats?${r.toString()}`,{},n),a=i.visitors??0,o=i.pageviews??0,s=a,c=s>0?o/s:0,l=c>0?Math.max(0,Math.min(1,1/Math.max(1,c))):0,u=i.avgSessionSec??0,d=new Date,f=new Date(Date.now()-B(t)*24*3600*1e3);return _.parse({visitors:a,pageviews:o,sessions:s,bounceRate:l,avgSessionSec:u,topPages:i.topPage?[{url:i.topPage.path,views:i.topPage.views}]:[],topCountries:i.topSource?[{country:i.topSource.channel,visitors:i.topSource.visitors}]:[],windowStart:f.toISOString(),windowEnd:d.toISOString(),daily:i.daily})}async getGoals(e,t){let n=new URLSearchParams({site_id:e});return this.v2Request(`/v1/cli/goals?${n.toString()}`,y,{},t)}async getLive(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/live?${n.toString()}`,t)}async getPages(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/pages?${n.toString()}`,t)}async getDevices(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/devices?${n.toString()}`,t)}async getGeo(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/geo?${n.toString()}`,t)}async getRetention(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/retention?${n.toString()}`,t)}async getUptime(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/uptime?${n.toString()}`,t)}async getSessions(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/sessions?${n.toString()}`,t)}async getHeatmaps(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/heatmaps?${n.toString()}`,t)}async getJourneys(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/journeys?${n.toString()}`,t)}async getInsights(e,t){let n=new URLSearchParams({site_id:e});return await this.v2RawJson(`/v1/cli/insights?${n.toString()}`,t)}async v2RawJson(e,n){let r=`${this.v2ApiBase}${e}`,i=await this.v2Headers(),a=await this.v2Fetch(r,{headers:i,signal:n});if(a.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers();a=await this.v2Fetch(r,{headers:e,signal:n})}if(!a.ok){let n=await a.text().catch(()=>``),r=n;try{r=JSON.parse(n)}catch{}throw new t(a.status,r,`GET ${e} → ${a.status}`)}return a.json()}streamCompaniesV2(e,t){return this.streamChannel(e,`companies`,t)}streamCompanies(e,t){return z(`streamCompanies`,2)}async getCompanies(e){R(`getCompanies`,2)}async getCompaniesSnapshot(e,t,n){let r=new URLSearchParams({site_id:e});t?.window&&r.set(`window`,t.window),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/companies?${r.toString()}`,{},n);return D.parse(i)}async runSqlQuery(e,n,r,i){let a=`${this.v2ApiBase}/v1/cli/query`,o=await this.v2Headers({"Content-Type":`application/json`}),s=await this.v2Fetch(a,{method:`POST`,headers:o,signal:i,body:JSON.stringify({site_id:e,sql:n,...r?.maxRows?{max_rows:r.maxRows}:{}})});if(!s.ok){let e=await s.text().catch(()=>``),n=e;try{n=JSON.parse(e)}catch{}throw new t(s.status,n,`POST /v1/cli/query → ${s.status}`)}let c=await s.json();return O.parse(c.data??c)}async getDeploys(e,t,n){let r=new URLSearchParams({site_id:e});t?.since&&r.set(`since`,t.since),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit)),t?.branch&&r.set(`branch`,t.branch),t?.onChartOnly&&r.set(`on_chart_only`,`true`);let i=await this.v2RequestRaw(`/v1/cli/deploys?${r.toString()}`,{},n);return A.parse(i)}async getProjects(e,t){let n=new URLSearchParams({site_id:e}),r=await this.v2RequestRaw(`/v1/cli/projects?${n.toString()}`,{},t);return M.parse(r)}async getErrors(e,t,n){let r=new URLSearchParams({site_id:e});t?.window&&r.set(`window`,t.window),typeof t?.limit==`number`&&r.set(`limit`,String(t.limit));let i=await this.v2RequestRaw(`/v1/cli/errors?${r.toString()}`,{},n);return T.parse(i)}streamErrorsV2(e,t){return this.streamChannel(e,`errors`,t)}streamErrors(e,t){return z(`streamErrors`,2)}async getEventsHistory(e,t){R(`getEventsHistory`,2)}forwardWebhook(e,t){return z(`forwardWebhook`,2)}async registerTunnel(e,t){R(`registerTunnel`,2)}async queryRaw(e,t,n){R(`queryRaw`,3)}async getCompletions(e,t){R(`getCompletions`,3)}async listApiKeys(e){return await this.v2RawJson(`/v1/cli/mutate/keys`,e)}async createApiKey(e,t){return await this.v2Mutate(`/v1/cli/mutate/keys`,`POST`,e,t)}async deleteApiKey(e,t){return await this.v2Mutate(`/v1/cli/mutate/keys/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async addDomain(e,t){return await this.v2Mutate(`/v1/cli/mutate/domains`,`POST`,e,t)}async deleteDomain(e,t){return await this.v2Mutate(`/v1/cli/mutate/domains/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async listTeam(e){return await this.v2RawJson(`/v1/cli/mutate/team`,e)}async inviteTeamMember(e,t){return await this.v2Mutate(`/v1/cli/mutate/team/invite`,`POST`,e,t)}async removeTeamMember(e,t){return await this.v2Mutate(`/v1/cli/mutate/team/members/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async updateTeamMemberRole(e,t,n){return await this.v2Mutate(`/v1/cli/mutate/team/members/${encodeURIComponent(e)}/role`,`PATCH`,{role:t},n)}async updateProfile(e,t){return await this.v2Mutate(`/v1/cli/mutate/profile`,`POST`,e,t)}async getPlanInfo(e){return await this.v2RawJson(`/v1/cli/mutate/plans/info`,e)}async upgradePlan(e,t){return await this.v2Mutate(`/v1/cli/mutate/plans/upgrade`,`POST`,{targetPlan:e},t)}async cancelPlan(e){return await this.v2Mutate(`/v1/cli/mutate/plans/cancel`,`POST`,{},e)}async getSettings(e){return await this.v2RawJson(`/v1/cli/mutate/settings`,e)}async getUsage(e){return await this.v2RawJson(`/v1/cli/mutate/usage`,e)}async setSetting(e,t,n){return await this.v2Mutate(`/v1/cli/mutate/settings`,`POST`,{key:e,value:t},n)}async listIntegrations(e){return await this.v2RawJson(`/v1/cli/mutate/integrations`,e)}async disconnectIntegration(e,t){return await this.v2Mutate(`/v1/cli/mutate/integrations/disconnect`,`POST`,{name:e},t)}async listGoals(e){return await this.v2RawJson(`/v1/cli/mutate/goals`,e)}async createGoal(e,t){return await this.v2Mutate(`/v1/cli/mutate/goals`,`POST`,e,t)}async deleteGoal(e,t){return await this.v2Mutate(`/v1/cli/mutate/goals/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async listNotes(e){return await this.v2RawJson(`/v1/cli/mutate/notes`,e)}async createNote(e,t){return await this.v2Mutate(`/v1/cli/mutate/notes`,`POST`,e,t)}async deleteNote(e,t){return await this.v2Mutate(`/v1/cli/mutate/notes/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async listAgencyClients(e){return await this.v2RawJson(`/v1/cli/mutate/agency/clients`,e)}async addAgencyClient(e,t){return await this.v2Mutate(`/v1/cli/mutate/agency/clients`,`POST`,e,t)}async removeAgencyClient(e,t){return await this.v2Mutate(`/v1/cli/mutate/agency/clients/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async sendAgencyReport(e,t){return await this.v2Mutate(`/v1/cli/mutate/agency/report/${encodeURIComponent(e)}`,`POST`,{},t)}async listWebhooks(e){return await this.v2RawJson(`/v1/cli/mutate/webhooks`,e)}async createWebhook(e,t){return await this.v2Mutate(`/v1/cli/mutate/webhooks`,`POST`,e,t)}async deleteWebhook(e,t){return await this.v2Mutate(`/v1/cli/mutate/webhooks/${encodeURIComponent(e)}`,`DELETE`,void 0,t)}async rotateWebhookSecret(e,t){return await this.v2Mutate(`/v1/cli/mutate/webhooks/${encodeURIComponent(e)}/rotate`,`POST`,{},t)}async testWebhook(e,t){return await this.v2Mutate(`/v1/cli/mutate/webhooks/${encodeURIComponent(e)}/test`,`POST`,{},t)}async getAuditLogs(e,t){let n=new URLSearchParams;e.since&&n.set(`since`,e.since),e.action&&n.set(`action`,e.action),e.actor&&n.set(`actor`,e.actor);let r=n.toString()?`/v1/cli/mutate/audit/logs?${n.toString()}`:`/v1/cli/mutate/audit/logs`;return await this.v2RawJson(r,t)}async exportAudit(e,n){let r=`${this.v2ApiBase}/v1/cli/mutate/audit/export?format=${encodeURIComponent(e.format)}`,i=await this.v2Headers(),a=await this.v2Fetch(r,{headers:i,signal:n});if(a.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers();a=await this.v2Fetch(r,{headers:e,signal:n})}if(!a.ok){let e=await a.text().catch(()=>``),n=e;try{n=JSON.parse(e)}catch{}throw new t(a.status,n,`GET /v1/cli/mutate/audit/export → ${a.status}`)}return a.text()}async getShare(e,t){let n=new URLSearchParams({siteId:e});return await this.v2RawJson(`/v1/cli/mutate/share?${n.toString()}`,t)}async enableShare(e,t){return await this.v2Mutate(`/v1/cli/mutate/share/enable`,`POST`,{siteId:e},t)}async disableShare(e,t){return await this.v2Mutate(`/v1/cli/mutate/share/disable`,`POST`,{siteId:e},t)}async v2Mutate(e,n,r,i){let a=`${this.v2ApiBase}${e}`,o=await this.v2Headers(r===void 0?{}:{"Content-Type":`application/json`}),s={method:n,headers:o,signal:i};r!==void 0&&(s.body=JSON.stringify(r));let c=await this.v2Fetch(a,s);if(c.status===401&&this.v2Token){this.v2Token=null;let e=await this.v2Headers(r===void 0?{}:{"Content-Type":`application/json`});c=await this.v2Fetch(a,{...s,headers:e})}if(!c.ok){let r=await c.text().catch(()=>``),i=r;try{i=JSON.parse(r)}catch{}throw new t(c.status,i,`${n} ${e} → ${c.status}`)}let l=c.headers.get(`content-type`)??``;return l.includes(`application/json`)?c.json():{}}async*streamChannel(e,t,n){let{connectWs:r}=await import(`./ws-client-Cp_nIj_N.js`),i=this.v2ApiBase.replace(/^https:\/\//,`wss://`).replace(/^http:\/\//,`ws://`),a=`${i}/v1/cli/stream/${encodeURIComponent(e)}?channels=${t}`,o=this.v2Token?.accessToken;for await(let e of r({url:a,bearer:o,signal:n})){if(e.type!==`message`)continue;let t=e.data;if(t&&typeof t==`object`){let e=t;yield e.event??t}}}async createTunnel(e,n,r){let i=`${this.v2ApiBase}/v1/cli/tunnels`,a=await this.v2Headers({"Content-Type":`application/json`}),o=await this.v2Fetch(i,{method:`POST`,headers:a,signal:r,body:JSON.stringify({site_id:e,target_pattern:n})});if(!o.ok){let e=await o.text().catch(()=>``);throw new t(o.status,e,`POST /v1/cli/tunnels → ${o.status}`)}let s=await o.json(),c=s.data??{};if(!c.tunnel_key||!c.public_url||!c.ws_url)throw new t(500,s,`createTunnel: malformed response`);return{tunnelKey:c.tunnel_key,publicUrl:c.public_url,wsUrl:c.ws_url,siteId:c.site_id??e}}tunnelClient(e){let t=this.v2Token?.accessToken;return{start:async(n,r)=>{let{WsTunnelClient:i}=await import(`./ws-client-Cp_nIj_N.js`),a=new i({url:e,bearer:t,signal:r});await a.start(n)}}}async listAlerts(e,t){let n=new URLSearchParams({site_id:e}),r=await this.v2RawJson(`/v1/cli/alerts?${n.toString()}`,t),i=Array.isArray(r)?r:r.alerts??r.data??[];return i.map(H)}async createAlert(e,t,n){let r={site_id:e,name:t.name??`${t.metric} ${t.op} ${t.threshold}`,metric:t.metric,threshold:t.threshold,comparator:t.op===`gt`?`>`:`<`,window:t.window,channel:t.channel??`in_app`,email:t.email??null},i=await this.v2Mutate(`/v1/cli/alerts`,`POST`,r,n),a=`data`in i&&i.data?i.data:i;return H(a)}async deleteAlert(e,t,n){let r=new URLSearchParams({site_id:e});await this.v2Mutate(`/v1/cli/alerts/${encodeURIComponent(t)}?${r.toString()}`,`DELETE`,void 0,n)}};function H(e){return{id:e.id,metric:e.metric,op:e.op,threshold:e.threshold,window:e.window,createdAt:e.createdAt??e.created_at??null}}export{V as ApiV2Client};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{classifyBump as e,fetchManifest as t,platformKey as n}from"./check-
|
|
1
|
+
import{classifyBump as e,fetchManifest as t,platformKey as n}from"./check-D9G0N7NB.js";import r from"node:path";import{promises as i}from"node:fs";import a from"semver";import o from"node:os";import s from"node:crypto";const c=`AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=`;async function l(e){let n=await t({cliBase:e.cliBase,fetchImpl:e.fetchImpl});return u({...e,manifest:n})}async function u(t){let{manifest:r,currentVersion:o,forceDowngrade:s}=t,c=e(o,r.latest);if(c===`none`)return{updated:!1,from:o,to:r.latest,reason:`already-latest`};if(c===`downgrade`&&!s)return{updated:!1,from:o,to:r.latest,reason:`downgrade-blocked`};r.minSupported&&a.lt(o,r.minSupported);let l=n(),u=r.platforms[l];if(!u)throw Error(`No release binary for platform ${l}`);let h=await d(u,t.fetchImpl);try{return await f(h,u.sha256),await p(u,r.latest,l),await m(h,t.binaryPath),{updated:!0,from:o,to:r.latest}}catch(e){throw await i.unlink(h).catch(()=>void 0),e}}async function d(e,t=fetch){let n=await t(e.url);if(!n.ok)throw Error(`Download failed: ${n.status}`);let a=Buffer.from(await n.arrayBuffer()),s=await i.mkdtemp(r.join(o.tmpdir(),`zenovay-update-`)),c=r.join(s,`zenovay.new`);return await i.writeFile(c,a,{mode:493}),c}async function f(e,t){let n=await i.readFile(e),r=s.createHash(`sha256`).update(n).digest(`hex`);if(r.toLowerCase()!==t.toLowerCase())throw Error(`Checksum mismatch: expected ${t}, got ${r}. Update REFUSED.`)}async function p(e,t,n){let r=Buffer.from(c,`base64`);if(r.length!==32)throw Error(`Invalid release public key — update REFUSED.`);let i=Buffer.from(`${e.sha256}|${t}|${n}`),a=Buffer.from(e.sig,`base64`),o=s.createPublicKey({key:Buffer.concat([Buffer.from(`302a300506032b6570032100`,`hex`),r]),format:`der`,type:`spki`}),l=s.verify(null,i,o,a);if(!l)throw Error(`Signature verification FAILED. Update REFUSED.`)}async function m(e,t){let n=`${t}.old-${Date.now()}`;try{await i.rename(t,n)}catch(e){if(e.code!==`ENOENT`)throw e}try{await i.rename(e,t),process.platform!==`win32`&&await i.chmod(t,493),await i.unlink(n).catch(()=>void 0)}catch(e){try{await i.rename(n,t)}catch{}throw e}}export{u as applyManifest,l as applyUpdate};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readConfig as e}from"./config-
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-UJJ6ube8.js";import{requireTier as r}from"./tier-uaU5pkTz.js";import{resolve as i}from"node:path";import{writeFile as a}from"node:fs/promises";function o(e){return e?e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e:`—`}function s(e){return e?new Date(e).toISOString().slice(0,19).replace(`T`,` `):`—`}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.getAuditLogs({since:c.since??`7d`,action:c.filterAction,actor:c.actor});if(c.json)return process.stdout.write(JSON.stringify(e,null,2)+`
|
|
2
2
|
`),0;if(e.logs.length===0)return process.stdout.write(`No audit log entries in the last ${c.since??`7d`}. Try --since 30d for a wider window.\n`),0;let t=[`when`,`action`,`resource`,`actor`],n=[19,32,28,14],r=e=>e.map((e,t)=>(e??``).padEnd(n[t])).join(` `);process.stdout.write(`
|
|
3
3
|
`+r(t)+`
|
|
4
4
|
`),process.stdout.write(r(n.map(e=>`─`.repeat(e)))+`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useTheme as e}from"./panel-
|
|
1
|
+
import{useTheme as e}from"./panel-jycoT562.js";import{Box as t,Text as n}from"ink";import r from"react";function i(){let e=process.stdout.columns;return typeof e==`number`&&e>0?e:80}function a({version:a,subtitle:o}){let{theme:s}=e(),c=i(),l=`ZENOVAY`,u=`v${a}`,d=`╭─ `,f=` · `,p=` `,m=`─╮`,h=d.length+l.length+f.length+u.length+p.length+m.length,g=Math.max(2,c-h),_=`─`.repeat(g),v=`─`.repeat(Math.max(2,c-2)),y=o??``,b=y.slice(0,Math.max(0,c-4)),x=` `.repeat(Math.max(1,c-2-1-b.length-1));return r.createElement(t,{flexDirection:`column`},r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:s.border},d),r.createElement(n,{color:s.accent,bold:!0},l),r.createElement(n,{color:s.dim},f,u),r.createElement(n,{color:s.border},p,_,m)),o?r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:s.border},`│ `),r.createElement(n,{color:s.fg},b),r.createElement(n,{color:s.border},x,`│`)):null,r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:s.border},`╰`,v,`╯`)))}export{a as Banner};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useTheme as e}from"./panel-
|
|
1
|
+
import{useTheme as e}from"./panel-jycoT562.js";import{Box as t,Text as n}from"ink";import r from"react";const i=[` `,`▏`,`▎`,`▍`,`▌`,`▋`,`▊`,`▉`,`█`];function a(e,t,n){let r=Math.max(0,Math.min(t*8,Math.round(e*t*8))),a=Math.floor(r/8),o=r%8,s=o>0&&a<t,c=s?i[o]??``:``,l=`█`.repeat(a)+c,u=Math.max(0,t-a-(s?1:0)),d=n===`outline`?`░`.repeat(u):` `.repeat(u);return l+d}function o({value:i,max:o,width:s=24,delta:c,label:l,theme:u,variant:d=`filled`,color:f,maxWidth:p,showPercent:m=!0}){let{theme:h}=e(),g=u??h,_=process.stdout.columns,v=typeof _==`number`&&_>4?_-4:80,y=p??v,b=Math.max(1,Math.min(s,y)),x=o<=0?1:o,S=Math.max(0,Math.min(1,i/x)),C=a(S,b,d),w=`${Math.round(S*100)}%`,T=f??g.accent,E=null;if(typeof c==`number`){let e=Math.abs(c);E=e<.5?r.createElement(n,{color:g.dim},` `,`→ `,e.toFixed(1),`%`):c>0?r.createElement(n,{color:g.success},` `,`↑ `,e.toFixed(1),`%`):r.createElement(n,{color:g.error},` `,`↓ `,e.toFixed(1),`%`)}return r.createElement(t,{flexDirection:`row`},l===void 0?null:r.createElement(n,{color:g.muted},l,` `),r.createElement(n,{color:T},C),m?r.createElement(n,{color:g.fg},` `,w):null,E)}export{o as Bar};
|
package/dist/bin.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{configDir as e,readConfig as t}from"./config-
|
|
2
|
+
import{configDir as e,readConfig as t}from"./config-CG7B8fR0.js";import{manifestSchema as n}from"./check-D9G0N7NB.js";import{applyManifest as r}from"./apply-oUMOH7u2.js";import"./api-CJnD6Auw.js";import"./token-store-C1AqhmDP.js";import{normalizeError as i}from"./error-codes-CCK850J9.js";import{cac as a}from"cac";import{fork as o,spawn as s}from"node:child_process";import c from"node:path";import{fileURLToPath as l}from"node:url";import{promises as u,readFileSync as d}from"node:fs";import f from"semver";import{z as p}from"zod";const m=2e3,h=3e4,g=5e3,_=5e3,v=36e5,y=new Set([`update`,`health`,`doctor`,`--version`,`-v`]),b=p.object({checkedAt:p.number(),latest:p.string()});function x(){return c.join(e(),`update-cache.json`)}async function S(){try{let e=await u.readFile(x(),`utf8`),t=b.safeParse(JSON.parse(e));return t.success?t.data:null}catch{return null}}async function C(t){try{await u.mkdir(e(),{recursive:!0,mode:448}),await u.writeFile(x(),JSON.stringify(t),{mode:384})}catch{}}const w=p.object({latest:p.string(),minSupported:p.string().optional(),platforms:p.record(p.string(),p.unknown()).optional(),downloads:p.record(p.string(),p.unknown()).optional()});async function T(e){if(E(e.argv))return;let t=null,n=await S();if(n&&Date.now()-n.checkedAt<v)t={latest:n.latest,platforms:{}};else{try{t=await D()}catch(e){N(`update check failed: ${e.message}`);return}t&&await C({checkedAt:Date.now(),latest:t.latest})}if(!t||!f.valid(e.currentVersion)||!f.valid(t.latest)||f.eq(e.currentVersion,t.latest)||f.lt(t.latest,e.currentVersion))return;let r=f.diff(e.currentVersion,t.latest);if(!r)return;let i=O();if(r===`patch`||r===`prepatch`){let n=await k(t,e,i);if(n&&i===`npm-global`)return;n&&M(e.argv);return}if(r===`minor`||r===`preminor`||r===`major`||r===`premajor`||r===`prerelease`){let n=await j(t.latest);if(!n){process.stderr.write(`Continuing with ${e.currentVersion}.\n`);return}let r=await k(t,e,i);if(r&&i===`npm-global`)return;r&&M(e.argv);return}}function E(e){if(process.env.ZENOVAY_NO_UPDATE_CHECK===`1`||process.env.CI===`true`||e.includes(`--no-update-check`))return!0;let t=e[2];return!!(t&&y.has(t))}async function D(){let e=O();if(e===`npm-global`||e===`npm-local`||e===`unknown`)try{let e=await fetch(`https://registry.npmjs.org/@zenovay/cli/latest`,{signal:AbortSignal.timeout(m),headers:{Accept:`application/json`}});if(!e.ok)return null;let t=await e.json();return t.version?{latest:t.version,platforms:{}}:null}catch{return null}let r=await t();try{let e=await fetch(`${r.cliBase}/version`,{signal:AbortSignal.timeout(m)});if(!e.ok)return null;let t=await e.json(),i=n.safeParse(t);if(i.success)return i.data;let a=w.safeParse(t);return a.success?{latest:a.data.latest,minSupported:a.data.minSupported,platforms:{}}:null}catch{return null}}function O(){let e=process.argv[1]??``;if(!e)return`unknown`;let t=e.replace(/\\/g,`/`);return t.includes(`/_npx/`)?`npm-local`:t.includes(`/node_modules/@zenovay/cli/`)?`npm-global`:t.includes(`/node_modules/.bin/zenovay`)?`npm-local`:t.includes(`/node_modules/`)?`unknown`:`binary`}async function k(e,n,i){if(i===`npm-local`)return process.stderr.write(`Update available — \`npm i -g @zenovay/cli@${e.latest}\` to upgrade.\n`),!1;if(i===`unknown`)return N(`unknown install method; skipping auto-update (latest ${e.latest})`),!1;if(i===`npm-global`)return await A(e.latest);try{let i=await t(),a=await Promise.race([r({currentVersion:n.currentVersion,cliBase:i.cliBase,binaryPath:n.binaryPath,manifest:e}),new Promise((e,t)=>setTimeout(()=>t(Error(`patch install timeout`)),g))]);return a.updated?!0:(N(`update skipped: ${a.reason??`unknown`}`),!1)}catch(e){return N(`update failed: ${e.message}`),!1}}function A(e){return new Promise(t=>{process.stderr.write(` Updating @zenovay/cli to ${e}...\n`);let n=process.platform===`win32`?`npm.cmd`:`npm`,r=[`install`,`-g`,`@zenovay/cli@${e}`],i={stdio:[`ignore`,`ignore`,`pipe`]},a=``,o=!1,c=s(n,r,i),l=setTimeout(()=>{if(!o){o=!0;try{c.kill(`SIGKILL`)}catch{}N(`npm install timed out after ${h/1e3}s; continuing with current version`),t(!1)}},h);c.stderr?.on(`data`,e=>{a+=e.toString(`utf8`)}),c.on(`error`,e=>{o||(o=!0,clearTimeout(l),N(`npm install error: ${e.message}`),t(!1))}),c.on(`exit`,n=>{o||(o=!0,clearTimeout(l),n===0&&(process.stderr.write(` ✔ Updated to ${e}. Re-run your command to use the new version.\n`),process.exit(0)),/EACCES|permission denied/i.test(a)?process.stderr.write(`Auto-update needs sudo for the global npm prefix. Run: sudo npm i -g @zenovay/cli@${e}\n`):N(`npm install exited ${n}; continuing with current version`),t(!1))})})}function j(e){return new Promise(t=>{if(!process.stdin.isTTY||!process.stderr.isTTY){t(!0);return}process.stderr.write(`New version ${e} available. Update? [Y/n] (auto-yes 5s) `);let n=!1,r=e=>{if(n)return;let r=e.toString(`utf8`).trim().toLowerCase();n=!0,i(),process.stderr.write(`
|
|
3
3
|
`),t(r===``||r===`y`||r===`yes`)},i=()=>{clearTimeout(a),process.stdin.off(`data`,r);try{process.stdin.pause()}catch{}},a=setTimeout(()=>{n||(n=!0,i(),process.stderr.write(`
|
|
4
|
-
`),t(!0))},_);try{process.stdin.resume(),process.stdin.on(`data`,r)}catch{i(),t(!0)}})}function M(e){try{let t=e.slice(1),n=s(process.execPath,t,{stdio:`inherit`});n.on(`exit`,e=>{process.exit(typeof e==`number`?e:0)}),n.on(`error`,()=>{})}catch{}}function N(e){if(process.env.ZENOVAY_DEBUG_UPDATE===`1`)try{process.stderr.write(`zenovay: ${e}\n`)}catch{}}
|
|
4
|
+
`),t(!0))},_);try{process.stdin.resume(),process.stdin.on(`data`,r)}catch{i(),t(!0)}})}function M(e){try{let t=e.slice(1),n=s(process.execPath,t,{stdio:`inherit`});n.on(`exit`,e=>{process.exit(typeof e==`number`?e:0)}),n.on(`error`,()=>{})}catch{}}function N(e){if(process.env.ZENOVAY_DEBUG_UPDATE===`1`)try{process.stderr.write(`zenovay: ${e}\n`)}catch{}}const P=c.dirname(l(import.meta.url)),F=c.join(P,`..`,`package.json`),I=JSON.parse(d(F,`utf8`)),L=I.version,R=process.argv[0]??`zenovay`;function z(){if(process.env.ZENOVAY_BACKGROUND_UPDATE===`1`&&!(process.env.ZENOVAY_NO_UPDATE_CHECK===`1`||process.env.CI===`true`))try{let e=c.join(P,`lib`,`update`,`worker.js`),t=o(e,[],{detached:!0,stdio:`ignore`});t.unref()}catch{}}const B=a(`zenovay`);B.version(L),B.help(),B.option(`-q, --quiet`,`Suppress spinners + interactive UI; implies --json`),B.option(`--team <name-or-id>`,"Team override for this command (alternative to `zenovay teams switch`)"),(process.argv.includes(`-q`)||process.argv.includes(`--quiet`))&&(process.env.ZENOVAY_FORMAT=`json`,process.argv.includes(`--json`)||process.argv.push(`--json`));const V=process.argv.findIndex(e=>e===`--team`);if(V!==-1&&process.argv[V+1]&&(process.env.ZENOVAY_TEAM_ID=process.argv[V+1]),!process.env.ZENOVAY_TEAM_ID)try{let e=process.env.HOME??process.env.USERPROFILE??``,t=c.join(e,`.config`,`zenovay`,`config.json`),n=d(t,`utf8`),r=JSON.parse(n);r.currentTeamId&&(process.env.ZENOVAY_TEAM_ID=r.currentTeamId)}catch{}B.command(`init`,`AI install wizard — add Zenovay tracking to your codebase`).option(`--json`,`Emit NDJSON events to stdout`).option(`--yes`,`Auto-approve all diffs (for CI)`).option(`--skip-mcp`,`Skip MCP client install`).option(`--skip-verify`,`Skip first-event verification`).action(async e=>{let{initCommand:t}=await import(`./init-C8KOSKzO.js`),n=await t({cliVersion:L,cwd:process.cwd(),json:e.json,yes:e.yes,skipMcp:e.skipMcp,skipVerify:e.skipVerify});process.exitCode=n}),B.command(`login`,`Authenticate via OAuth device flow`).option(`--json`,`Emit NDJSON events`).option(`--no-browser`,`Skip opening the browser automatically`).action(async e=>{let{loginCommand:t}=await import(`./login-CYaCSVUe.js`),n=await t({cliVersion:L,json:e.json,openBrowser:e.browser!==!1,onCode:e=>{process.stdout.write(`\n Open this URL to authorize the CLI:\n ${e.verificationUriComplete??e.verificationUri}\n Or enter code: ${e.userCode}\n\n`)}});!e.json&&n.email?process.stdout.write(`\n ✔ Logged in as ${n.email}\n Try \`zenovay overview\` to see your dashboard, or \`zenovay --help\` for the full command list.\n\n`):e.json||process.stdout.write(`
|
|
5
5
|
✔ Logged in.
|
|
6
6
|
|
|
7
|
-
`)}),H.command(`logout`,`Revoke current session and delete local auth`).option(`--json`,``).action(async e=>{let{logoutCommand:t}=await import(`./logout-1ohk4uie.js`);await t({cliVersion:z,json:e.json})}),H.command(`ai`,`3-mode AI assistant (install / chat / mcp)`).option(`--mode <mode>`,`install | chat | mcp`).option(`--json`,``).action(async e=>{let{aiCommand:t}=await import(`./ai-B8r28ZBm.js`),n=await t({cliVersion:z,cwd:process.cwd(),mode:e.mode,json:e.json});process.exitCode=n}),H.command(`watch`,"[ANALYTICS] Alias for `analytics` (dashboard summary)").option(`--site-id <id>`,`Site ID`).option(`--interval <ms>`,`Poll interval ms (legacy; ignored by analytics)`,{default:15e3}).option(`--json`,``).action(async e=>{let{analyticsCommand:t}=await import(`./analytics-DZpf8Q9f.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`analytics`,`[ANALYTICS] Landing dashboard — visitors, pageviews, bounce, top pages`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{analyticsCommand:t}=await import(`./analytics-DZpf8Q9f.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`overview`,"[ANALYTICS] Alias for `analytics` (kept for back-compat with V1 scripts)").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{analyticsCommand:t}=await import(`./analytics-DZpf8Q9f.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`home`,`[ACCOUNT] Top-level summary — sites + this-week deltas`).option(`--json`,``).action(async e=>{let{homeCommand:t}=await import(`./home-CtsY-gj0.js`);process.exitCode=await t({cliVersion:z,json:e.json})}),H.command(`live`,`[ANALYTICS] Real-time visitors + globe + recent events (2s polling)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{liveCommand:t}=await import(`./live-k32y1phk.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`pages`,`[ANALYTICS] Top pages by views — last 24h`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{pagesCommand:t}=await import(`./pages-CAYP4Abn.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`devices`,`[ANALYTICS] Device / browser / OS breakdown — last 24h`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{devicesCommand:t}=await import(`./devices-C8xVqaBs.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`geo`,`[ANALYTICS] Countries + cities + globe — last 24h`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{geoCommand:t}=await import(`./geo-BaCNZ7-S.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`retention`,`[BEHAVIOR] Cohort retention heatmap — D1 / D7 / D30 (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{retentionCommand:t}=await import(`./retention-DQPI6wVN.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`uptime`,`[BEHAVIOR] Uptime monitors with status + p95 (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{uptimeCommand:t}=await import(`./uptime-DACm8Hdh.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`sessions`,`[BEHAVIOR] Recent session-replay list (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{sessionsCommand:t}=await import(`./sessions-Dv-Z29cQ.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`heatmaps`,`[BEHAVIOR] Recent heatmap captures (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{heatmapsCommand:t}=await import(`./heatmaps-e1Q72VWJ.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`journeys`,`[BEHAVIOR] Page-to-page transition flow (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{journeysCommand:t}=await import(`./journeys-zPmCha98.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`insights`,`[INTELLIGENCE] AI-generated anomaly / trend / recommendation cards (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{insightsCommand:t}=await import(`./insights-wx3wIgGV.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json});process.exitCode=n}),H.command(`events tail`,`Stream live events`).option(`--site-id <id>`,`Site ID`,{default:``}).option(`--filter <expr>`,`Filter expression (e.g. 'type=pageview AND country=US')`).option(`--forward-to <url>`,`POST each event to a webhook with HMAC-SHA256 signature`).option(`--replay-24h`,`Replay the last 24h before going live`).option(`--set-forward-secret <hex>`,`Persist the HMAC secret used by --forward-to`).option(`--json`,``).action(async e=>{let{eventsTailCommand:t}=await import(`./events-tail-CXJUK5ka.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json,filter:e.filter,forwardTo:e.forwardTo,replay24h:e.replay24h,setForwardSecret:e.setForwardSecret});process.exitCode=n}),H.command(`health`,`Run self-diagnostic checks`).option(`--json`,``).action(async e=>{let{healthCommand:t}=await import(`./health-DfgPNC1A.js`),n=await t({cliVersion:z,binaryPath:B,json:e.json});process.exitCode=n}),H.command(`doctor`,`AI-assisted self-healing`).option(`--json`,``).action(async e=>{let{doctorCommand:t}=await import(`./doctor-K37xh3M7.js`),n=await t({cliVersion:z,binaryPath:B,json:e.json});process.exitCode=n}),H.command(`stats`,`One-shot dashboard summary (scriptable by default)`).option(`--site-id <id>`,`Site ID`).option(`--range <range>`,`Time range: 24h | 7d | 30d`,{default:`24h`}).option(`--watch`,`Auto-refresh every 60s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{statsCommand:t}=await import(`./stats-DRy2d3At.js`),n=await t({cliVersion:z,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),H.command(`sources`,`Traffic source breakdown with delta arrows`).option(`--site-id <id>`,`Site ID`).option(`--period <p>`,`Period: 7d | 30d | 90d | 1y`,{default:`30d`}).option(`--compare <c>`,`Comparison window (use "prev" for period-over-period)`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{sourcesCommand:t}=await import(`./sources-DL_o-kkA.js`),n=await t({cliVersion:z,siteId:e.siteId,period:e.period,compare:e.compare,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),H.command(`vitals`,`Core Web Vitals dashboard (LCP / INP / CLS / TTFB / FCP)`).option(`--site-id <id>`,`Site ID`).option(`--url <path>`,`Filter to a single URL`).option(`--device <type>`,`Filter by device: mobile | desktop`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`7d`}).option(`--watch`,`Auto-refresh every 5 minutes`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{vitalsCommand:t}=await import(`./vitals-lpeK0mbA.js`),n=await t({cliVersion:z,siteId:e.siteId,url:e.url,device:e.device,window:e.window,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),H.command(`revenue`,`MRR / ARR / transaction series`).option(`--site-id <id>`,`Site ID`).option(`--range <r>`,`Time range: 24h | 7d | 30d | 1y`,{default:`30d`}).option(`--watch`,`Auto-refresh every 5 minutes`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{revenueCommand:t}=await import(`./revenue-CD1YwoZj.js`),n=await t({cliVersion:z,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),H.command(`funnels`,`List available funnels`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{funnelCommand:t}=await import(`./funnel-nm9X3Od7.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),H.command(`themes`,`List available themes with colored swatches`).option(`--validate <path>`,`Validate a custom theme JSON file`).option(`--json`,`Emit themes JSON to stdout`).action(async e=>{let{themesCommand:t}=await import(`./themes-CRvhjrRx.js`),n=await t({cliVersion:z,validate:e.validate,json:e.json});process.exitCode=n}),H.command(`completions [shell]`,`Emit shell-completion script (bash | zsh | fish | nushell | pwsh)`).option(`--list`,`List supported shells`).action(async(e,t)=>{let{completionsCommand:n}=await import(`./completions-CXAOfyWo.js`),r=await n({shell:e,list:t.list});process.exitCode=r}),H.command(`query [sql]`,`Restricted SQL REPL over the analytics schema (Scale+)`).option(`--site-id <id>`,`Site ID`).option(`--max-rows <n>`,`Cap result row count`,{default:1e3}).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async(e,t)=>{let{queryCommand:n}=await import(`./query-X38xyHCI.js`),r=await n({cliVersion:z,siteId:t.siteId,sql:e,maxRows:typeof t.maxRows==`string`?Number(t.maxRows):t.maxRows,json:t.json,csv:t.csv,tsv:t.tsv,ndjson:t.ndjson});process.exitCode=r}),H.command(`companies`,`B2B identification feed (Scale+)`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`24h`}).option(`--limit <n>`,`Max rows`,{default:100}).option(`--new-only`,`Show only newly identified companies (first-seen in last hour)`).option(`--watch`,`Auto-refresh every 30s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{companiesCommand:t}=await import(`./companies-BToqUnFi.js`),n=await t({cliVersion:z,siteId:e.siteId,window:e.window,limit:typeof e.limit==`string`?Number(e.limit):e.limit,newOnly:e.newOnly,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),H.command(`projects`,`List your tracked projects`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{projectsCommand:t}=await import(`./projects-BC8pmo7u.js`),n=await t({cliVersion:z,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),H.command(`deploys`,`Recent GitHub commits overlaid on charts (Wave 4 W5)`).option(`--site-id <id>`,`Site ID`).option(`--branch <name>`,`Filter to a single branch (e.g. main, develop)`).option(`--since <iso>`,`Only commits after this ISO timestamp`).option(`--limit <n>`,`Max rows`,{default:50}).option(`--connect`,`Print the GitHub-integration deep link in app.zenovay.com`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{deploysCommand:t}=await import(`./deploys-CgNr5r7M.js`),n=await t({cliVersion:z,siteId:e.siteId,branch:e.branch,since:e.since,limit:typeof e.limit==`string`?Number(e.limit):e.limit,connect:e.connect,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),H.command(`webhooks forward`,`Forward webhook events to a local URL (stripe-listen-style; W3)`).option(`--to <url>`,`Local URL to POST events to (e.g. localhost:3000/webhook)`).option(`--site-id <id>`,`Site ID`).option(`--sign`,`HMAC-sign each forwarded request with X-Zenovay-Signature`).option(`--secret <hex>`,`HMAC secret (auto-derived from tunnel key if --sign without --secret)`).option(`--max-retries <n>`,`Per-request retry count`,{default:3}).action(async e=>{let{webhooksForwardCommand:t}=await import(`./webhooks-forward-BUoKx2Dz.js`),n=await t({cliVersion:z,to:e.to,siteId:e.siteId,sign:e.sign,secret:e.secret,maxRetries:typeof e.maxRetries==`string`?Number(e.maxRetries):e.maxRetries});process.exitCode=n}),H.command(`errors`,`Recent error snapshot (Wave 2 lead-in; SSE coming in V2.1)`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`24h`}).option(`--limit <n>`,`Max errors to fetch`,{default:100}).option(`--search <q>`,`Filter by class or message substring`).option(`--watch`,`Auto-refresh every 30s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{errorsCommand:t}=await import(`./errors-BXwphY11.js`),n=await t({cliVersion:z,siteId:e.siteId,window:e.window,limit:typeof e.limit==`string`?Number(e.limit):e.limit,search:e.search,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),H.command(`funnel <id>`,`Funnel drop-off chart for a specific funnel`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 7d | 30d`,{default:`30d`}).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async(e,t)=>{let{funnelCommand:n}=await import(`./funnel-nm9X3Od7.js`),r=await n({cliVersion:z,siteId:t.siteId,funnelId:e,window:t.window,json:t.json,csv:t.csv,tsv:t.tsv,ndjson:t.ndjson});process.exitCode=r}),H.command(`api-keys [action] [id]`,`[MANAGE] api-keys list | create [--name --scope] | delete <id>`).option(`--name <n>`,`Human-readable label (create)`).option(`--scope <scope>`,`read | write (create)`,{default:`read`}).option(`--yes`,`Skip confirmation (delete)`).option(`--json`,``).action(async(e,t,n)=>{let{apiKeysCommand:r}=await import(`./api-keys-DsQR075b.js`),i=e??`list`;process.exitCode=await r({cliVersion:z,action:i,id:t,name:n.name,scope:n.scope===`write`?`write`:`read`,yes:n.yes,json:n.json})}),H.command(`domains [action] [arg]`,`[MANAGE] domains list | add <url> [--name] | delete <id>`).option(`--name <n>`,`Friendly project name (add; default: domain itself)`).option(`--yes`,`Skip confirmation (delete)`).option(`--json`,``).action(async(e,t,n)=>{let{domainsCommand:r}=await import(`./domains-Bfx2vdwv.js`),i=e??`list`;process.exitCode=await r({cliVersion:z,action:i,url:i===`add`?t:void 0,id:i===`delete`?t:void 0,name:n.name,yes:n.yes,json:n.json})}),H.command(`team [action] [arg] [arg2]`,`[MANAGE] team list | invite <email> [--role] | remove <userId> | role <userId> <admin|member> (Pro+)`).option(`--role <role>`,`admin | member (invite)`,{default:`member`}).option(`--yes`,`Skip confirmation (remove)`).option(`--json`,``).action(async(e,t,n,r)=>{let{teamCommand:i}=await import(`./team-Bg-ggtky.js`),a=e??`list`,o;a===`role`?o=n===`admin`?`admin`:`member`:a===`invite`&&(o=r.role===`admin`?`admin`:`member`),process.exitCode=await i({cliVersion:z,action:a,email:a===`invite`?t:void 0,userId:a===`remove`||a===`role`?t:void 0,role:o,yes:r.yes,json:r.json})}),H.command(`profile [action]`,`[ACCOUNT] profile show | edit [--name --notifications]`).option(`--name <n>`,`New display name (edit)`).option(`--notifications <pref>`,`email | none (edit)`).option(`--json`,``).action(async(e,t)=>{let n=e??`show`,r=t.notifications===`email`||t.notifications===`none`?t.notifications:void 0,{profileCommand:i}=await import(`./profile-DQJdZ-s_.js`);process.exitCode=await i({cliVersion:z,action:n,name:t.name,notifications:r,json:t.json})}),H.command(`plans [action] [arg] [arg2]`,`[ACCOUNT] plans info | upgrade <pro|scale> | cancel --yes | payment update`).option(`--yes`,"Required for `cancel`").option(`--json`,``).action(async(e,t,n,r)=>{let i=e??`info`,{plansCommand:a}=await import(`./plans-D8aqF_lo.js`),o;if(i===`upgrade`&&t){let e=String(t).toLowerCase();(e===`pro`||e===`scale`||e===`enterprise`)&&(o=e)}let s=i===`payment`&&t===`update`||i===`payment`?`update`:void 0;process.exitCode=await a({cliVersion:z,action:i,targetPlan:o,paymentAction:s,yes:r.yes,json:r.json})}),H.command(`billing [action]`,"[ACCOUNT] Alias for `plans info`").option(`--json`,``).action(async(e,t)=>{let{plansCommand:n}=await import(`./plans-D8aqF_lo.js`);process.exitCode=await n({cliVersion:z,action:`info`,json:t.json})}),H.command(`settings [action] [key] [value]`,`[ACCOUNT] settings get [key] | set <key> <value>`).option(`--json`,``).action(async(e,t,n,r)=>{let i=e??`get`,{settingsCommand:a}=await import(`./settings-BsczzB3M.js`);process.exitCode=await a({cliVersion:z,action:i,key:t||void 0,value:n||void 0,json:r.json})}),H.command(`integrations [action] [name]`,`[ACCOUNT] integrations list | connect <gsc|github> | disconnect <gsc|github>`).option(`--yes`,`Skip confirmation (disconnect)`).option(`--json`,``).action(async(e,t,n)=>{let r=e??`list`,i=t===`gsc`||t===`github`?t:void 0,{integrationsCommand:a}=await import(`./integrations-B6IO1dM0.js`);process.exitCode=await a({cliVersion:z,action:r,name:i,yes:n.yes,json:n.json})}),H.command(`goals [action] [id]`,`[ACCOUNT] goals list | create [--name --type --target] | delete <id> (Pro+)`).option(`--name <n>`,`Goal name (create)`).option(`--type <t>`,`pageview | event (create)`).option(`--target <v>`,`URL pattern or event name (create)`).option(`--yes`,`Skip confirmation (delete)`).option(`--json`,``).action(async(e,t,n)=>{let r=e??`list`,i=n.type===`event`||n.type===`pageview`?n.type:void 0,{goalsCommand:a}=await import(`./goals-D1qL286b.js`);process.exitCode=await a({cliVersion:z,action:r,id:t,name:n.name,type:i,target:n.target,yes:n.yes,json:n.json})}),H.command(`notes [action] [id]`,`[ACCOUNT] notes list | create [--content --site-id] | delete <id>`).option(`--content <text>`,`Note body (create)`).option(`--site-id <id>`,`Attach to a specific site (create; defaults to current)`).option(`--yes`,`Skip confirmation (delete)`).option(`--json`,``).action(async(e,t,n)=>{let r=e??`list`,{notesCommand:i}=await import(`./notes-Cepz-K00.js`);process.exitCode=await i({cliVersion:z,action:r,id:t,content:n.content,siteId:n.siteId,yes:n.yes,json:n.json})}),H.command(`agency [action] [arg] [arg2]`,`[ACCOUNT] agency clients list | clients add [--email --name] | clients remove <id> | report send <clientId> (Scale+)`).option(`--email <e>`,`Client contact email (clients add)`).option(`--name <n>`,`Client name (clients add)`).option(`--yes`,`Skip confirmation (clients remove)`).option(`--json`,``).action(async(e,t,n,r)=>{let{agencyCommand:i}=await import(`./agency-DEixFVRT.js`),a=`clients-list`,o;e===`clients`?t===`add`?a=`clients-add`:t===`remove`?(a=`clients-remove`,o=n):a=`clients-list`:e===`report`&&t===`send`&&(a=`report-send`,o=n),process.exitCode=await i({cliVersion:z,action:a,id:o,email:r.email,name:r.name,yes:r.yes,json:r.json})}),H.command(`analytics live`,"[ANALYTICS] Alias for `live`").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{liveCommand:t}=await import(`./live-k32y1phk.js`);process.exitCode=await t({cliVersion:z,siteId:e.siteId,json:e.json})}),H.command(`analytics funnels`,"[ANALYTICS] Alias for `funnels`").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{funnelCommand:t}=await import(`./funnel-nm9X3Od7.js`);process.exitCode=await t({cliVersion:z,siteId:e.siteId,json:e.json})}),H.command(`analytics goals`,"[ANALYTICS] Alias for `goals list` (Pro+)").option(`--json`,``).action(async e=>{let{goalsCommand:t}=await import(`./goals-D1qL286b.js`);process.exitCode=await t({cliVersion:z,action:`list`,json:e.json})}),H.command(`analytics insights`,"[ANALYTICS] Alias for `insights` (Pro+)").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{insightsCommand:t}=await import(`./insights-wx3wIgGV.js`);process.exitCode=await t({cliVersion:z,siteId:e.siteId,json:e.json})}),H.command(`analytics profiles`,"[ANALYTICS] User-profiles list (NOT `profile`, which is current-user)").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{visitorsCommand:t}=await import(`./visitors-CrF-_BuG.js`);process.exitCode=await t({cliVersion:z,siteId:e.siteId,json:e.json})}),H.command(`analytics companies`,"[ANALYTICS] Alias for `companies` (Scale+)").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{companiesCommand:t}=await import(`./companies-BToqUnFi.js`);process.exitCode=await t({cliVersion:z,siteId:e.siteId,json:e.json})}),H.command(`use [site]`,`Set / show / reset your default site (used when --site-id is omitted)`).option(`--reset`,`Clear the stored default site`).option(`--show`,`Print the current default and exit`).option(`--json`,`Emit JSON`).action(async(e,t)=>{let{useCommand:n}=await import(`./use-DJ0b_xNo.js`),r=await n({cliVersion:z,match:e,reset:t.reset,show:t.show,json:t.json});process.exitCode=r}),H.command(`update`,`Manually install the latest version`).option(`--check`,`Don't install — just print latest`).option(`--force-downgrade`,`Allow downgrading to an older version`).option(`--no-update-check`,`Disable auto-update for this invocation`).option(`--json`,``).action(async e=>{let{updateCommand:t}=await import(`./update-DWBRR_PD.js`);await t({cliVersion:z,binaryPath:B,check:e.check,forceDowngrade:e.forceDowngrade,json:e.json})}),H.command(`usage`,`[ACCOUNT] Current month events vs plan limits + headcounts`).option(`--json`,``).action(async e=>{let{usageCommand:t}=await import(`./usage-BhLXHEkY.js`);process.exitCode=await t({cliVersion:z,json:e.json})}),H.command(`globe`,`[ANALYTICS] Live 3D globe — visitors plotted on a Braille sphere`).option(`--site-id <id>`,`Site ID`).option(`--browser`,`Open the dashboard's Mapbox globe in your browser instead of the terminal version`).option(`--json`,``).action(async e=>{let{globeCommand:t}=await import(`./globe-B4iKPH4T.js`);process.exitCode=await t({cliVersion:z,siteId:e.siteId,browser:e.browser,json:e.json})}),H.command(`webhooks [action] [arg]`,`[MANAGE] webhooks list | add <url> [--events] | delete <id> | rotate <id> | test <id>`).option(`--events <list>`,`Comma-separated event types (add)`).option(`--yes`,`Skip confirmation (delete/rotate)`).option(`--json`,``).action(async(e,t,n)=>{let r=e??`list`,{webhooksCommand:i}=await import(`./webhooks-Ddhz2P7n.js`);process.exitCode=await i({cliVersion:z,action:r,url:r===`add`?t:void 0,id:r===`delete`||r===`rotate`||r===`test`?t:void 0,events:n.events,yes:n.yes,json:n.json})}),H.command(`audit [action]`,`[ACCOUNT] audit list [--since --action --actor] | export [--format --out] (Pro+)`).option(`--since <window>`,`Window like 24h, 7d, 30d (list)`,{default:`7d`}).option(`--action <pattern>`,`Filter by action string (list)`).option(`--actor <userId>`,`Filter by actor user ID (list)`).option(`--format <fmt>`,`ndjson | csv | json (export)`,{default:`ndjson`}).option(`--out <file>`,`Output file path (export). Defaults to stdout`).option(`--json`,``).action(async(e,t)=>{let n=e??`list`,r=t.format===`csv`||t.format===`json`?t.format:`ndjson`,{auditCommand:i}=await import(`./audit-CfOJ3rNW.js`);process.exitCode=await i({cliVersion:z,action:n,since:t.since,filterAction:t.action,actor:t.actor,format:r,out:t.out,json:t.json})}),H.command(`share [action]`,`[ACCOUNT] share enable | disable | url — public dashboard share for the current site`).option(`--site-id <id>`,`Site ID (defaults to your current default site)`).option(`--yes`,`Skip confirmation (disable)`).option(`--json`,``).action(async(e,t)=>{let n=e??`url`,{shareCommand:r}=await import(`./share-BQjP_Anq.js`);process.exitCode=await r({cliVersion:z,action:n,siteId:t.siteId,yes:t.yes,json:t.json})}),H.command(`commands`,`Emit the machine-readable command tree (for AI agents and shell-completion regen)`).option(`--json`,``).action(async e=>{let{commandsCommand:t}=await import(`./commands-DbkdKFGz.js`);process.exitCode=await t({cliVersion:z,json:e.json})}),H.command(`teams [action] [arg]`,`[ACCOUNT] teams list | switch <name-or-id> | current | reset`).option(`--json`,``).action(async(e,t,n)=>{let r=e??`list`,{teamsCommand:i}=await import(`./teams-Dvh7_Gkg.js`);process.exitCode=await i({cliVersion:z,action:r,match:r===`switch`?t:void 0,json:n.json})}),H.parse(process.argv,{run:!1}),(async()=>{await T({binaryPath:B,currentVersion:z,argv:process.argv}),V();try{let e=H.matchedCommand,t=process.argv.slice(2).filter(e=>!e.startsWith(`-`)),n=process.argv.includes(`--help`)||process.argv.includes(`-h`);if(!e&&t.length>0&&!n&&(process.stderr.write(`Unknown command: \`${t.join(` `)}\`\nRun \`zenovay --help\` to see all commands.\n`),process.exit(2)),!e&&t.length===0&&!n){H.outputHelp();return}await H.runMatchedCommand()}catch(e){let t=F(e),n=process.env.ZENOVAY_FORMAT===`json`||process.argv.includes(`--json`)||process.argv.includes(`-q`)||process.argv.includes(`--quiet`);n?process.stderr.write(JSON.stringify(t)+`
|
|
7
|
+
`)}),B.command(`logout`,`Revoke current session and delete local auth`).option(`--json`,``).action(async e=>{let{logoutCommand:t}=await import(`./logout-Cp7T5T1Y.js`);await t({cliVersion:L,json:e.json})}),B.command(`ai`,`3-mode AI assistant (install / chat / mcp)`).option(`--mode <mode>`,`install | chat | mcp`).option(`--json`,``).action(async e=>{let{aiCommand:t}=await import(`./ai-Dz_MAHHV.js`),n=await t({cliVersion:L,cwd:process.cwd(),mode:e.mode,json:e.json});process.exitCode=n}),B.command(`watch`,"[ANALYTICS] Alias for `analytics` (dashboard summary)").option(`--site-id <id>`,`Site ID`).option(`--interval <ms>`,`Poll interval ms (legacy; ignored by analytics)`,{default:15e3}).option(`--json`,``).action(async e=>{let{analyticsCommand:t}=await import(`./analytics-5ztZSLLH.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`analytics`,`[ANALYTICS] Landing dashboard — visitors, pageviews, bounce, top pages`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{analyticsCommand:t}=await import(`./analytics-5ztZSLLH.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`overview`,"[ANALYTICS] Alias for `analytics`").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{analyticsCommand:t}=await import(`./analytics-5ztZSLLH.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`home`,`[ACCOUNT] Top-level summary — sites + this-week deltas`).option(`--json`,``).action(async e=>{let{homeCommand:t}=await import(`./home-DL_Ty0eK.js`);process.exitCode=await t({cliVersion:L,json:e.json})}),B.command(`live`,`[ANALYTICS] Real-time visitors + globe + recent events (2s polling)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{liveCommand:t}=await import(`./live-BO8Wl0Q3.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`pages`,`[ANALYTICS] Top pages by views — last 24h`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{pagesCommand:t}=await import(`./pages-Bi57FO27.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`devices`,`[ANALYTICS] Device / browser / OS breakdown — last 24h`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{devicesCommand:t}=await import(`./devices-BQnWRrD3.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`geo`,`[ANALYTICS] Countries + cities + globe — last 24h`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{geoCommand:t}=await import(`./geo-BAXdGLKJ.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`retention`,`[BEHAVIOR] Cohort retention heatmap — D1 / D7 / D30 (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{retentionCommand:t}=await import(`./retention-6HhdWwsd.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`uptime`,`[BEHAVIOR] Uptime monitors with status + p95 (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{uptimeCommand:t}=await import(`./uptime-Bmg-epd-.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`sessions`,`[BEHAVIOR] Recent session-replay list (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{sessionsCommand:t}=await import(`./sessions-CvSKjWsw.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`heatmaps`,`[BEHAVIOR] Recent heatmap captures (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{heatmapsCommand:t}=await import(`./heatmaps-DkY7BW0E.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`journeys`,`[BEHAVIOR] Page-to-page transition flow (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{journeysCommand:t}=await import(`./journeys-CQMP6cvE.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`insights`,`[INTELLIGENCE] AI-generated anomaly / trend / recommendation cards (Pro+)`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{insightsCommand:t}=await import(`./insights-BDxlGN5s.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json});process.exitCode=n}),B.command(`events tail`,`Stream live events`).option(`--site-id <id>`,`Site ID`,{default:``}).option(`--filter <expr>`,`Filter expression (e.g. 'type=pageview AND country=US')`).option(`--forward-to <url>`,`POST each event to a webhook with HMAC-SHA256 signature`).option(`--replay-24h`,`Replay the last 24h before going live`).option(`--set-forward-secret <hex>`,`Persist the HMAC secret used by --forward-to`).option(`--json`,``).action(async e=>{let{eventsTailCommand:t}=await import(`./events-tail-CE5QxNmF.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json,filter:e.filter,forwardTo:e.forwardTo,replay24h:e.replay24h,setForwardSecret:e.setForwardSecret});process.exitCode=n}),B.command(`health`,`Run self-diagnostic checks`).option(`--json`,``).action(async e=>{let{healthCommand:t}=await import(`./health-CAnAYv9x.js`),n=await t({cliVersion:L,binaryPath:R,json:e.json});process.exitCode=n}),B.command(`doctor`,`AI-assisted self-healing`).option(`--json`,``).action(async e=>{let{doctorCommand:t}=await import(`./doctor-DjmsSn5Z.js`),n=await t({cliVersion:L,binaryPath:R,json:e.json});process.exitCode=n}),B.command(`stats`,`One-shot dashboard summary (scriptable by default)`).option(`--site-id <id>`,`Site ID`).option(`--range <range>`,`Time range: 24h | 7d | 30d`,{default:`24h`}).option(`--watch`,`Auto-refresh every 60s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{statsCommand:t}=await import(`./stats-DRRgb-C3.js`),n=await t({cliVersion:L,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),B.command(`sources`,`Traffic source breakdown with delta arrows`).option(`--site-id <id>`,`Site ID`).option(`--period <p>`,`Period: 7d | 30d | 90d | 1y`,{default:`30d`}).option(`--compare <c>`,`Comparison window (use "prev" for period-over-period)`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{sourcesCommand:t}=await import(`./sources-Dtp05gd2.js`),n=await t({cliVersion:L,siteId:e.siteId,period:e.period,compare:e.compare,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),B.command(`vitals`,`Core Web Vitals dashboard (LCP / INP / CLS / TTFB / FCP)`).option(`--site-id <id>`,`Site ID`).option(`--url <path>`,`Filter to a single URL`).option(`--device <type>`,`Filter by device: mobile | desktop`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`7d`}).option(`--watch`,`Auto-refresh every 5 minutes`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{vitalsCommand:t}=await import(`./vitals-CRE0nVgp.js`),n=await t({cliVersion:L,siteId:e.siteId,url:e.url,device:e.device,window:e.window,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),B.command(`revenue`,`MRR / ARR / transaction series`).option(`--site-id <id>`,`Site ID`).option(`--range <r>`,`Time range: 24h | 7d | 30d | 1y`,{default:`30d`}).option(`--watch`,`Auto-refresh every 5 minutes`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{revenueCommand:t}=await import(`./revenue-CdXv5fdi.js`),n=await t({cliVersion:L,siteId:e.siteId,range:e.range,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),B.command(`funnels`,`List available funnels`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{funnelCommand:t}=await import(`./funnel-4A9Q_ZCD.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),B.command(`themes`,`List available themes with colored swatches`).option(`--validate <path>`,`Validate a custom theme JSON file`).option(`--json`,`Emit themes JSON to stdout`).action(async e=>{let{themesCommand:t}=await import(`./themes-DVChFf6Y.js`),n=await t({cliVersion:L,validate:e.validate,json:e.json});process.exitCode=n}),B.command(`completions [shell]`,`Emit shell-completion script (bash | zsh | fish | nushell | pwsh)`).option(`--list`,`List supported shells`).action(async(e,t)=>{let{completionsCommand:n}=await import(`./completions-Ba0Zr-G3.js`),r=await n({shell:e,list:t.list});process.exitCode=r}),B.command(`query [sql]`,`Restricted SQL REPL over the analytics schema (Scale+)`).option(`--site-id <id>`,`Site ID`).option(`--max-rows <n>`,`Cap result row count`,{default:1e3}).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async(e,t)=>{let{queryCommand:n}=await import(`./query-BmeQkD1w.js`),r=await n({cliVersion:L,siteId:t.siteId,sql:e,maxRows:typeof t.maxRows==`string`?Number(t.maxRows):t.maxRows,json:t.json,csv:t.csv,tsv:t.tsv,ndjson:t.ndjson});process.exitCode=r}),B.command(`companies`,`B2B identification feed (Scale+)`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`24h`}).option(`--limit <n>`,`Max rows`,{default:100}).option(`--new-only`,`Show only newly identified companies (first-seen in last hour)`).option(`--watch`,`Auto-refresh every 30s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{companiesCommand:t}=await import(`./companies-CH3F-hmU.js`),n=await t({cliVersion:L,siteId:e.siteId,window:e.window,limit:typeof e.limit==`string`?Number(e.limit):e.limit,newOnly:e.newOnly,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),B.command(`projects`,`List your tracked projects`).option(`--site-id <id>`,`Site ID`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{projectsCommand:t}=await import(`./projects-t5f3WFmw.js`),n=await t({cliVersion:L,siteId:e.siteId,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),B.command(`deploys`,`[OPERATIONS] Recent deploy markers overlaid on charts`).option(`--site-id <id>`,`Site ID`).option(`--branch <name>`,`Filter to a single branch (e.g. main, develop)`).option(`--since <iso>`,`Only commits after this ISO timestamp`).option(`--limit <n>`,`Max rows`,{default:50}).option(`--connect`,`Print the GitHub-integration deep link in app.zenovay.com`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{deploysCommand:t}=await import(`./deploys-B79-S9yT.js`),n=await t({cliVersion:L,siteId:e.siteId,branch:e.branch,since:e.since,limit:typeof e.limit==`string`?Number(e.limit):e.limit,connect:e.connect,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),B.command(`webhooks forward`,`[OPERATIONS] Forward webhook events to a local URL (stripe-listen-style tunnel)`).option(`--to <url>`,`Local URL to POST events to (e.g. localhost:3000/webhook)`).option(`--site-id <id>`,`Site ID`).option(`--sign`,`HMAC-sign each forwarded request with X-Zenovay-Signature`).option(`--secret <hex>`,`HMAC secret (auto-derived from tunnel key if --sign without --secret)`).option(`--max-retries <n>`,`Per-request retry count`,{default:3}).action(async e=>{let{webhooksForwardCommand:t}=await import(`./webhooks-forward-X4iUnLrU.js`),n=await t({cliVersion:L,to:e.to,siteId:e.siteId,sign:e.sign,secret:e.secret,maxRetries:typeof e.maxRetries==`string`?Number(e.maxRetries):e.maxRetries});process.exitCode=n}),B.command(`errors`,`[BEHAVIOR] Recent JS / HTTP error snapshot`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 24h | 7d | 30d | 90d`,{default:`24h`}).option(`--limit <n>`,`Max errors to fetch`,{default:100}).option(`--search <q>`,`Filter by class or message substring`).option(`--watch`,`Auto-refresh every 30s`).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async e=>{let{errorsCommand:t}=await import(`./errors-CmbIkaPX.js`),n=await t({cliVersion:L,siteId:e.siteId,window:e.window,limit:typeof e.limit==`string`?Number(e.limit):e.limit,search:e.search,watch:e.watch,json:e.json,csv:e.csv,tsv:e.tsv,ndjson:e.ndjson});process.exitCode=n}),B.command(`funnel <id>`,`Funnel drop-off chart for a specific funnel`).option(`--site-id <id>`,`Site ID`).option(`--window <w>`,`Time window: 7d | 30d`,{default:`30d`}).option(`--json`,``).option(`--csv`,``).option(`--tsv`,``).option(`--ndjson`,``).action(async(e,t)=>{let{funnelCommand:n}=await import(`./funnel-4A9Q_ZCD.js`),r=await n({cliVersion:L,siteId:t.siteId,funnelId:e,window:t.window,json:t.json,csv:t.csv,tsv:t.tsv,ndjson:t.ndjson});process.exitCode=r}),B.command(`api-keys [action] [id]`,`[MANAGE] api-keys list | create [--name --scope] | delete <id>`).option(`--name <n>`,`Human-readable label (create)`).option(`--scope <scope>`,`read | write (create)`,{default:`read`}).option(`--yes`,`Skip confirmation (delete)`).option(`--json`,``).action(async(e,t,n)=>{let{apiKeysCommand:r}=await import(`./api-keys-D85DV2qg.js`),i=e??`list`;process.exitCode=await r({cliVersion:L,action:i,id:t,name:n.name,scope:n.scope===`write`?`write`:`read`,yes:n.yes,json:n.json})}),B.command(`domains [action] [arg]`,`[MANAGE] domains list | add <url> [--name] | delete <id>`).option(`--name <n>`,`Friendly project name (add; default: domain itself)`).option(`--yes`,`Skip confirmation (delete)`).option(`--json`,``).action(async(e,t,n)=>{let{domainsCommand:r}=await import(`./domains-Bg3Tt8bm.js`),i=e??`list`;process.exitCode=await r({cliVersion:L,action:i,url:i===`add`?t:void 0,id:i===`delete`?t:void 0,name:n.name,yes:n.yes,json:n.json})}),B.command(`team [action] [arg] [arg2]`,`[MANAGE] team list | invite <email> [--role] | remove <userId> | role <userId> <admin|member> (Pro+)`).option(`--role <role>`,`admin | member (invite)`,{default:`member`}).option(`--yes`,`Skip confirmation (remove)`).option(`--json`,``).action(async(e,t,n,r)=>{let{teamCommand:i}=await import(`./team-q747Nwe6.js`),a=e??`list`,o;a===`role`?o=n===`admin`?`admin`:`member`:a===`invite`&&(o=r.role===`admin`?`admin`:`member`),process.exitCode=await i({cliVersion:L,action:a,email:a===`invite`?t:void 0,userId:a===`remove`||a===`role`?t:void 0,role:o,yes:r.yes,json:r.json})}),B.command(`profile [action]`,`[ACCOUNT] profile show | edit [--name --notifications]`).option(`--name <n>`,`New display name (edit)`).option(`--notifications <pref>`,`email | none (edit)`).option(`--json`,``).action(async(e,t)=>{let n=e??`show`,r=t.notifications===`email`||t.notifications===`none`?t.notifications:void 0,{profileCommand:i}=await import(`./profile-GGQyYHdV.js`);process.exitCode=await i({cliVersion:L,action:n,name:t.name,notifications:r,json:t.json})}),B.command(`plans [action] [arg] [arg2]`,`[ACCOUNT] plans info | upgrade <pro|scale> | cancel --yes | payment update`).option(`--yes`,"Required for `cancel`").option(`--json`,``).action(async(e,t,n,r)=>{let i=e??`info`,{plansCommand:a}=await import(`./plans-BXm8QsVF.js`),o;if(i===`upgrade`&&t){let e=String(t).toLowerCase();(e===`pro`||e===`scale`||e===`enterprise`)&&(o=e)}let s=i===`payment`&&t===`update`||i===`payment`?`update`:void 0;process.exitCode=await a({cliVersion:L,action:i,targetPlan:o,paymentAction:s,yes:r.yes,json:r.json})}),B.command(`billing [action]`,"[ACCOUNT] Alias for `plans info`").option(`--json`,``).action(async(e,t)=>{let{plansCommand:n}=await import(`./plans-BXm8QsVF.js`);process.exitCode=await n({cliVersion:L,action:`info`,json:t.json})}),B.command(`settings [action] [key] [value]`,`[ACCOUNT] settings get [key] | set <key> <value>`).option(`--json`,``).action(async(e,t,n,r)=>{let i=e??`get`,{settingsCommand:a}=await import(`./settings-CtEE3MFe.js`);process.exitCode=await a({cliVersion:L,action:i,key:t||void 0,value:n||void 0,json:r.json})}),B.command(`integrations [action] [name]`,`[ACCOUNT] integrations list | connect <gsc|github> | disconnect <gsc|github>`).option(`--yes`,`Skip confirmation (disconnect)`).option(`--json`,``).action(async(e,t,n)=>{let r=e??`list`,i=t===`gsc`||t===`github`?t:void 0,{integrationsCommand:a}=await import(`./integrations-Eu2LbV95.js`);process.exitCode=await a({cliVersion:L,action:r,name:i,yes:n.yes,json:n.json})}),B.command(`goals [action] [id]`,`[ACCOUNT] goals list | create [--name --type --target] | delete <id> (Pro+)`).option(`--name <n>`,`Goal name (create)`).option(`--type <t>`,`pageview | event (create)`).option(`--target <v>`,`URL pattern or event name (create)`).option(`--yes`,`Skip confirmation (delete)`).option(`--json`,``).action(async(e,t,n)=>{let r=e??`list`,i=n.type===`event`||n.type===`pageview`?n.type:void 0,{goalsCommand:a}=await import(`./goals-B32fvItX.js`);process.exitCode=await a({cliVersion:L,action:r,id:t,name:n.name,type:i,target:n.target,yes:n.yes,json:n.json})}),B.command(`notes [action] [id]`,`[ACCOUNT] notes list | create [--content --site-id] | delete <id>`).option(`--content <text>`,`Note body (create)`).option(`--site-id <id>`,`Attach to a specific site (create; defaults to current)`).option(`--yes`,`Skip confirmation (delete)`).option(`--json`,``).action(async(e,t,n)=>{let r=e??`list`,{notesCommand:i}=await import(`./notes-BsegG0Q-.js`);process.exitCode=await i({cliVersion:L,action:r,id:t,content:n.content,siteId:n.siteId,yes:n.yes,json:n.json})}),B.command(`agency [action] [arg] [arg2]`,`[ACCOUNT] agency clients list | clients add [--email --name] | clients remove <id> | report send <clientId> (Scale+)`).option(`--email <e>`,`Client contact email (clients add)`).option(`--name <n>`,`Client name (clients add)`).option(`--yes`,`Skip confirmation (clients remove)`).option(`--json`,``).action(async(e,t,n,r)=>{let{agencyCommand:i}=await import(`./agency-Ba8f5PMP.js`),a=`clients-list`,o;e===`clients`?t===`add`?a=`clients-add`:t===`remove`?(a=`clients-remove`,o=n):a=`clients-list`:e===`report`&&t===`send`&&(a=`report-send`,o=n),process.exitCode=await i({cliVersion:L,action:a,id:o,email:r.email,name:r.name,yes:r.yes,json:r.json})}),B.command(`analytics live`,"[ANALYTICS] Alias for `live`").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{liveCommand:t}=await import(`./live-BO8Wl0Q3.js`);process.exitCode=await t({cliVersion:L,siteId:e.siteId,json:e.json})}),B.command(`analytics funnels`,"[ANALYTICS] Alias for `funnels`").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{funnelCommand:t}=await import(`./funnel-4A9Q_ZCD.js`);process.exitCode=await t({cliVersion:L,siteId:e.siteId,json:e.json})}),B.command(`analytics goals`,"[ANALYTICS] Alias for `goals list` (Pro+)").option(`--json`,``).action(async e=>{let{goalsCommand:t}=await import(`./goals-B32fvItX.js`);process.exitCode=await t({cliVersion:L,action:`list`,json:e.json})}),B.command(`analytics insights`,"[ANALYTICS] Alias for `insights` (Pro+)").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{insightsCommand:t}=await import(`./insights-BDxlGN5s.js`);process.exitCode=await t({cliVersion:L,siteId:e.siteId,json:e.json})}),B.command(`analytics profiles`,"[ANALYTICS] User-profiles list (NOT `profile`, which is current-user)").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{visitorsCommand:t}=await import(`./visitors-D7FmGVz1.js`);process.exitCode=await t({cliVersion:L,siteId:e.siteId,json:e.json})}),B.command(`analytics companies`,"[ANALYTICS] Alias for `companies` (Scale+)").option(`--site-id <id>`,`Site ID`).option(`--json`,``).action(async e=>{let{companiesCommand:t}=await import(`./companies-CH3F-hmU.js`);process.exitCode=await t({cliVersion:L,siteId:e.siteId,json:e.json})}),B.command(`use [site]`,`Set / show / reset your default site (used when --site-id is omitted)`).option(`--reset`,`Clear the stored default site`).option(`--show`,`Print the current default and exit`).option(`--json`,`Emit JSON`).action(async(e,t)=>{let{useCommand:n}=await import(`./use-SGwWI1Rq.js`),r=await n({cliVersion:L,match:e,reset:t.reset,show:t.show,json:t.json});process.exitCode=r}),B.command(`update`,`Manually install the latest version`).option(`--check`,`Don't install — just print latest`).option(`--force-downgrade`,`Allow downgrading to an older version`).option(`--no-update-check`,`Disable auto-update for this invocation`).option(`--json`,``).action(async e=>{let{updateCommand:t}=await import(`./update-DrsZLYAQ.js`);await t({cliVersion:L,binaryPath:R,check:e.check,forceDowngrade:e.forceDowngrade,json:e.json})}),B.command(`usage`,`[ACCOUNT] Current month events vs plan limits + headcounts`).option(`--json`,``).action(async e=>{let{usageCommand:t}=await import(`./usage-ZJK4hekT.js`);process.exitCode=await t({cliVersion:L,json:e.json})}),B.command(`globe`,`[ANALYTICS] Live 3D globe — visitors plotted on a Braille sphere`).option(`--site-id <id>`,`Site ID`).option(`--browser`,`Open the dashboard's Mapbox globe in your browser instead of the terminal version`).option(`--json`,``).action(async e=>{let{globeCommand:t}=await import(`./globe-DMOyP2MN.js`);process.exitCode=await t({cliVersion:L,siteId:e.siteId,browser:e.browser,json:e.json})}),B.command(`webhooks [action] [arg]`,`[MANAGE] webhooks list | add <url> [--events] | delete <id> | rotate <id> | test <id>`).option(`--events <list>`,`Comma-separated event types (add)`).option(`--yes`,`Skip confirmation (delete/rotate)`).option(`--json`,``).action(async(e,t,n)=>{let r=e??`list`,{webhooksCommand:i}=await import(`./webhooks-Ck6zBgz3.js`);process.exitCode=await i({cliVersion:L,action:r,url:r===`add`?t:void 0,id:r===`delete`||r===`rotate`||r===`test`?t:void 0,events:n.events,yes:n.yes,json:n.json})}),B.command(`audit [action]`,`[ACCOUNT] audit list [--since --action --actor] | export [--format --out] (Pro+)`).option(`--since <window>`,`Window like 24h, 7d, 30d (list)`,{default:`7d`}).option(`--action <pattern>`,`Filter by action string (list)`).option(`--actor <userId>`,`Filter by actor user ID (list)`).option(`--format <fmt>`,`ndjson | csv | json (export)`,{default:`ndjson`}).option(`--out <file>`,`Output file path (export). Defaults to stdout`).option(`--json`,``).action(async(e,t)=>{let n=e??`list`,r=t.format===`csv`||t.format===`json`?t.format:`ndjson`,{auditCommand:i}=await import(`./audit-DqPlGP-B.js`);process.exitCode=await i({cliVersion:L,action:n,since:t.since,filterAction:t.action,actor:t.actor,format:r,out:t.out,json:t.json})}),B.command(`share [action]`,`[ACCOUNT] share enable | disable | url — public dashboard share for the current site`).option(`--site-id <id>`,`Site ID (defaults to your current default site)`).option(`--yes`,`Skip confirmation (disable)`).option(`--json`,``).action(async(e,t)=>{let n=e??`url`,{shareCommand:r}=await import(`./share-5a0qKu3z.js`);process.exitCode=await r({cliVersion:L,action:n,siteId:t.siteId,yes:t.yes,json:t.json})}),B.command(`commands`,`Emit the machine-readable command tree (for AI agents and shell-completion regen)`).option(`--json`,``).action(async e=>{let{commandsCommand:t}=await import(`./commands-BrU-VT7M.js`);process.exitCode=await t({cliVersion:L,json:e.json})}),B.command(`teams [action] [arg]`,`[ACCOUNT] teams list | switch <name-or-id> | current | reset`).option(`--json`,``).action(async(e,t,n)=>{let r=e??`list`,{teamsCommand:i}=await import(`./teams-nDIrOaly.js`);process.exitCode=await i({cliVersion:L,action:r,match:r===`switch`?t:void 0,json:n.json})}),B.command(`self-test`,`[OPERATIONS] Run all read commands + security probes; print pass/fail summary`).option(`--quick`,`Run a 10-test subset (faster)`).option(`--verbose`,`Include full stdout/stderr per test`).option(`--parallel <n>`,`Concurrent subprocesses (default 4)`,{default:4}).option(`--json`,`Emit NDJSON one line per test result + final summary`).action(async e=>{let{selfTestCommand:t}=await import(`./self-test-BSSwSeXl.js`);process.exitCode=await t({cliVersion:L,quick:!!e.quick,verbose:!!e.verbose,parallel:Number(e.parallel)||4,json:!!e.json})}),B.command(`tour`,`[OPERATIONS] Interactive 8-step walkthrough of the CLI`).option(`--non-interactive`,`Print all 8 steps as a flat document (no prompts)`).action(async e=>{let{tourCommand:t}=await import(`./tour-Dp2WmQUO.js`);process.exitCode=await t({cliVersion:L,nonInteractive:!!(e[`non-interactive`]||e.nonInteractive)})}),B.command(`alerts [action] [id]`,`[MANAGE] alerts list | create [--metric --op --threshold --window] | delete <id> (Pro+)`).option(`--site-id <id>`,`Site ID (defaults to your current default site)`).option(`--metric <name>`,`Metric to watch (visitors|pageviews|bounce_rate|errors|lcp|inp|cls|uptime|revenue)`).option(`--op <gt|lt>`,`Comparison operator`).option(`--threshold <num>`,`Numeric threshold`).option(`--window <e.g. 1h>`,`Rolling window (5m|1h|24h|7d)`).option(`--name <label>`,`Optional friendly label for the alert`).option(`--channel <chan>`,`Notification channel: in_app | email | webhook (default in_app)`).option(`--email <addr>`,`Notification email (required when --channel email)`).option(`--yes`,`Skip confirmation prompt on delete`).option(`--json`,``).action(async(e,t,n)=>{let r=e??`list`,i=new Set([`list`,`create`,`delete`]);i.has(r)||(process.stderr.write(n.json?JSON.stringify({type:`error`,code:`validation_failed`,message:`Unknown alerts action: ${e}`,hint:`Run zenovay alerts --help`})+`
|
|
8
|
+
`:`\n✗ Unknown action: '${e}'\n Valid: list | create | delete. Run \`zenovay alerts --help\`\n`),process.exit(2));let{alertsCommand:a}=await import(`./alerts-qoMz5CX-.js`);process.exitCode=await a({cliVersion:L,action:r,siteId:n.siteId,metric:n.metric,op:n.op,threshold:n.threshold,window:n.window,id:t,yes:!!n.yes,json:!!n.json})}),B.command(`export <type>`,`[OPERATIONS] Export data: analytics | sessions (Pro+) | heatmaps (Pro+)`).option(`--site-id <id>`,`Site ID (defaults to your current default site)`).option(`--range <range>`,`Time range: 7d | 30d | 90d`,{default:`30d`}).option(`--format <fmt>`,`Output format: csv | json`,{default:`csv`}).option(`--out <file>`,`Write to file instead of stdout`).option(`--json`,``).action(async(e,t)=>{let n=new Set([`analytics`,`sessions`,`heatmaps`]);n.has(e)||(process.stderr.write(t.json?JSON.stringify({type:`error`,code:`validation_failed`,message:`Unknown export type: ${e}`,hint:`Valid: analytics | sessions | heatmaps`})+`
|
|
9
|
+
`:`\n✗ Unknown export type: '${e}'\n Valid: analytics | sessions | heatmaps. Run \`zenovay export --help\`\n`),process.exit(2));let r=t.format===`json`?`json`:`csv`,{exportCommand:i}=await import(`./export-CNhqB2nk.js`);process.exitCode=await i({type:e,cliVersion:L,siteId:t[`site-id`]||t.siteId,range:t.range,format:r,out:t.out,json:!!t.json})}),B.command(`visitors`,`[ANALYTICS] Live visitor table with sortable rows`).option(`--site-id <id>`,`Site ID`).option(`--min-duration <seconds>`,`Filter to sessions ≥ N seconds`,{default:0}).option(`--json`,``).action(async e=>{let{visitorsCommand:t}=await import(`./visitors-D7FmGVz1.js`);process.exitCode=await t({cliVersion:L,siteId:e.siteId,minDuration:Number(e[`min-duration`]||e.minDuration)||0,json:!!e.json})}),B.command(`status`,"[OPERATIONS] Alias of `health` — self-diagnostic checks").option(`--json`,``).action(async e=>{let{healthCommand:t}=await import(`./health-CAnAYv9x.js`);process.exitCode=await t({cliVersion:L,binaryPath:R,json:!!e.json})}),B.parse(process.argv,{run:!1}),(async()=>{await T({binaryPath:R,currentVersion:L,argv:process.argv}),z();try{let e=B.matchedCommand,t=process.argv.slice(2).filter(e=>!e.startsWith(`-`)),n=process.argv.includes(`--help`)||process.argv.includes(`-h`);if(!e&&t.length>0&&!n&&(process.stderr.write(`Unknown command: \`${t.join(` `)}\`\nRun \`zenovay --help\` to see all commands.\n`),process.exit(2)),!e&&t.length===0&&!n){B.outputHelp();return}await B.runMatchedCommand()}catch(e){let t=i(e),n=process.env.ZENOVAY_FORMAT===`json`||process.argv.includes(`--json`)||process.argv.includes(`-q`)||process.argv.includes(`--quiet`);n?process.stderr.write(JSON.stringify(t)+`
|
|
8
10
|
`):(process.stderr.write(`\n✗ ${t.message}\n`),t.hint&&process.stderr.write(` ${t.hint}\n`)),process.exit(1)}})();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"./formatter-mW0Yk3Nt.js";import{isHeadless as e}from"./emit-DBbMG9mK.js";const t={flag:`--site-id <id>`,description:`Site ID`},n={flag:`--json`,description:`Emit JSON`},r=[n,{flag:`--csv`,description:`Emit CSV`},{flag:`--tsv`,description:`Emit TSV`},{flag:`--ndjson`,description:`Emit NDJSON`}],i=[{name:`analytics`,description:`Landing dashboard — visitors, pageviews, bounce, top pages`,group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`overview`,description:"Alias for `analytics` (kept for back-compat)",group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`watch`,description:"Alias for `analytics` (deprecated)",group:`ANALYTICS`,tier:`free`,options:[t,{flag:`--interval <ms>`,description:`Poll interval ms (legacy; ignored)`,default:15e3},n]},{name:`home`,description:`Top-level summary — sites + this-week deltas`,group:`ANALYTICS`,tier:`free`,options:[n]},{name:`live`,description:`Real-time visitors + globe + recent events (2s polling)`,group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`pages`,description:`Top pages by views — last 24h`,group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`devices`,description:`Device / browser / OS breakdown — last 24h`,group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`geo`,description:`Countries + cities + globe — last 24h`,group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`sources`,description:`Traffic source breakdown with delta arrows`,group:`ANALYTICS`,tier:`free`,options:[t,{flag:`--period <p>`,description:`7d | 30d | 90d | 1y`,default:`30d`},{flag:`--compare <c>`,description:`Comparison window (use "prev" for period-over-period)`},...r]},{name:`revenue`,description:`MRR / ARR / transaction series`,group:`ANALYTICS`,tier:`free`,options:[t,{flag:`--range <r>`,description:`24h | 7d | 30d | 1y`,default:`30d`},{flag:`--watch`,description:`Auto-refresh every 5 minutes`},...r]},{name:`stats`,description:`One-shot dashboard summary (scriptable by default)`,group:`ANALYTICS`,tier:`free`,options:[t,{flag:`--range <range>`,description:`24h | 7d | 30d`,default:`24h`},{flag:`--watch`,description:`Auto-refresh every 60s`},...r]},{name:`globe`,description:"Hint — use `zenovay live` for the terminal real-time view",group:`ANALYTICS`,tier:`free`,options:[n]},{name:`vitals`,description:`Core Web Vitals dashboard (LCP / INP / CLS / TTFB / FCP)`,group:`BEHAVIOR`,tier:`pro`,options:[t,{flag:`--url <path>`,description:`Filter to a single URL`},{flag:`--device <type>`,description:`mobile | desktop`},{flag:`--window <w>`,description:`24h | 7d | 30d | 90d`,default:`7d`},{flag:`--watch`,description:`Auto-refresh every 5 minutes`},...r]},{name:`retention`,description:`Cohort retention heatmap — D1 / D7 / D30 (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,n]},{name:`uptime`,description:`Uptime monitors with status + p95 (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,n]},{name:`sessions`,description:`Recent session-replay list (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,n]},{name:`heatmaps`,description:`Recent heatmap captures (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,n]},{name:`journeys`,description:`Page-to-page transition flow (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,n]},{name:`errors`,description:`Recent error snapshot (SSE coming in V2.1)`,group:`BEHAVIOR`,tier:`pro`,options:[t,{flag:`--window <w>`,description:`24h | 7d | 30d | 90d`,default:`24h`},{flag:`--limit <n>`,description:`Max errors to fetch`,default:100},{flag:`--search <q>`,description:`Filter by class or message substring`},{flag:`--watch`,description:`Auto-refresh every 30s`},...r]},{name:`funnels`,description:`List available funnels (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,...r]},{name:`funnel`,description:`Funnel drop-off chart for a specific funnel (Pro+)`,group:`BEHAVIOR`,tier:`pro`,actions:[`<id>`],options:[t,{flag:`--window <w>`,description:`7d | 30d`,default:`30d`},...r]},{name:`insights`,description:`AI-generated anomaly / trend / recommendation cards (Pro+)`,group:`INTELLIGENCE`,tier:`pro`,options:[t,n]},{name:`companies`,description:`B2B identification feed (Scale+)`,group:`INTELLIGENCE`,tier:`scale`,options:[t,{flag:`--window <w>`,description:`24h | 7d | 30d | 90d`,default:`24h`},{flag:`--limit <n>`,description:`Max rows`,default:100},{flag:`--new-only`,description:`Show only newly identified companies (first-seen in last hour)`},{flag:`--watch`,description:`Auto-refresh every 30s`},...r]},{name:`query`,description:`Restricted SQL REPL over the analytics schema (Scale+)`,group:`INTELLIGENCE`,tier:`scale`,actions:[`[sql]`],options:[t,{flag:`--max-rows <n>`,description:`Cap result row count`,default:1e3},...r]},{name:`ai`,description:`3-mode AI assistant (install / chat / mcp)`,group:`INTELLIGENCE`,tier:`free`,options:[{flag:`--mode <mode>`,description:`install | chat | mcp`},n]},{name:`api-keys`,description:`API key management`,group:`MANAGE`,tier:`free`,actions:[`list`,`create`,`delete`],options:[{flag:`--name <n>`,description:`Human-readable label (create)`},{flag:`--scope <scope>`,description:`read | write (create)`,default:`read`},{flag:`--yes`,description:`Skip confirmation (delete)`},n]},{name:`domains`,description:`Domain (tracked-website) management`,group:`MANAGE`,tier:`free`,actions:[`list`,`add`,`delete`],options:[{flag:`--name <n>`,description:`Friendly project name (add; default: domain itself)`},{flag:`--yes`,description:`Skip confirmation (delete)`},n]},{name:`team`,description:`Team member + invitation management (Pro+)`,group:`MANAGE`,tier:`pro`,actions:[`list`,`invite`,`remove`,`role`],options:[{flag:`--role <role>`,description:`admin | member (invite)`,default:`member`},{flag:`--yes`,description:`Skip confirmation (remove)`},n]},{name:`profile`,description:`Current-user profile`,group:`ACCOUNT`,tier:`free`,actions:[`show`,`edit`],options:[{flag:`--name <n>`,description:`New display name (edit)`},{flag:`--notifications <pref>`,description:`email | none (edit)`},n]},{name:`plans`,description:`Subscription plan management`,group:`ACCOUNT`,tier:`free`,actions:[`info`,`upgrade`,`cancel`,`payment`],options:[{flag:`--yes`,description:"Required for `cancel`"},n]},{name:`billing`,description:"Alias for `plans info`",group:`ACCOUNT`,tier:`free`,options:[n]},{name:`settings`,description:`Get / set user settings`,group:`ACCOUNT`,tier:`free`,actions:[`get`,`set`],options:[n]},{name:`integrations`,description:`Connect / disconnect external integrations (gsc, github)`,group:`ACCOUNT`,tier:`free`,actions:[`list`,`connect`,`disconnect`],options:[{flag:`--yes`,description:`Skip confirmation (disconnect)`},n]},{name:`goals`,description:`Goal management (Pro+)`,group:`ACCOUNT`,tier:`pro`,actions:[`list`,`create`,`delete`],options:[{flag:`--name <n>`,description:`Goal name (create)`},{flag:`--type <t>`,description:`pageview | event (create)`},{flag:`--target <v>`,description:`URL pattern or event name (create)`},{flag:`--yes`,description:`Skip confirmation (delete)`},n]},{name:`notes`,description:`Annotation / note management`,group:`ACCOUNT`,tier:`free`,actions:[`list`,`create`,`delete`],options:[{flag:`--content <text>`,description:`Note body (create)`},{flag:`--site-id <id>`,description:`Attach to a specific site (create; defaults to current)`},{flag:`--yes`,description:`Skip confirmation (delete)`},n]},{name:`agency`,description:`Agency client + report management (Scale+)`,group:`ACCOUNT`,tier:`scale`,actions:[`clients list`,`clients add`,`clients remove`,`report send`],options:[{flag:`--email <e>`,description:`Client contact email (clients add)`},{flag:`--name <n>`,description:`Client name (clients add)`},{flag:`--yes`,description:`Skip confirmation (clients remove)`},n]},{name:`usage`,description:`Current month events vs plan limits + headcounts`,group:`ACCOUNT`,tier:`free`,options:[n]},{name:`events tail`,description:`Stream live events`,group:`OPERATIONS`,tier:`free`,options:[{flag:`--site-id <id>`,description:`Site ID`,default:``},{flag:`--filter <expr>`,description:`Filter expression (e.g. 'type=pageview AND country=US')`},{flag:`--forward-to <url>`,description:`POST each event to a webhook with HMAC-SHA256 signature`},{flag:`--replay-24h`,description:`Replay the last 24h before going live`},{flag:`--set-forward-secret <hex>`,description:`Persist the HMAC secret used by --forward-to`},n]},{name:`deploys`,description:`Recent GitHub commits overlaid on charts`,group:`OPERATIONS`,tier:`free`,options:[t,{flag:`--branch <name>`,description:`Filter to a single branch (e.g. main, develop)`},{flag:`--since <iso>`,description:`Only commits after this ISO timestamp`},{flag:`--limit <n>`,description:`Max rows`,default:50},{flag:`--connect`,description:`Print the GitHub-integration deep link in app.zenovay.com`},...r]},{name:`webhooks forward`,description:`Forward webhook events to a local URL (stripe-listen-style)`,group:`OPERATIONS`,tier:`free`,options:[{flag:`--to <url>`,description:`Local URL to POST events to (e.g. localhost:3000/webhook)`},t,{flag:`--sign`,description:`HMAC-sign each forwarded request with X-Zenovay-Signature`},{flag:`--secret <hex>`,description:`HMAC secret (auto-derived from tunnel key if --sign without --secret)`},{flag:`--max-retries <n>`,description:`Per-request retry count`,default:3}]},{name:`projects`,description:`List your tracked projects`,group:`OPERATIONS`,tier:`free`,options:[t,...r]},{name:`use`,description:`Set / show / reset your default site (used when --site-id is omitted)`,group:`OPERATIONS`,tier:`free`,actions:[`[site]`],options:[{flag:`--reset`,description:`Clear the stored default site`},{flag:`--show`,description:`Print the current default and exit`},n]},{name:`init`,description:`AI install wizard — add Zenovay tracking to your codebase`,group:`OPERATIONS`,tier:`free`,options:[{flag:`--json`,description:`Emit NDJSON events to stdout`},{flag:`--yes`,description:`Auto-approve all diffs (for CI)`},{flag:`--skip-mcp`,description:`Skip MCP client install`},{flag:`--skip-verify`,description:`Skip first-event verification`}]},{name:`login`,description:`Authenticate via OAuth device flow`,group:`OPERATIONS`,tier:`free`,options:[n,{flag:`--no-browser`,description:`Skip opening the browser automatically`}]},{name:`logout`,description:`Revoke current session and delete local auth`,group:`OPERATIONS`,tier:`free`,options:[n]},{name:`health`,description:`Run self-diagnostic checks`,group:`OPERATIONS`,tier:`free`,options:[n]},{name:`doctor`,description:`AI-assisted self-healing + AI-agent detection`,group:`OPERATIONS`,tier:`free`,options:[n]},{name:`update`,description:`Manually install the latest version`,group:`OPERATIONS`,tier:`free`,options:[{flag:`--check`,description:`Don't install — just print latest`},{flag:`--force-downgrade`,description:`Allow downgrading to an older version`},{flag:`--no-update-check`,description:`Disable auto-update for this invocation`},n]},{name:`themes`,description:`List available themes with colored swatches`,group:`OPERATIONS`,tier:`free`,options:[{flag:`--validate <path>`,description:`Validate a custom theme JSON file`},n]},{name:`completions`,description:`Emit shell-completion script (bash | zsh | fish | nushell | pwsh)`,group:`OPERATIONS`,tier:`free`,actions:[`[shell]`],options:[{flag:`--list`,description:`List supported shells`}]},{name:`commands`,description:`Dump the full command tree as JSON (for AI-agent discovery)`,group:`OPERATIONS`,tier:`free`,options:[n]}];async function a(t){let n={version:t.cliVersion,commands:i},r=e({json:t.json}),a=JSON.stringify(n,null,r?0:2);return process.stdout.write(a+`
|
|
1
|
+
import"./formatter-KOe_hjhc.js";import{isHeadless as e}from"./emit-B8RbnBJe.js";const t={flag:`--site-id <id>`,description:`Site ID`},n={flag:`--json`,description:`Emit JSON`},r=[n,{flag:`--csv`,description:`Emit CSV`},{flag:`--tsv`,description:`Emit TSV`},{flag:`--ndjson`,description:`Emit NDJSON`}],i=[{name:`analytics`,description:`Landing dashboard — visitors, pageviews, bounce, top pages`,group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`overview`,description:"Alias for `analytics` (kept for back-compat)",group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`watch`,description:"Alias for `analytics` (deprecated)",group:`ANALYTICS`,tier:`free`,options:[t,{flag:`--interval <ms>`,description:`Poll interval ms (legacy; ignored)`,default:15e3},n]},{name:`home`,description:`Top-level summary — sites + this-week deltas`,group:`ANALYTICS`,tier:`free`,options:[n]},{name:`live`,description:`Real-time visitors + globe + recent events (2s polling)`,group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`pages`,description:`Top pages by views — last 24h`,group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`devices`,description:`Device / browser / OS breakdown — last 24h`,group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`geo`,description:`Countries + cities + globe — last 24h`,group:`ANALYTICS`,tier:`free`,options:[t,n]},{name:`sources`,description:`Traffic source breakdown with delta arrows`,group:`ANALYTICS`,tier:`free`,options:[t,{flag:`--period <p>`,description:`7d | 30d | 90d | 1y`,default:`30d`},{flag:`--compare <c>`,description:`Comparison window (use "prev" for period-over-period)`},...r]},{name:`revenue`,description:`MRR / ARR / transaction series`,group:`ANALYTICS`,tier:`free`,options:[t,{flag:`--range <r>`,description:`24h | 7d | 30d | 1y`,default:`30d`},{flag:`--watch`,description:`Auto-refresh every 5 minutes`},...r]},{name:`stats`,description:`One-shot dashboard summary (scriptable by default)`,group:`ANALYTICS`,tier:`free`,options:[t,{flag:`--range <range>`,description:`24h | 7d | 30d`,default:`24h`},{flag:`--watch`,description:`Auto-refresh every 60s`},...r]},{name:`globe`,description:"Hint — use `zenovay live` for the terminal real-time view",group:`ANALYTICS`,tier:`free`,options:[n]},{name:`vitals`,description:`Core Web Vitals dashboard (LCP / INP / CLS / TTFB / FCP)`,group:`BEHAVIOR`,tier:`pro`,options:[t,{flag:`--url <path>`,description:`Filter to a single URL`},{flag:`--device <type>`,description:`mobile | desktop`},{flag:`--window <w>`,description:`24h | 7d | 30d | 90d`,default:`7d`},{flag:`--watch`,description:`Auto-refresh every 5 minutes`},...r]},{name:`retention`,description:`Cohort retention heatmap — D1 / D7 / D30 (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,n]},{name:`uptime`,description:`Uptime monitors with status + p95 (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,n]},{name:`sessions`,description:`Recent session-replay list (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,n]},{name:`heatmaps`,description:`Recent heatmap captures (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,n]},{name:`journeys`,description:`Page-to-page transition flow (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,n]},{name:`errors`,description:`Recent error snapshot (SSE coming in V2.1)`,group:`BEHAVIOR`,tier:`pro`,options:[t,{flag:`--window <w>`,description:`24h | 7d | 30d | 90d`,default:`24h`},{flag:`--limit <n>`,description:`Max errors to fetch`,default:100},{flag:`--search <q>`,description:`Filter by class or message substring`},{flag:`--watch`,description:`Auto-refresh every 30s`},...r]},{name:`funnels`,description:`List available funnels (Pro+)`,group:`BEHAVIOR`,tier:`pro`,options:[t,...r]},{name:`funnel`,description:`Funnel drop-off chart for a specific funnel (Pro+)`,group:`BEHAVIOR`,tier:`pro`,actions:[`<id>`],options:[t,{flag:`--window <w>`,description:`7d | 30d`,default:`30d`},...r]},{name:`insights`,description:`AI-generated anomaly / trend / recommendation cards (Pro+)`,group:`INTELLIGENCE`,tier:`pro`,options:[t,n]},{name:`companies`,description:`B2B identification feed (Scale+)`,group:`INTELLIGENCE`,tier:`scale`,options:[t,{flag:`--window <w>`,description:`24h | 7d | 30d | 90d`,default:`24h`},{flag:`--limit <n>`,description:`Max rows`,default:100},{flag:`--new-only`,description:`Show only newly identified companies (first-seen in last hour)`},{flag:`--watch`,description:`Auto-refresh every 30s`},...r]},{name:`query`,description:`Restricted SQL REPL over the analytics schema (Scale+)`,group:`INTELLIGENCE`,tier:`scale`,actions:[`[sql]`],options:[t,{flag:`--max-rows <n>`,description:`Cap result row count`,default:1e3},...r]},{name:`ai`,description:`3-mode AI assistant (install / chat / mcp)`,group:`INTELLIGENCE`,tier:`free`,options:[{flag:`--mode <mode>`,description:`install | chat | mcp`},n]},{name:`api-keys`,description:`API key management`,group:`MANAGE`,tier:`free`,actions:[`list`,`create`,`delete`],options:[{flag:`--name <n>`,description:`Human-readable label (create)`},{flag:`--scope <scope>`,description:`read | write (create)`,default:`read`},{flag:`--yes`,description:`Skip confirmation (delete)`},n]},{name:`domains`,description:`Domain (tracked-website) management`,group:`MANAGE`,tier:`free`,actions:[`list`,`add`,`delete`],options:[{flag:`--name <n>`,description:`Friendly project name (add; default: domain itself)`},{flag:`--yes`,description:`Skip confirmation (delete)`},n]},{name:`team`,description:`Team member + invitation management (Pro+)`,group:`MANAGE`,tier:`pro`,actions:[`list`,`invite`,`remove`,`role`],options:[{flag:`--role <role>`,description:`admin | member (invite)`,default:`member`},{flag:`--yes`,description:`Skip confirmation (remove)`},n]},{name:`profile`,description:`Current-user profile`,group:`ACCOUNT`,tier:`free`,actions:[`show`,`edit`],options:[{flag:`--name <n>`,description:`New display name (edit)`},{flag:`--notifications <pref>`,description:`email | none (edit)`},n]},{name:`plans`,description:`Subscription plan management`,group:`ACCOUNT`,tier:`free`,actions:[`info`,`upgrade`,`cancel`,`payment`],options:[{flag:`--yes`,description:"Required for `cancel`"},n]},{name:`billing`,description:"Alias for `plans info`",group:`ACCOUNT`,tier:`free`,options:[n]},{name:`settings`,description:`Get / set user settings`,group:`ACCOUNT`,tier:`free`,actions:[`get`,`set`],options:[n]},{name:`integrations`,description:`Connect / disconnect external integrations (gsc, github)`,group:`ACCOUNT`,tier:`free`,actions:[`list`,`connect`,`disconnect`],options:[{flag:`--yes`,description:`Skip confirmation (disconnect)`},n]},{name:`goals`,description:`Goal management (Pro+)`,group:`ACCOUNT`,tier:`pro`,actions:[`list`,`create`,`delete`],options:[{flag:`--name <n>`,description:`Goal name (create)`},{flag:`--type <t>`,description:`pageview | event (create)`},{flag:`--target <v>`,description:`URL pattern or event name (create)`},{flag:`--yes`,description:`Skip confirmation (delete)`},n]},{name:`notes`,description:`Annotation / note management`,group:`ACCOUNT`,tier:`free`,actions:[`list`,`create`,`delete`],options:[{flag:`--content <text>`,description:`Note body (create)`},{flag:`--site-id <id>`,description:`Attach to a specific site (create; defaults to current)`},{flag:`--yes`,description:`Skip confirmation (delete)`},n]},{name:`agency`,description:`Agency client + report management (Scale+)`,group:`ACCOUNT`,tier:`scale`,actions:[`clients list`,`clients add`,`clients remove`,`report send`],options:[{flag:`--email <e>`,description:`Client contact email (clients add)`},{flag:`--name <n>`,description:`Client name (clients add)`},{flag:`--yes`,description:`Skip confirmation (clients remove)`},n]},{name:`usage`,description:`Current month events vs plan limits + headcounts`,group:`ACCOUNT`,tier:`free`,options:[n]},{name:`events tail`,description:`Stream live events`,group:`OPERATIONS`,tier:`free`,options:[{flag:`--site-id <id>`,description:`Site ID`,default:``},{flag:`--filter <expr>`,description:`Filter expression (e.g. 'type=pageview AND country=US')`},{flag:`--forward-to <url>`,description:`POST each event to a webhook with HMAC-SHA256 signature`},{flag:`--replay-24h`,description:`Replay the last 24h before going live`},{flag:`--set-forward-secret <hex>`,description:`Persist the HMAC secret used by --forward-to`},n]},{name:`deploys`,description:`Recent GitHub commits overlaid on charts`,group:`OPERATIONS`,tier:`free`,options:[t,{flag:`--branch <name>`,description:`Filter to a single branch (e.g. main, develop)`},{flag:`--since <iso>`,description:`Only commits after this ISO timestamp`},{flag:`--limit <n>`,description:`Max rows`,default:50},{flag:`--connect`,description:`Print the GitHub-integration deep link in app.zenovay.com`},...r]},{name:`webhooks forward`,description:`Forward webhook events to a local URL (stripe-listen-style)`,group:`OPERATIONS`,tier:`free`,options:[{flag:`--to <url>`,description:`Local URL to POST events to (e.g. localhost:3000/webhook)`},t,{flag:`--sign`,description:`HMAC-sign each forwarded request with X-Zenovay-Signature`},{flag:`--secret <hex>`,description:`HMAC secret (auto-derived from tunnel key if --sign without --secret)`},{flag:`--max-retries <n>`,description:`Per-request retry count`,default:3}]},{name:`projects`,description:`List your tracked projects`,group:`OPERATIONS`,tier:`free`,options:[t,...r]},{name:`use`,description:`Set / show / reset your default site (used when --site-id is omitted)`,group:`OPERATIONS`,tier:`free`,actions:[`[site]`],options:[{flag:`--reset`,description:`Clear the stored default site`},{flag:`--show`,description:`Print the current default and exit`},n]},{name:`init`,description:`AI install wizard — add Zenovay tracking to your codebase`,group:`OPERATIONS`,tier:`free`,options:[{flag:`--json`,description:`Emit NDJSON events to stdout`},{flag:`--yes`,description:`Auto-approve all diffs (for CI)`},{flag:`--skip-mcp`,description:`Skip MCP client install`},{flag:`--skip-verify`,description:`Skip first-event verification`}]},{name:`login`,description:`Authenticate via OAuth device flow`,group:`OPERATIONS`,tier:`free`,options:[n,{flag:`--no-browser`,description:`Skip opening the browser automatically`}]},{name:`logout`,description:`Revoke current session and delete local auth`,group:`OPERATIONS`,tier:`free`,options:[n]},{name:`health`,description:`Run self-diagnostic checks`,group:`OPERATIONS`,tier:`free`,options:[n]},{name:`doctor`,description:`AI-assisted self-healing + AI-agent detection`,group:`OPERATIONS`,tier:`free`,options:[n]},{name:`update`,description:`Manually install the latest version`,group:`OPERATIONS`,tier:`free`,options:[{flag:`--check`,description:`Don't install — just print latest`},{flag:`--force-downgrade`,description:`Allow downgrading to an older version`},{flag:`--no-update-check`,description:`Disable auto-update for this invocation`},n]},{name:`themes`,description:`List available themes with colored swatches`,group:`OPERATIONS`,tier:`free`,options:[{flag:`--validate <path>`,description:`Validate a custom theme JSON file`},n]},{name:`completions`,description:`Emit shell-completion script (bash | zsh | fish | nushell | pwsh)`,group:`OPERATIONS`,tier:`free`,actions:[`[shell]`],options:[{flag:`--list`,description:`List supported shells`}]},{name:`commands`,description:`Dump the full command tree as JSON (for AI-agent discovery)`,group:`OPERATIONS`,tier:`free`,options:[n]}];async function a(t){let n={version:t.cliVersion,commands:i},r=e({json:t.json}),a=JSON.stringify(n,null,r?0:2);return process.stdout.write(a+`
|
|
2
2
|
`),0}export{a as commandsCommand};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-UJJ6ube8.js";import{formatTabular as r,selectFormat as i}from"./formatter-KOe_hjhc.js";import"./panel-jycoT562.js";import"./banner-gVm7GaJF.js";import"./prompt-Db9Y7CVt.js";import"./keybar-BYQ2Bam1.js";import{resolveSiteId as a}from"./resolve-site-CZEwJoBj.js";import{DataTable as o}from"./data-table-BnWXIW9M.js";import{runAnalyticalScreen as s}from"./analytical-screen-BGMW3z_2.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}function f(e){return e==null?`—`:e>=500?`Enterprise`:e>=50?`Growth`:`SMB`}async function p(p){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:p.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:p.siteId,headless:!!(p.json||p.csv||p.tsv||p.ndjson),cliVersion:p.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(p),b=p.window??`24h`,x=p.limit??100,S=[{key:`lastSeenAt`,label:`when`,width:6,format:e=>d(String(e))},{key:`name`,label:`company`,width:24,format:e=>String(e).slice(0,24)},{key:`employeeCount`,label:`tier`,width:11,format:e=>f(typeof e==`number`?e:null)},{key:`industry`,label:`industry`,width:18,format:e=>String(e??`—`).slice(0,18)},{key:`visitCount`,label:`visits`,width:6,align:`right`},{key:`isNew`,label:``,width:5,format:e=>e?`NEW`:``}];return s({cliVersion:p.cliVersion,title:`companies · ${_} · ${b}`,commandName:`companies`,authToken:h?.accessToken??null,refreshIntervalMs:p.watch?3e4:0,fetcher:e=>g.getCompaniesSnapshot(_,{window:b,limit:x},e),format:y,headlessEmit:(e,t)=>{let n=p.newOnly?e.companies.filter(e=>e.isNew):e.companies;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of n)process.stdout.write(JSON.stringify(e)+`
|
|
2
|
+
`);else process.stdout.write(JSON.stringify({companies:n,total:n.length},null,2));return}process.stdout.write(r(n,[`name`,`domain`,`industry`,`employeeCount`,`visitCount`,`firstSeenAt`,`lastSeenAt`,`isNew`],t))},panels:[{id:`summary`,title:`Now`,render:e=>{let t=e.companies.filter(e=>e.isNew).length,n=e.companies.filter(e=>(e.employeeCount??0)>=500).length;return u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.total),u.createElement(l,{color:`gray`},` companies in `,b)),u.createElement(l,{color:`gray`},u.createElement(l,{color:`green`},`● `,t,` new`),` · `,n,` enterprise`))}},{id:`feed`,title:`Feed`,render:e=>{let t=p.newOnly?e.companies.filter(e=>e.isNew):e.companies;return t.length===0?u.createElement(l,{color:`gray`},`— no `,p.newOnly?`new `:``,`companies in window —`):u.createElement(o,{data:t.slice(0,30),columns:S,headerStyle:`accent`})}}]})}export{p as companiesCommand};
|