@epilot/cli 0.1.99 → 0.1.102

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,7 +29,7 @@ npm install -g @epilot/cli
29
29
 
30
30
  <!-- usage-help -->
31
31
  ```
32
- epilot v0.1.99 — CLI for epilot APIs
32
+ epilot v0.1.102 — CLI for epilot APIs
33
33
 
34
34
  USAGE
35
35
  epilot <api> <operationId> [params...] [flags]
@@ -17,6 +17,9 @@
17
17
  {
18
18
  "name": "Dashboards"
19
19
  },
20
+ {
21
+ "name": "Insights"
22
+ },
20
23
  {
21
24
  "name": "Visualisations"
22
25
  },
@@ -33,6 +36,53 @@
33
36
  "tags": [
34
37
  "Dashboards"
35
38
  ],
39
+ "parameters": [
40
+ {
41
+ "$ref": "#/components/parameters/Search"
42
+ },
43
+ {
44
+ "$ref": "#/components/parameters/CreatedBy"
45
+ },
46
+ {
47
+ "$ref": "#/components/parameters/CreatedAfter"
48
+ },
49
+ {
50
+ "$ref": "#/components/parameters/CreatedBefore"
51
+ },
52
+ {
53
+ "$ref": "#/components/parameters/UpdatedAfter"
54
+ },
55
+ {
56
+ "$ref": "#/components/parameters/UpdatedBefore"
57
+ },
58
+ {
59
+ "$ref": "#/components/parameters/SharedWith"
60
+ },
61
+ {
62
+ "$ref": "#/components/parameters/Owner"
63
+ },
64
+ {
65
+ "$ref": "#/components/parameters/AccessibleTo"
66
+ },
67
+ {
68
+ "$ref": "#/components/parameters/Favorite"
69
+ },
70
+ {
71
+ "$ref": "#/components/parameters/FavoritesFirst"
72
+ },
73
+ {
74
+ "$ref": "#/components/parameters/Sort"
75
+ },
76
+ {
77
+ "$ref": "#/components/parameters/Order"
78
+ },
79
+ {
80
+ "$ref": "#/components/parameters/Limit"
81
+ },
82
+ {
83
+ "$ref": "#/components/parameters/Offset"
84
+ }
85
+ ],
36
86
  "responses": {
37
87
  "200": {
38
88
  "description": "List of dashboards available to the user",
@@ -46,8 +96,15 @@
46
96
  "items": {
47
97
  "$ref": "#/components/schemas/Dashboard"
48
98
  }
99
+ },
100
+ "pagination": {
101
+ "$ref": "#/components/schemas/Pagination"
49
102
  }
50
- }
103
+ },
104
+ "required": [
105
+ "results",
106
+ "pagination"
107
+ ]
51
108
  }
52
109
  }
53
110
  }
@@ -85,6 +142,81 @@
85
142
  }
86
143
  }
87
144
  },
145
+ "/v1/dashboard/dashboards/favorites": {
146
+ "get": {
147
+ "operationId": "listFavoriteDashboardIds",
148
+ "summary": "listFavoriteDashboardIds",
149
+ "description": "Returns the current user's favorited dashboard ids, with no dashboard metadata. Lets a\nclient decide whether to default to a favorites-only view without first fetching the full\ndashboards list.\n",
150
+ "tags": [
151
+ "Dashboards"
152
+ ],
153
+ "responses": {
154
+ "200": {
155
+ "description": "The current user's favorited dashboard ids",
156
+ "content": {
157
+ "application/json": {
158
+ "schema": {
159
+ "type": "object",
160
+ "properties": {
161
+ "dashboard_ids": {
162
+ "type": "array",
163
+ "items": {
164
+ "$ref": "#/components/schemas/DashboardID"
165
+ }
166
+ },
167
+ "total": {
168
+ "type": "integer"
169
+ }
170
+ },
171
+ "required": [
172
+ "dashboard_ids",
173
+ "total"
174
+ ]
175
+ }
176
+ }
177
+ }
178
+ }
179
+ }
180
+ }
181
+ },
182
+ "/v1/dashboard/dashboards/{id}/favorite": {
183
+ "parameters": [
184
+ {
185
+ "name": "id",
186
+ "in": "path",
187
+ "required": true,
188
+ "schema": {
189
+ "$ref": "#/components/schemas/DashboardID"
190
+ }
191
+ }
192
+ ],
193
+ "put": {
194
+ "operationId": "favoriteDashboard",
195
+ "summary": "favoriteDashboard",
196
+ "description": "Marks the dashboard as favorited by the current user. Idempotent — favoriting an\nalready-favorited dashboard is not an error. Requires only view-level access to the\ndashboard (unlike the edit-level check on `PATCH .../dashboards/{id}`).\n",
197
+ "tags": [
198
+ "Dashboards"
199
+ ],
200
+ "responses": {
201
+ "204": {
202
+ "description": "The dashboard is now favorited by the current user"
203
+ }
204
+ }
205
+ },
206
+ "delete": {
207
+ "operationId": "unfavoriteDashboard",
208
+ "summary": "unfavoriteDashboard",
209
+ "description": "Removes the current user's favorite for the dashboard. Idempotent — unfavoriting a\ndashboard that was not favorited is not an error, and neither is unfavoriting one that no\nlonger exists or is no longer shared with you. Requires no access to the dashboard, so that\na stale favorite always remains removable.\n",
210
+ "tags": [
211
+ "Dashboards"
212
+ ],
213
+ "responses": {
214
+ "204": {
215
+ "description": "The dashboard is no longer favorited by the current user"
216
+ }
217
+ }
218
+ }
219
+ },
88
220
  "/v1/dashboard/dashboards/{id}": {
89
221
  "parameters": [
90
222
  {
@@ -146,6 +278,36 @@
146
278
  }
147
279
  }
148
280
  },
281
+ "patch": {
282
+ "operationId": "patchDashboard",
283
+ "summary": "patchDashboard",
284
+ "description": "Partially update a dashboard by ID. Update content (title/tiles) and/or manage sharing\n(owners, shared_with, org_access) — only owners may change sharing.\n`owners` and `shared_with` replace the whole array (send the complete list); omit them to leave\nsharing unchanged, or send `shared_with: []` to revoke all per-user grants.\n",
285
+ "tags": [
286
+ "Dashboards"
287
+ ],
288
+ "requestBody": {
289
+ "description": "The dashboard fields to update",
290
+ "content": {
291
+ "application/json": {
292
+ "schema": {
293
+ "$ref": "#/components/schemas/DashboardPatch"
294
+ }
295
+ }
296
+ }
297
+ },
298
+ "responses": {
299
+ "200": {
300
+ "description": "The updated dashboard",
301
+ "content": {
302
+ "application/json": {
303
+ "schema": {
304
+ "$ref": "#/components/schemas/Dashboard"
305
+ }
306
+ }
307
+ }
308
+ }
309
+ }
310
+ },
149
311
  "delete": {
150
312
  "operationId": "deleteDashboard",
151
313
  "summary": "deleteDashboard",
@@ -167,6 +329,265 @@
167
329
  }
168
330
  }
169
331
  },
332
+ "/v1/dashboard/insights": {
333
+ "get": {
334
+ "operationId": "listInsights",
335
+ "summary": "listInsights",
336
+ "description": "List insights (saved charts) available to the user",
337
+ "tags": [
338
+ "Insights"
339
+ ],
340
+ "parameters": [
341
+ {
342
+ "$ref": "#/components/parameters/Search"
343
+ },
344
+ {
345
+ "$ref": "#/components/parameters/VisualisationIdFilter"
346
+ },
347
+ {
348
+ "$ref": "#/components/parameters/TagsFilter"
349
+ },
350
+ {
351
+ "$ref": "#/components/parameters/TagsMatch"
352
+ },
353
+ {
354
+ "$ref": "#/components/parameters/CreatedBy"
355
+ },
356
+ {
357
+ "$ref": "#/components/parameters/CreatedAfter"
358
+ },
359
+ {
360
+ "$ref": "#/components/parameters/CreatedBefore"
361
+ },
362
+ {
363
+ "$ref": "#/components/parameters/UpdatedAfter"
364
+ },
365
+ {
366
+ "$ref": "#/components/parameters/UpdatedBefore"
367
+ },
368
+ {
369
+ "$ref": "#/components/parameters/SharedWith"
370
+ },
371
+ {
372
+ "$ref": "#/components/parameters/Owner"
373
+ },
374
+ {
375
+ "$ref": "#/components/parameters/AccessibleTo"
376
+ },
377
+ {
378
+ "$ref": "#/components/parameters/Sort"
379
+ },
380
+ {
381
+ "$ref": "#/components/parameters/Order"
382
+ },
383
+ {
384
+ "$ref": "#/components/parameters/Limit"
385
+ },
386
+ {
387
+ "$ref": "#/components/parameters/Offset"
388
+ }
389
+ ],
390
+ "responses": {
391
+ "200": {
392
+ "description": "List of insights available to the user",
393
+ "content": {
394
+ "application/json": {
395
+ "schema": {
396
+ "type": "object",
397
+ "properties": {
398
+ "results": {
399
+ "type": "array",
400
+ "items": {
401
+ "$ref": "#/components/schemas/Insight"
402
+ }
403
+ },
404
+ "pagination": {
405
+ "$ref": "#/components/schemas/Pagination"
406
+ }
407
+ },
408
+ "required": [
409
+ "results",
410
+ "pagination"
411
+ ]
412
+ }
413
+ }
414
+ }
415
+ }
416
+ }
417
+ },
418
+ "post": {
419
+ "operationId": "createInsight",
420
+ "summary": "createInsight",
421
+ "description": "Create a new insight (saved chart). The caller becomes the owner.",
422
+ "tags": [
423
+ "Insights"
424
+ ],
425
+ "requestBody": {
426
+ "description": "The insight to create",
427
+ "content": {
428
+ "application/json": {
429
+ "schema": {
430
+ "$ref": "#/components/schemas/Insight"
431
+ }
432
+ }
433
+ }
434
+ },
435
+ "responses": {
436
+ "201": {
437
+ "description": "The created insight",
438
+ "content": {
439
+ "application/json": {
440
+ "schema": {
441
+ "$ref": "#/components/schemas/Insight"
442
+ }
443
+ }
444
+ }
445
+ }
446
+ }
447
+ }
448
+ },
449
+ "/v1/dashboard/insights/tags": {
450
+ "get": {
451
+ "operationId": "listInsightTags",
452
+ "summary": "listInsightTags",
453
+ "description": "List the distinct tags used by insights in the organization (for filter facets)",
454
+ "tags": [
455
+ "Insights"
456
+ ],
457
+ "responses": {
458
+ "200": {
459
+ "description": "Distinct tags used by insights in the organization",
460
+ "content": {
461
+ "application/json": {
462
+ "schema": {
463
+ "type": "object",
464
+ "properties": {
465
+ "results": {
466
+ "type": "array",
467
+ "items": {
468
+ "type": "string"
469
+ }
470
+ }
471
+ }
472
+ }
473
+ }
474
+ }
475
+ }
476
+ }
477
+ }
478
+ },
479
+ "/v1/dashboard/insights/{id}": {
480
+ "parameters": [
481
+ {
482
+ "name": "id",
483
+ "in": "path",
484
+ "required": true,
485
+ "schema": {
486
+ "$ref": "#/components/schemas/InsightID"
487
+ }
488
+ }
489
+ ],
490
+ "get": {
491
+ "operationId": "getInsight",
492
+ "summary": "getInsight",
493
+ "description": "Get insight by ID",
494
+ "tags": [
495
+ "Insights"
496
+ ],
497
+ "responses": {
498
+ "200": {
499
+ "description": "The insight with the passed ID",
500
+ "content": {
501
+ "application/json": {
502
+ "schema": {
503
+ "$ref": "#/components/schemas/Insight"
504
+ }
505
+ }
506
+ }
507
+ }
508
+ }
509
+ },
510
+ "put": {
511
+ "operationId": "putInsight",
512
+ "summary": "putInsight",
513
+ "description": "Replace an insight's content by ID. Sharing is managed via patchInsight.",
514
+ "tags": [
515
+ "Insights"
516
+ ],
517
+ "requestBody": {
518
+ "description": "The updated insight",
519
+ "content": {
520
+ "application/json": {
521
+ "schema": {
522
+ "$ref": "#/components/schemas/Insight"
523
+ }
524
+ }
525
+ }
526
+ },
527
+ "responses": {
528
+ "200": {
529
+ "description": "The insight with the passed ID",
530
+ "content": {
531
+ "application/json": {
532
+ "schema": {
533
+ "$ref": "#/components/schemas/Insight"
534
+ }
535
+ }
536
+ }
537
+ }
538
+ }
539
+ },
540
+ "patch": {
541
+ "operationId": "patchInsight",
542
+ "summary": "patchInsight",
543
+ "description": "Partially update an insight by ID. Update content (name/description/visualisation/tags) and/or\nmanage sharing (owners, shared_with, org_access) — only owners may change sharing.\n`owners` and `shared_with` replace the whole array (send the complete list); omit them to leave\nsharing unchanged, or send `shared_with: []` to revoke all per-user grants.\n",
544
+ "tags": [
545
+ "Insights"
546
+ ],
547
+ "requestBody": {
548
+ "description": "The insight fields to update",
549
+ "content": {
550
+ "application/json": {
551
+ "schema": {
552
+ "$ref": "#/components/schemas/InsightPatch"
553
+ }
554
+ }
555
+ }
556
+ },
557
+ "responses": {
558
+ "200": {
559
+ "description": "The updated insight",
560
+ "content": {
561
+ "application/json": {
562
+ "schema": {
563
+ "$ref": "#/components/schemas/Insight"
564
+ }
565
+ }
566
+ }
567
+ }
568
+ }
569
+ },
570
+ "delete": {
571
+ "operationId": "deleteInsight",
572
+ "summary": "deleteInsight",
573
+ "description": "Delete an insight by ID. Only owners may delete.",
574
+ "tags": [
575
+ "Insights"
576
+ ],
577
+ "responses": {
578
+ "200": {
579
+ "description": "The deleted insight",
580
+ "content": {
581
+ "application/json": {
582
+ "schema": {
583
+ "$ref": "#/components/schemas/Insight"
584
+ }
585
+ }
586
+ }
587
+ }
588
+ }
589
+ }
590
+ },
170
591
  "/v1/dashboard/visualisations": {
171
592
  "get": {
172
593
  "operationId": "listAvailableVisualisations",
@@ -251,72 +672,313 @@
251
672
  "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
252
673
  },
253
674
  "Dashboard": {
675
+ "description": "A dashboard configuration. A dashboard is a canvas whose tiles arrange and\nposition insights (saved charts). Tiles may reference an insight by `insight_id`\nor, for backwards compatibility, embed a visualisation inline.\n",
676
+ "allOf": [
677
+ {
678
+ "$ref": "#/components/schemas/AccessControl"
679
+ },
680
+ {
681
+ "type": "object",
682
+ "properties": {
683
+ "id": {
684
+ "$ref": "#/components/schemas/DashboardID"
685
+ },
686
+ "title": {
687
+ "type": "string",
688
+ "example": "Employee Dashboard"
689
+ },
690
+ "tiles": {
691
+ "type": "array",
692
+ "items": {
693
+ "$ref": "#/components/schemas/DashboardTile"
694
+ },
695
+ "example": [
696
+ {
697
+ "id": "e4af1297-1fd6-440f-9846-f475f580d40f",
698
+ "coordinates": {},
699
+ "insight_id": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e"
700
+ }
701
+ ]
702
+ },
703
+ "favorited": {
704
+ "description": "Whether the requesting user has favorited this dashboard.",
705
+ "type": "boolean",
706
+ "readOnly": true,
707
+ "example": false
708
+ }
709
+ },
710
+ "required": [
711
+ "title",
712
+ "tiles"
713
+ ]
714
+ }
715
+ ]
716
+ },
717
+ "DashboardTileID": {
718
+ "description": "Unique identifier for a tile in a dashboard",
719
+ "type": "string",
720
+ "format": "uuid",
721
+ "example": "e4af1297-1fd6-440f-9846-f475f580d40f"
722
+ },
723
+ "SharePermission": {
724
+ "description": "Permission level granted to a user (or the whole organization) on a shared resource.\n`view` allows read-only access; `edit` additionally allows updating the content.\nFull control (delete and managing sharing) is reserved for owners.\n",
725
+ "type": "string",
726
+ "enum": [
727
+ "view",
728
+ "edit"
729
+ ],
730
+ "example": "view"
731
+ },
732
+ "ShareGrant": {
733
+ "description": "Grants a single user a permission level on a resource",
254
734
  "type": "object",
255
- "description": "Adashboard configuration with tiles",
256
735
  "properties": {
257
- "id": {
258
- "$ref": "#/components/schemas/DashboardID"
736
+ "user_id": {
737
+ "description": "The id of the user the resource is shared with",
738
+ "type": "string",
739
+ "example": "10598"
259
740
  },
260
- "title": {
741
+ "permission": {
742
+ "$ref": "#/components/schemas/SharePermission"
743
+ }
744
+ },
745
+ "required": [
746
+ "user_id",
747
+ "permission"
748
+ ]
749
+ },
750
+ "OrgAccess": {
751
+ "description": "Optional organization-wide grant. When set, every user in the resource's organization\nis granted this permission level. `null` (or omitted) means the resource is not shared\norg-wide.\n",
752
+ "anyOf": [
753
+ {
754
+ "type": "string",
755
+ "enum": [
756
+ "view",
757
+ "edit"
758
+ ]
759
+ },
760
+ {
761
+ "enum": [
762
+ null
763
+ ]
764
+ }
765
+ ],
766
+ "example": "view"
767
+ },
768
+ "AccessControl": {
769
+ "description": "Ownership and sharing metadata common to dashboards and insights. `created_*`/`updated_*`\nfields are managed by the server. `owners`, `shared_with` and `org_access` describe who\nmay access the resource. New resources are private to their creator until shared.\n",
770
+ "type": "object",
771
+ "properties": {
772
+ "created_by": {
773
+ "description": "Id of the user who created the resource",
774
+ "type": "string",
775
+ "readOnly": true,
776
+ "example": "10598"
777
+ },
778
+ "created_at": {
779
+ "type": "string",
780
+ "format": "date-time",
781
+ "readOnly": true
782
+ },
783
+ "updated_by": {
784
+ "description": "Id of the user who last updated the resource",
261
785
  "type": "string",
262
- "example": "Employee Dashboard"
786
+ "readOnly": true,
787
+ "example": "10598"
263
788
  },
264
- "tiles": {
789
+ "updated_at": {
790
+ "type": "string",
791
+ "format": "date-time",
792
+ "readOnly": true
793
+ },
794
+ "owner_org_id": {
795
+ "description": "Id of the organisation that owns the resource. Set at creation time and immutable.",
796
+ "type": "string",
797
+ "readOnly": true,
798
+ "example": "739224"
799
+ },
800
+ "owners": {
801
+ "description": "User ids with full control over the resource (view, edit, delete and manage sharing).\nThe creator is always an owner. There must always be at least one owner.\n",
265
802
  "type": "array",
266
803
  "items": {
267
- "$ref": "#/components/schemas/DashboardTile"
804
+ "type": "string"
268
805
  },
269
806
  "example": [
270
- {
271
- "id": "e4af1297-1fd6-440f-9846-f475f580d40f",
272
- "coordinates": {},
273
- "visualisation": "timechart",
274
- "visualisation_config": {
275
- "query": {
276
- "dataset": "entity_operations",
277
- "measure": "count_operations",
278
- "filters": [
279
- {
280
- "operation": [
281
- "createEntity"
282
- ]
283
- },
284
- {
285
- "entity_schema": [
286
- "opportunity"
287
- ]
288
- }
289
- ],
290
- "dimensions": [
291
- {
292
- "time_with_granularity": "month"
293
- },
294
- {
295
- "entity_attribute": "source.title"
296
- }
297
- ]
298
- },
299
- "options": {
300
- "type": "line"
301
- }
807
+ "10598"
808
+ ]
809
+ },
810
+ "shared_with": {
811
+ "description": "Per-user sharing grants",
812
+ "type": "array",
813
+ "items": {
814
+ "$ref": "#/components/schemas/ShareGrant"
815
+ }
816
+ },
817
+ "org_access": {
818
+ "$ref": "#/components/schemas/OrgAccess"
819
+ }
820
+ }
821
+ },
822
+ "AccessControlUpdate": {
823
+ "description": "Sharing fields that can be mutated via PATCH (owners only). `owners` and `shared_with` are\nfull replacements of their arrays, not merges — omit a field to leave it unchanged.\n",
824
+ "type": "object",
825
+ "properties": {
826
+ "owners": {
827
+ "description": "Replaces the entire list of owner user ids. Must keep at least one owner (else 400).\nOmit to leave owners unchanged.\n",
828
+ "type": "array",
829
+ "items": {
830
+ "type": "string"
831
+ }
832
+ },
833
+ "shared_with": {
834
+ "description": "Replaces the entire list of per-user grants — any existing grant not included is removed.\nOmit to leave sharing unchanged; send an empty array to revoke all per-user grants.\n",
835
+ "type": "array",
836
+ "items": {
837
+ "$ref": "#/components/schemas/ShareGrant"
838
+ }
839
+ },
840
+ "org_access": {
841
+ "$ref": "#/components/schemas/OrgAccess"
842
+ }
843
+ }
844
+ },
845
+ "DashboardPatch": {
846
+ "description": "Fields that can be partially updated on a dashboard",
847
+ "allOf": [
848
+ {
849
+ "$ref": "#/components/schemas/AccessControlUpdate"
850
+ },
851
+ {
852
+ "type": "object",
853
+ "properties": {
854
+ "title": {
855
+ "type": "string",
856
+ "example": "Employee Dashboard"
857
+ },
858
+ "tiles": {
859
+ "type": "array",
860
+ "items": {
861
+ "$ref": "#/components/schemas/DashboardTile"
302
862
  }
303
863
  }
304
- ]
864
+ }
305
865
  }
306
- },
307
- "required": [
308
- "title",
309
- "tiles"
310
866
  ]
311
867
  },
312
- "DashboardTileID": {
313
- "description": "Unique identifier for a tile in a dashboard",
868
+ "InsightID": {
869
+ "description": "Unique identifier for an insight (a saved chart / visualisation)",
314
870
  "type": "string",
315
871
  "format": "uuid",
316
- "example": "e4af1297-1fd6-440f-9846-f475f580d40f"
872
+ "example": "8d2e1c7a-3b4f-4a2e-9c1d-2f3a4b5c6d7e"
873
+ },
874
+ "Insight": {
875
+ "description": "An insight is a saved, reusable chart definition (a visualisation plus its query/options).\nInsights exist independently of dashboards: they can be created, shared and edited on their\nown, and referenced by one or more dashboard tiles via `insight_id`.\n",
876
+ "allOf": [
877
+ {
878
+ "$ref": "#/components/schemas/AccessControl"
879
+ },
880
+ {
881
+ "type": "object",
882
+ "properties": {
883
+ "id": {
884
+ "$ref": "#/components/schemas/InsightID"
885
+ },
886
+ "name": {
887
+ "description": "Human readable name of the insight",
888
+ "type": "string",
889
+ "example": "Opportunities created by journeys every month"
890
+ },
891
+ "description": {
892
+ "type": "string",
893
+ "example": "Monthly count of opportunities grouped by source journey"
894
+ },
895
+ "visualisation_id": {
896
+ "$ref": "#/components/schemas/VisualisationId"
897
+ },
898
+ "visualisation_config": {
899
+ "$ref": "#/components/schemas/VisualisationConfig"
900
+ },
901
+ "tags": {
902
+ "$ref": "#/components/schemas/Tags"
903
+ }
904
+ },
905
+ "required": [
906
+ "name",
907
+ "visualisation_id"
908
+ ]
909
+ }
910
+ ]
911
+ },
912
+ "InsightPatch": {
913
+ "description": "Fields that can be partially updated on an insight",
914
+ "allOf": [
915
+ {
916
+ "$ref": "#/components/schemas/AccessControlUpdate"
917
+ },
918
+ {
919
+ "type": "object",
920
+ "properties": {
921
+ "name": {
922
+ "type": "string"
923
+ },
924
+ "description": {
925
+ "type": "string"
926
+ },
927
+ "visualisation_id": {
928
+ "$ref": "#/components/schemas/VisualisationId"
929
+ },
930
+ "visualisation_config": {
931
+ "$ref": "#/components/schemas/VisualisationConfig"
932
+ },
933
+ "tags": {
934
+ "$ref": "#/components/schemas/Tags"
935
+ }
936
+ }
937
+ }
938
+ ]
939
+ },
940
+ "Tags": {
941
+ "description": "Free-form labels for grouping and filtering insights",
942
+ "type": "array",
943
+ "items": {
944
+ "type": "string"
945
+ },
946
+ "example": [
947
+ "revenue",
948
+ "marketing"
949
+ ]
950
+ },
951
+ "Pagination": {
952
+ "description": "Offset-based pagination metadata for list responses",
953
+ "type": "object",
954
+ "properties": {
955
+ "total": {
956
+ "description": "Total number of results matching the query (ignoring limit/offset)",
957
+ "type": "integer"
958
+ },
959
+ "limit": {
960
+ "description": "Page size used for this response",
961
+ "type": "integer"
962
+ },
963
+ "offset": {
964
+ "description": "Number of results skipped before this page",
965
+ "type": "integer"
966
+ },
967
+ "has_more": {
968
+ "description": "Whether more results exist beyond this page",
969
+ "type": "boolean"
970
+ }
971
+ },
972
+ "required": [
973
+ "total",
974
+ "limit",
975
+ "offset",
976
+ "has_more"
977
+ ]
317
978
  },
318
979
  "DashboardTile": {
319
980
  "type": "object",
981
+ "description": "A positioned tile on a dashboard canvas. A tile references a saved insight via\n`insight_id`. Inline `visualisation_id`/`visualisation_config` remain supported for\nbackwards compatibility (ad-hoc tiles that are not backed by a shared insight).\n",
320
982
  "properties": {
321
983
  "id": {
322
984
  "$ref": "#/components/schemas/DashboardTileID"
@@ -328,6 +990,10 @@
328
990
  "type": "string",
329
991
  "example": "Number of opportunities created by journeys every month"
330
992
  },
993
+ "insight_id": {
994
+ "description": "Reference to a saved insight rendered by this tile",
995
+ "$ref": "#/components/schemas/InsightID"
996
+ },
331
997
  "visualisation_id": {
332
998
  "$ref": "#/components/schemas/VisualisationId"
333
999
  },
@@ -461,6 +1127,211 @@
461
1127
  }
462
1128
  }
463
1129
  },
1130
+ "parameters": {
1131
+ "Search": {
1132
+ "name": "q",
1133
+ "in": "query",
1134
+ "required": false,
1135
+ "description": "Free-text search over name/title and description (case-insensitive substring).",
1136
+ "schema": {
1137
+ "type": "string"
1138
+ }
1139
+ },
1140
+ "VisualisationIdFilter": {
1141
+ "name": "visualisation_id",
1142
+ "in": "query",
1143
+ "required": false,
1144
+ "description": "Filter insights by one or more visualisation ids.",
1145
+ "style": "form",
1146
+ "explode": true,
1147
+ "schema": {
1148
+ "type": "array",
1149
+ "items": {
1150
+ "$ref": "#/components/schemas/VisualisationId"
1151
+ }
1152
+ }
1153
+ },
1154
+ "TagsFilter": {
1155
+ "name": "tags",
1156
+ "in": "query",
1157
+ "required": false,
1158
+ "description": "Filter by one or more tags (see tags_match for any/all semantics).",
1159
+ "style": "form",
1160
+ "explode": true,
1161
+ "schema": {
1162
+ "type": "array",
1163
+ "items": {
1164
+ "type": "string"
1165
+ }
1166
+ }
1167
+ },
1168
+ "TagsMatch": {
1169
+ "name": "tags_match",
1170
+ "in": "query",
1171
+ "required": false,
1172
+ "description": "Whether a result must match any (default) or all of the given tags.",
1173
+ "schema": {
1174
+ "type": "string",
1175
+ "enum": [
1176
+ "any",
1177
+ "all"
1178
+ ],
1179
+ "default": "any"
1180
+ }
1181
+ },
1182
+ "CreatedBy": {
1183
+ "name": "created_by",
1184
+ "in": "query",
1185
+ "required": false,
1186
+ "description": "Filter by the id of the creating user.",
1187
+ "schema": {
1188
+ "type": "string"
1189
+ }
1190
+ },
1191
+ "CreatedAfter": {
1192
+ "name": "created_after",
1193
+ "in": "query",
1194
+ "required": false,
1195
+ "schema": {
1196
+ "type": "string",
1197
+ "format": "date-time"
1198
+ }
1199
+ },
1200
+ "CreatedBefore": {
1201
+ "name": "created_before",
1202
+ "in": "query",
1203
+ "required": false,
1204
+ "schema": {
1205
+ "type": "string",
1206
+ "format": "date-time"
1207
+ }
1208
+ },
1209
+ "UpdatedAfter": {
1210
+ "name": "updated_after",
1211
+ "in": "query",
1212
+ "required": false,
1213
+ "schema": {
1214
+ "type": "string",
1215
+ "format": "date-time"
1216
+ }
1217
+ },
1218
+ "UpdatedBefore": {
1219
+ "name": "updated_before",
1220
+ "in": "query",
1221
+ "required": false,
1222
+ "schema": {
1223
+ "type": "string",
1224
+ "format": "date-time"
1225
+ }
1226
+ },
1227
+ "SharedWith": {
1228
+ "name": "shared_with",
1229
+ "in": "query",
1230
+ "required": false,
1231
+ "description": "Filter to resources shared with any of the given user ids.",
1232
+ "style": "form",
1233
+ "explode": true,
1234
+ "schema": {
1235
+ "type": "array",
1236
+ "items": {
1237
+ "type": "string"
1238
+ }
1239
+ }
1240
+ },
1241
+ "Owner": {
1242
+ "name": "owner",
1243
+ "in": "query",
1244
+ "required": false,
1245
+ "description": "Filter to resources owned by any of the given user ids.",
1246
+ "style": "form",
1247
+ "explode": true,
1248
+ "schema": {
1249
+ "type": "array",
1250
+ "items": {
1251
+ "type": "string"
1252
+ }
1253
+ }
1254
+ },
1255
+ "AccessibleTo": {
1256
+ "name": "accessible_to",
1257
+ "in": "query",
1258
+ "required": false,
1259
+ "description": "Filter to resources the given user id may view (owner, shared, org-wide or legacy).",
1260
+ "schema": {
1261
+ "type": "string"
1262
+ }
1263
+ },
1264
+ "Favorite": {
1265
+ "name": "favorite",
1266
+ "in": "query",
1267
+ "required": false,
1268
+ "description": "Dashboards only. Filter to only (`true`) or exclude (`false`) the requesting user's\nfavorited dashboards. A user with zero favorites and `favorite=true` gets an empty page,\nnot the unfiltered list.\n",
1269
+ "schema": {
1270
+ "type": "boolean"
1271
+ }
1272
+ },
1273
+ "FavoritesFirst": {
1274
+ "name": "favorites_first",
1275
+ "in": "query",
1276
+ "required": false,
1277
+ "description": "Dashboards only. No filtering — sorts the requesting user's favorited dashboards first,\npreserving the existing secondary ordering (`sort`/`order`) otherwise.\n",
1278
+ "schema": {
1279
+ "type": "boolean"
1280
+ }
1281
+ },
1282
+ "Sort": {
1283
+ "name": "sort",
1284
+ "in": "query",
1285
+ "required": false,
1286
+ "description": "Field to sort by. `name` and `title` are aliases for the resource's display name and are normalised per resource: dashboards sort by `title` and insights by `name`, whichever of the two values is sent. String sorts are case-insensitive.",
1287
+ "schema": {
1288
+ "type": "string",
1289
+ "enum": [
1290
+ "created_at",
1291
+ "updated_at",
1292
+ "name",
1293
+ "title"
1294
+ ],
1295
+ "default": "updated_at"
1296
+ }
1297
+ },
1298
+ "Order": {
1299
+ "name": "order",
1300
+ "in": "query",
1301
+ "required": false,
1302
+ "description": "Sort direction. Defaults to ascending (preserving the pre-migration order).",
1303
+ "schema": {
1304
+ "type": "string",
1305
+ "enum": [
1306
+ "asc",
1307
+ "desc"
1308
+ ],
1309
+ "default": "asc"
1310
+ }
1311
+ },
1312
+ "Limit": {
1313
+ "name": "limit",
1314
+ "in": "query",
1315
+ "required": false,
1316
+ "description": "Maximum results to return (max 200). Omit to return all matching results (pagination is opt-in).",
1317
+ "schema": {
1318
+ "type": "integer",
1319
+ "minimum": 1,
1320
+ "maximum": 200
1321
+ }
1322
+ },
1323
+ "Offset": {
1324
+ "name": "offset",
1325
+ "in": "query",
1326
+ "required": false,
1327
+ "description": "Number of results to skip, for pagination. Use with limit (page N = offset N*limit).",
1328
+ "schema": {
1329
+ "type": "integer",
1330
+ "minimum": 0,
1331
+ "default": 0
1332
+ }
1333
+ }
1334
+ },
464
1335
  "securitySchemes": {
465
1336
  "EpilotAuth": {
466
1337
  "type": "http",
@@ -1348,10 +1348,22 @@
1348
1348
  "post": {
1349
1349
  "operationId": "createSmtpConnection",
1350
1350
  "summary": "createSmtpConnection",
1351
- "description": "Creates a new custom SMTP connection. Runs a live verify against the SMTP server\nbefore persisting; on failure the request is rejected and nothing is saved.\nThe password is encrypted via KMS before being written to DynamoDB.\n",
1351
+ "description": "Creates a new custom SMTP connection. Runs a live verify against the SMTP server\nbefore persisting; on failure the request is rejected and nothing is saved. Pass\n`skip_test=true` to store the configuration untested instead.\n",
1352
1352
  "tags": [
1353
1353
  "Custom SMTP"
1354
1354
  ],
1355
+ "parameters": [
1356
+ {
1357
+ "name": "skip_test",
1358
+ "in": "query",
1359
+ "required": false,
1360
+ "description": "Save without running the live verify. Use when the server is not reachable from\nepilot yet, or when a referenced `{{ env.* }}` secret has not been set. The\nconnection is stored untested — `last_test_status` is left unset rather than\nclaimed as `ok` — and env references are not resolved either, since an\nunresolvable one is expected in this case.\n",
1361
+ "schema": {
1362
+ "type": "boolean",
1363
+ "default": false
1364
+ }
1365
+ }
1366
+ ],
1355
1367
  "requestBody": {
1356
1368
  "required": true,
1357
1369
  "content": {
@@ -1428,10 +1440,22 @@
1428
1440
  "put": {
1429
1441
  "operationId": "updateSmtpConnection",
1430
1442
  "summary": "updateSmtpConnection",
1431
- "description": "Partial update; omitted fields keep their existing values. The merged\nconfiguration is verified against the SMTP server before persisting.\n",
1443
+ "description": "Partial update; omitted fields keep their existing values. The merged\nconfiguration is verified against the SMTP server before persisting. Pass\n`skip_test=true` to store it untested instead, which also clears any previous\ntest result — it described a configuration that no longer applies.\n",
1432
1444
  "tags": [
1433
1445
  "Custom SMTP"
1434
1446
  ],
1447
+ "parameters": [
1448
+ {
1449
+ "name": "skip_test",
1450
+ "in": "query",
1451
+ "required": false,
1452
+ "description": "Save without running the live verify. Use when the server is not reachable from\nepilot yet, or when a referenced `{{ env.* }}` secret has not been set. The\nconnection is stored untested — `last_test_status` is left unset rather than\nclaimed as `ok` — and env references are not resolved either, since an\nunresolvable one is expected in this case.\n",
1453
+ "schema": {
1454
+ "type": "boolean",
1455
+ "default": false
1456
+ }
1457
+ }
1458
+ ],
1435
1459
  "requestBody": {
1436
1460
  "required": true,
1437
1461
  "content": {
@@ -3335,8 +3359,8 @@
3335
3359
  "description": "Hostname of the SMTP server (e.g. smtp.mailgun.org)"
3336
3360
  },
3337
3361
  "smtp_port": {
3338
- "type": "integer",
3339
- "description": "SMTP port (typically 587 for STARTTLS or 465 for TLS)"
3362
+ "type": "string",
3363
+ "description": "SMTP port (typically 587 for STARTTLS or 465 for TLS). A string, because it\nmay hold a `{{ env.your_key }}` reference rather than a literal port.\n"
3340
3364
  },
3341
3365
  "smtp_secure": {
3342
3366
  "type": "string",
@@ -3408,9 +3432,17 @@
3408
3432
  "type": "string"
3409
3433
  },
3410
3434
  "smtp_port": {
3411
- "type": "integer",
3412
- "minimum": 1,
3413
- "maximum": 65535
3435
+ "description": "A port between 1 and 65535, or a `{{ env.your_key }}` template resolving to\none. An integer is still accepted, so callers predating the template support\nkeep working.\n",
3436
+ "oneOf": [
3437
+ {
3438
+ "type": "string"
3439
+ },
3440
+ {
3441
+ "type": "integer",
3442
+ "minimum": 1,
3443
+ "maximum": 65535
3444
+ }
3445
+ ]
3414
3446
  },
3415
3447
  "smtp_secure": {
3416
3448
  "type": "string",
@@ -3437,9 +3469,17 @@
3437
3469
  "type": "string"
3438
3470
  },
3439
3471
  "smtp_port": {
3440
- "type": "integer",
3441
- "minimum": 1,
3442
- "maximum": 65535
3472
+ "description": "A port between 1 and 65535, or a `{{ env.your_key }}` template resolving to\none. An integer is still accepted, so callers predating the template support\nkeep working.\n",
3473
+ "oneOf": [
3474
+ {
3475
+ "type": "string"
3476
+ },
3477
+ {
3478
+ "type": "integer",
3479
+ "minimum": 1,
3480
+ "maximum": 65535
3481
+ }
3482
+ ]
3443
3483
  },
3444
3484
  "smtp_secure": {
3445
3485
  "type": "string",
@@ -3947,7 +3947,7 @@
3947
3947
  "description": "ISO 8601 timestamp to filter jobs created after this time (e.g., 2023-01-01T00:00:00Z).",
3948
3948
  "type": "string",
3949
3949
  "format": "date-time",
3950
- "example": "2023-01-01T00:00:00Z"
3950
+ "example": "2023-01-01T00:00:00.000Z"
3951
3951
  }
3952
3952
  },
3953
3953
  {
@@ -5097,6 +5097,17 @@
5097
5097
  "items": {
5098
5098
  "type": "string"
5099
5099
  }
5100
+ },
5101
+ "widget_visibility": {
5102
+ "type": "object",
5103
+ "description": "Per-widget on/off state for the entity-details widget grid, keyed by widget id (a capability widget's `component`, or `summary` for the synthesized summary card). Holds only the admin's deviations from each widget's declared default: a widget absent from this map falls back to its ui_hook `default_visible`, and then to visible. Do not seed this map from migrations — doing so would freeze today's defaults into the schema.",
5104
+ "additionalProperties": {
5105
+ "type": "boolean"
5106
+ },
5107
+ "example": {
5108
+ "next_best_action": true,
5109
+ "address_map": false
5110
+ }
5100
5111
  }
5101
5112
  }
5102
5113
  },
@@ -7448,6 +7459,11 @@
7448
7459
  "$ref": "#/components/schemas/Attribute"
7449
7460
  }
7450
7461
  },
7462
+ "variant_overridable": {
7463
+ "type": "boolean",
7464
+ "default": false,
7465
+ "description": "Allow conditional variants of the entity to override the values managed by this\ncapability. Only meaningful on schemas that declare `conditions` and on capabilities\nthat render an attribute group (`EntityAttributes:Group` ui hook), e.g. pricing tiers.\nAttributes carried by the capability opt in individually via their own\n`variant_overridable` flag.\n"
7466
+ },
7451
7467
  "_purpose": {
7452
7468
  "type": "array",
7453
7469
  "items": {
@@ -7555,6 +7571,16 @@
7555
7571
  "required": [
7556
7572
  "action"
7557
7573
  ]
7574
+ },
7575
+ "default_visible": {
7576
+ "type": "boolean",
7577
+ "description": "Whether this widget is switched on by default for entity types that have the capability. Only meaningful on the `EntityDetailsV2:Widget` hook. Defaults to true when omitted. An admin's explicit choice in the entity builder is stored in the schema's `ui_config.widget_visibility` and wins over this.",
7578
+ "example": false
7579
+ },
7580
+ "pricing_tier_setting": {
7581
+ "type": "string",
7582
+ "description": "The pricing-tier settings key an organisation must have enabled to use this widget. Omit for widgets available to everyone. Resolved against `GET /v2/pricing-tiers/me` as `override_settings[key].enabled ?? settings[key].enabled`. Note this is commercial packaging enforced in the UI, not a security control — the key must also be added to the pricing tier settings list in epilot-admin-portal, or it can never be switched on for a tier.",
7583
+ "example": "entity_address_maps"
7558
7584
  }
7559
7585
  },
7560
7586
  "required": [
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  API_LIST
4
- } from "../chunk-5Y4OYCNI.js";
4
+ } from "../chunk-CR6NZAXB.js";
5
5
 
6
6
  // bin/epilot.ts
7
7
  import { runMain } from "citty";
@@ -11,7 +11,7 @@ import { defineCommand } from "citty";
11
11
  var main = defineCommand({
12
12
  meta: {
13
13
  name: "epilot",
14
- version: "0.1.99",
14
+ version: "0.1.102",
15
15
  description: "CLI for epilot APIs"
16
16
  },
17
17
  args: {
@@ -30,8 +30,8 @@ var main = defineCommand({
30
30
  auth: () => import("../auth-WMXFMPWE.js").then((m) => m.default),
31
31
  profile: () => import("../profile-OZJL5ZPT.js").then((m) => m.default),
32
32
  config: () => import("../config-DGZIMLZK.js").then((m) => m.default),
33
- completion: () => import("../completion-W5V6EYUZ.js").then((m) => m.default),
34
- upgrade: () => import("../upgrade-T2AWIWQL.js").then((m) => m.default),
33
+ completion: () => import("../completion-JKVTLZX7.js").then((m) => m.default),
34
+ upgrade: () => import("../upgrade-MIWXKJAW.js").then((m) => m.default),
35
35
  "access-token": () => import("../access-token-WWE6BDJH.js").then((m) => m.default),
36
36
  address: () => import("../address-EH3C4CVB.js").then((m) => m.default),
37
37
  "address-suggestions": () => import("../address-suggestions-RRSLOBFW.js").then((m) => m.default),
@@ -134,13 +134,13 @@ process.stderr.on("error", (err) => {
134
134
  if (err.code === "EPIPE") process.exit(0);
135
135
  throw err;
136
136
  });
137
- var VERSION = true ? "0.1.99" : (await null).default.version;
137
+ var VERSION = true ? "0.1.102" : (await null).default.version;
138
138
  var reorderedArgv = hoistFlagsAfterSubcommand(process.argv.slice(2));
139
139
  process.argv = [process.argv[0], process.argv[1], ...reorderedArgv];
140
140
  var args = process.argv.slice(2);
141
141
  var completionsIdx = args.indexOf("--_completions");
142
142
  if (completionsIdx >= 0) {
143
- const { handleCompletions } = await import("../completion-W5V6EYUZ.js");
143
+ const { handleCompletions } = await import("../completion-JKVTLZX7.js");
144
144
  handleCompletions(args[completionsIdx + 1], args[completionsIdx + 2]);
145
145
  process.exit(0);
146
146
  }
@@ -485,13 +485,24 @@ var API_LIST = [
485
485
  kebabName: "dashboard",
486
486
  title: "Dashboard API",
487
487
  serverUrl: "https://dashboard.sls.epilot.io",
488
- operationCount: 7,
488
+ operationCount: 18,
489
489
  operationIds: [
490
490
  "listDashboards",
491
491
  "createDashboard",
492
+ "listFavoriteDashboardIds",
493
+ "favoriteDashboard",
494
+ "unfavoriteDashboard",
492
495
  "getDashboard",
493
496
  "putDashboard",
497
+ "patchDashboard",
494
498
  "deleteDashboard",
499
+ "listInsights",
500
+ "createInsight",
501
+ "listInsightTags",
502
+ "getInsight",
503
+ "putInsight",
504
+ "patchInsight",
505
+ "deleteInsight",
495
506
  "listAvailableVisualisations",
496
507
  "listAvailableExamples"
497
508
  ]
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  API_LIST
4
- } from "./chunk-5Y4OYCNI.js";
4
+ } from "./chunk-CR6NZAXB.js";
5
5
  import {
6
6
  DIM,
7
7
  GREEN,
@@ -72,7 +72,7 @@ ${GREEN}${BOLD}Upgraded to @epilot/cli@${latest}${RESET}
72
72
  }
73
73
  });
74
74
  var getCurrentVersion = () => {
75
- if (true) return "0.1.99";
75
+ if (true) return "0.1.102";
76
76
  try {
77
77
  const output = execSync("npm ls -g @epilot/cli --depth=0 --json 2>/dev/null", {
78
78
  encoding: "utf-8",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epilot/cli",
3
- "version": "0.1.99",
3
+ "version": "0.1.102",
4
4
  "description": "CLI for epilot APIs",
5
5
  "type": "module",
6
6
  "bin": {