@epilot/cli 0.1.98 → 0.1.101

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.98 — CLI for epilot APIs
32
+ epilot v0.1.101 — 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",
@@ -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": [
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.0.3",
3
3
  "info": {
4
4
  "title": "Integration Toolkit API",
5
- "version": "1.8.0",
5
+ "version": "1.10.0",
6
6
  "description": "API for integrating with external systems in a standardised way."
7
7
  },
8
8
  "tags": [
@@ -3891,6 +3891,16 @@
3891
3891
  }
3892
3892
  }
3893
3893
  ],
3894
+ "requestBody": {
3895
+ "required": false,
3896
+ "content": {
3897
+ "application/json": {
3898
+ "schema": {
3899
+ "$ref": "#/components/schemas/ExecuteErpImportRequest"
3900
+ }
3901
+ }
3902
+ }
3903
+ },
3894
3904
  "responses": {
3895
3905
  "200": {
3896
3906
  "description": "Execution started",
@@ -3911,6 +3921,16 @@
3911
3921
  "409": {
3912
3922
  "$ref": "#/components/responses/Conflict"
3913
3923
  },
3924
+ "422": {
3925
+ "description": "The verdict carries warnings and `ack_warnings` was not true",
3926
+ "content": {
3927
+ "application/json": {
3928
+ "schema": {
3929
+ "$ref": "#/components/schemas/ErrorResponseBase"
3930
+ }
3931
+ }
3932
+ }
3933
+ },
3914
3934
  "500": {
3915
3935
  "$ref": "#/components/responses/InternalServerError"
3916
3936
  }
@@ -4005,6 +4025,57 @@
4005
4025
  }
4006
4026
  }
4007
4027
  },
4028
+ "ExecuteErpImportRequest": {
4029
+ "type": "object",
4030
+ "description": "Confirmation options. Required only when the verdict carries warnings — a clean import needs no body at all.",
4031
+ "properties": {
4032
+ "ack_warnings": {
4033
+ "type": "boolean",
4034
+ "description": "The caller has seen `validation.issues` and accepts them. Required when `validation.warnings` is greater than 0; ignored otherwise."
4035
+ }
4036
+ }
4037
+ },
4038
+ "ErpImportIssue": {
4039
+ "type": "object",
4040
+ "description": "A problem found during validation, scoped to the file as a whole rather than to individual rows. See `code` for the kinds reported.",
4041
+ "required": [
4042
+ "code",
4043
+ "severity",
4044
+ "message"
4045
+ ],
4046
+ "properties": {
4047
+ "code": {
4048
+ "type": "string",
4049
+ "description": "Enum of possible issue codes.\n",
4050
+ "enum": [
4051
+ "UNIQUE_ID_COLUMN_MISSING",
4052
+ "MAPPED_COLUMN_MISSING",
4053
+ "MALFORMED_ROW",
4054
+ "INVALID_ENCODING",
4055
+ "EMPTY_FILE",
4056
+ "TOO_MANY_ROWS"
4057
+ ]
4058
+ },
4059
+ "severity": {
4060
+ "type": "string",
4061
+ "enum": [
4062
+ "warning",
4063
+ "blocking"
4064
+ ]
4065
+ },
4066
+ "message": {
4067
+ "type": "string",
4068
+ "description": "User-facing explanation. Lists at most 10 column names; `columns` has all of them."
4069
+ },
4070
+ "columns": {
4071
+ "type": "array",
4072
+ "description": "The columns this issue is about, so clients render names rather than parsing the message.",
4073
+ "items": {
4074
+ "type": "string"
4075
+ }
4076
+ }
4077
+ }
4078
+ },
4008
4079
  "ErpImportValidation": {
4009
4080
  "type": "object",
4010
4081
  "description": "Validate-phase summary: what the file will create, and whether it may be confirmed. Absent until the validate phase completes. No per-row detail is kept — a rejected file is corrected and imported again.",
@@ -4031,6 +4102,13 @@
4031
4102
  "type": "integer"
4032
4103
  },
4033
4104
  "description": "Distinct entities the file expresses, keyed by entity slug."
4105
+ },
4106
+ "issues": {
4107
+ "type": "array",
4108
+ "description": "Whole-file issues. At most 20 are kept; the count of everything found is in blocking and warnings. Warnings here are what `ack_warnings` on `:execute` acknowledges.",
4109
+ "items": {
4110
+ "$ref": "#/components/schemas/ErpImportIssue"
4111
+ }
4034
4112
  }
4035
4113
  }
4036
4114
  },
@@ -4055,16 +4133,21 @@
4055
4133
  "type": "object",
4056
4134
  "description": "Why the import failed — present if and only if status = FAILED.",
4057
4135
  "required": [
4058
- "type",
4136
+ "code",
4059
4137
  "message"
4060
4138
  ],
4061
4139
  "properties": {
4062
- "type": {
4140
+ "code": {
4063
4141
  "type": "string",
4064
- "description": "VALIDATION_BLOCKED = blocking row issues (see `validation`); PROCESSING_ERROR = a named, deterministic failure — retrying the same file cannot help; INTERNAL_ERROR = crashed or never started, so retry.",
4142
+ "description": "Enum of possible error codes.\n",
4065
4143
  "enum": [
4066
4144
  "VALIDATION_BLOCKED",
4067
- "PROCESSING_ERROR",
4145
+ "FILE_FORMAT_UNSUPPORTED",
4146
+ "FILE_UNAVAILABLE",
4147
+ "VALIDATE_TIMEOUT",
4148
+ "IMPORT_TIMEOUT",
4149
+ "USE_CASE_NOT_USABLE",
4150
+ "IMPORT_NO_PROGRESS",
4068
4151
  "INTERNAL_ERROR"
4069
4152
  ]
4070
4153
  },
@@ -4125,7 +4208,7 @@
4125
4208
  },
4126
4209
  "status": {
4127
4210
  "type": "string",
4128
- "description": "PENDING → VALIDATING → READY → PROCESSING → IMPORTED, with FAILED reachable from any working status, and CANCELLING → CANCELLED reachable from VALIDATING or PROCESSING via :abort. IMPORTED, FAILED and CANCELLED are terminal and final.\nIMPORTED means every row was handed to the platform, not that the platform finished — per-row outcomes live in monitoring, filtered by correlation_id. A file that fails validation is FAILED with error.type = VALIDATION_BLOCKED.\nREADY is legitimately idle for as long as the user takes to confirm, so it carries no running work and never goes stale.\nCANCELLING is transient and cooperative: the abort has been recorded but the worker only notices at its next batch boundary. Rows already published stay published — a stop is not a rollback.",
4211
+ "description": "PENDING → VALIDATING → READY → PROCESSING → IMPORTED, with FAILED reachable from any working status, and CANCELLING → CANCELLED reachable from VALIDATING or PROCESSING via :abort. IMPORTED, FAILED and CANCELLED are terminal and final.\nIMPORTED means every row was handed to the platform, not that the platform finished — per-row outcomes live in monitoring, filtered by correlation_id. A file that fails validation is FAILED with error.code = VALIDATION_BLOCKED.\nREADY is legitimately idle for as long as the user takes to confirm, so it carries no running work and never goes stale.\nCANCELLING is transient and cooperative: the abort has been recorded but the worker only notices at its next batch boundary. Rows already published stay published — a stop is not a rollback.",
4129
4212
  "enum": [
4130
4213
  "PENDING",
4131
4214
  "VALIDATING",
@@ -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.98",
14
+ version: "0.1.101",
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-S2DSGM2Z.js").then((m) => m.default),
33
+ completion: () => import("../completion-JKVTLZX7.js").then((m) => m.default),
34
+ upgrade: () => import("../upgrade-SWIOU3HC.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.98" : (await null).default.version;
137
+ var VERSION = true ? "0.1.101" : (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.98";
75
+ if (true) return "0.1.101";
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.98",
3
+ "version": "0.1.101",
4
4
  "description": "CLI for epilot APIs",
5
5
  "type": "module",
6
6
  "bin": {