vgs-cli 1.35.0.dev2__py3-none-any.whl → 1.36.0.dev1__py3-none-any.whl

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 (80) hide show
  1. vgs_cli-1.36.0.dev1.data/data/vgscli/console-route-schema.yaml +47 -0
  2. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/form-template.yaml +1 -1
  3. vgs_cli-1.36.0.dev1.data/data/vgscli/theme.tcss +445 -0
  4. {vgs_cli-1.35.0.dev2.dist-info → vgs_cli-1.36.0.dev1.dist-info}/METADATA +50 -1
  5. vgs_cli-1.36.0.dev1.dist-info/RECORD +118 -0
  6. vgscli/_version.py +1 -1
  7. vgscli/audits_api.py +9 -8
  8. vgscli/auth_server.py +28 -13
  9. vgscli/callback_server.py +18 -5
  10. vgscli/cert_manager_api.py +8 -7
  11. vgscli/cli/__init__.py +32 -5
  12. vgscli/cli/commands/apply.py +34 -50
  13. vgscli/cli/commands/certificate.py +2 -1
  14. vgscli/cli/commands/delete.py +7 -4
  15. vgscli/cli/commands/generate.py +2 -1
  16. vgscli/cli/commands/get.py +26 -67
  17. vgscli/cli_utils.py +2 -5
  18. vgscli/collect_forms.py +16 -93
  19. vgscli/collect_forms_api.py +9 -8
  20. vgscli/console/__init__.py +1 -0
  21. vgscli/console/app.py +2321 -0
  22. vgscli/console/auth.py +32 -0
  23. vgscli/console/backend.py +284 -0
  24. vgscli/console/bootstrap.py +20 -0
  25. vgscli/console/commands.py +96 -0
  26. vgscli/console/context.py +60 -0
  27. vgscli/console/form_editor.py +142 -0
  28. vgscli/console/intro.py +123 -0
  29. vgscli/console/mutation_screen.py +749 -0
  30. vgscli/console/responsive.py +20 -0
  31. vgscli/console/tenant_onboarding_screen.py +613 -0
  32. vgscli/console/theme.tcss +445 -0
  33. vgscli/console/workflows/__init__.py +8 -0
  34. vgscli/console/workflows/forms.py +36 -0
  35. vgscli/console/workflows/mutation.py +261 -0
  36. vgscli/console/workflows/routes.py +41 -0
  37. vgscli/console/workflows/tenant.py +220 -0
  38. vgscli/console_config.py +47 -0
  39. vgscli/diagnostics.py +41 -0
  40. vgscli/errors.py +65 -52
  41. vgscli/operations/__init__.py +1 -0
  42. vgscli/operations/context.py +48 -0
  43. vgscli/operations/documents.py +29 -0
  44. vgscli/operations/errors.py +80 -0
  45. vgscli/operations/form_documents.py +108 -0
  46. vgscli/operations/forms.py +174 -0
  47. vgscli/operations/logs.py +171 -0
  48. vgscli/operations/models.py +56 -0
  49. vgscli/operations/routes.py +240 -0
  50. vgscli/operations/tenant_details.py +110 -0
  51. vgscli/recovery_journal.py +158 -0
  52. vgscli/resource-templates/form-template.yaml +1 -1
  53. vgscli/secure_store.py +109 -0
  54. vgscli/telemetry.py +748 -0
  55. vgscli/tenant_creation.py +14 -9
  56. vgscli/token_handler.py +8 -7
  57. vgscli/validation-schemas/console-route-schema.yaml +47 -0
  58. vgscli/vgs.py +33 -2
  59. vgs_cli-1.35.0.dev2.dist-info/RECORD +0 -82
  60. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/collect-form-api-schema.yaml +0 -0
  61. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/collect-form-schema.yaml +0 -0
  62. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/credentials-admin.yaml +0 -0
  63. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/http-route-template.yaml +0 -0
  64. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/notification-integration-schema.yaml +0 -0
  65. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/notification-template.yaml +0 -0
  66. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/public-credential-collect.yaml +0 -0
  67. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/read-credentials-no-pci.yaml +0 -0
  68. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/read-credentials-with-pci.yaml +0 -0
  69. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/service-account-schema.yaml +0 -0
  70. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/sftp-route-template.yaml +0 -0
  71. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/tenant-schema.yaml +0 -0
  72. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/tenant-template.yaml +0 -0
  73. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/vault-resources.yaml +0 -0
  74. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/vault-schema.yaml +0 -0
  75. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/vault-template.yaml +0 -0
  76. {vgs_cli-1.35.0.dev2.data → vgs_cli-1.36.0.dev1.data}/data/vgscli/vgs-cli.yaml +0 -0
  77. {vgs_cli-1.35.0.dev2.dist-info → vgs_cli-1.36.0.dev1.dist-info}/WHEEL +0 -0
  78. {vgs_cli-1.35.0.dev2.dist-info → vgs_cli-1.36.0.dev1.dist-info}/entry_points.txt +0 -0
  79. {vgs_cli-1.35.0.dev2.dist-info → vgs_cli-1.36.0.dev1.dist-info}/licenses/LICENSE +0 -0
  80. {vgs_cli-1.35.0.dev2.dist-info → vgs_cli-1.36.0.dev1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,47 @@
1
+ $schema: http://json-schema.org/draft-07/schema#
2
+ type: object
3
+ additionalProperties: true
4
+ required: [version, data]
5
+ properties:
6
+ version:
7
+ const: 1
8
+ data:
9
+ type: array
10
+ items:
11
+ type: object
12
+ additionalProperties: true
13
+ required: [type, attributes]
14
+ properties:
15
+ id:
16
+ type: string
17
+ minLength: 1
18
+ type:
19
+ const: rule_chain
20
+ attributes:
21
+ type: object
22
+ additionalProperties: true
23
+ required: [protocol, destination_override_endpoint, entries]
24
+ properties:
25
+ protocol:
26
+ type: string
27
+ pattern: '^(?i:http|https)$'
28
+ source_endpoint:
29
+ type: [string, 'null']
30
+ destination_override_endpoint:
31
+ type: [string, 'null']
32
+ host_endpoint:
33
+ type: [string, 'null']
34
+ tags:
35
+ type: object
36
+ additionalProperties: true
37
+ entries:
38
+ type: array
39
+ items:
40
+ type: object
41
+ additionalProperties: true
42
+ properties:
43
+ phase: {type: string}
44
+ operation: {type: string}
45
+ targets:
46
+ type: array
47
+ items: {type: string}
@@ -6,7 +6,7 @@ data:
6
6
  id: auto-generated
7
7
 
8
8
  # Display name of the Collect Form.
9
- name: Auto Generated
9
+ name: Default
10
10
 
11
11
  # Card attributes to collect alongside the card number. Set an attribute to
12
12
  # true to enable it; leave it false to keep it disabled. Run
@@ -0,0 +1,445 @@
1
+ /*
2
+ * The shell is a fixed layout: only inner panes scroll, never the screen.
3
+ * The screen keeps the panel tone so widget margins never expose a dark gutter.
4
+ */
5
+ Screen {
6
+ background: $panel;
7
+ color: $text;
8
+ layout: vertical;
9
+ overflow: hidden hidden;
10
+ }
11
+
12
+ /* Scrollbars stay slim and track-less, and only appear on real overflow. */
13
+ * {
14
+ scrollbar-size: 1 1;
15
+ scrollbar-background: $panel;
16
+ scrollbar-background-hover: $panel;
17
+ scrollbar-background-active: $panel;
18
+ scrollbar-corner-color: $panel;
19
+ }
20
+
21
+ #brand {
22
+ height: 3;
23
+ padding: 1 2;
24
+ background: $panel;
25
+ }
26
+
27
+ #brand-name {
28
+ width: 1fr;
29
+ color: $console-blue;
30
+ text-style: bold;
31
+ }
32
+
33
+ #cli-version {
34
+ width: auto;
35
+ color: $text-muted;
36
+ }
37
+
38
+ #context-header {
39
+ height: 3;
40
+ padding: 0 2 1 2;
41
+ background: $panel;
42
+ }
43
+
44
+ #context-details {
45
+ width: 1fr;
46
+ height: 2;
47
+ }
48
+
49
+ .context-row {
50
+ width: 100%;
51
+ height: 1;
52
+ }
53
+
54
+ .context-label {
55
+ width: auto;
56
+ height: 1;
57
+ color: $console-blue;
58
+ text-style: bold;
59
+ margin-right: 1;
60
+ }
61
+
62
+ .context-name {
63
+ width: auto;
64
+ height: 1;
65
+ color: $text;
66
+ text-style: bold;
67
+ margin-right: 1;
68
+ }
69
+
70
+ .context-id {
71
+ width: auto;
72
+ height: 1;
73
+ color: $text-muted;
74
+ }
75
+
76
+ #environment-badge {
77
+ width: auto;
78
+ min-width: 12;
79
+ height: 1;
80
+ margin: 0;
81
+ padding: 0 1;
82
+ color: $text-muted;
83
+ background: $surface;
84
+ text-style: bold;
85
+ content-align: center middle;
86
+ }
87
+
88
+ #environment-badge.sandbox {
89
+ color: $background;
90
+ background: $success;
91
+ }
92
+
93
+ #environment-badge.live {
94
+ color: $background;
95
+ background: $error;
96
+ }
97
+
98
+ #status-line {
99
+ height: 1;
100
+ padding: 0 4;
101
+ color: $text-muted;
102
+ background: $panel;
103
+ }
104
+
105
+ Input, TextArea {
106
+ border: none;
107
+ background: $console-elevated;
108
+ }
109
+
110
+ Input:focus, TextArea:focus {
111
+ border: none;
112
+ background: $panel;
113
+ background-tint: $primary 8%;
114
+ }
115
+
116
+ #content {
117
+ height: 1fr;
118
+ /* No bottom padding: the scrolling list uses every remaining row. */
119
+ padding: 2 3 0 3;
120
+ background: $panel;
121
+ overflow: hidden hidden;
122
+ }
123
+
124
+ #content-scroll {
125
+ height: 1fr;
126
+ background: $panel;
127
+ overflow-x: hidden;
128
+ }
129
+
130
+ #screen-context {
131
+ height: auto;
132
+ margin-bottom: 1;
133
+ color: $text-muted;
134
+ }
135
+
136
+ #section-tabs {
137
+ display: none;
138
+ height: 1;
139
+ color: $text-muted;
140
+ }
141
+
142
+ #section-tabs:focus {
143
+ background-tint: $primary 6%;
144
+ }
145
+
146
+ #resource-menu {
147
+ display: none;
148
+ height: auto;
149
+ /* Rows, not padding, own the scroll viewport, and one resource is always
150
+ one line so scrolling reaches every row. */
151
+ padding: 0 2;
152
+ text-wrap: nowrap;
153
+ text-overflow: ellipsis;
154
+ background: $console-elevated;
155
+ }
156
+
157
+ #resource-menu:focus {
158
+ background: $console-elevated;
159
+ background-tint: $primary 6%;
160
+ }
161
+
162
+ #screen-body {
163
+ height: auto;
164
+ }
165
+
166
+ #intro-banner {
167
+ height: auto;
168
+ margin-bottom: 1;
169
+ color: $text;
170
+ }
171
+
172
+ Screen.home #content {
173
+ padding: 1 3 0 3;
174
+ }
175
+
176
+ .title, .dialog-title {
177
+ text-style: bold;
178
+ color: $primary;
179
+ margin-bottom: 1;
180
+ }
181
+
182
+ #composer-bar {
183
+ dock: bottom;
184
+ height: auto;
185
+ padding: 0 0 1 0;
186
+ background: $panel;
187
+ }
188
+
189
+ #composer {
190
+ height: 3;
191
+ margin: 0 2;
192
+ padding: 1 2;
193
+ background: $console-elevated;
194
+ content-align: left middle;
195
+ }
196
+
197
+ #command-palette {
198
+ display: none;
199
+ max-height: 16;
200
+ margin: 0 2;
201
+ padding: 1 2;
202
+ background: $console-elevated;
203
+ border: none;
204
+ overflow-x: hidden;
205
+ }
206
+
207
+ #command-list {
208
+ height: auto;
209
+ }
210
+
211
+ #help-dialog {
212
+ width: 80%;
213
+ height: 75%;
214
+ margin: 2 8;
215
+ padding: 2 3;
216
+ background: $panel;
217
+ border: round $border-blurred;
218
+ overflow-x: hidden;
219
+ }
220
+
221
+ #mutation-dialog, #yaml-editor-dialog, #form-editor-dialog, #tenant-onboarding-dialog, #recovery-dialog {
222
+ width: 100%;
223
+ height: 100%;
224
+ margin: 0;
225
+ padding: 1 2;
226
+ background: $panel;
227
+ }
228
+
229
+ #recovery-details {
230
+ height: 1fr;
231
+ padding: 1 2;
232
+ background: $panel;
233
+ }
234
+
235
+ #tenant-onboarding-history {
236
+ height: auto;
237
+ min-height: 0;
238
+ max-height: 8;
239
+ padding: 1 2;
240
+ margin-bottom: 1;
241
+ background: $panel;
242
+ overflow-x: hidden;
243
+ scrollbar-background: $panel;
244
+ scrollbar-background-hover: $panel;
245
+ scrollbar-background-active: $panel;
246
+ scrollbar-corner-color: $panel;
247
+ }
248
+
249
+ #tenant-onboarding-question-area {
250
+ height: 1fr;
251
+ min-height: 7;
252
+ align: left middle;
253
+ }
254
+
255
+ #tenant-onboarding-question-area > * {
256
+ width: 100%;
257
+ }
258
+
259
+ #tenant-onboarding-transcript {
260
+ height: auto;
261
+ }
262
+
263
+ #tenant-onboarding-progress {
264
+ height: auto;
265
+ margin-top: 1;
266
+ }
267
+
268
+ #tenant-onboarding-progress.running {
269
+ color: $warning;
270
+ }
271
+
272
+ #tenant-onboarding-progress.complete {
273
+ color: $success;
274
+ }
275
+
276
+ #tenant-onboarding-progress.failed {
277
+ color: $error;
278
+ }
279
+
280
+ #tenant-onboarding-question {
281
+ height: auto;
282
+ min-height: 1;
283
+ margin-bottom: 1;
284
+ color: $secondary;
285
+ text-style: bold;
286
+ }
287
+
288
+ #tenant-onboarding-options, #tenant-onboarding-attributes {
289
+ height: auto;
290
+ max-height: 12;
291
+ margin-bottom: 1;
292
+ background: $console-elevated;
293
+ border: none;
294
+ }
295
+
296
+ #tenant-onboarding-attributes-done {
297
+ display: none;
298
+ width: 16;
299
+ margin-bottom: 1;
300
+ }
301
+
302
+ #tenant-onboarding-dialog.attribute-step #tenant-onboarding-history {
303
+ height: 6;
304
+ min-height: 4;
305
+ }
306
+
307
+ #tenant-onboarding-dialog.attribute-step #tenant-onboarding-question-area {
308
+ align: left top;
309
+ }
310
+
311
+ #tenant-onboarding-dialog.attribute-step #tenant-onboarding-attributes {
312
+ height: 1fr;
313
+ }
314
+
315
+ #tenant-onboarding-input {
316
+ display: none;
317
+ height: 3;
318
+ margin-bottom: 1;
319
+ content-align: left middle;
320
+ }
321
+
322
+ #tenant-onboarding-error {
323
+ height: auto;
324
+ color: $error;
325
+ }
326
+
327
+ #yaml-editor-error {
328
+ height: auto;
329
+ color: $error;
330
+ }
331
+
332
+ #resource-yaml {
333
+ height: 1fr;
334
+ min-height: 12;
335
+ padding: 1 2;
336
+ background: $background;
337
+ scrollbar-background: $background;
338
+ scrollbar-background-hover: $background;
339
+ scrollbar-background-active: $background;
340
+ scrollbar-corner-color: $background;
341
+ }
342
+
343
+ #yaml-editor-hint, #mutation-editor-hint {
344
+ height: 1;
345
+ margin-bottom: 1;
346
+ color: $text-muted;
347
+ }
348
+
349
+ #form-editor-dialog > Input {
350
+ height: 3;
351
+ margin-bottom: 1;
352
+ }
353
+
354
+ .form-editor-label {
355
+ height: 1;
356
+ color: $secondary;
357
+ text-style: bold;
358
+ }
359
+
360
+ #form-editor-question {
361
+ height: auto;
362
+ margin-bottom: 1;
363
+ color: $secondary;
364
+ text-style: bold;
365
+ }
366
+
367
+ #form-editor-attributes {
368
+ height: 1fr;
369
+ min-height: 12;
370
+ margin-bottom: 1;
371
+ background: $console-elevated;
372
+ border: none;
373
+ }
374
+
375
+ #form-editor-error {
376
+ height: auto;
377
+ color: $error;
378
+ }
379
+
380
+ .action-hint {
381
+ height: 1;
382
+ color: $text-muted;
383
+ }
384
+
385
+ #mutation-preview {
386
+ height: 1fr;
387
+ overflow-x: hidden;
388
+ overflow-y: auto;
389
+ margin: 1 0;
390
+ padding: 1 2;
391
+ background: $surface;
392
+ scrollbar-background: $surface;
393
+ scrollbar-background-hover: $surface;
394
+ scrollbar-background-active: $surface;
395
+ scrollbar-corner-color: $surface;
396
+ }
397
+
398
+ .mutation-actions {
399
+ height: 3;
400
+ }
401
+
402
+ Button {
403
+ min-width: 14;
404
+ margin-right: 1;
405
+ border: none;
406
+ color: $text;
407
+ background: $console-elevated;
408
+ }
409
+
410
+ Button:hover {
411
+ color: $text;
412
+ background: $console-elevated;
413
+ }
414
+
415
+ Button:focus {
416
+ color: $background;
417
+ background: $console-blue;
418
+ text-style: bold;
419
+ }
420
+
421
+ Button:disabled {
422
+ border: none;
423
+ background: $surface;
424
+ }
425
+
426
+ .hint {
427
+ height: 1;
428
+ color: $text-muted;
429
+ }
430
+
431
+ .narrow #help-dialog {
432
+ width: 100%;
433
+ height: 100%;
434
+ margin: 0;
435
+ }
436
+
437
+ .too-small #content {
438
+ display: none;
439
+ }
440
+
441
+ .too-small #status-line {
442
+ height: 3;
443
+ color: $warning;
444
+ content-align: center middle;
445
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vgs-cli
3
- Version: 1.35.0.dev2
3
+ Version: 1.36.0.dev1
4
4
  Summary: VGS Client
5
5
  Home-page: https://github.com/verygoodsecurity/vgs-cli
6
6
  Author: Very Good Security
@@ -34,6 +34,7 @@ Requires-Dist: Jinja2>=2.10
34
34
  Requires-Dist: vgs-api-client<1,>=0.0.51
35
35
  Requires-Dist: async-timeout
36
36
  Requires-Dist: packaging<26,>=23
37
+ Requires-Dist: textual<8.3,>=8.2.8
37
38
  Dynamic: author
38
39
  Dynamic: author-email
39
40
  Dynamic: classifier
@@ -59,6 +60,7 @@ Command Line Tool for programmatic configurations on VGS.
59
60
  - [Installation](#installation)
60
61
  - [PyPI](#pypi)
61
62
  - [Run](#run)
63
+ - [Try the Console feature branch](#try-the-console-feature-branch)
62
64
  - [Running in Docker](#running-in-docker)
63
65
  - [AI agent skill](#ai-agent-skill)
64
66
  - [Commands](#commands)
@@ -71,6 +73,7 @@ Command Line Tool for programmatic configurations on VGS.
71
73
  - [Service accounts](#service-accounts)
72
74
  - [Certificates](#certificates)
73
75
  - [Automation with VGS CLI](#automation-with-vgs-cli)
76
+ - [Telemetry](#telemetry)
74
77
 
75
78
  ## Requirements
76
79
  [Python 3.11 or newer](https://www.python.org/downloads/) with OpenSSL 1.1.1 or newer, or [Docker](https://docs.docker.com/get-docker/).
@@ -93,6 +96,45 @@ Verify the installation:
93
96
  vgs --version
94
97
  ```
95
98
 
99
+ ## Try the Console feature branch
100
+
101
+ After the feature branch is available in an existing repository checkout,
102
+ switch to it and prepare the local Python environment:
103
+
104
+ ```bash
105
+ git switch feature/cli-ui
106
+ scripts/dev.sh setup
107
+ ```
108
+
109
+ Launch the feature with an authorized VGS account:
110
+
111
+ ```bash
112
+ scripts/dev.sh cli console
113
+ ```
114
+
115
+ In the Console:
116
+
117
+ 1. Complete browser authentication and select a SANDBOX context.
118
+ 2. Open **Organization**, select **Tenants**, then choose **Create tenant**.
119
+ 3. Enter a unique tenant name and complete one of the CMP, HTTP, SFTP, or
120
+ no-use-case paths.
121
+ 4. Review the retained answers before selecting **Create tenant**. This action
122
+ creates real SANDBOX resources.
123
+ 5. Confirm that the completed tenant becomes the active Console context. For an
124
+ HTTP use case, review the separate route draft before submitting it. SFTP
125
+ route configuration remains a separate later step. Every SANDBOX tenant
126
+ created by the CLI includes the standard CLI-managed Collect Form.
127
+
128
+ To try **Import tenant**, generate a local template, replace its example name
129
+ and organization ID, then select it with the Console's native file picker:
130
+
131
+ ```bash
132
+ scripts/dev.sh cli generate tenant > /tmp/vgs-cli-tenant.yaml
133
+ ```
134
+
135
+ Keep `environment: SANDBOX`; the Console rejects LIVE tenant imports. Do not
136
+ commit generated tenant files, credentials, tokens, or command output.
137
+
96
138
  ## Running in Docker
97
139
 
98
140
  Check our [official documentation](https://docs.verygoodsecurity.com/vault/developer-tools/vgs-cli/docker).
@@ -153,6 +195,7 @@ Use **tenant** and `--tenant/-T` in new commands. Legacy vault commands and
153
195
  requires the organization ID either in `tenant.yaml` as `data.organizationId`
154
196
  or through `-O/--organization`; if both are present, they must match.
155
197
 
198
+
156
199
  ### Organization notifications
157
200
 
158
201
  | Command | Purpose |
@@ -244,3 +287,9 @@ for the full workflow.
244
287
  ## Automation with VGS CLI
245
288
 
246
289
  If you want to use the VGS CLI for automation, create a [service account](https://docs.verygoodsecurity.com/vault/developer-tools/vgs-cli/service-account).
290
+
291
+ ## Telemetry
292
+
293
+ VGS CLI collects limited usage analytics to help VGS understand how the CLI is
294
+ used and improve the product. To disable telemetry, set
295
+ `VGS_CLI_TELEMETRY_OPTOUT=1` or `DO_NOT_TRACK=1`.