@zenovay/cli 0.1.34 → 0.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +35 -0
  2. package/dist/{agency-DEixFVRT.js → agency-Ba8f5PMP.js} +1 -1
  3. package/dist/ai-Dz_MAHHV.js +11 -0
  4. package/dist/alerts-Cxea5iYt.js +3 -0
  5. package/dist/{analytical-screen-BpTK5dCY.js → analytical-screen-BGMW3z_2.js} +1 -1
  6. package/dist/analytics-5ztZSLLH.js +1 -0
  7. package/dist/api-CJnD6Auw.js +1 -0
  8. package/dist/api-keys-DyFEtD2q.js +4 -0
  9. package/dist/api-v2-CfYUL93L.js +1 -0
  10. package/dist/{api-v2-B_kZhVxd.js → api-v2-UJJ6ube8.js} +1 -1
  11. package/dist/{apply-D2xZJdvQ.js → apply-oUMOH7u2.js} +1 -1
  12. package/dist/{audit-CfOJ3rNW.js → audit-DqPlGP-B.js} +1 -1
  13. package/dist/{banner-BPQh2F8l.js → banner-gVm7GaJF.js} +1 -1
  14. package/dist/{bar-BNmNGwlD.js → bar-BPHTpgfb.js} +1 -1
  15. package/dist/bin.js +5 -3
  16. package/dist/{commands-DbkdKFGz.js → commands-BrU-VT7M.js} +1 -1
  17. package/dist/companies-CH3F-hmU.js +2 -0
  18. package/dist/completions-Ba0Zr-G3.js +135 -0
  19. package/dist/{config-Cmi_f_SY.js → config-CG7B8fR0.js} +1 -1
  20. package/dist/config-CUWIr4Qh.js +1 -0
  21. package/dist/{data-table-BUyOP6Nc.js → data-table-BnWXIW9M.js} +1 -1
  22. package/dist/deploys-B79-S9yT.js +2 -0
  23. package/dist/devices-BQnWRrD3.js +1 -0
  24. package/dist/{doctor-K37xh3M7.js → doctor-DjmsSn5Z.js} +1 -1
  25. package/dist/domains-B4WXSAV9.js +8 -0
  26. package/dist/emit-B8RbnBJe.js +2 -0
  27. package/dist/{empty-state-Dkho-_3J.js → empty-state-BkS6DKWZ.js} +1 -1
  28. package/dist/error-codes-Iig3PBVk.js +2 -0
  29. package/dist/errors-CmbIkaPX.js +2 -0
  30. package/dist/{events-tail-CXJUK5ka.js → events-tail-CE5QxNmF.js} +1 -1
  31. package/dist/examples-B8b7EpXo.js +1 -0
  32. package/dist/export-BhWUB0S0.js +4 -0
  33. package/dist/{funnel-nm9X3Od7.js → funnel-4A9Q_ZCD.js} +1 -1
  34. package/dist/geo-BAXdGLKJ.js +1 -0
  35. package/dist/globe-DMOyP2MN.js +2 -0
  36. package/dist/goals-CINA9D6R.js +7 -0
  37. package/dist/health-CAnAYv9x.js +1 -0
  38. package/dist/health-DAyE161Z.js +1 -0
  39. package/dist/heatmaps-DkY7BW0E.js +1 -0
  40. package/dist/home-DL_Ty0eK.js +2 -0
  41. package/dist/init-C13-OX68.js +79 -0
  42. package/dist/init-C8KOSKzO.js +1 -0
  43. package/dist/insights-BDxlGN5s.js +1 -0
  44. package/dist/{integrations-B6IO1dM0.js → integrations-Eu2LbV95.js} +1 -1
  45. package/dist/journeys-CQMP6cvE.js +1 -0
  46. package/dist/{keybar-C7YkmK1U.js → keybar-BYQ2Bam1.js} +1 -1
  47. package/dist/live-BO8Wl0Q3.js +1 -0
  48. package/dist/login-CYaCSVUe.js +1 -0
  49. package/dist/login-D2ll-nBp.js +2 -0
  50. package/dist/logout-Cp7T5T1Y.js +2 -0
  51. package/dist/{metric-card-BRHv93Un.js → metric-card-DHIjVzNg.js} +1 -1
  52. package/dist/{notes-Cepz-K00.js → notes-BsegG0Q-.js} +1 -1
  53. package/dist/pages-Bi57FO27.js +1 -0
  54. package/dist/{plans-D8aqF_lo.js → plans-BXm8QsVF.js} +1 -1
  55. package/dist/{profile-DQJdZ-s_.js → profile-GGQyYHdV.js} +1 -1
  56. package/dist/{progress-row-DFOvHAc5.js → progress-row-C7gQLX4T.js} +1 -1
  57. package/dist/projects-t5f3WFmw.js +2 -0
  58. package/dist/{prompt-BURfUNxp.js → prompt-Db9Y7CVt.js} +1 -1
  59. package/dist/query-BmeQkD1w.js +8 -0
  60. package/dist/resolve-site-CZEwJoBj.js +2 -0
  61. package/dist/retention-6HhdWwsd.js +1 -0
  62. package/dist/revenue-CdXv5fdi.js +2 -0
  63. package/dist/secrets-A956dF9B.js +1 -0
  64. package/dist/secrets-BszMfkn1.js +1 -0
  65. package/dist/self-test-D_DxZxUB.js +4 -0
  66. package/dist/sessions-CvSKjWsw.js +1 -0
  67. package/dist/{settings-BsczzB3M.js → settings-CtEE3MFe.js} +1 -1
  68. package/dist/{share-BQjP_Anq.js → share-5a0qKu3z.js} +1 -1
  69. package/dist/sources-Dtp05gd2.js +2 -0
  70. package/dist/sparkline-BlAQSlYZ.js +1 -0
  71. package/dist/stats-DRRgb-C3.js +2 -0
  72. package/dist/{team-Bg-ggtky.js → team-q747Nwe6.js} +1 -1
  73. package/dist/{teams-Dvh7_Gkg.js → teams-nDIrOaly.js} +1 -1
  74. package/dist/{themes-CRvhjrRx.js → themes-DVChFf6Y.js} +1 -1
  75. package/dist/{tier-DyX4EObq.js → tier-uaU5pkTz.js} +1 -1
  76. package/dist/token-store-C1AqhmDP.js +1 -0
  77. package/dist/token-store-DpyCOgNw.js +1 -0
  78. package/dist/tour-Dp2WmQUO.js +8 -0
  79. package/dist/{update-DWBRR_PD.js → update-DrsZLYAQ.js} +1 -1
  80. package/dist/uptime-Bmg-epd-.js +1 -0
  81. package/dist/usage-ZJK4hekT.js +3 -0
  82. package/dist/use-SGwWI1Rq.js +3 -0
  83. package/dist/visitors-D7FmGVz1.js +2 -0
  84. package/dist/vitals-CRE0nVgp.js +2 -0
  85. package/dist/watch-DeWYzdo4.js +1 -0
  86. package/dist/webhooks-CD7IvAxr.js +10 -0
  87. package/dist/webhooks-forward-X4iUnLrU.js +3 -0
  88. package/dist/wizard-bin.js +1 -1
  89. package/dist/{ws-client-_BBjvKCb.js → ws-client-Cp_nIj_N.js} +1 -1
  90. package/package.json +2 -2
  91. package/dist/ai-B8r28ZBm.js +0 -11
  92. package/dist/analytics-DZpf8Q9f.js +0 -1
  93. package/dist/api-CeB_9iPg.js +0 -1
  94. package/dist/api-keys-DsQR075b.js +0 -7
  95. package/dist/companies-BToqUnFi.js +0 -2
  96. package/dist/completions-CXAOfyWo.js +0 -113
  97. package/dist/deploys-CgNr5r7M.js +0 -2
  98. package/dist/devices-C8xVqaBs.js +0 -1
  99. package/dist/domains-Bfx2vdwv.js +0 -11
  100. package/dist/emit-DBbMG9mK.js +0 -1
  101. package/dist/errors-BXwphY11.js +0 -2
  102. package/dist/geo-BaCNZ7-S.js +0 -1
  103. package/dist/globe-B4iKPH4T.js +0 -2
  104. package/dist/goals-D1qL286b.js +0 -10
  105. package/dist/health-ChZuTNP2.js +0 -1
  106. package/dist/health-DfgPNC1A.js +0 -1
  107. package/dist/heatmaps-e1Q72VWJ.js +0 -1
  108. package/dist/home-CtsY-gj0.js +0 -2
  109. package/dist/init-BVUEPvVr.js +0 -62
  110. package/dist/init-CJ1Py9a8.js +0 -1
  111. package/dist/insights-wx3wIgGV.js +0 -1
  112. package/dist/journeys-zPmCha98.js +0 -1
  113. package/dist/live-k32y1phk.js +0 -1
  114. package/dist/login-BSDS_gNS.js +0 -1
  115. package/dist/login-B_CW06vS.js +0 -1
  116. package/dist/logout-1ohk4uie.js +0 -2
  117. package/dist/pages-CAYP4Abn.js +0 -1
  118. package/dist/projects-BC8pmo7u.js +0 -2
  119. package/dist/query-X38xyHCI.js +0 -8
  120. package/dist/resolve-site-BUpzvcMz.js +0 -2
  121. package/dist/retention-DQPI6wVN.js +0 -1
  122. package/dist/revenue-CD1YwoZj.js +0 -2
  123. package/dist/sessions-Dv-Z29cQ.js +0 -1
  124. package/dist/sources-DL_o-kkA.js +0 -2
  125. package/dist/sparkline-Bkfzqe4x.js +0 -1
  126. package/dist/stats-DRy2d3At.js +0 -2
  127. package/dist/uptime-DACm8Hdh.js +0 -1
  128. package/dist/usage-BhLXHEkY.js +0 -3
  129. package/dist/use-DJ0b_xNo.js +0 -5
  130. package/dist/visitors-CrF-_BuG.js +0 -2
  131. package/dist/vitals-lpeK0mbA.js +0 -2
  132. package/dist/watch-BMrHdnHX.js +0 -1
  133. package/dist/webhooks-Ddhz2P7n.js +0 -15
  134. package/dist/webhooks-forward-BUoKx2Dz.js +0 -3
  135. /package/dist/{check-Comj8AkL.js → check-D9G0N7NB.js} +0 -0
  136. /package/dist/{client-WzSy90dG.js → client-CN2wyAL7.js} +0 -0
  137. /package/dist/{confirm-D_aKHknn.js → confirm-Dk3CEdpn.js} +0 -0
  138. /package/dist/{fmt-DSJbiH8w.js → fmt-CdJ3NqAG.js} +0 -0
  139. /package/dist/{formatter-mW0Yk3Nt.js → formatter-KOe_hjhc.js} +0 -0
  140. /package/dist/{globe-BrlflaZ1.js → globe-WYN8kVDK.js} +0 -0
  141. /package/dist/{panel-uygscwY5.js → panel-jycoT562.js} +0 -0
  142. /package/dist/{ui-BRls3_H3.js → ui-hZ5oXnwY.js} +0 -0
  143. /package/dist/{wrapper-BgssVzXH.js → wrapper-Ce_PZUZ9.js} +0 -0
@@ -0,0 +1,135 @@
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{getCachedTier as r}from"./tier-uaU5pkTz.js";import i from"node:path";import{promises as a}from"node:fs";import o from"node:os";const s=[{name:`init`,description:`AI install wizard`},{name:`login`,description:`Authenticate via OAuth device flow`},{name:`logout`,description:`Revoke session and clear local auth`},{name:`ai`,description:`3-mode AI assistant`},{name:`watch`,description:`Live TUI dashboard`},{name:`events`,description:`Stream live events`},{name:`health`,description:`Self-diagnostic checks`},{name:`doctor`,description:`AI-assisted self-healing`},{name:`update`,description:`Install latest version`},{name:`visitors`,description:`Live visitor table`},{name:`sources`,description:`Traffic source breakdown`},{name:`vitals`,description:`Core Web Vitals dashboard`},{name:`revenue`,description:`MRR / ARR / transaction series`},{name:`funnel`,description:`Funnel drop-off chart`},{name:`funnels`,description:`List funnels`},{name:`stats`,description:`One-shot dashboard summary`},{name:`errors`,description:`Recent error snapshot`},{name:`companies`,description:`B2B identification feed`},{name:`projects`,description:`List tracked projects`},{name:`query`,description:`SQL REPL over analytics schema`},{name:`completions`,description:`Emit shell-completion script`},{name:`export`,description:`Bulk-export analytics / sessions / heatmaps`}],c=`--site-id.--json.--csv.--tsv.--ndjson.--watch.--limit.--window.--period.--range.--device.--url.--compare.--max-rows.--filter.--forward-to.--replay-24h.--search.--new-only.--min-duration.--out.--format.--type.--funnel-id.--help.--version`.split(`.`),l=[`catppuccin-mocha`,`catppuccin-latte`,`dracula`,`tokyo-night`,`nord`],u=[`pageview`,`click`,`scroll`,`form_submit`,`purchase`,`goal_completed`,`error`],d=[`funnel`,`session`,`page`,`site`,`saved-query`,`theme`,`event-type`,`country`];function f(){let e=s.map(e=>e.name).join(` `),t=c.join(` `);return`# zenovay bash completion
2
+ # Install: zenovay completions bash > /usr/local/etc/bash_completion.d/zenovay
3
+ _zenovay() {
4
+ local cur prev opts
5
+ COMPREPLY=()
6
+ cur="\${COMP_WORDS[COMP_CWORD]}"
7
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
8
+ if [[ "\${COMP_CWORD}" == "1" ]]; then
9
+ opts="${e}"
10
+ COMPREPLY=( $(compgen -W "\${opts}" -- "\${cur}") )
11
+ return 0
12
+ fi
13
+ case "\${prev}" in
14
+ --funnel-id|funnel) COMPREPLY=( $(compgen -W "$(zenovay completions _values funnel 2>/dev/null)" -- "\${cur}") ); return 0 ;;
15
+ --site-id) COMPREPLY=( $(compgen -W "$(zenovay completions _values site 2>/dev/null)" -- "\${cur}") ); return 0 ;;
16
+ --session-id) COMPREPLY=( $(compgen -W "$(zenovay completions _values session 2>/dev/null)" -- "\${cur}") ); return 0 ;;
17
+ --url|--page) COMPREPLY=( $(compgen -W "$(zenovay completions _values page 2>/dev/null)" -- "\${cur}") ); return 0 ;;
18
+ --theme) COMPREPLY=( $(compgen -W "${l.join(` `)}" -- "\${cur}") ); return 0 ;;
19
+ --type) COMPREPLY=( $(compgen -W "$(zenovay completions _values event-type 2>/dev/null)" -- "\${cur}") ); return 0 ;;
20
+ --country) COMPREPLY=( $(compgen -W "$(zenovay completions _values country 2>/dev/null)" -- "\${cur}") ); return 0 ;;
21
+ --window) COMPREPLY=( $(compgen -W "24h 7d 30d 90d 1y" -- "\${cur}") ); return 0 ;;
22
+ --period) COMPREPLY=( $(compgen -W "7d 30d 90d 1y" -- "\${cur}") ); return 0 ;;
23
+ --range) COMPREPLY=( $(compgen -W "24h 7d 30d 90d" -- "\${cur}") ); return 0 ;;
24
+ --device) COMPREPLY=( $(compgen -W "mobile desktop tablet" -- "\${cur}") ); return 0 ;;
25
+ --compare) COMPREPLY=( $(compgen -W "prev none" -- "\${cur}") ); return 0 ;;
26
+ --format) COMPREPLY=( $(compgen -W "json csv tsv ndjson" -- "\${cur}") ); return 0 ;;
27
+ esac
28
+ COMPREPLY=( $(compgen -W "${t}" -- "\${cur}") )
29
+ }
30
+ complete -F _zenovay zenovay zv
31
+ `}function p(){let e=s.map(e=>` '${e.name}:${e.description}'`).join(` \\
32
+ `);return`#compdef zenovay zv
33
+ # zenovay zsh completion
34
+ # Install: zenovay completions zsh > ~/.zsh/completions/_zenovay && compinit
35
+ _zenovay_dyn() {
36
+ # zsh helper that calls the CLI for slot-aware values, line-by-line.
37
+ local type=$1
38
+ local -a values
39
+ values=(\${(f)"$(zenovay completions _values $type 2>/dev/null)"})
40
+ _describe -t values "$type" values
41
+ }
42
+
43
+ _zenovay() {
44
+ local -a commands
45
+ commands=(
46
+ ${e}
47
+ )
48
+ _arguments -C \\
49
+ '1: :->command' \\
50
+ '*: :->args'
51
+ case $state in
52
+ command) _describe 'command' commands ;;
53
+ args)
54
+ case "\${words[2]}" in
55
+ *)
56
+ _arguments \\
57
+ '--site-id[Site ID]:site:_zenovay_dyn site' \\
58
+ '--funnel-id[Funnel ID]:funnel:_zenovay_dyn funnel' \\
59
+ '--session-id[Session ID]:session:_zenovay_dyn session' \\
60
+ '--page[Page URL]:page:_zenovay_dyn page' \\
61
+ '--country[Country code]:country:_zenovay_dyn country' \\
62
+ '--type[Event type]:type:_zenovay_dyn event-type' \\
63
+ '--json[Emit JSON to stdout]' \\
64
+ '--csv[Emit CSV to stdout]' \\
65
+ '--tsv[Emit TSV to stdout]' \\
66
+ '--ndjson[Emit NDJSON streaming]' \\
67
+ '--watch[Auto-refresh]' \\
68
+ '--limit[Max rows]:n:' \\
69
+ '--min-duration[Filter visitors below N seconds]:n:' \\
70
+ '--window[Time window]:w:(24h 7d 30d 90d 1y)' \\
71
+ '--period[Period]:p:(7d 30d 90d 1y)' \\
72
+ '--range[Range]:r:(24h 7d 30d 90d)' \\
73
+ '--device[Device type]:d:(mobile desktop tablet)' \\
74
+ '--theme[Theme]:t:(${l.join(` `)})' \\
75
+ '--format[Output format]:f:(json csv tsv ndjson)' \\
76
+ '--max-rows[Max query rows]:n:' \\
77
+ '--out[Output file]:file:_files'
78
+ ;;
79
+ esac
80
+ ;;
81
+ esac
82
+ }
83
+ _zenovay "$@"
84
+ `}function m(){let e=[`# zenovay fish completion`,`# Install: zenovay completions fish > ~/.config/fish/completions/zenovay.fish`,``];for(let t of s)e.push(`complete -c zenovay -n "__fish_use_subcommand" -a ${t.name} -d '${t.description.replace(/'/g,`\\'`)}'`),e.push(`complete -c zv -n "__fish_use_subcommand" -a ${t.name} -d '${t.description.replace(/'/g,`\\'`)}'`);for(let t of c){let n=t.replace(/^--/,``);e.push(`complete -c zenovay -l ${n}`)}return e.push(`complete -c zenovay -l site-id -f -a "(zenovay completions _values site 2>/dev/null)"`),e.push(`complete -c zenovay -l funnel-id -f -a "(zenovay completions _values funnel 2>/dev/null)"`),e.push(`complete -c zenovay -l session-id -f -a "(zenovay completions _values session 2>/dev/null)"`),e.push(`complete -c zenovay -l page -f -a "(zenovay completions _values page 2>/dev/null)"`),e.push(`complete -c zenovay -l country -f -a "(zenovay completions _values country 2>/dev/null)"`),e.push(`complete -c zenovay -l type -f -a "(zenovay completions _values event-type 2>/dev/null)"`),e.push(`complete -c zenovay -l theme -a "${l.join(` `)}"`),e.push(`complete -c zenovay -l window -a "24h 7d 30d 90d 1y"`),e.push(`complete -c zenovay -l period -a "7d 30d 90d 1y"`),e.push(`complete -c zenovay -l range -a "24h 7d 30d 90d"`),e.push(`complete -c zenovay -l device -a "mobile desktop tablet"`),e.push(`complete -c zenovay -l compare -a "prev none"`),e.push(`complete -c zenovay -l format -a "json csv tsv ndjson"`),e.join(`
85
+ `)+`
86
+ `}function h(){return`# zenovay nushell completion
87
+ # Add to your config.nu (or source as a separate file)
88
+ def "nu-complete zenovay-commands" [] {
89
+ [
90
+ ${s.map(e=>` { value: "${e.name}", description: "${e.description}" }`).join(`,
91
+ `)}
92
+ ]
93
+ }
94
+
95
+ extern "zenovay" [
96
+ command?: string@"nu-complete zenovay-commands"
97
+ --site-id: string
98
+ --json
99
+ --csv
100
+ --tsv
101
+ --ndjson
102
+ --watch
103
+ --limit: int
104
+ --window: string
105
+ --period: string
106
+ --range: string
107
+ --device: string
108
+ --theme: string
109
+ --max-rows: int
110
+ --help
111
+ --version
112
+ ]
113
+
114
+ extern "zv" [
115
+ command?: string@"nu-complete zenovay-commands"
116
+ ]
117
+ `}function g(){let e=s.map(e=>`'${e.name}'`).join(`, `);return`# zenovay PowerShell completion
118
+ # Install: zenovay completions pwsh >> $PROFILE
119
+ $scriptBlock = {
120
+ param($wordToComplete, $commandAst, $cursorPosition)
121
+ $commands = @(${e})
122
+ $commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
123
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
124
+ }
125
+ }
126
+ Register-ArgumentCompleter -CommandName zenovay -ScriptBlock $scriptBlock
127
+ Register-ArgumentCompleter -CommandName zv -ScriptBlock $scriptBlock
128
+ `}const _=5*60*1e3;function v(){return i.join(o.homedir(),`.zenovay`,`completions-cache.json`)}async function y(){try{let e=await a.readFile(v(),`utf8`),t=JSON.parse(e);return t&&typeof t==`object`?t:{}}catch{return{}}}async function b(e){let t=v();await a.mkdir(i.dirname(t),{recursive:!0,mode:448}),await a.writeFile(t,JSON.stringify(e),{mode:384})}async function x(e,t,n,i){switch(e){case`funnel`:{let e=await t.listFunnels(n);return e.funnels.map(e=>e.id)}case`session`:{let e=await t.getSessions(n);return e.map(e=>e.id)}case`page`:{let e=await t.getPages(n);return e.map(e=>e.path)}case`site`:{let e=await t.getSites();return e.map(e=>e.id)}case`saved-query`:{let e=await r(t).catch(()=>`free`);return[]}case`theme`:return l.slice();case`event-type`:return u.slice();case`country`:{let e=await t.getGeo(n);return e.countries.map(e=>e.country)}}}async function S(t){let n=await e();if(n.defaultSiteId)return n.defaultSiteId;try{let e=await t.getSites();if(e.length===1)return e[0].id}catch{}return`default`}async function C(r){let i=r;if(!d.includes(i))return process.stderr.write(`Unknown completion type '${r}'.\n`),2;if(i===`theme`||i===`event-type`){let e=i===`theme`?l:u;for(let t of e)process.stdout.write(`${t}\n`);return 0}let a=await e(),o=await t({strict:!1}).catch(()=>null);if(!o)return 0;let s=new n({config:a,cliVersion:`0`,token:o}),c=i===`site`||i===`saved-query`?`__global__`:await S(s),f=`${i}:${c}`,p=await y(),m=p[f];if(m&&Date.now()-m.ts<_){for(let e of m.values)process.stdout.write(`${e}\n`);return 0}let h=[];try{h=await x(i,s,c,`0`)}catch{m&&(h=m.values)}p[f]={ts:Date.now(),values:h},await b(p).catch(()=>void 0);for(let e of h)process.stdout.write(`${e}\n`);return 0}async function w(e){let t=e.shell?.toLowerCase();if(t===`_values`)return e.valuesType?C(e.valuesType):(process.stderr.write(`Usage: zenovay completions _values <${d.join(`|`)}>\n`),2);if(e.list||!t)return process.stdout.write(`Available shells: bash, zsh, fish, nushell, pwsh
129
+ Usage:
130
+ zenovay completions bash > /usr/local/etc/bash_completion.d/zenovay
131
+ zenovay completions zsh > ~/.zsh/completions/_zenovay
132
+ zenovay completions fish > ~/.config/fish/completions/zenovay.fish
133
+ zenovay completions nushell >> $env.HOME/.config/nushell/config.nu
134
+ zenovay completions pwsh >> $PROFILE
135
+ `),0;switch(t){case`bash`:return process.stdout.write(f()),0;case`zsh`:return process.stdout.write(p()),0;case`fish`:return process.stdout.write(m()),0;case`nu`:case`nushell`:return process.stdout.write(h()),0;case`pwsh`:case`powershell`:return process.stdout.write(g()),0;default:return process.stderr.write(`✗ Unknown shell '${t}'. Supported: bash, zsh, fish, nushell, pwsh.\n`),2}}export{w as completionsCommand};
@@ -1 +1 @@
1
- import e from"node:path";import{promises as t}from"node:fs";import{z as n}from"zod";import r from"node:os";const i=n.object({theme:n.string().optional(),apiBase:n.string().url().default(`https://api.zenovay.com`),cliBase:n.string().url().default(`https://cli.zenovay.com`),region:n.enum([`us`,`eu`,`auto`]).default(`auto`),telemetry:n.boolean().default(!1),noUpdateCheck:n.boolean().default(!1),lastUpdateNotice:n.number().optional(),forwardSecret:n.string().optional(),defaultSiteId:n.string().optional(),defaultSiteName:n.string().optional(),cachedTier:n.string().optional(),cachedTierAt:n.number().optional(),currentTeamId:n.string().optional(),currentTeamName:n.string().optional()}),a={apiBase:`https://api.zenovay.com`,cliBase:`https://cli.zenovay.com`,region:`auto`,telemetry:!1,noUpdateCheck:!1};function o(){if(process.platform===`win32`){let t=process.env.APPDATA??e.join(r.homedir(),`AppData`,`Roaming`);return e.join(t,`zenovay`)}let t=process.env.XDG_CONFIG_HOME??e.join(r.homedir(),`.config`);return e.join(t,`zenovay`)}function s(){return e.join(o(),`config.json`)}async function c(){let e=s();try{let n=await t.readFile(e,`utf8`),r=i.safeParse(JSON.parse(n));return r.success?r.data:a}catch(e){if(e.code===`ENOENT`)return a;throw e}}async function l(e){let n=o();await t.mkdir(n,{recursive:!0,mode:448});let r=s();await t.writeFile(r,JSON.stringify(e,null,2),{mode:384}),process.platform!==`win32`&&await t.chmod(r,384)}async function u(e){let t=await c(),n=i.parse({...t,...e});return await l(n),n}export{o as configDir,s as configPath,c as readConfig,u as updateConfig};
1
+ import e from"node:path";import{promises as t}from"node:fs";import{z as n}from"zod";import r from"node:os";const i=n.object({theme:n.string().optional(),apiBase:n.string().url().default(`https://api.zenovay.com`),cliBase:n.string().url().default(`https://cli.zenovay.com`),region:n.enum([`us`,`eu`,`auto`]).default(`auto`),telemetry:n.boolean().default(!1),noUpdateCheck:n.boolean().default(!1),lastUpdateNotice:n.number().optional(),forwardSecret:n.string().optional(),defaultSiteId:n.string().optional(),defaultSiteName:n.string().optional(),cachedTier:n.string().optional(),cachedTierAt:n.number().optional(),currentTeamId:n.string().optional(),currentTeamName:n.string().optional()}),a={apiBase:`https://api.zenovay.com`,cliBase:`https://cli.zenovay.com`,region:`auto`,telemetry:!1,noUpdateCheck:!1};function o(){if(process.platform===`win32`){let t=process.env.APPDATA??e.join(r.homedir(),`AppData`,`Roaming`);return e.join(t,`zenovay`)}let t=process.env.XDG_CONFIG_HOME??e.join(r.homedir(),`.config`);return e.join(t,`zenovay`)}function s(){return e.join(o(),`config.json`)}async function c(){let e=s();try{let n=await t.readFile(e,`utf8`),r=i.safeParse(JSON.parse(n));return r.success?r.data:a}catch(e){if(e.code===`ENOENT`)return a;throw e}}async function l(e){let n=o();await t.mkdir(n,{recursive:!0,mode:448});let r=s();await t.writeFile(r,JSON.stringify(e,null,2),{mode:384}),process.platform!==`win32`&&await t.chmod(r,384)}async function u(e){let t=await c(),n=i.parse({...t,...e});return await l(n),n}export{a as DEFAULT_CONFIG,o as configDir,s as configPath,i as configSchema,c as readConfig,u as updateConfig,l as writeConfig};
@@ -0,0 +1 @@
1
+ import{DEFAULT_CONFIG as e,configDir as t,configPath as n,configSchema as r,readConfig as i,updateConfig as a,writeConfig as o}from"./config-CG7B8fR0.js";export{i as readConfig};
@@ -1 +1 @@
1
- import{useTheme as e}from"./panel-uygscwY5.js";import{Box as t,Text as n}from"ink";import r from"react";function i(e,t){return e.length<=t?e:t<=1?e.slice(0,t):`${e.slice(0,t-1)}…`}function a(e,t,n){if(e.length>=t)return i(e,t);let r=t-e.length;return n===`right`?` `.repeat(r)+e:e+` `.repeat(r)}function o(e){return e.label??e.header??``}function s(e,t){return e.map(e=>{if(typeof e.width==`number`&&e.width>0)return e.width;let n=o(e).length;for(let r of t){let t=r[e.key],i=e.format?e.format(t,r):String(t??``);i.length>n&&(n=i.length)}return Math.max(3,n)})}function c({columns:i,data:c,zebra:l=!1,headerStyle:u=`plain`}){let{theme:d}=e(),f=s(i,c),p=f.reduce((e,t)=>e+t,0)+i.length*3+1,m=(e,t,n)=>{let r=e;return f.forEach((e,i)=>{r+=`─`.repeat(e+2),r+=i===f.length-1?n:t}),r},h=m(`╭`,`┬`,`╮`),g=m(`├`,`┼`,`┤`),_=m(`╰`,`┴`,`╯`),v=i.map((e,t)=>a(o(e),f[t]??o(e).length,e.align??`left`)).join(` │ `),y=u===`accent`?d.accent:d.fg;return r.createElement(t,{flexDirection:`column`,width:p},r.createElement(n,{color:d.border},h),r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:d.border},`│ `),r.createElement(n,{color:y,bold:!0},v),r.createElement(n,{color:d.border},` │`)),r.createElement(n,{color:d.border},g),c.map((e,o)=>{let s=l&&o%2==1,c=s?d.muted:d.fg,u=i.map((t,n)=>{let r=e[t.key],i=t.format?t.format(r,e):String(r??``);return a(i,f[n]??i.length,t.align??`left`)}).join(` │ `);return r.createElement(t,{key:o,flexDirection:`row`},r.createElement(n,{color:d.border},`│ `),r.createElement(n,{color:c},u),r.createElement(n,{color:d.border},` │`))}),r.createElement(n,{color:d.border},_))}export{c as DataTable};
1
+ import{useTheme as e}from"./panel-jycoT562.js";import{Box as t,Text as n}from"ink";import r from"react";function i(e,t){return e.length<=t?e:t<=1?e.slice(0,t):`${e.slice(0,t-1)}…`}function a(e,t,n){if(e.length>=t)return i(e,t);let r=t-e.length;return n===`right`?` `.repeat(r)+e:e+` `.repeat(r)}function o(e){return e.label??e.header??``}function s(e,t){return e.map(e=>{if(typeof e.width==`number`&&e.width>0)return e.width;let n=o(e).length;for(let r of t){let t=r[e.key],i=e.format?e.format(t,r):String(t??``);i.length>n&&(n=i.length)}return Math.max(3,n)})}function c({columns:i,data:c,zebra:l=!1,headerStyle:u=`plain`}){let{theme:d}=e(),f=s(i,c),p=f.reduce((e,t)=>e+t,0)+i.length*3+1,m=(e,t,n)=>{let r=e;return f.forEach((e,i)=>{r+=`─`.repeat(e+2),r+=i===f.length-1?n:t}),r},h=m(`╭`,`┬`,`╮`),g=m(`├`,`┼`,`┤`),_=m(`╰`,`┴`,`╯`),v=i.map((e,t)=>a(o(e),f[t]??o(e).length,e.align??`left`)).join(` │ `),y=u===`accent`?d.accent:d.fg;return r.createElement(t,{flexDirection:`column`,width:p},r.createElement(n,{color:d.border},h),r.createElement(t,{flexDirection:`row`},r.createElement(n,{color:d.border},`│ `),r.createElement(n,{color:y,bold:!0},v),r.createElement(n,{color:d.border},` │`)),r.createElement(n,{color:d.border},g),c.map((e,o)=>{let s=l&&o%2==1,c=s?d.muted:d.fg,u=i.map((t,n)=>{let r=e[t.key],i=t.format?t.format(r,e):String(r??``);return a(i,f[n]??i.length,t.align??`left`)}).join(` │ `);return r.createElement(t,{key:o,flexDirection:`row`},r.createElement(n,{color:d.border},`│ `),r.createElement(n,{color:c},u),r.createElement(n,{color:d.border},` │`))}),r.createElement(n,{color:d.border},_))}export{c as DataTable};
@@ -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`}async function f(f){if(f.connect){let t=await e(),n=t.apiBase.replace(`api.zenovay.com`,`app.zenovay.com`),r=`${n}/settings/integrations/github`;return process.stdout.write(`\n Connect GitHub to Zenovay:\n ${r}\n\n Open this URL in your browser. Zenovay re-uses the same GitHub\n OAuth app you already authorized for login (auth-zenovay), so\n no separate "Zenovay Deploys" app is needed. Pick the repos you\n want to track and deploys will appear here automatically.\n\n`),0}let p=await e(),m=await t({strict:!1}),h=new n({config:p,cliVersion:f.cliVersion,token:m}),g,_;try{({siteId:g,site:_}=await a(h,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let v=i(f),y=f.limit??50,b=[{key:`pushed_at`,label:`when`,width:6,format:e=>d(String(e))},{key:`branch`,label:`branch`,width:14,format:e=>String(e??`—`).slice(0,14)},{key:`commit_sha`,label:`commit`,width:9,format:e=>String(e).slice(0,8)},{key:`commit_author`,label:`author`,width:16,format:e=>String(e??`—`).slice(0,16)},{key:`commit_message`,label:`message`,width:40,format:e=>String(e??`—`).slice(0,40)},{key:`show_on_chart`,label:`chart`,width:5,format:e=>e?`●`:`○`}];return s({cliVersion:f.cliVersion,title:`deploys · ${g}`,commandName:`deploys`,authToken:m?.accessToken??null,refreshIntervalMs:0,fetcher:e=>h.getDeploys(g,{branch:f.branch,since:f.since,limit:y},e),format:v,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let t of e.deploys)process.stdout.write(JSON.stringify(t)+`
2
+ `);else process.stdout.write(JSON.stringify(e,null,2));return}process.stdout.write(r(e.deploys,[`pushed_at`,`branch`,`commit_sha`,`commit_author`,`commit_message`,`repository`,`commit_url`,`show_on_chart`],t))},panels:[{id:`summary`,title:`Summary`,render:e=>{let t=e.deploys.filter(e=>e.show_on_chart).length,n=new Set(e.deploys.map(e=>e.repository).filter(e=>!!e));return u.createElement(c,{flexDirection:`column`},u.createElement(l,null,u.createElement(l,{bold:!0},e.total),u.createElement(l,{color:`gray`},` commits`,f.branch?` · branch=${f.branch}`:``)),u.createElement(l,{color:`gray`},u.createElement(l,{color:`magenta`},`● `,t,` on chart`),u.createElement(l,null,` · `),u.createElement(l,null,n.size,` `,n.size===1?`repo`:`repos`)))}},{id:`list`,title:`Recent`,render:e=>e.deploys.length===0?u.createElement(c,{flexDirection:`column`},u.createElement(l,{color:`gray`},`— no commits yet —`),u.createElement(l,{color:`gray`},"Run `zenovay deploys --connect` to wire up the GitHub integration.")):u.createElement(o,{data:e.deploys.slice(0,30),columns:b,headerStyle:`accent`})}]})}export{f as deploysCommand};
@@ -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{resolveSiteId as c}from"./resolve-site-CZEwJoBj.js";import{DataTable as l}from"./data-table-BnWXIW9M.js";import{EmptyState as u}from"./empty-state-BkS6DKWZ.js";import{Box as d,Text as f,render as p,useApp as m,useInput as h}from"ink";import g,{useEffect as _,useState as v}from"react";import y from"ink-spinner";async function b(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getDevices(u);return r({type:`devices.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=p(g.createElement(x,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=m(),[p,b]=v(null),[x,S]=v(!0),[C,w]=v(null);if(h(e=>{e===`q`&&(c(),i(0))}),_(()=>{let n=!1;return(async()=>{try{let r=await e.getDevices(t);n||(b(r),S(!1))}catch(e){n||(w(e.message),S(!1))}})(),()=>{n=!0}},[e,t]),x)return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(a,{title:`Loading`,state:`busy`},g.createElement(d,null,g.createElement(f,{color:`magenta`},g.createElement(y,{type:`dots`})),g.createElement(f,null,` Fetching breakdown…`))));if(C)return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(u,{reason:`error`,headline:`Failed to load`,hint:C}));let T=!p||p.devices.length===0&&p.browsers.length===0&&p.os.length===0;if(T)return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(u,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let E=[{key:`name`,label:`name`,width:16},{key:`visitors`,label:`visitors`,align:`right`,width:8}];return g.createElement(d,{flexDirection:`column`},g.createElement(o,{version:r,subtitle:`devices · ${n}`}),g.createElement(d,{flexDirection:`row`},g.createElement(a,{title:`Devices`},p.devices.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(l,{columns:E,data:p.devices,zebra:!0})),g.createElement(a,{title:`Browsers`},p.browsers.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(l,{columns:E,data:p.browsers,zebra:!0})),g.createElement(a,{title:`OS`},p.os.length===0?g.createElement(f,{color:`gray`},`— —`):g.createElement(l,{columns:E,data:p.os,zebra:!0}))),g.createElement(s,{items:[{key:`q`,label:`quit`}]}))};export{b as devicesCommand};
@@ -1,4 +1,4 @@
1
- import{readConfig as e}from"./config-Cmi_f_SY.js";import"./check-Comj8AkL.js";import{ApiClient as t,readToken as n}from"./api-CeB_9iPg.js";import{parseSseStream as r}from"./client-WzSy90dG.js";import"./formatter-mW0Yk3Nt.js";import{emit as i,isHeadless as a}from"./emit-DBbMG9mK.js";import"./panel-uygscwY5.js";import{runHealthChecks as o}from"./health-ChZuTNP2.js";import{join as s}from"node:path";import{homedir as c,platform as l}from"node:os";import{stat as u}from"node:fs/promises";async function d(){let e=c(),t=l()===`darwin`,n=[{name:`Claude Code`,path:s(e,`.claude`)},{name:`Cursor`,path:t?s(e,`Library`,`Application Support`,`Cursor`):s(e,`.config`,`Cursor`)},{name:`Windsurf`,path:t?s(e,`Library`,`Application Support`,`Windsurf`):s(e,`.config`,`Windsurf`)},{name:`VS Code`,path:s(e,`.vscode`)}];return Promise.all(n.map(async e=>{try{return await u(e.path),{name:e.name,installed:!0,configPath:e.path}}catch{return{name:e.name,installed:!1}}}))}async function f(s){let c=await o({cliVersion:s.cliVersion,binaryPath:s.binaryPath}),l=await d();if(a(s))process.stdout.write(`${JSON.stringify({type:`doctor.agents`,agents:l})}\n`);else{process.stdout.write(`
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./check-D9G0N7NB.js";import{ApiClient as t}from"./api-CJnD6Auw.js";import{readToken as n}from"./token-store-C1AqhmDP.js";import{parseSseStream as r}from"./client-CN2wyAL7.js";import"./formatter-KOe_hjhc.js";import{emit as i,isHeadless as a}from"./emit-B8RbnBJe.js";import"./panel-jycoT562.js";import{runHealthChecks as o}from"./health-DAyE161Z.js";import{join as s}from"node:path";import{homedir as c,platform as l}from"node:os";import{stat as u}from"node:fs/promises";async function d(){let e=c(),t=l()===`darwin`,n=[{name:`Claude Code`,path:s(e,`.claude`)},{name:`Cursor`,path:t?s(e,`Library`,`Application Support`,`Cursor`):s(e,`.config`,`Cursor`)},{name:`Windsurf`,path:t?s(e,`Library`,`Application Support`,`Windsurf`):s(e,`.config`,`Windsurf`)},{name:`VS Code`,path:s(e,`.vscode`)}];return Promise.all(n.map(async e=>{try{return await u(e.path),{name:e.name,installed:!0,configPath:e.path}}catch{return{name:e.name,installed:!1}}}))}async function f(s){let c=await o({cliVersion:s.cliVersion,binaryPath:s.binaryPath}),l=await d();if(a(s))process.stdout.write(`${JSON.stringify({type:`doctor.agents`,agents:l})}\n`);else{process.stdout.write(`
2
2
  AI Agents:
3
3
  `);for(let e of l){let t=e.installed?`\x1B[32m✔\x1B[0m`:`\x1B[2m✗\x1B[0m`,n=e.installed&&e.configPath?` \x1b[2m${e.configPath}\x1b[0m`:``;process.stdout.write(` ${t} ${e.name}${n}\n`)}process.stdout.write(`
4
4
  `)}let u=c.filter(e=>e.status===`fail`);if(u.length===0)return a(s)||process.stdout.write(`All checks pass — no healing needed.
@@ -0,0 +1,8 @@
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-Iig3PBVk.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-jycoT562.js";import"./banner-gVm7GaJF.js";import"./prompt-Db9Y7CVt.js";import{resolveSiteId as c}from"./resolve-site-CZEwJoBj.js";import{fmtNumber as l,formatTable as u,shortId as d}from"./fmt-CdJ3NqAG.js";async function f(i){let o=await e(),f=await t({strict:!1});if(!f)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let p=new r({config:o,cliVersion:i.cliVersion,token:f}),m;try{({siteId:m}=await c(p,{explicit:void 0,headless:!0,cliVersion:i.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let h;try{h=await p.getProjects(m)}catch(e){return n(e,{command:`domains list`})}let g=h.projects??[];if(i.json)return a(s(g,`domains.list`),{legacyKey:`domains`,legacyValue:g}),0;if(g.length===0)return process.stdout.write(`
2
+ No domains tracked yet — add one with \`zenovay domains add <url>\`.
3
+
4
+ `),0;let _=[{key:`isCurrent`,header:``,width:1,format:e=>e?`*`:` `},{key:`name`,header:`name`,width:18,format:e=>String(e??`—`)},{key:`domain`,header:`domain`,width:28,format:e=>String(e??`—`)},{key:`tier`,header:`tier`,width:6,format:e=>String(e??`—`)},{key:`pageviews24h`,header:`24h pv`,width:8,align:`right`,format:e=>l(Number(e??0))},{key:`id`,header:`id`,width:14,format:e=>d(String(e))}];return process.stdout.write(`
5
+ `),process.stdout.write(` domains · ${g.length} tracked\n\n`),process.stdout.write(u({rows:g,cols:_})),process.stdout.write(`
6
+ * = current default site (set with \`zenovay use <name>\`)
7
+ `),process.stdout.write(" Add with `zenovay domains add <url>`, remove with `zenovay domains delete <id>`.\n\n"),0}async function p(s){if(s.action===`list`)return f(s);let c=await e(),l=await t({strict:!1}),u=new r({config:c,cliVersion:s.cliVersion,token:l});try{switch(s.action){case`add`:{if(!s.url)return process.stderr.write("Error: <url> is required for `domains add`.\n"),2;let e=await u.addDomain({url:s.url,name:s.name});return s.json?(a(o(e,`domains.item`,{siteId:e.id})),0):e.already_exists?(process.stdout.write(`Domain "${e.domain}" is already tracked (id: ${e.id}, tracking code: ${e.trackingCode}).\n`),0):(process.stdout.write(`\n✔ Domain added.\n id: ${e.id}\n domain: ${e.domain}\n trackingCode: ${e.trackingCode}\n\n Add this script to your site:\n <script defer data-id="${e.trackingCode}" src="https://api.zenovay.com/z.js"></script>\n\n Or run \`zenovay init\` to install it automatically.\n\n`),0)}case`delete`:{if(!s.id)return process.stderr.write("Error: domain id is required for `domains delete`.\n"),2;let e=await i({resource:`domain`,name:d(s.id),yes:s.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
8
+ `),1;let t=await u.deleteDomain(s.id);return s.json?(a(o(t,`domains.deleted`)),0):(process.stdout.write(`✔ Deleted domain ${d(s.id)}.\n`),0)}}}catch(e){return n(e,{command:`domains ${s.action}`})}}export{p as domainsCommand};
@@ -0,0 +1,2 @@
1
+ import{formatEvent as e,formatTabular as t}from"./formatter-KOe_hjhc.js";function n(e){return typeof e==`object`&&!!e&&Array.isArray(e._columns)&&Array.isArray(e._rows)}function r(){let e=process.argv;for(let t=0;t<e.length;t++){let n=e[t];if(n){if(n===`--json`)return`json`;if(n===`--csv`)return`csv`;if(n===`--tsv`)return`tsv`;if(n===`--ndjson`)return`ndjson`;if(n===`--format`&&t+1<e.length){let n=(e[t+1]??``).toLowerCase();if(n===`json`||n===`csv`||n===`tsv`||n===`ndjson`)return n}if(n.startsWith(`--format=`)){let e=n.slice(9).toLowerCase();if(e===`json`||e===`csv`||e===`tsv`||e===`ndjson`)return e}}}let t=(process.env.ZENOVAY_FORMAT??``).toLowerCase();return t===`json`||t===`csv`||t===`tsv`||t===`ndjson`?t:`ndjson`}function i(e={}){if(e.json||e.csv||e.tsv||e.ndjson||!process.stdout.isTTY||process.env.CI===`true`||process.env.CI===`1`||process.env.NO_COLOR!=null&&process.env.NO_COLOR!==``)return!0;let t=(process.env.ZENOVAY_FORMAT??``).toLowerCase();return t===`json`||t===`ndjson`||t===`csv`||t===`tsv`}function a(i){let a=r();if(n(i)){process.stdout.write(t(i._rows,i._columns,a));return}if(a===`ndjson`){let e={ts:new Date().toISOString(),...i};process.stdout.write(`${JSON.stringify(e)}\n`);return}process.stdout.write(e({ts:new Date().toISOString(),...i},a))}function o(){let e=process.env.ZENOVAY_CLI_VERSION??`0`,t=process.argv.slice(2).filter(e=>!e.startsWith(`-`)),n=t.join(` `)||`unknown`;return{cliVersion:e,command:n}}function s(e){let t=o(),n={cliVersion:e?.cliVersion??t.cliVersion,command:e?.command??t.command};return e?.siteId&&(n.siteId=e.siteId),e?.teamId&&(n.teamId=e.teamId),e?.cached!==void 0&&(n.cached=e.cached),n}function c(e,t,n){return{type:t,ts:new Date().toISOString(),data:e,meta:s(n)}}function l(e,t,n){return{type:t,ts:new Date().toISOString(),data:{items:e,total:e.length},meta:s(n)}}function u(e,t,n){return{type:t,ts:new Date().toISOString(),data:e,meta:s(n)}}function d(e,t){let n={...e};t?.legacyKey&&(n[t.legacyKey]=t.legacyValue,process.env.ZENOVAY_DEPRECATION_WARN===`1`&&process.stderr.write(`[deprecation] '${t.legacyKey}' top-level key is going away in 0.1.40. Read \`data.items\` instead.\n`)),process.stdout.write(JSON.stringify(n)+`
2
+ `)}export{a as emit,d as emitEnvelope,i as isHeadless,u as wrapItem,l as wrapList,c as wrapSnapshot};
@@ -1 +1 @@
1
- import{useTheme as e}from"./panel-uygscwY5.js";import{Box as t,Text as n}from"ink";import r from"react";const i={"no-data":`○`,"tier-gated":`◆`,error:`✗`},a=`https://app.zenovay.com/billing`;function o({headline:o,hint:s,reason:c=`no-data`,cta:l,width:u}){let{theme:d}=e(),f=i[c],p=c===`error`?d.error:c===`tier-gated`?d.accent2:d.muted,m=l??(c===`tier-gated`?`Upgrade → ${a}`:void 0);return r.createElement(t,{flexDirection:`column`,alignItems:`center`,width:u},r.createElement(n,{color:p,bold:!0},f),r.createElement(n,{color:d.typography.title.color,bold:d.typography.title.bold},o),s?r.createElement(n,{color:d.dim},s):null,m?r.createElement(n,{color:d.accent},m):null)}export{o as EmptyState};
1
+ import{useTheme as e}from"./panel-jycoT562.js";import{Box as t,Text as n}from"ink";import r from"react";const i={"no-data":`○`,"tier-gated":`◆`,error:`✗`},a=`https://app.zenovay.com/billing`;function o({headline:o,hint:s,reason:c=`no-data`,cta:l,width:u}){let{theme:d}=e(),f=i[c],p=c===`error`?d.error:c===`tier-gated`?d.accent2:d.muted,m=l??(c===`tier-gated`?`Upgrade → ${a}`:void 0);return r.createElement(t,{flexDirection:`column`,alignItems:`center`,width:u},r.createElement(n,{color:p,bold:!0},f),r.createElement(n,{color:d.typography.title.color,bold:d.typography.title.bold},o),s?r.createElement(n,{color:d.dim},s):null,m?r.createElement(n,{color:d.accent},m):null)}export{o as EmptyState};
@@ -0,0 +1,2 @@
1
+ import{ApiError as e}from"./api-CJnD6Auw.js";function t(e){let t=process.env.HOME??process.env.USERPROFILE??``;return t&&e.includes(t)?e.split(t).join(`~`):e}function n(n){if(n instanceof e){let e=n.status,r=t(n.message),i=n.body,a=typeof i==`object`&&!!i&&(i.message??i.error)||void 0,o=a?t(String(a)):r,s=new Set([`auth_required`,`auth_invalid`,`tier_insufficient`,`forbidden`,`not_found`,`validation_failed`,`rate_limited`,`idempotency_replay`,`network_error`,`server_error`,`unknown`]);if(i?.type===`error`&&typeof i.code==`string`&&s.has(i.code))return{type:`error`,code:i.code,message:o,...i.hint?{hint:t(String(i.hint))}:{}};if(e===401){let e=/no\s+token|missing\s+(token|auth)|not\s+(logged|authenticated)/i.test(r);return{type:`error`,code:e?`auth_required`:`auth_invalid`,message:o,hint:e?"Run `zenovay login` to authenticate.":"Your session expired. Run `zenovay login` to re-authenticate."}}if(e===402){let e=i?.upgradeUrl??i?.upgrade_url??`https://app.zenovay.com/billing`;return{type:`error`,code:`tier_insufficient`,message:o,hint:`Upgrade your plan: ${e}`}}if(e===403)return{type:`error`,code:`forbidden`,message:o,hint:`You do not have permission for this action.`};if(e===404)return{type:`error`,code:`not_found`,message:o};if(e===400||e===422)return{type:`error`,code:`validation_failed`,message:o,hint:`Check the command flags and arguments.`};if(e===429)return{type:`error`,code:`rate_limited`,message:o,hint:`You hit a rate limit. Wait a moment and retry.`};if(e===409){let e=/idempot/i.test(r)||/idempot/i.test(String(a??``));return e?{type:`error`,code:`idempotency_replay`,message:o,hint:`Same idempotency key was used for a different request body.`}:{type:`error`,code:`unknown`,message:o}}return e>=500&&e<600?{type:`error`,code:`server_error`,message:o,hint:`Server-side issue. Try again shortly or check status.zenovay.com.`}:{type:`error`,code:`unknown`,message:o}}let r=n,i=r?.code??r?.cause?.code;if(i===`ENOTFOUND`||i===`ECONNREFUSED`||i===`ETIMEDOUT`||i===`EAI_AGAIN`)return{type:`error`,code:`network_error`,message:t(String(r?.message??i)),hint:`Check your internet connection and try again.`};if(n instanceof Error){let e=t(n.message);return/abort/i.test(e),{type:`error`,code:`unknown`,message:e}}return{type:`error`,code:`unknown`,message:typeof n==`string`?t(n):`An unknown error occurred.`}}function r(){let e=process.env.ZENOVAY_CLI_VERSION??`0`,t=process.argv.slice(2).filter(e=>!e.startsWith(`-`)),n=t.join(` `)||`unknown`;return{cliVersion:e,command:n}}function i(e,t){let i=n(e),a=r(),o={cliVersion:t?.cliVersion??a.cliVersion,command:t?.command??a.command,...t};return{...i,ts:new Date().toISOString(),meta:o}}function a(){return!!(process.argv.includes(`--json`)||process.argv.includes(`-q`)||process.argv.includes(`--quiet`)||process.env.ZENOVAY_FORMAT===`json`||process.env.ZENOVAY_FORMAT===`ndjson`||!process.stdout.isTTY||process.env.CI===`true`||process.env.CI===`1`)}function o(e,t){let n=i(e,t);return a()?process.stderr.write(JSON.stringify(n)+`
2
+ `):(process.stderr.write(`\n✗ ${n.message}\n`),n.hint&&process.stderr.write(` ${n.hint}\n`)),n.code===`validation_failed`||n.code===`auth_required`?2:1}export{o as emitErrorEnvelope,n as normalizeError};
@@ -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"./progress-row-C7gQLX4T.js";import"./prompt-Db9Y7CVt.js";import"./keybar-BYQ2Bam1.js";import{spark as a}from"./sparkline-BlAQSlYZ.js";import{resolveSiteId as o}from"./resolve-site-CZEwJoBj.js";import{DataTable as s}from"./data-table-BnWXIW9M.js";import"./bar-BPHTpgfb.js";import{runAnalyticalScreen as c}from"./analytical-screen-BGMW3z_2.js";import"./ui-hZ5oXnwY.js";import{Box as l,Text as u}from"ink";import d from"react";function f(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function p(e){let t=Math.max(0,Math.floor((Date.now()-new Date(e).getTime())/1e3));return t<60?`${t}s`:t<3600?`${Math.floor(t/60)}m`:t<86400?`${Math.floor(t/3600)}h`:`${Math.floor(t/86400)}d`}async function m(m){let h=await e(),g=await t({strict:!1}),_=new n({config:h,cliVersion:m.cliVersion,token:g}),v,y;try{({siteId:v,site:y}=await o(_,{explicit:m.siteId,headless:!!(m.json||m.csv||m.tsv||m.ndjson),cliVersion:m.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let b=i(m),x=m.window??`24h`,S=m.limit??100,C=[{key:`ts`,label:`when`,width:6,format:e=>p(String(e))},{key:`class`,label:`class`,width:18,format:e=>String(e)},{key:`message`,label:`message`,width:42,format:e=>f(String(e??``),42)},{key:`page`,label:`page`,width:24,format:e=>String(e??`—`)},{key:`device`,label:`device`,width:8,format:e=>String(e??`—`)}];return c({cliVersion:m.cliVersion,title:`errors · ${v} · ${x}`,commandName:`errors`,authToken:g?.accessToken??null,refreshIntervalMs:m.watch?3e4:0,fetcher:e=>_.getErrors(v,{window:x,limit:S},e),format:b,headlessEmit:(e,t)=>{let n=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors;if(t===`json`||t===`ndjson`){if(t===`ndjson`)for(let e of n)process.stdout.write(JSON.stringify(e)+`
2
+ `);else process.stdout.write(JSON.stringify({errors:n,total:n.length},null,2));return}process.stdout.write(r(n,[`ts`,`class`,`message`,`page`,`device`,`fingerprint`],t))},panels:[{id:`summary`,title:`Recent errors`,render:e=>{let t=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors,n=new Map,r=Date.now(),i=60;for(let e of t){let t=new Date(e.ts).getTime(),a=Math.floor((r-t)/(60*1e3));if(a<0||a>=i)continue;let o=n.get(e.class)??Array(i).fill(0),s=i-1-a;o[s]+=1,n.set(e.class,o)}let o=[...n.entries()].sort((e,t)=>t[1].reduce((e,t)=>e+t,0)-e[1].reduce((e,t)=>e+t,0)).slice(0,6);return d.createElement(l,{flexDirection:`column`},d.createElement(u,null,d.createElement(u,{bold:!0},t.length),d.createElement(u,{color:`gray`},` errors in `,x)),o.length===0?null:d.createElement(l,{flexDirection:`column`,marginTop:1},o.map(([e,t])=>d.createElement(u,{key:e},d.createElement(u,{color:`red`},e.padEnd(20).slice(0,20)),` `,d.createElement(u,{color:`gray`},a(t,30))))))}},{id:`table`,title:`Detail`,render:e=>{let t=m.search?e.errors.filter(e=>e.class.toLowerCase().includes(m.search.toLowerCase())||e.message.toLowerCase().includes(m.search.toLowerCase())):e.errors;return t.length===0?d.createElement(u,{color:`gray`},`— no errors `,m.search?`matching "${m.search}"`:`in window`,` —`):d.createElement(s,{data:t.slice(0,30),columns:C,headerStyle:`accent`})}}]})}export{m as errorsCommand};
@@ -1,4 +1,4 @@
1
- import{readConfig as e,updateConfig as t}from"./config-Cmi_f_SY.js";import{ApiClient as n,readToken as r}from"./api-CeB_9iPg.js";import{parseSseStream as i}from"./client-WzSy90dG.js";import"./formatter-mW0Yk3Nt.js";import{isHeadless as a}from"./emit-DBbMG9mK.js";import{Panel as o}from"./panel-uygscwY5.js";import{Banner as s}from"./banner-BPQh2F8l.js";import{TextInput as c}from"./prompt-BURfUNxp.js";import{Keybar as l}from"./keybar-C7YkmK1U.js";import u from"node:path";import{promises as d}from"node:fs";import f from"node:os";import p from"node:crypto";import{Box as m,Static as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useRef as S,useState as C}from"react";const w=new Set([`type`,`page`,`country`,`device`,`user_id`,`sessionId`,`referrer`,`ts`,`url`,`method`,`status`]);function T(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(/\s/.test(r)){n+=1;continue}if(r===`(`){t.push({kind:`lparen`}),n+=1;continue}if(r===`)`){t.push({kind:`rparen`}),n+=1;continue}if(r===`"`||r===`'`){let i=r,a=n+1,o=``;for(;a<e.length&&e[a]!==i;)e[a]===`\\`&&a+1<e.length?(o+=e[a+1],a+=2):(o+=e[a],a+=1);if(a>=e.length)throw Error(`filter: unterminated string starting at column ${n+1}`);t.push({kind:`string`,value:o}),n=a+1;continue}if(r===`!`&&e[n+1]===`=`){t.push({kind:`op`,value:`!=`}),n+=2;continue}if(r===`!`&&e[n+1]===`~`){t.push({kind:`op`,value:`!~`}),n+=2;continue}if(r===`=`){t.push({kind:`op`,value:`=`}),n+=1;continue}if(r===`~`){t.push({kind:`op`,value:`~`}),n+=1;continue}let i=n;for(;n<e.length&&!/[\s()=!~]/.test(e[n])&&e[n]!==`"`&&e[n]!==`'`;)n+=1;let a=e.slice(i,n);if(a.length===0)throw Error(`filter: unexpected character at column ${i+1}`);let o=a.toUpperCase();o===`AND`?t.push({kind:`and`}):o===`OR`?t.push({kind:`or`}):t.push({kind:`ident`,value:a})}return t}function E(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function D(e,t,n){let r=e==null?``:String(e);switch(t){case`=`:return r===n;case`!=`:return r!==n;case`~`:{let e=new RegExp(E(n),`i`);return e.test(r)}case`!~`:{let e=new RegExp(E(n),`i`);return!e.test(r)}}}function O(e){return e.tokens[e.pos]}function k(e){let t=e.tokens[e.pos];return e.pos+=1,t}function A(e){let t=O(e);if(!t)throw Error(`filter: unexpected end of expression`);if(t.kind===`lparen`){k(e);let t=j(e),n=k(e);if(!n||n.kind!==`rparen`)throw Error(`filter: missing closing ")"`);return t}if(t.kind!==`ident`)throw Error(`filter: expected key, got ${t.kind}`);k(e);let n=t.value;if(!w.has(n))throw Error(`filter: unknown key "${n}". Allowed: ${[...w].join(`, `)}`);let r=k(e);if(!r||r.kind!==`op`)throw Error(`filter: expected operator after "${n}"`);let i=k(e);if(!i||i.kind!==`ident`&&i.kind!==`string`)throw Error(`filter: expected value after operator "${r.value}"`);let a=r.value,o=i.value;return e=>D(e[n],a,o)}function j(e){let t=A(e);for(;;){let n=O(e);if(!n)break;if(n.kind===`and`){k(e);let n=A(e),r=t;t=e=>r(e)&&n(e);continue}if(n.kind===`or`){k(e);let n=A(e),r=t;t=e=>r(e)||n(e);continue}break}return t}function M(e){if(typeof e!=`string`||e.trim().length===0)throw Error(`filter: expression is empty`);let t=T(e);if(t.length===0)throw Error(`filter: expression is empty`);let n={tokens:t,pos:0},r=j(n);if(n.pos!==t.length){let e=n.tokens[n.pos];throw Error(`filter: unexpected trailing token "${N(e)}"`)}return r}function N(e){return e.kind===`ident`||e.kind===`string`||e.kind===`op`?e.value:e.kind}const P=10*1024*1024;var F=class{currentBytes=0;initialized=!1;writeQueue=Promise.resolve();constructor(e,t=P){this.filePath=e,this.maxBytes=t}async init(){if(!this.initialized){this.initialized=!0;try{await d.mkdir(u.dirname(this.filePath),{recursive:!0,mode:448})}catch{}try{let e=await d.stat(this.filePath);this.currentBytes=e.size}catch{this.currentBytes=0}}}append(e){let t=(async()=>{await this.init();let t=e.endsWith(`
1
+ import{readConfig as e,updateConfig as t}from"./config-CG7B8fR0.js";import{ApiClient as n}from"./api-CJnD6Auw.js";import{readToken as r}from"./token-store-C1AqhmDP.js";import{parseSseStream as i}from"./client-CN2wyAL7.js";import"./formatter-KOe_hjhc.js";import{isHeadless as a}from"./emit-B8RbnBJe.js";import{Panel as o}from"./panel-jycoT562.js";import{Banner as s}from"./banner-gVm7GaJF.js";import{TextInput as c}from"./prompt-Db9Y7CVt.js";import{Keybar as l}from"./keybar-BYQ2Bam1.js";import u from"node:path";import{promises as d}from"node:fs";import f from"node:os";import p from"node:crypto";import{Box as m,Static as h,Text as g,render as _,useApp as v,useInput as y}from"ink";import b,{useEffect as x,useRef as S,useState as C}from"react";const w=new Set([`type`,`page`,`country`,`device`,`user_id`,`sessionId`,`referrer`,`ts`,`url`,`method`,`status`]);function T(e){let t=[],n=0;for(;n<e.length;){let r=e[n];if(/\s/.test(r)){n+=1;continue}if(r===`(`){t.push({kind:`lparen`}),n+=1;continue}if(r===`)`){t.push({kind:`rparen`}),n+=1;continue}if(r===`"`||r===`'`){let i=r,a=n+1,o=``;for(;a<e.length&&e[a]!==i;)e[a]===`\\`&&a+1<e.length?(o+=e[a+1],a+=2):(o+=e[a],a+=1);if(a>=e.length)throw Error(`filter: unterminated string starting at column ${n+1}`);t.push({kind:`string`,value:o}),n=a+1;continue}if(r===`!`&&e[n+1]===`=`){t.push({kind:`op`,value:`!=`}),n+=2;continue}if(r===`!`&&e[n+1]===`~`){t.push({kind:`op`,value:`!~`}),n+=2;continue}if(r===`=`){t.push({kind:`op`,value:`=`}),n+=1;continue}if(r===`~`){t.push({kind:`op`,value:`~`}),n+=1;continue}let i=n;for(;n<e.length&&!/[\s()=!~]/.test(e[n])&&e[n]!==`"`&&e[n]!==`'`;)n+=1;let a=e.slice(i,n);if(a.length===0)throw Error(`filter: unexpected character at column ${i+1}`);let o=a.toUpperCase();o===`AND`?t.push({kind:`and`}):o===`OR`?t.push({kind:`or`}):t.push({kind:`ident`,value:a})}return t}function E(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function D(e,t,n){let r=e==null?``:String(e);switch(t){case`=`:return r===n;case`!=`:return r!==n;case`~`:{let e=new RegExp(E(n),`i`);return e.test(r)}case`!~`:{let e=new RegExp(E(n),`i`);return!e.test(r)}}}function O(e){return e.tokens[e.pos]}function k(e){let t=e.tokens[e.pos];return e.pos+=1,t}function A(e){let t=O(e);if(!t)throw Error(`filter: unexpected end of expression`);if(t.kind===`lparen`){k(e);let t=j(e),n=k(e);if(!n||n.kind!==`rparen`)throw Error(`filter: missing closing ")"`);return t}if(t.kind!==`ident`)throw Error(`filter: expected key, got ${t.kind}`);k(e);let n=t.value;if(!w.has(n))throw Error(`filter: unknown key "${n}". Allowed: ${[...w].join(`, `)}`);let r=k(e);if(!r||r.kind!==`op`)throw Error(`filter: expected operator after "${n}"`);let i=k(e);if(!i||i.kind!==`ident`&&i.kind!==`string`)throw Error(`filter: expected value after operator "${r.value}"`);let a=r.value,o=i.value;return e=>D(e[n],a,o)}function j(e){let t=A(e);for(;;){let n=O(e);if(!n)break;if(n.kind===`and`){k(e);let n=A(e),r=t;t=e=>r(e)&&n(e);continue}if(n.kind===`or`){k(e);let n=A(e),r=t;t=e=>r(e)||n(e);continue}break}return t}function M(e){if(typeof e!=`string`||e.trim().length===0)throw Error(`filter: expression is empty`);let t=T(e);if(t.length===0)throw Error(`filter: expression is empty`);let n={tokens:t,pos:0},r=j(n);if(n.pos!==t.length){let e=n.tokens[n.pos];throw Error(`filter: unexpected trailing token "${N(e)}"`)}return r}function N(e){return e.kind===`ident`||e.kind===`string`||e.kind===`op`?e.value:e.kind}const P=10*1024*1024;var F=class{currentBytes=0;initialized=!1;writeQueue=Promise.resolve();constructor(e,t=P){this.filePath=e,this.maxBytes=t}async init(){if(!this.initialized){this.initialized=!0;try{await d.mkdir(u.dirname(this.filePath),{recursive:!0,mode:448})}catch{}try{let e=await d.stat(this.filePath);this.currentBytes=e.size}catch{this.currentBytes=0}}}append(e){let t=(async()=>{await this.init();let t=e.endsWith(`
2
2
  `)?e:`${e}\n`,n=Buffer.byteLength(t,`utf8`);this.currentBytes+n>this.maxBytes&&await this.rotate();try{await d.appendFile(this.filePath,t,{mode:384}),this.currentBytes+=n}catch(e){process.stderr.write(`[scrollback] append failed: ${e.message}\n`)}})();return this.writeQueue=this.writeQueue.then(()=>t,()=>t),t}async rotate(){let e=e=>{if(e===0)return this.filePath;let t=u.parse(this.filePath);return u.join(t.dir,`${t.name}.${e}${t.ext}`)};try{await d.unlink(e(3))}catch{}for(let t=2;t>=0;--t)try{await d.rename(e(t),e(t+1))}catch(n){n.code!==`ENOENT`&&process.stderr.write(`[scrollback] rotate ${e(t)} failed: ${n.message}\n`)}this.currentBytes=0}async close(){await this.writeQueue}};const I=5e3,L=33,R=`─── replay end, live below ───`;async function z(i){if(i.setForwardSecret)return await t({forwardSecret:i.setForwardSecret}),process.stdout.write(`Forward secret saved.
3
3
  `),0;let o=await e(),s=await r({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:i.cliVersion,token:s}),l=null;if(i.filter)try{l=M(i.filter)}catch(e){return process.stderr.write(`Invalid --filter expression: ${e.message}\n`),2}if(a(i))return H(c,i,l,o.forwardSecret);let d=i.scrollbackPath??u.join(f.homedir(),`.zenovay`,`events-scrollback.log`);return new Promise(e=>{let{unmount:t}=_(b.createElement(U,{api:c,opts:i,predicate:l,forwardSecret:o.forwardSecret,scrollbackPath:d,onExit:n=>{t(),e(n)}}))})}function B(e){return{raw:JSON.stringify(e),parsed:e}}async function V(e,t,n){let r=JSON.stringify(n),i=p.createHmac(`sha256`,t).update(r).digest(`hex`);try{await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Zenovay-Signature":`sha256=${i}`},body:r})}catch{}}async function H(e,t,n,r){let a=new AbortController;process.on(`SIGINT`,()=>a.abort());let o=()=>new Date().toISOString();try{let s=await e.openEventsStream(t.siteId,a.signal);for await(let e of i(s)){if(e.type===`error`)return process.stdout.write(`${JSON.stringify({ts:o(),type:`error`,code:e.code,message:e.message})}\n`),1;if(e.type===`done`)return 0;let i=e;if(n&&!n(i))continue;process.stdout.write(`${JSON.stringify({ts:o(),...i})}\n`),t.forwardTo&&r&&await V(t.forwardTo,r,{event:e,ts:o(),site_id:t.siteId})}return 0}catch(e){return process.stdout.write(`${JSON.stringify({ts:o(),type:`error`,code:`stream_failed`,message:e.message})}\n`),1}}const U=({api:e,opts:t,predicate:n,forwardSecret:r,scrollbackPath:a,onExit:u})=>{let{exit:f}=v(),p=S([]),_=S(null),[w,T]=C([]),[E,D]=C(null),[O,k]=C(!1),[A,j]=C(null);_.current||=new F(a),y(n=>{if(!O){if(E){D(null);return}if(n===`q`){f(),u(0);return}if(n===`f`){let e=p.current[p.current.length-1];e&&D(e);return}if(n===`w`){k(!0);return}if(n===`r`){G(e,t.siteId,p,j);return}}}),x(()=>{let e=setInterval(()=>{let e=p.current.slice(-100);T(e)},L);return()=>clearInterval(e)},[]),x(()=>{let a=new AbortController,o=!1;return(async()=>{t.replay24h&&await G(e,t.siteId,p,j);try{let s=await e.openEventsStream(t.siteId,a.signal);for await(let e of i(s)){if(o)break;if(e.type===`error`){let t={raw:`[ERR ${e.code}] ${e.message}`};W(p,t),_.current?.append(t.raw);continue}if(e.type===`done`)break;let i=e;if(n&&!n(i))continue;let a=B(e);W(p,a),_.current?.append(a.raw),t.forwardTo&&r&&V(t.forwardTo,r,{event:e,ts:new Date().toISOString(),site_id:t.siteId})}}catch(e){let t={raw:`[DISCONNECT] ${e.message}`};W(p,t)}})(),()=>{o=!0,a.abort(),_.current?.close()}},[e,t.siteId,t.replay24h,t.forwardTo,n,r]);let M=async e=>{let t=e.trim()||`events.ndjson`;try{let e=p.current.map(e=>e.raw).join(`
4
4
  `)+`
@@ -0,0 +1 @@
1
+ const e={analytics:[`zenovay analytics # interactive dashboard`,`zenovay analytics --json | jq .data.visitors`,`zenovay analytics --range 7d`,`zenovay analytics --csv > today.csv`],live:[`zenovay live # 2s-poll real-time view`,`zenovay live --json # one-shot snapshot`,`zenovay live --site-id <UUID>`],pages:[`zenovay pages # top pages, last 24h`,`zenovay pages --json | jq '.data.items[] | select(.views > 50)'`,`zenovay pages --csv > top-pages.csv`],sources:[`zenovay sources # bars + delta arrows`,`zenovay sources --period 30d --csv`,`zenovay sources --json | jq '.data.items[] | select(.channel=="organic")'`,`zenovay sources --compare prev # period-over-period delta`],devices:[`zenovay devices # device + browser + OS breakdown`,`zenovay devices --json`,`zenovay devices --csv > devices.csv`],geo:[`zenovay geo # country + city + globe`,`zenovay geo --json | jq '.data.countries[]'`],retention:[`zenovay retention # D1 / D7 / D30 cohort heatmap`,`zenovay retention --json`],uptime:[`zenovay uptime # monitor list with p95`,`zenovay uptime --json | jq '.data.items[] | select(.status=="down")'`],sessions:[`zenovay sessions # recent replay list`,`zenovay sessions --limit 10`,`zenovay sessions --json`],heatmaps:[`zenovay heatmaps # recent captures`,`zenovay heatmaps --json`],journeys:[`zenovay journeys # page-to-page transitions`,`zenovay journeys --json | jq .data`],insights:[`zenovay insights # AI-generated cards`,`zenovay insights --json | jq '.data.items[] | .title'`],"events tail":[`zenovay events tail # NDJSON stream`,`zenovay events tail --filter 'type=pageview AND country=US'`,`zenovay events tail --replay-24h`,`zenovay events tail --forward-to http://localhost:3000/hook`],errors:[`zenovay errors # last 24h error snapshot`,`zenovay errors --window 7d --limit 50`,`zenovay errors --search "TypeError"`,`zenovay errors --json | jq '.data.items[] | .message'`],funnels:[`zenovay funnels # list saved funnels`,`zenovay funnels --json`],funnel:[`zenovay funnel <id> # drop-off chart`,`zenovay funnel <id> --window 7d`,`zenovay funnel <id> --json | jq '.data.steps'`],query:[`zenovay query "SELECT count(*) FROM events"`,`zenovay query # interactive REPL (Scale+)`,`zenovay query --max-rows 5000 "SELECT path, count(*) FROM pageviews GROUP BY 1"`],companies:[`zenovay companies # B2B identification feed`,`zenovay companies --new-only --watch`,`zenovay companies --json | jq '.data.items[] | .domain'`],visitors:[`zenovay visitors # user profiles list`,`zenovay visitors --min-duration 60s`,`zenovay visitors --json`],vitals:[`zenovay vitals # LCP / INP / CLS / TTFB / FCP`,`zenovay vitals --window 30d --device mobile`,`zenovay vitals --url /pricing`,`zenovay vitals --csv > web-vitals.csv`],revenue:[`zenovay revenue # MRR / ARR / transactions`,`zenovay revenue --range 1y`,`zenovay revenue --json | jq '.data.mrr'`],home:[`zenovay home # this-week deltas across all sites`,`zenovay home --json`],usage:[`zenovay usage # events vs plan limits`,`zenovay usage --json | jq '.data.events.thisMonth'`],profile:[`zenovay profile show`,`zenovay profile edit --name "Valerio A."`,`zenovay profile edit --notifications email`,`zenovay profile show --json`],plans:[`zenovay plans info # current tier + limits`,`zenovay plans upgrade pro`,`zenovay plans cancel --yes`,`zenovay plans payment update # update card on file`],settings:[`zenovay settings get # all settings`,`zenovay settings get cookielessTracking`,`zenovay settings set cookielessTracking true`],integrations:[`zenovay integrations list`,`zenovay integrations connect gsc # Google Search Console`,`zenovay integrations connect github`,`zenovay integrations disconnect gsc --yes`],goals:[`zenovay goals list`,`zenovay goals create --name "Signup" --type pageview --target /signup/done`,`zenovay goals delete <id> --yes`],notes:[`zenovay notes list`,`zenovay notes create --content "Pricing change shipped"`,`zenovay notes delete <id> --yes`],audit:[`zenovay audit list # recent audit-log entries`,`zenovay audit list --since 7d --action website_deleted`,`zenovay audit list --actor valerio.amirani@zenovay.com`,`zenovay audit export --format csv --out audit.csv`],share:[`zenovay share enable # turn on public dashboard`,`zenovay share url # print shareable URL`,`zenovay share disable`],agency:[`zenovay agency clients list`,`zenovay agency clients add --email lead@acme.com --name Acme`,`zenovay agency clients remove <id> --yes`,`zenovay agency report send <clientId>`],"api-keys":[`zenovay api-keys list`,`zenovay api-keys create --name "CI" --scope read`,`zenovay api-keys delete <id> --yes`],domains:[`zenovay domains list`,`zenovay domains add https://example.com --name "Marketing site"`,`zenovay domains delete <id> --yes`],team:[`zenovay team list`,`zenovay team invite alice@example.com --role admin`,`zenovay team remove <userId> --yes`,`zenovay team role <userId> admin`],webhooks:[`zenovay webhooks list`,`zenovay webhooks add https://hook.example.com --events alert.fired,deploy.created`,`zenovay webhooks rotate <id>`,`zenovay webhooks test <id>`],alerts:[`zenovay alerts list`,`zenovay alerts create --metric bounce_rate --op gt --threshold 0.7 --window 1h`,`zenovay alerts delete <id> --yes`],export:[`zenovay export analytics --range 7d --format csv > 7d.csv`,`zenovay export analytics --range 30d --format json --out 30d.json`,`zenovay export sessions --range 7d --format csv`,`zenovay export heatmaps --range 30d --format json`],init:[`zenovay init # AI install wizard`,`npx @zenovay/wizard # one-shot install (no global)`,`zenovay init --yes --skip-mcp # CI-friendly`],login:[`zenovay login # OAuth device flow`,`zenovay login --no-browser # print URL only`,`zenovay login --json # machine-readable progress`],logout:[`zenovay logout`,`zenovay logout --json`],health:[`zenovay health # 9-check self-diagnostic`,`zenovay health --json | jq '.checks[] | select(.status=="fail")'`],status:["zenovay status # alias of `health`",`zenovay status --json`],doctor:[`zenovay doctor # AI-assisted self-healing`,`zenovay doctor --json`],update:[`zenovay update # install latest`,`zenovay update --check # print latest, do nothing`,`zenovay update --force-downgrade`],use:[`zenovay use # show current default site`,`zenovay use skynovay.com # set default by URL`,`zenovay use --reset`,`zenovay use --show --json`],teams:[`zenovay teams list`,`zenovay teams switch "Zenovay Scale"`,`zenovay teams current`,`zenovay teams reset`],globe:["zenovay globe # hint — see `zenovay live`",`zenovay globe --json`],projects:[`zenovay projects # tracked-website list`,`zenovay projects --json`,`zenovay projects --csv > sites.csv`],deploys:[`zenovay deploys # recent commits`,`zenovay deploys --branch main --since 2026-04-01`,`zenovay deploys --connect # print integration deep link`],themes:[`zenovay themes # swatches for all themes`,`zenovay themes --validate ./my-theme.json`],completions:[`zenovay completions zsh >> ~/.zshrc`,`zenovay completions bash >> ~/.bashrc`,`zenovay completions fish > ~/.config/fish/completions/zenovay.fish`,`zenovay completions --list`],commands:[`zenovay commands # full tree as JSON`,`zenovay commands --json | jq '.commands[].name'`],"self-test":[`zenovay self-test # full suite (~20s)`,`zenovay self-test --quick # ~10 representative tests`,`zenovay self-test --json | jq -r 'select(.status=="fail")'`,`zenovay self-test --verbose # include raw stdout/stderr`],tour:[`zenovay tour # 8-step interactive walkthrough`,`zenovay tour --non-interactive # flat read-the-output document`],ai:[`zenovay ai # pick a mode interactively`,`zenovay ai --mode install`,`zenovay ai --mode chat`,`zenovay ai --mode mcp`],stats:[`zenovay stats # one-shot dashboard`,`zenovay stats --range 7d`,`zenovay stats --watch`,`zenovay stats --json | jq '.data.daily[] | .visitors'`]};export{e as EXAMPLES};
@@ -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-Iig3PBVk.js";import{ApiV2Client as r}from"./api-v2-UJJ6ube8.js";import{requireTier as i}from"./tier-uaU5pkTz.js";import{formatTabular as a}from"./formatter-KOe_hjhc.js";import{emitEnvelope as o,wrapItem as s}from"./emit-B8RbnBJe.js";import"./panel-jycoT562.js";import"./banner-gVm7GaJF.js";import"./prompt-Db9Y7CVt.js";import{resolveSiteId as c}from"./resolve-site-CZEwJoBj.js";import{resolve as l}from"node:path";import{writeFile as u}from"node:fs/promises";function d(e,t,n){return a(e,t,n)}function f(e){let t=(e??`30d`).toLowerCase();return t===`7d`||t===`30d`||t===`90d`?t:`30d`}function p(e,t){t||process.stderr.isTTY&&process.stderr.write(`${e}\n`)}async function m(a){let d=await e(),m=await t({strict:!1}),_=new r({config:d,cliVersion:a.cliVersion,token:m});if(a.type!==`analytics`&&a.type!==`sessions`&&a.type!==`heatmaps`){let e=`Unknown export type '${a.type}'. Use one of: analytics, sessions, heatmaps.`;return a.json?n(Error(e),{command:`export`,cliVersion:a.cliVersion}):(process.stderr.write(`Error: ${e}\n`),2)}let v=a.format===`json`?`json`:`csv`,y=f(a.range),b=!!a.json;if(a.type===`sessions`||a.type===`heatmaps`)try{await i(_,`pro`)}catch(e){return a.json?n(e,{command:`export ${a.type}`,cliVersion:a.cliVersion}):(process.stderr.write(`${e.message}\n`),2)}let x;try{({siteId:x}=await c(_,{explicit:a.siteId,headless:b,cliVersion:a.cliVersion}))}catch(e){return a.json?n(e,{command:`export ${a.type}`,cliVersion:a.cliVersion}):(process.stderr.write(`${e.message}\n`),2)}try{p(`→ Fetching ${a.type} ${y}...`,b);let{rows:e,columns:t}=await h(_,a.type,x,y),n=g(e,t,v),r=a.out?l(process.cwd(),a.out):null;return r?(await u(r,n,`utf8`),a.json?(o(s({rowsWritten:e.length,file:r,format:v,range:y,type:a.type},`export.completed`,{siteId:x,command:`export ${a.type}`,cliVersion:a.cliVersion})),0):(process.stdout.write(`✓ Exported ${e.length} rows to ${r}\n`),0)):(process.stdout.write(n),n.endsWith(`
2
+ `)||process.stdout.write(`
3
+ `),a.json&&o(s({rowsWritten:e.length,file:null,format:v,range:y,type:a.type},`export.completed`,{siteId:x,command:`export ${a.type}`,cliVersion:a.cliVersion})),0)}catch(e){return a.json?n(e,{command:`export ${a.type}`,cliVersion:a.cliVersion}):(process.stderr.write(`✗ ${e.message}\n`),1)}}async function h(e,t,n,r){if(t===`analytics`){let t=await e.getStats(n,r);if(t.daily&&t.daily.length>0){let e=t.daily.map(e=>({date:e.date,visitors:e.visitors,pageviews:e.pageviews}));return{rows:e,columns:[`date`,`visitors`,`pageviews`]}}let i=[{range:r,visitors:t.visitors,pageviews:t.pageviews,sessions:t.sessions,bounceRate:t.bounceRate,avgSessionSec:t.avgSessionSec,windowStart:t.windowStart,windowEnd:t.windowEnd}];return{rows:i,columns:[`range`,`visitors`,`pageviews`,`sessions`,`bounceRate`,`avgSessionSec`,`windowStart`,`windowEnd`]}}if(t===`sessions`){let t=await e.getSessions(n),r=t.map(e=>({id:e.id,visitor:e.visitor,durationMs:e.duration,startedAt:e.startedAt,pageCount:e.pageCount,deviceType:e.deviceType??``}));return{rows:r,columns:[`id`,`visitor`,`durationMs`,`startedAt`,`pageCount`,`deviceType`]}}let i=await e.getHeatmaps(n),a=i.map(e=>({id:e.id,url:e.url,type:e.type,captureCount:e.captureCount,createdAt:e.createdAt}));return{rows:a,columns:[`id`,`url`,`type`,`captureCount`,`createdAt`]}}function g(e,t,n){if(n===`json`){let n=e.map(e=>{let n={};for(let r of t)n[String(r)]=e[r];return n});return JSON.stringify(n,null,2)+`
4
+ `}return d(e,t,`csv`)}export{m as exportCommand};
@@ -1,3 +1,3 @@
1
- import{readConfig as e}from"./config-Cmi_f_SY.js";import{readToken as t}from"./api-CeB_9iPg.js";import{ApiV2Client as n}from"./api-v2-B_kZhVxd.js";import{formatTabular as r,selectFormat as i}from"./formatter-mW0Yk3Nt.js";import"./panel-uygscwY5.js";import"./banner-BPQh2F8l.js";import"./prompt-BURfUNxp.js";import"./keybar-C7YkmK1U.js";import{resolveSiteId as a}from"./resolve-site-BUpzvcMz.js";import{DataTable as o}from"./data-table-BUyOP6Nc.js";import{runAnalyticalScreen as s}from"./analytical-screen-BpTK5dCY.js";import{Box as c,Text as l}from"ink";import u from"react";function d(e,t){let n=Math.round(e*t);return`█`.repeat(Math.max(0,Math.min(t,n)))+`░`.repeat(Math.max(0,t-n))}async function f(f){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:f.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(f);if(!f.funnelId){let e=[{key:`name`,label:`name`,width:30},{key:`stepCount`,label:`steps`,width:6,align:`right`},{key:`id`,label:`id`,width:36,format:e=>String(e).slice(0,36)}];return s({cliVersion:f.cliVersion,title:`funnels · ${_}`,commandName:`funnels`,authToken:h?.accessToken??null,refreshIntervalMs:0,fetcher:e=>g.listFunnels(_,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
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,t){let n=Math.round(e*t);return`█`.repeat(Math.max(0,Math.min(t,n)))+`░`.repeat(Math.max(0,t-n))}async function f(f){let m=await e(),h=await t({strict:!1}),g=new n({config:m,cliVersion:f.cliVersion,token:h}),_,v;try{({siteId:_,site:v}=await a(g,{explicit:f.siteId,headless:!!(f.json||f.csv||f.tsv||f.ndjson),cliVersion:f.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let y=i(f);if(!f.funnelId){let e=[{key:`name`,label:`name`,width:30},{key:`stepCount`,label:`steps`,width:6,align:`right`},{key:`id`,label:`id`,width:36,format:e=>String(e).slice(0,36)}];return s({cliVersion:f.cliVersion,title:`funnels · ${_}`,commandName:`funnels`,authToken:h?.accessToken??null,refreshIntervalMs:0,fetcher:e=>g.listFunnels(_,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
2
2
  `);return}process.stdout.write(r(e.funnels,[`id`,`name`,`stepCount`],t))},panels:[{id:`funnels`,title:`Funnels`,render:t=>t.funnels.length===0?u.createElement(l,{color:`gray`},`— no funnels defined —`):u.createElement(o,{data:t.funnels,columns:e,headerStyle:`accent`})},{id:`hint`,title:`Next`,render:()=>u.createElement(l,{color:`gray`},"Run `zenovay funnel <id>` for drop-off detail.")}]})}let b=f.window??`30d`;return s({cliVersion:f.cliVersion,title:`funnel · ${f.funnelId} · ${b}`,commandName:`funnel`,authToken:h?.accessToken??null,refreshIntervalMs:0,fetcher:e=>g.getFunnel(_,f.funnelId,b,e),format:y,headlessEmit:(e,t)=>{if(t===`json`||t===`ndjson`){process.stdout.write(JSON.stringify(e,null,t===`json`?2:0)),t===`ndjson`&&process.stdout.write(`
3
3
  `);return}process.stdout.write(r(e.steps,[`id`,`name`,`visitors`,`conversions`],t))},panels:[{id:`overview`,title:p(`Overview`),render:e=>u.createElement(c,{flexDirection:`column`},u.createElement(l,{bold:!0},e.name),u.createElement(l,{color:`gray`},e.totalEntries.toLocaleString(),` entries · `,e.totalCompletions.toLocaleString(),` completed (`,(e.conversionRate*100).toFixed(1),`%)`))},{id:`flow`,title:`Flow`,render:e=>{let t=e.totalEntries||1;return u.createElement(c,{flexDirection:`column`},e.steps.map((n,r)=>{let i=n.visitors/t,a=e.steps[r-1],o=a?a.visitors-n.visitors:0,s=a?o/Math.max(1,a.visitors)*100:0;return u.createElement(c,{key:n.id,flexDirection:`column`},a?u.createElement(l,{color:`red`},` `,`↓ drop `,o.toLocaleString(),` (`,s.toFixed(1),`%)`):null,u.createElement(l,null,u.createElement(l,{bold:!0},`${r+1}. ${n.name}`.padEnd(22).slice(0,22)),` `,u.createElement(l,{color:`magenta`},d(i,30)),` `,u.createElement(l,null,(i*100).toFixed(1).padStart(5),`% `),u.createElement(l,{color:`gray`},n.visitors.toLocaleString())))}))}}]})}function p(e){return e}export{f as funnelCommand};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-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{resolveSiteId as c}from"./resolve-site-CZEwJoBj.js";import{DataTable as l}from"./data-table-BnWXIW9M.js";import{EmptyState as u}from"./empty-state-BkS6DKWZ.js";import{Globe as d}from"./globe-WYN8kVDK.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let l=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await c(l,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(i(a)){let e=await l.getGeo(u);return r({type:`geo.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:l,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:c}=h(),[m,x]=y(null),[S,C]=y(!0),[w,T]=y(null);if(g(e=>{e===`q`&&(c(),i(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getGeo(t);n||(x(r),C(!1))}catch(e){n||(T(e.message),C(!1))}})(),()=>{n=!0}},[e,t]),S)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(a,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching geo…`))));if(w)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(u,{reason:`error`,headline:`Failed to load`,hint:w}));let E=!m||m.countries.length===0&&m.cities.length===0;if(E)return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(u,{reason:`no-data`,headline:`No data yet`,hint:`Visit your site to send the first event`}));let D=[{key:`country`,label:`country`,width:18},{key:`visitors`,label:`visitors`,align:`right`,width:8}],O=[{key:`city`,label:`city`,width:20},{key:`country`,label:`country`,width:12},{key:`visitors`,label:`visitors`,align:`right`,width:8}],k=process.stdout.columns??80;return _.createElement(f,{flexDirection:`column`},_.createElement(o,{version:r,subtitle:`geo · ${n}`}),_.createElement(f,{flexDirection:`row`},_.createElement(a,{title:`Countries`},m.countries.length===0?_.createElement(p,{color:`gray`},`— —`):_.createElement(l,{columns:D,data:m.countries.slice(0,15),zebra:!0})),_.createElement(a,{title:`Globe`},_.createElement(d,{data:[],width:Math.max(36,k-60),height:12}))),_.createElement(a,{title:`Cities`},m.cities.length===0?_.createElement(p,{color:`gray`},`— —`):_.createElement(l,{columns:O,data:m.cities.slice(0,20),zebra:!0})),_.createElement(s,{items:[{key:`q`,label:`quit`}]}))};export{x as geoCommand};
@@ -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"./formatter-KOe_hjhc.js";import{emit as r,isHeadless as i}from"./emit-B8RbnBJe.js";import{Panel as a,useTheme as o}from"./panel-jycoT562.js";import{Banner as s}from"./banner-gVm7GaJF.js";import"./prompt-Db9Y7CVt.js";import{Keybar as c}from"./keybar-BYQ2Bam1.js";import{resolveSiteId as l}from"./resolve-site-CZEwJoBj.js";import{EmptyState as u}from"./empty-state-BkS6DKWZ.js";import{Bar as d}from"./bar-BPHTpgfb.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useMemo as y,useRef as b,useState as x}from"react";import ee from"ink-spinner";import S from"open";const C={DZ:{lat:28.0339,lng:1.6596,name:`Algeria`,spread:8},EG:{lat:26.8206,lng:30.8025,name:`Egypt`,spread:6},ET:{lat:9.145,lng:40.4897,name:`Ethiopia`,spread:6},GH:{lat:7.9465,lng:-1.0232,name:`Ghana`,spread:3},KE:{lat:-.0236,lng:37.9062,name:`Kenya`,spread:4},MA:{lat:31.7917,lng:-7.0926,name:`Morocco`,spread:5},NG:{lat:9.082,lng:8.6753,name:`Nigeria`,spread:5},ZA:{lat:-30.5595,lng:22.9375,name:`South Africa`,spread:7},TZ:{lat:-6.369,lng:34.8888,name:`Tanzania`,spread:5},UG:{lat:1.3733,lng:32.2903,name:`Uganda`,spread:3},TN:{lat:33.8869,lng:9.5375,name:`Tunisia`,spread:3},SN:{lat:14.4974,lng:-14.4524,name:`Senegal`,spread:3},CI:{lat:7.54,lng:-5.5471,name:`Côte d'Ivoire`,spread:3},CM:{lat:7.3697,lng:12.3547,name:`Cameroon`,spread:4},AO:{lat:-11.2027,lng:17.8739,name:`Angola`,spread:6},MZ:{lat:-18.6657,lng:35.5296,name:`Mozambique`,spread:6},ZW:{lat:-19.0154,lng:29.1549,name:`Zimbabwe`,spread:4},ZM:{lat:-13.1339,lng:27.8493,name:`Zambia`,spread:5},RW:{lat:-1.9403,lng:29.8739,name:`Rwanda`,spread:1.5},MG:{lat:-18.7669,lng:46.8691,name:`Madagascar`,spread:5},LY:{lat:26.3351,lng:17.2283,name:`Libya`,spread:8},SD:{lat:12.8628,lng:30.2176,name:`Sudan`,spread:7},US:{lat:39.0902,lng:-98.5795,name:`United States`,spread:18},CA:{lat:56.1304,lng:-106.3468,name:`Canada`,spread:22},MX:{lat:23.6345,lng:-102.5528,name:`Mexico`,spread:9},BR:{lat:-10.235,lng:-51.9253,name:`Brazil`,spread:18},AR:{lat:-38.4161,lng:-63.6167,name:`Argentina`,spread:11},CL:{lat:-35.6751,lng:-71.543,name:`Chile`,spread:11},CO:{lat:4.5709,lng:-74.2973,name:`Colombia`,spread:6},PE:{lat:-9.19,lng:-75.0152,name:`Peru`,spread:7},VE:{lat:6.4238,lng:-66.5897,name:`Venezuela`,spread:6},EC:{lat:-1.8312,lng:-78.1834,name:`Ecuador`,spread:3},BO:{lat:-16.2902,lng:-63.5887,name:`Bolivia`,spread:6},UY:{lat:-32.5228,lng:-55.7658,name:`Uruguay`,spread:2.5},PY:{lat:-23.4425,lng:-58.4438,name:`Paraguay`,spread:4},GT:{lat:15.7835,lng:-90.2308,name:`Guatemala`,spread:2},CU:{lat:21.5218,lng:-77.7812,name:`Cuba`,spread:3},DO:{lat:18.7357,lng:-70.1627,name:`Dominican Republic`,spread:1.5},CR:{lat:9.7489,lng:-83.7534,name:`Costa Rica`,spread:1.2},PA:{lat:8.538,lng:-80.7821,name:`Panama`,spread:1.5},HN:{lat:15.2,lng:-86.2419,name:`Honduras`,spread:2},PR:{lat:18.2208,lng:-66.5901,name:`Puerto Rico`,spread:.6},JM:{lat:18.1096,lng:-77.2975,name:`Jamaica`,spread:.7},TT:{lat:10.6918,lng:-61.2225,name:`Trinidad and Tobago`,spread:.6},GB:{lat:55.3781,lng:-3.436,name:`United Kingdom`,spread:3},IE:{lat:53.4129,lng:-8.2439,name:`Ireland`,spread:2},FR:{lat:46.6034,lng:1.8883,name:`France`,spread:4},DE:{lat:51.1657,lng:10.4515,name:`Germany`,spread:3.5},IT:{lat:41.8719,lng:12.5674,name:`Italy`,spread:3.5},ES:{lat:40.4637,lng:-3.7492,name:`Spain`,spread:4},PT:{lat:39.3999,lng:-8.2245,name:`Portugal`,spread:2},NL:{lat:52.1326,lng:5.2913,name:`Netherlands`,spread:1.2},BE:{lat:50.5039,lng:4.4699,name:`Belgium`,spread:1},CH:{lat:46.8182,lng:8.2275,name:`Switzerland`,spread:1.4},AT:{lat:47.5162,lng:14.5501,name:`Austria`,spread:2},PL:{lat:51.9194,lng:19.1451,name:`Poland`,spread:3.5},CZ:{lat:49.8175,lng:15.473,name:`Czechia`,spread:1.8},SE:{lat:60.1282,lng:18.6435,name:`Sweden`,spread:5},NO:{lat:60.472,lng:8.4689,name:`Norway`,spread:5},FI:{lat:61.9241,lng:25.7482,name:`Finland`,spread:4},DK:{lat:56.2639,lng:9.5018,name:`Denmark`,spread:1.5},IS:{lat:64.9631,lng:-19.0208,name:`Iceland`,spread:3},GR:{lat:39.0742,lng:21.8243,name:`Greece`,spread:3},TR:{lat:38.9637,lng:35.2433,name:`Turkey`,spread:6},RO:{lat:45.9432,lng:24.9668,name:`Romania`,spread:3},HU:{lat:47.1625,lng:19.5033,name:`Hungary`,spread:2},UA:{lat:48.3794,lng:31.1656,name:`Ukraine`,spread:5},RU:{lat:61.524,lng:80,name:`Russia`,spread:28},BG:{lat:42.7339,lng:25.4858,name:`Bulgaria`,spread:2},HR:{lat:45.1,lng:15.2,name:`Croatia`,spread:2},RS:{lat:44.0165,lng:21.0059,name:`Serbia`,spread:2},SK:{lat:48.669,lng:19.699,name:`Slovakia`,spread:1.8},SI:{lat:46.1512,lng:14.9955,name:`Slovenia`,spread:1.2},LT:{lat:55.1694,lng:23.8813,name:`Lithuania`,spread:1.5},LV:{lat:56.8796,lng:24.6032,name:`Latvia`,spread:1.5},EE:{lat:58.5953,lng:25.0136,name:`Estonia`,spread:1.5},BY:{lat:53.7098,lng:27.9534,name:`Belarus`,spread:3},MD:{lat:47.4116,lng:28.3699,name:`Moldova`,spread:1.2},AL:{lat:41.1533,lng:20.1683,name:`Albania`,spread:1},MK:{lat:41.6086,lng:21.7453,name:`North Macedonia`,spread:1},BA:{lat:43.9159,lng:17.6791,name:`Bosnia and Herzegovina`,spread:1.2},ME:{lat:42.7087,lng:19.3744,name:`Montenegro`,spread:.8},XK:{lat:42.6026,lng:20.903,name:`Kosovo`,spread:.7},LU:{lat:49.8153,lng:6.1296,name:`Luxembourg`,spread:.4},MT:{lat:35.9375,lng:14.3754,name:`Malta`,spread:.3},CY:{lat:35.1264,lng:33.4299,name:`Cyprus`,spread:.6},CN:{lat:35.8617,lng:104.1954,name:`China`,spread:18},JP:{lat:36.2048,lng:138.2529,name:`Japan`,spread:5},KR:{lat:35.9078,lng:127.7669,name:`South Korea`,spread:2},IN:{lat:20.5937,lng:78.9629,name:`India`,spread:12},ID:{lat:-2.7893,lng:113.9213,name:`Indonesia`,spread:12},PH:{lat:12.8797,lng:121.774,name:`Philippines`,spread:5},VN:{lat:14.0583,lng:108.2772,name:`Vietnam`,spread:5},TH:{lat:15.87,lng:100.9925,name:`Thailand`,spread:4},MY:{lat:4.2105,lng:101.9758,name:`Malaysia`,spread:4},SG:{lat:1.3521,lng:103.8198,name:`Singapore`,spread:.3},PK:{lat:30.3753,lng:69.3451,name:`Pakistan`,spread:6},BD:{lat:23.685,lng:90.3563,name:`Bangladesh`,spread:3},LK:{lat:7.8731,lng:80.7718,name:`Sri Lanka`,spread:2},MM:{lat:21.9162,lng:95.956,name:`Myanmar`,spread:6},KH:{lat:12.5657,lng:104.991,name:`Cambodia`,spread:3},LA:{lat:19.8563,lng:102.4955,name:`Laos`,spread:3},NP:{lat:28.3949,lng:84.124,name:`Nepal`,spread:3},IR:{lat:32.4279,lng:53.688,name:`Iran`,spread:7},IQ:{lat:33.2232,lng:43.6793,name:`Iraq`,spread:4},IL:{lat:31.0461,lng:34.8516,name:`Israel`,spread:1},SA:{lat:23.8859,lng:45.0792,name:`Saudi Arabia`,spread:8},AE:{lat:23.4241,lng:53.8478,name:`UAE`,spread:2},QA:{lat:25.3548,lng:51.1839,name:`Qatar`,spread:.6},KW:{lat:29.3117,lng:47.4818,name:`Kuwait`,spread:.8},OM:{lat:21.4735,lng:55.9754,name:`Oman`,spread:4},JO:{lat:30.5852,lng:36.2384,name:`Jordan`,spread:2},LB:{lat:33.8547,lng:35.8623,name:`Lebanon`,spread:.7},SY:{lat:34.8021,lng:38.9968,name:`Syria`,spread:3},YE:{lat:15.5527,lng:48.5164,name:`Yemen`,spread:4},AF:{lat:33.9391,lng:67.71,name:`Afghanistan`,spread:5},KZ:{lat:48.0196,lng:66.9237,name:`Kazakhstan`,spread:13},UZ:{lat:41.3775,lng:64.5853,name:`Uzbekistan`,spread:5},TM:{lat:38.9697,lng:59.5563,name:`Turkmenistan`,spread:5},KG:{lat:41.2044,lng:74.7661,name:`Kyrgyzstan`,spread:3},TJ:{lat:38.861,lng:71.2761,name:`Tajikistan`,spread:3},AZ:{lat:40.1431,lng:47.5769,name:`Azerbaijan`,spread:2},GE:{lat:42.3154,lng:43.3569,name:`Georgia`,spread:2},AM:{lat:40.0691,lng:45.0382,name:`Armenia`,spread:1.2},HK:{lat:22.3193,lng:114.1694,name:`Hong Kong`,spread:.3},TW:{lat:23.6978,lng:120.9605,name:`Taiwan`,spread:1.5},AU:{lat:-25.2744,lng:133.7751,name:`Australia`,spread:18},NZ:{lat:-40.9006,lng:174.886,name:`New Zealand`,spread:5},PG:{lat:-6.314,lng:143.9555,name:`Papua New Guinea`,spread:5},FJ:{lat:-16.578,lng:179.4144,name:`Fiji`,spread:1}},w=Object.fromEntries(Object.entries(C).map(([e,t])=>[e,{lat:t.lat,lng:t.lng}]));function T(e){return!e||e.length!==2?null:C[e.toUpperCase()]??null}function E(e,t){let n=T(e);if(!n||t<=0)return[];let r=[],i=0;for(let t=0;t<e.length;t++)i=i*31+e.charCodeAt(t)>>>0;for(let e=0;e<t;e++){i=i+1831565813>>>0;let e=i;e=Math.imul(e^e>>>15,e|1)>>>0,e=(e^e+(Math.imul(e^e>>>7,e|61)>>>0))>>>0;let t=((e^e>>>14)>>>0)/4294967296;i=i+2246822507>>>0;let a=i;a=Math.imul(a^a>>>15,a|1)>>>0,a=(a^a+(Math.imul(a^a>>>7,a|61)>>>0))>>>0;let o=((a^a>>>14)>>>0)/4294967296,s=n.spread*Math.sqrt(t),c=o*2*Math.PI;r.push({lat:n.lat+s*Math.sin(c)*.7,lng:n.lng+s*Math.cos(c)/Math.max(.3,Math.cos(n.lat*Math.PI/180))})}return r}const D=360,O=180,k=new Uint8Array(D*O),A=new Uint8Array(D*O),j=[`__OCEAN__`];function M(e){let t=(e%360+360)%360;return Math.floor(t)}function N(e){return Math.max(0,Math.min(O-1,Math.floor(90-e)))}function P(e,t,n){let r=N(e),i=M(t);k[r*D+i]=1,A[r*D+i]=n}for(let e of Object.keys(C)){let t=C[e];j.push(e);let n=j.length-1,r=Math.max(.5,t.spread*.85),i=Math.max(.25,Math.cos(t.lat*Math.PI/180)),a=Math.max(.5,t.spread/i),o=Math.floor(t.lat-r),s=Math.ceil(t.lat+r),c=Math.floor(t.lng-a),l=Math.ceil(t.lng+a);for(let e=o;e<=s;e++)for(let i=c;i<=l;i++){let o=(e-t.lat)/r,s=(i-t.lng)/a;s*s+o*o>1||P(e,i,n)}}const F=new Uint8Array(k);for(let e=1;e<O-1;e++)for(let t=0;t<D;t++){if(k[e*D+t])continue;let n=0,r=0;for(let i=-1;i<=1;i++)for(let a=-1;a<=1;a++){if(i===0&&a===0)continue;let o=(t+a+D)%D;k[(e+i)*D+o]&&(n++,r||=A[(e+i)*D+o]??0)}n>=4&&(F[e*D+t]=1,A[e*D+t]=r)}k.set(F);const I=new Uint8Array(D*O);for(let e=0;e<O;e++)for(let t=0;t<D;t++){let n=A[e*D+t];if(!n)continue;let r=e>0?A[(e-1)*D+t]:0,i=e<O-1?A[(e+1)*D+t]:0,a=A[e*D+(t-1+D)%D],o=A[e*D+(t+1)%D];(r!==n||i!==n||a!==n||o!==n)&&(I[e*D+t]=1)}function L(e,t){if(e<-90||e>90)return 0;let n=Math.max(0,Math.min(O-1,Math.floor(90-e))),r=(t%360+360)%360,i=Math.floor(r);return k[n*D+i]===1?1:0}function R(e,t){if(e<-90||e>90)return 0;let n=Math.max(0,Math.min(O-1,Math.floor(90-e))),r=(t%360+360)%360,i=Math.floor(r);return I[n*D+i]===1?1:0}function z(e){return e*Math.PI/180}function B(e,t){let n=z(e),r=z(t);return{x:Math.cos(n)*Math.sin(r),y:Math.sin(n),z:Math.cos(n)*Math.cos(r)}}function V(e,t){let n=Math.cos(t),r=Math.sin(t);return{x:n*e.x+r*e.z,y:e.y,z:-r*e.x+n*e.z}}function H(e,t){let n=Math.cos(t),r=Math.sin(t);return{x:e.x,y:n*e.y-r*e.z,z:r*e.y+n*e.z}}function U(e,t){let n=e*2,r=t*4;return{dw:n,dh:r,bits:new Uint8Array(n*r)}}function W(e,t,n){t<0||t>=e.dw||n<0||n>=e.dh||(e.bits[n*e.dw+t]=1)}function G(e,t,n,r){let i=r*r;for(let a=-r;a<=r;a++)for(let o=-r;o<=r;o++)o*o+a*a<=i&&W(e,Math.round(t+o),Math.round(n+a))}const K=[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[0,3],[1,3]];function q(e,t,n){let r=0;for(let i=0;i<K.length;i++){let[a,o]=K[i],s=t*2+a,c=n*4+o;e.bits[c*e.dw+s]&&(r|=1<<i)}return r===0?` `:String.fromCodePoint(10240+r)}function J(e,t,n){let r=0;for(let i=0;i<4;i++)for(let a=0;a<2;a++){let o=t*2+a,s=n*4+i;e.bits[s*e.dw+o]&&r++}return r===0?` `:r<=2?`·`:r<=5?`○`:`●`}function Y(e){if(e)return!0;let t=process.env;if(t.NO_COLOR||t.ZENOVAY_GLOBE===`ascii`)return!0;let n=(t.LANG||t.LC_ALL||t.LC_CTYPE||``).toLowerCase();return!!(n&&!n.includes(`utf`))}function X(e,t,n){if(e.z<0)return null;let r=t/2,i=n/2,a=Math.min(t,n/2)*.95;return{x:r+e.x*a,y:i-e.y*a}}function Z(e){let t=e.dw/2,n=e.dh/2,r=Math.min(e.dw,e.dh/2)*.95,i=Math.round(2*Math.PI*r);for(let a=0;a<i;a++){let o=a/i*2*Math.PI,s=Math.round(t+r*Math.cos(o)),c=Math.round(n+r*Math.sin(o));W(e,s,c)}}function te(e,t,n){for(let r of[-60,-30,0,30,60])for(let i=-180;i<=180;i+=4){let a=H(V(B(r,i),t),n),o=X(a,e.dw,e.dh);o&&W(e,Math.round(o.x),Math.round(o.y))}for(let r=-180;r<180;r+=30)for(let i=-85;i<=85;i+=4){let a=H(V(B(i,r),t),n),o=X(a,e.dw,e.dh);o&&W(e,Math.round(o.x),Math.round(o.y))}}function ne({visitors:e,highlight:t,width:n=50,height:r=25,rotationDeg:i=0,tiltDeg:a=20,gridlines:s=!0,asciiOnly:c}){let{theme:l}=o(),u=Y(c),d=U(n,r),m=U(n,r),h=U(n,r),g=U(n,r),v=U(n,r),y=z(i),b=z(-a);Z(d),s&&te(d,y,b);{let e=m.dw/2,t=m.dh/2,n=Math.min(m.dw,m.dh/2)*.95,r=Math.cos(y),i=Math.sin(y),a=Math.cos(b),o=Math.sin(b);for(let s=0;s<m.dh;s++){let c=(t-s)/n;if(!(c<-1||c>1))for(let t=0;t<m.dw;t++){let l=(t-e)/n,u=l*l+c*c;if(u>1)continue;let d=Math.sqrt(1-u),f=l,p=c,g=a*p+o*d,_=-o*p+a*d,v=r*f-i*_,y=i*f+r*_,b=Math.asin(g)*(180/Math.PI),x=Math.atan2(v,y)*(180/Math.PI);L(b,x)&&(W(m,t,s),R(b,x)&&W(h,t,s))}}}for(let t of e){let e=H(V(B(t.lat,t.lng),y),b),n=X(e,g.dw,g.dh);if(!n)continue;let r=typeof t.freshness==`number`?t.freshness:.5;G(g,n.x,n.y,r>.7?2:1)}if(t&&t.length>0)for(let e of t){let t=H(V(B(e.lat,e.lng),y),b),n=X(t,v.dw,v.dh);if(!n)continue;G(v,n.x,n.y,2)}let x=[];for(let e=0;e<r;e++){let t=[],r=null,i=(e,n)=>{r&&r.color===e?r.text+=n:(r={color:e,text:n},t.push(r))};for(let r=0;r<n;r++){let n=u?J(v,r,e):q(v,r,e);if(n!==` `){i(l.warn,n);continue}let a=u?J(g,r,e):q(g,r,e);if(a!==` `){i(l.accent,a);continue}let o=u?J(h,r,e):q(h,r,e);if(o!==` `){i(l.fg,o);continue}let s=u?J(m,r,e):q(m,r,e);if(s!==` `){i(l.success,s);continue}let c=u?J(d,r,e):q(d,r,e);if(c!==` `){i(l.muted,c);continue}let f=t.length>0?t[t.length-1]:void 0;i(f?f.color:l.muted,` `)}x.push(_.createElement(f,{key:e},_.createElement(p,null,t.map((e,t)=>_.createElement(p,{key:t,color:e.color,bold:!0},e.text)))))}return _.createElement(f,{flexDirection:`column`},x)}async function Q(e,t,n){let r=await e.getGeo(t).catch(()=>({countries:[],cities:[]})),i=(r.countries??[]).map(e=>{let t=T(e.country),r=n.get(e.country)??0;return{code:e.country,visitors:e.visitors,lat:t?.lat,lng:t?.lng,freshness:e.visitors>r?1:.4}});return{countries:i,totalVisitors:i.reduce((e,t)=>e+t.visitors,0),unknownCount:i.filter(e=>typeof e.lat!=`number`).reduce((e,t)=>e+t.visitors,0),lastFetchedAt:Date.now()}}async function re(a){let o=await e(),s=await t({strict:!1});if(!s)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let c=new n({config:o,cliVersion:a.cliVersion,token:s}),u,d;try{({siteId:u,site:d}=await l(c,{explicit:a.siteId,headless:!!a.json,cliVersion:a.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let f=d?.url?d.url.replace(/^https?:\/\//,``).replace(/\/$/,``):d?.name??u;if(a.browser){let e=`https://app.zenovay.com/domains/${encodeURIComponent(u)}?tab=globe`;a.json?process.stdout.write(JSON.stringify({openedUrl:e})+`
2
+ `):process.stdout.write(`\n Opening Mapbox globe in your default browser:\n ${e}\n\n`);try{await S(e)}catch{}return 0}if(i(a)){let e=await Q(c,u,new Map);return r({type:`globe.snapshot`,data:{countries:e.countries,total:e.totalVisitors,unknownCount:e.unknownCount}}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement($,{api:c,siteId:u,siteLabel:f,cliVersion:a.cliVersion,onExit:n=>{t(),e(n)}}))})}const ie=5e3,ae=60,oe=1,se=80,$=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:l}=h(),{theme:m}=o(),[C,w]=x(null),[D,O]=x(!0),[k,A]=x(null),[j,M]=x(0),[N,P]=x(!1),[F,I]=x(20),[L,R]=x(1),[z,B]=x(0),V=b(new Map);g(n=>{if(n===`q`){l(),i(0);return}if(n===` `){P(e=>!e);return}if(n===`+`||n===`=`){R(e=>Math.min(1.6,e+.1));return}if(n===`-`||n===`_`){R(e=>Math.max(.7,e-.1));return}if(n===`t`){I(e=>(e+15)%60);return}if(n===`j`){B(e=>e+1);return}if(n===`k`){B(e=>Math.max(0,e-1));return}if(n===`w`){let e=`https://app.zenovay.com/domains/${encodeURIComponent(t)}?tab=globe`;S(e).catch(()=>{});return}if(n===`o`&&C){let e=C.countries[z];e?.lng!==void 0&&(M(-e.lng),P(!0));return}n===`r`&&(async()=>{try{let n=await Q(e,t,V.current);V.current=new Map(n.countries.map(e=>[e.code,e.visitors])),w(n)}catch(e){A(e.message)}})()}),v(()=>{let n=!1,r=null,i=async()=>{try{let r=await Q(e,t,V.current);if(n)return;V.current=new Map(r.countries.map(e=>[e.code,e.visitors])),w(r),O(!1)}catch(e){n||(A(e.message),O(!1))}n||(r=setTimeout(i,ie))};return i(),()=>{n=!0,r&&clearTimeout(r)}},[e,t]),v(()=>{if(N)return;let e=setInterval(()=>{M(e=>(e+oe)%360)},ae);return()=>clearInterval(e)},[N]);let H=y(()=>{if(!C)return[];let e=[];for(let t of C.countries){if(typeof t.lat!=`number`||typeof t.lng!=`number`)continue;let n=Math.min(se,Math.max(3,t.visitors*5));for(let r of E(t.code,n))e.push({lat:r.lat,lng:r.lng,freshness:t.freshness})}return e},[C]),U=y(()=>{if(!C)return[];let e=C.countries[Math.min(z,C.countries.length-1)];return!e||typeof e.lat!=`number`?[]:E(e.code,Math.min(80,Math.max(8,e.visitors*4)))},[C,z]),W=`globe · ${n} · live`,G=[{key:`q`,label:`quit`},{key:`j/k`,label:`select country`},{key:`o`,label:`orbit to selected`},{key:`space`,label:N?`resume`:`pause`},{key:`t`,label:`tilt ${F}°`},{key:`+/-`,label:`zoom`},{key:`w`,label:`open Mapbox view in browser`},{key:`r`,label:`refresh`}];if(D)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),_.createElement(a,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`cyan`},_.createElement(ee,{type:`dots`})),_.createElement(p,null,` Spinning up Earth…`))));if(k)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),_.createElement(u,{reason:`error`,headline:`Failed to load`,hint:k}),_.createElement(c,{items:G}));if(!C||C.countries.length===0&&C.unknownCount===0)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),_.createElement(u,{reason:`no-data`,headline:`No geolocated visitors yet`,hint:`Visit your site to populate the map.`}),_.createElement(c,{items:G}));let K=process.stdout.columns??100,q=36,J=Math.max(40,Math.min(90,K-q-4)),Y=Math.round(J*L),X=Math.round(Y*.5),Z=C.countries.slice(0,12),te=Math.max(1,...Z.map(e=>e.visitors)),re=Math.max(1,Math.floor((Date.now()-C.lastFetchedAt)/1e3)),$=C.countries[Math.min(z,C.countries.length-1)],ce=$?T($.code):null;return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:W}),$?_.createElement(f,{flexDirection:`row`,marginBottom:1},_.createElement(f,{width:2}),_.createElement(f,{borderStyle:`round`,borderColor:m.warn,paddingX:1},_.createElement(p,{color:m.warn,bold:!0},ce?.name??$.code),_.createElement(p,{color:m.dim},` · `),_.createElement(p,{color:m.fg},$.visitors,` visitor`,$.visitors===1?``:`s`))):null,_.createElement(f,{flexDirection:`row`},_.createElement(f,{flexDirection:`column`,marginRight:2},_.createElement(ne,{visitors:H,highlight:U,width:Y,height:X,rotationDeg:j,tiltDeg:F}),_.createElement(f,{marginTop:1},_.createElement(p,{color:m.dim},C.totalVisitors,` visitors · `,C.countries.length,` countries`,C.unknownCount>0?` · ${C.unknownCount} unmapped`:``,` · `,N?`rotation paused`:`↻ ${oe}°/${ae}ms`,` · refreshed `,re,`s ago`))),_.createElement(f,{flexDirection:`column`,width:q},_.createElement(a,{title:`Live by country`},Z.map((e,t)=>{let n=t===Math.min(z,C.countries.length-1),r=e.freshness>.7,i=n?m.warn:r?m.success:m.fg;return _.createElement(f,{key:e.code,flexDirection:`row`},_.createElement(f,{width:2},_.createElement(p,{color:m.warn},n?`›`:` `)),_.createElement(f,{width:3},_.createElement(p,{color:i,bold:n},e.code)),_.createElement(d,{value:e.visitors,max:te,width:14,showPercent:!1}),_.createElement(f,{width:6},_.createElement(p,{color:m.muted},String(e.visitors).padStart(5))))})),C.countries.length>12?_.createElement(f,{marginTop:1},_.createElement(p,{color:m.muted},`+`,C.countries.length-12,` more (j/k to scroll)`)):null)),_.createElement(c,{items:G}))};export{re as globeCommand};
@@ -0,0 +1,7 @@
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-Iig3PBVk.js";import{ApiV2Client as r}from"./api-v2-UJJ6ube8.js";import{requireTier as i}from"./tier-uaU5pkTz.js";import{confirmDestructive as a}from"./confirm-Dk3CEdpn.js";import"./formatter-KOe_hjhc.js";import{emitEnvelope as o,wrapItem as s,wrapList as c}from"./emit-B8RbnBJe.js";function l(e){return e.length>12?`${e.slice(0,8)}…${e.slice(-4)}`:e}function u(e){return e?new Date(e).toISOString().slice(0,10):`—`}async function d(d){let f=await e(),p=await t({strict:!1}),m=new r({config:f,cliVersion:d.cliVersion,token:p});try{await i(m,`pro`)}catch(e){return n(e,{command:`goals ${d.action}`})}try{switch(d.action){case`list`:{let{goals:e}=await m.listGoals();if(d.json)return o(c(e,`goals.list`),{legacyKey:`goals`,legacyValue:e}),0;if(e.length===0)return process.stdout.write("No goals yet. Create one with `zenovay goals create --name <n> --type <pageview|event> --target <url-or-event>`.\n"),0;let t=[14,24,10,30,10],n=e=>e.map((e,n)=>(e??``).padEnd(t[n])).join(` `);process.stdout.write(`
2
+ `+n([`id`,`name`,`type`,`target`,`created`])+`
3
+ `),process.stdout.write(n(t.map(e=>`─`.repeat(e)))+`
4
+ `);for(let r of e)process.stdout.write(n([l(r.id),(r.name??``).slice(0,t[1]),r.type,(r.target??`—`).slice(0,t[3]),u(r.createdAt)])+`
5
+ `);return process.stdout.write(`
6
+ `),0}case`create`:{if(!d.name||!d.type||!d.target)return process.stderr.write("Error: --name, --type (pageview|event), and --target are required for `goals create`.\n"),2;if(d.type!==`pageview`&&d.type!==`event`)return process.stderr.write("Error: --type must be `pageview` or `event`.\n"),2;let e=await m.createGoal({name:d.name,type:d.type,target:d.target});return d.json?(o(s(e,`goals.item`)),0):(process.stdout.write(`✔ Goal created: ${e.name} (${e.type} → ${e.target}, id ${e.id}).\n`),0)}case`delete`:{if(!d.id)return process.stderr.write("Error: goal id is required for `goals delete`.\n"),2;let e=await a({resource:`goal`,name:l(d.id),yes:d.yes,destructive:!0});if(!e)return process.stdout.write(`Cancelled.
7
+ `),1;let t=await m.deleteGoal(d.id);return d.json?(o(s(t,`goals.deleted`)),0):(process.stdout.write(`✔ Deleted goal ${l(d.id)}.\n`),0)}}}catch(e){return n(e,{command:`goals ${d.action}`})}}export{d as goalsCommand};
@@ -0,0 +1 @@
1
+ import"./config-CG7B8fR0.js";import"./check-D9G0N7NB.js";import"./api-CJnD6Auw.js";import"./token-store-C1AqhmDP.js";import"./formatter-KOe_hjhc.js";import"./emit-B8RbnBJe.js";import"./panel-jycoT562.js";import{HealthReport as e,exitCodeFor as t,healthCommand as n,runHealthChecks as r}from"./health-DAyE161Z.js";export{n as healthCommand};
@@ -0,0 +1 @@
1
+ import{configPath as e,readConfig as t}from"./config-CG7B8fR0.js";import{fetchManifest as n}from"./check-D9G0N7NB.js";import{ApiClient as r}from"./api-CJnD6Auw.js";import{readToken as i}from"./token-store-C1AqhmDP.js";import{isHeadless as a}from"./emit-B8RbnBJe.js";import{Panel as o}from"./panel-jycoT562.js";import s from"node:path";import{promises as c}from"node:fs";import l from"node:os";import{Box as u,Text as d,render as f}from"ink";import p from"react";const m=6*60*60*1e3;function h(){return s.join(l.homedir(),`.zenovay`,`update.json`)}async function g(){try{let e=await c.readFile(h(),`utf8`);return JSON.parse(e)}catch{return null}}async function _(e){let t=h();await c.mkdir(s.dirname(t),{recursive:!0,mode:448}),await c.writeFile(t,JSON.stringify(e,null,2))}async function v(){let e=await t();if(e.noUpdateCheck||process.env.ZENOVAY_NO_UPDATE_CHECK===`1`||process.env.CI===`true`)return null;let r=await g();if(r&&Date.now()-r.fetchedAt<m)return r;try{let t=await n({cliBase:e.cliBase}),i={manifest:t,fetchedAt:Date.now(),lastNoticeAt:r?.lastNoticeAt};return await _(i),i}catch{return r}}async function y(){try{await v()}catch{}process.exit(0)}import.meta.url===`file://${process.argv[1]}`&&y();const b=2e3,x=5e3;async function S(e,t){let n=`${e}/mcp`,r=Date.now(),i=new AbortController,a=setTimeout(()=>i.abort(),b);try{let a=await t(n,{method:`GET`,signal:i.signal}),o=Date.now()-r;return a.ok?{name:`MCP server`,status:`pass`,detail:`${e}/mcp · ${o}ms`,latencyMs:o}:{name:`MCP server`,status:`fail`,detail:`HTTP ${a.status}`,latencyMs:o}}catch(e){return{name:`MCP server`,status:`fail`,detail:e.message}}finally{clearTimeout(a)}}async function C(){try{let t=await c.readFile(e(),`utf8`),n=JSON.parse(t),r=n.openaiApiKey;return typeof r==`string`&&r.trim().length>0?{name:`OpenAI key`,status:`pass`,detail:`configured`}:{name:`OpenAI key`,status:`warn`,detail:"not set (run `zenovay ai` to configure)"}}catch(e){return e.code===`ENOENT`?{name:`OpenAI key`,status:`warn`,detail:`no config file`}:{name:`OpenAI key`,status:`warn`,detail:`unreadable config`}}}async function w(){let e=l.homedir(),t=[s.join(e,`.zshrc`),s.join(e,`.bashrc`),s.join(e,`.config`,`fish`,`completions`,`zenovay.fish`)],n=[];for(let e of t)try{let t=await c.readFile(e,`utf8`);(/zenovay\s+(complet|--?complet)/i.test(t)||/_zenovay/.test(t)||/complete\s+-c\s+zenovay/.test(t))&&n.push(s.basename(e))}catch{}return n.length>0?{name:`Completions`,status:`pass`,detail:n.join(`, `)}:{name:`Completions`,status:`warn`,detail:"not installed (run `zenovay completions` after Wave 3)"}}async function T(e,t,n,r){if(!e||!t)return{name:`Events stream`,status:`skip`,detail:`not authenticated`};let i=new AbortController,a=setTimeout(()=>i.abort(),x),o=Date.now();try{let t=await e.openEventsStream(`probe`,i.signal),r=t.body?.getReader();if(r){let e=Promise.race([r.read().then(()=>`first`),new Promise(e=>setTimeout(()=>e(`timeout`),1500))]);await e;try{r.cancel()}catch{}}let a=Date.now()-o;return{name:`Events stream`,status:`pass`,detail:`${n}/v1/cli/events/tail · ${a}ms`,latencyMs:a}}catch(e){let t=e.message;return/40\d/.test(t)?{name:`Events stream`,status:`pass`,detail:`endpoint reachable (auth-gated)`}:{name:`Events stream`,status:`fail`,detail:t}}finally{clearTimeout(a)}}async function E(n){let a=n.fetchImpl??fetch,o=[],s=await t().catch(()=>null);o.push({name:`Binary`,status:`pass`,detail:`v${n.cliVersion} (${n.binaryPath})`}),o.push({name:`Config file`,status:s?`pass`:`warn`,detail:e()});let c=await i({strict:!1}).catch(()=>null);o.push({name:`Auth`,status:c?`pass`:`fail`,detail:c?`logged in${c.email?` as ${c.email}`:``}`:`not logged in`});let l=null;if(s)try{l=new r({config:s,cliVersion:n.cliVersion,token:c,fetchImpl:a});let e=await l.ping();o.push({name:`API connection`,status:`pass`,detail:`${s.apiBase.replace(/^https?:\/\//,``)} · ${e.latencyMs}ms`,latencyMs:e.latencyMs})}catch(e){o.push({name:`API connection`,status:`fail`,detail:`${e.message}`})}let u=await g().catch(()=>null);o.push({name:`Auto-update`,status:s?.noUpdateCheck?`warn`:`pass`,detail:s?.noUpdateCheck?`disabled`:u?`latest=${u.manifest.latest}`:`manifest not yet fetched`});let d=s?.apiBase??`https://api.zenovay.com`;return o.push(await S(d,a)),o.push(await C()),o.push(await w()),o.push(await T(l,!!c,d,a)),o}function D(e){return e.some(e=>e.status===`fail`)?1:0}async function O(e){let t=await E(e),n=D(t),r=n===0;return a({json:e.json})?(process.stdout.write(`${JSON.stringify({checks:t,passed:r})}\n`),n):new Promise(e=>{let{unmount:r}=f(p.createElement(k,{checks:t}),{exitOnCtrlC:!0});setImmediate(()=>{r(),e(n)})})}const k=({checks:e})=>p.createElement(o,{title:`Zenovay CLI health check`,state:`idle`},e.map(e=>p.createElement(u,{key:e.name},p.createElement(d,{color:j(e.status)},A(e.status)),p.createElement(d,null,` `),p.createElement(d,{bold:!0},e.name.padEnd(18)),p.createElement(d,{color:`gray`},e.detail))));function A(e){return e===`pass`?`✔`:e===`warn`?`⚠`:e===`skip`?`∼`:`✗`}function j(e){return e===`pass`?`green`:e===`warn`?`yellow`:e===`skip`?`gray`:`red`}export{k as HealthReport,D as exitCodeFor,O as healthCommand,E as runHealthChecks};
@@ -0,0 +1 @@
1
+ import{readConfig as e}from"./config-CG7B8fR0.js";import"./api-CJnD6Auw.js";import{readToken as t}from"./token-store-C1AqhmDP.js";import{ApiV2Client as n}from"./api-v2-UJJ6ube8.js";import{requireTier as r}from"./tier-uaU5pkTz.js";import"./formatter-KOe_hjhc.js";import{emit as i,isHeadless as a}from"./emit-B8RbnBJe.js";import{Panel as o}from"./panel-jycoT562.js";import{Banner as s}from"./banner-gVm7GaJF.js";import"./prompt-Db9Y7CVt.js";import{Keybar as c}from"./keybar-BYQ2Bam1.js";import{resolveSiteId as l}from"./resolve-site-CZEwJoBj.js";import{DataTable as u}from"./data-table-BnWXIW9M.js";import{EmptyState as d}from"./empty-state-BkS6DKWZ.js";import{Box as f,Text as p,render as m,useApp as h,useInput as g}from"ink";import _,{useEffect as v,useState as y}from"react";import b from"ink-spinner";async function x(o){let s=await e(),c=await t({strict:!1});if(!c)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let u=new n({config:s,cliVersion:o.cliVersion,token:c});try{await r(u,`pro`)}catch(e){return process.stderr.write(`${e.message}\n`),2}let d,f;try{({siteId:d,site:f}=await l(u,{explicit:o.siteId,headless:!!o.json,cliVersion:o.cliVersion}))}catch(e){return process.stderr.write(`${e.message}\n`),2}let p=f?.url?f.url.replace(/^https?:\/\//,``).replace(/\/$/,``):f?.name??d;if(a(o)){let e=await u.getHeatmaps(d);return i({type:`heatmaps.snapshot`,data:e}),0}return new Promise(e=>{let{unmount:t}=m(_.createElement(S,{api:u,siteId:d,siteLabel:p,cliVersion:o.cliVersion,onExit:n=>{t(),e(n)}}))})}const S=({api:e,siteId:t,siteLabel:n,cliVersion:r,onExit:i})=>{let{exit:a}=h(),[l,m]=y(null),[x,S]=y(!0),[C,w]=y(null);if(g(e=>{e===`q`&&(a(),i(0))}),v(()=>{let n=!1;return(async()=>{try{let r=await e.getHeatmaps(t);n||(m(r),S(!1))}catch(e){n||(w(e.message),S(!1))}})(),()=>{n=!0}},[e,t]),x)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(o,{title:`Loading`,state:`busy`},_.createElement(f,null,_.createElement(p,{color:`magenta`},_.createElement(b,{type:`dots`})),_.createElement(p,null,` Fetching heatmaps…`))));if(C)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(d,{reason:`error`,headline:`Failed to load`,hint:C}));if(!l||l.length===0)return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(d,{reason:`no-data`,headline:`No heatmaps yet`,hint:`Enable heatmaps in your site settings`}));let T=[{key:`url`,label:`page`,width:36},{key:`type`,label:`type`,width:12},{key:`captureCount`,label:`captures`,align:`right`,width:10},{key:`createdAt`,label:`first seen`,width:24}];return _.createElement(f,{flexDirection:`column`},_.createElement(s,{version:r,subtitle:`heatmaps · ${n}`}),_.createElement(o,{title:`Heatmaps (${l.length})`},_.createElement(u,{columns:T,data:l,zebra:!0})),_.createElement(f,{marginTop:1},_.createElement(p,{color:`gray`},`Open any heatmap at https://app.zenovay.com/heatmaps`)),_.createElement(c,{items:[{key:`q`,label:`quit`}]}))};export{x as heatmapsCommand};
@@ -0,0 +1,2 @@
1
+ import{readConfig as e}from"./config-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{isHeadless as r}from"./emit-B8RbnBJe.js";import{Panel as i}from"./panel-jycoT562.js";import{Banner as a}from"./banner-gVm7GaJF.js";import{Keybar as o}from"./keybar-BYQ2Bam1.js";import{DataTable as s}from"./data-table-BnWXIW9M.js";import{EmptyState as c}from"./empty-state-BkS6DKWZ.js";import{Box as l,Text as u,render as d,useApp as f,useInput as p}from"ink";import m,{useEffect as h,useState as g}from"react";import _ from"ink-spinner";function v(e){if(!e)return`—`;let t=new Date(e);return Number.isNaN(t.getTime())?`—`:t.toISOString().slice(0,10)}async function y(e){let t=await e.me().catch(()=>null),n=t?.user.name?.trim()||t?.user.email||`you`,r=await e.getSites().catch(()=>[]),i=r.map(e=>({id:e.id,name:e.name,domain:e.url.replace(/^https?:\/\//,``).replace(/\/$/,``),lastActive:e.lastActiveAt??null})),a={visitors:0,pageviews:0,deltaPct:null};if(r.length>0){let t=r[0].id,[n,i]=await Promise.all([e.getStats(t,`7d`).catch(()=>null),e.getSources(t,`7d`,`prev`).catch(()=>null)]);n&&(a.visitors=n.visitors,a.pageviews=n.pageviews);let o=i?.sources?.filter(e=>typeof e.delta==`number`)??[];if(o.length>0){let e=o.reduce((e,t)=>e+(t.delta??0),0);a.deltaPct=e/o.length*100}}return{sites:i,weekly:a,userLabel:n}}async function b(i){let a=await e(),o=await t({strict:!1});if(!o)return process.stderr.write("Not logged in — run `zenovay login` first.\n"),2;let s=new n({config:a,cliVersion:i.cliVersion,token:o});if(r(i))try{let e=await y(s);return process.stdout.write(JSON.stringify({sites:e.sites,weekly:{visitors:e.weekly.visitors,pageviews:e.weekly.pageviews,deltaPct:e.weekly.deltaPct}},null,2)+`
2
+ `),0}catch(e){return process.stderr.write(`✗ ${e.message}\n`),1}return new Promise(e=>{let{unmount:t}=d(m.createElement(x,{api:s,cliVersion:i.cliVersion,onExit:n=>{t(),e(n)}}))})}const x=({api:e,cliVersion:t,onExit:n})=>{let{exit:r}=f(),[d,b]=g(null),[x,S]=g(!0),[C,w]=g(null);p(e=>{e===`q`&&(r(),n(0))}),h(()=>{let t=!1;return(async()=>{try{let n=await y(e);t||(b(n),S(!1))}catch(e){t||(w(e.message),S(!1))}})(),()=>{t=!0}},[e]);let T=`home · ${d?.userLabel??`…`}`,E=[{key:`q`,label:`quit`}];if(x)return m.createElement(l,{flexDirection:`column`},m.createElement(a,{version:t,subtitle:T}),m.createElement(i,{title:`Loading`,state:`busy`},m.createElement(l,null,m.createElement(u,{color:`cyan`},m.createElement(_,{type:`dots`})),m.createElement(u,null,` Fetching your home dashboard…`))));if(C)return m.createElement(l,{flexDirection:`column`},m.createElement(a,{version:t,subtitle:T}),m.createElement(c,{reason:`error`,headline:`Failed to load`,hint:C}),m.createElement(o,{items:E}));if(!d)return m.createElement(l,{flexDirection:`column`},m.createElement(a,{version:t,subtitle:T}),m.createElement(c,{reason:`no-data`,headline:`No data`}),m.createElement(o,{items:E}));let D=[{key:`name`,label:`site`,width:24},{key:`domain`,label:`domain`,width:32},{key:`lastActive`,label:`last active`,width:12,format:e=>v(e)}],O=d.weekly.deltaPct===null?`—`:`${d.weekly.deltaPct>=0?`+`:``}${d.weekly.deltaPct.toFixed(1)}%`;return m.createElement(l,{flexDirection:`column`},m.createElement(a,{version:t,subtitle:T}),m.createElement(i,{title:`Your sites (${d.sites.length})`},d.sites.length===0?m.createElement(u,{color:`gray`},"No sites yet — run `zenovay init` to add one."):m.createElement(s,{columns:D,data:d.sites,zebra:!0})),m.createElement(i,{title:`This week`},m.createElement(u,null,m.createElement(u,{color:`cyan`},`Visitors`),` `,d.weekly.visitors.toLocaleString(),` `,m.createElement(u,{color:`cyan`},`Pageviews`),` `,d.weekly.pageviews.toLocaleString(),` `,m.createElement(u,{color:`cyan`},`Δ vs last week`),` `,O)),m.createElement(o,{items:E}))};export{b as homeCommand};