@epilot/cli 0.1.118 → 0.1.120

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.118 — CLI for epilot APIs
32
+ epilot v0.1.120 — CLI for epilot APIs
33
33
 
34
34
  USAGE
35
35
  epilot <api> <operationId> [params...] [flags]
@@ -1008,6 +1008,17 @@
1008
1008
  "type": "string",
1009
1009
  "description": "Optional unit of the consumption value. Defaults to unit present on the relevant Meter Counter.",
1010
1010
  "example": "kWh"
1011
+ },
1012
+ "label": {
1013
+ "type": "object",
1014
+ "additionalProperties": {
1015
+ "type": "string"
1016
+ },
1017
+ "description": "Optional localized label for this individual value, keyed by ISO 3166-1 alpha-2 language code (same shape as `VisualizationTypeOption.label`). When present, the portal renders it as the data point label instead of the default timestamp-derived label (e.g. to name billing periods or tariff windows).\n",
1018
+ "example": {
1019
+ "en": "Billing period 1",
1020
+ "de": "Abrechnungszeitraum 1"
1021
+ }
1011
1022
  }
1012
1023
  },
1013
1024
  "required": [
@@ -7213,8 +7224,8 @@
7213
7224
  "in": "query",
7214
7225
  "schema": {
7215
7226
  "type": "string",
7216
- "description": "Key to sort by",
7217
- "example": "due_date:asc"
7227
+ "description": "Key to sort by. Pass a comma-separated list to apply additional keys as tiebreakers, in order of precedence.",
7228
+ "example": "paid_date:desc,booking_date:desc"
7218
7229
  }
7219
7230
  }
7220
7231
  ],
@@ -8031,6 +8042,58 @@
8031
8042
  }
8032
8043
  }
8033
8044
  },
8045
+ "/v2/portal/engagement/tasks": {
8046
+ "get": {
8047
+ "operationId": "getOutstandingTasks",
8048
+ "summary": "Get outstanding workflow tasks for the portal user",
8049
+ "description": "Returns all outstanding workflow journey tasks for the authenticated portal user, across their opportunity, order and contract entities. Each task is an active workflow step that exposes a journey the customer still needs to fill out.",
8050
+ "tags": [
8051
+ "ECP"
8052
+ ],
8053
+ "security": [
8054
+ {
8055
+ "PortalAuth": []
8056
+ }
8057
+ ],
8058
+ "responses": {
8059
+ "200": {
8060
+ "description": "List of outstanding workflow tasks for the portal user",
8061
+ "content": {
8062
+ "application/json": {
8063
+ "schema": {
8064
+ "type": "object",
8065
+ "required": [
8066
+ "tasks",
8067
+ "total"
8068
+ ],
8069
+ "properties": {
8070
+ "tasks": {
8071
+ "type": "array",
8072
+ "items": {
8073
+ "$ref": "#/components/schemas/OutstandingTask"
8074
+ }
8075
+ },
8076
+ "total": {
8077
+ "type": "integer",
8078
+ "example": 0
8079
+ }
8080
+ }
8081
+ }
8082
+ }
8083
+ }
8084
+ },
8085
+ "401": {
8086
+ "$ref": "#/components/responses/Unauthorized"
8087
+ },
8088
+ "403": {
8089
+ "$ref": "#/components/responses/Forbidden"
8090
+ },
8091
+ "500": {
8092
+ "$ref": "#/components/responses/InternalServerError"
8093
+ }
8094
+ }
8095
+ }
8096
+ },
8034
8097
  "/v2/portal/entity/{slug}/{id}/workflows/linearized": {
8035
8098
  "get": {
8036
8099
  "operationId": "getEntityPortalWorkflows",
@@ -9881,6 +9944,192 @@
9881
9944
  }
9882
9945
  }
9883
9946
  },
9947
+ "/v2/portal/notifications": {
9948
+ "get": {
9949
+ "operationId": "listPortalNotifications",
9950
+ "summary": "listPortalNotifications",
9951
+ "description": "Lists the 360 notifications addressed to the authenticated portal user, newest first. The organization and the portal user are derived from the authenticated session, so a user can only ever read their own notifications.",
9952
+ "tags": [
9953
+ "ECP"
9954
+ ],
9955
+ "security": [
9956
+ {
9957
+ "PortalAuth": []
9958
+ }
9959
+ ],
9960
+ "parameters": [
9961
+ {
9962
+ "in": "query",
9963
+ "name": "cursor",
9964
+ "required": false,
9965
+ "schema": {
9966
+ "type": "string"
9967
+ },
9968
+ "description": "Base64 encoded cursor returned by a previous call, used for pagination."
9969
+ },
9970
+ {
9971
+ "in": "query",
9972
+ "name": "limit",
9973
+ "required": false,
9974
+ "schema": {
9975
+ "type": "integer"
9976
+ },
9977
+ "description": "The maximum number of notifications to return."
9978
+ }
9979
+ ],
9980
+ "responses": {
9981
+ "200": {
9982
+ "description": "List of notifications for the authenticated portal user.",
9983
+ "content": {
9984
+ "application/json": {
9985
+ "schema": {
9986
+ "type": "object",
9987
+ "properties": {
9988
+ "cursor": {
9989
+ "type": "string",
9990
+ "description": "Base64 encoded cursor to fetch the next page. Absent when there are no more results."
9991
+ },
9992
+ "total_unread": {
9993
+ "type": "integer",
9994
+ "description": "Total number of unread notifications for the user."
9995
+ },
9996
+ "results": {
9997
+ "type": "array",
9998
+ "items": {
9999
+ "$ref": "#/components/schemas/PortalNotification"
10000
+ }
10001
+ }
10002
+ }
10003
+ }
10004
+ }
10005
+ }
10006
+ },
10007
+ "401": {
10008
+ "$ref": "#/components/responses/Unauthorized"
10009
+ },
10010
+ "403": {
10011
+ "$ref": "#/components/responses/Forbidden"
10012
+ },
10013
+ "500": {
10014
+ "$ref": "#/components/responses/InternalServerError"
10015
+ }
10016
+ }
10017
+ }
10018
+ },
10019
+ "/v2/portal/notifications/unread-count": {
10020
+ "get": {
10021
+ "operationId": "getPortalNotificationsUnreadCount",
10022
+ "summary": "getPortalNotificationsUnreadCount",
10023
+ "description": "Returns the number of unread notifications for the authenticated portal user.",
10024
+ "tags": [
10025
+ "ECP"
10026
+ ],
10027
+ "security": [
10028
+ {
10029
+ "PortalAuth": []
10030
+ }
10031
+ ],
10032
+ "responses": {
10033
+ "200": {
10034
+ "description": "Unread notification count.",
10035
+ "content": {
10036
+ "application/json": {
10037
+ "schema": {
10038
+ "type": "object",
10039
+ "properties": {
10040
+ "count": {
10041
+ "type": "integer",
10042
+ "example": 3
10043
+ }
10044
+ }
10045
+ }
10046
+ }
10047
+ }
10048
+ },
10049
+ "401": {
10050
+ "$ref": "#/components/responses/Unauthorized"
10051
+ },
10052
+ "403": {
10053
+ "$ref": "#/components/responses/Forbidden"
10054
+ },
10055
+ "500": {
10056
+ "$ref": "#/components/responses/InternalServerError"
10057
+ }
10058
+ }
10059
+ }
10060
+ },
10061
+ "/v2/portal/notifications/read-all": {
10062
+ "put": {
10063
+ "operationId": "markAllPortalNotificationsRead",
10064
+ "summary": "markAllPortalNotificationsRead",
10065
+ "description": "Marks all notifications of the authenticated portal user as read.",
10066
+ "tags": [
10067
+ "ECP"
10068
+ ],
10069
+ "security": [
10070
+ {
10071
+ "PortalAuth": []
10072
+ }
10073
+ ],
10074
+ "responses": {
10075
+ "204": {
10076
+ "description": "All notifications marked as read."
10077
+ },
10078
+ "401": {
10079
+ "$ref": "#/components/responses/Unauthorized"
10080
+ },
10081
+ "403": {
10082
+ "$ref": "#/components/responses/Forbidden"
10083
+ },
10084
+ "500": {
10085
+ "$ref": "#/components/responses/InternalServerError"
10086
+ }
10087
+ }
10088
+ }
10089
+ },
10090
+ "/v2/portal/notifications/{id}/read": {
10091
+ "put": {
10092
+ "operationId": "markPortalNotificationRead",
10093
+ "summary": "markPortalNotificationRead",
10094
+ "description": "Marks a single notification of the authenticated portal user as read.",
10095
+ "tags": [
10096
+ "ECP"
10097
+ ],
10098
+ "security": [
10099
+ {
10100
+ "PortalAuth": []
10101
+ }
10102
+ ],
10103
+ "parameters": [
10104
+ {
10105
+ "in": "path",
10106
+ "name": "id",
10107
+ "required": true,
10108
+ "schema": {
10109
+ "type": "integer"
10110
+ },
10111
+ "description": "Numeric id of the notification to mark as read."
10112
+ }
10113
+ ],
10114
+ "responses": {
10115
+ "204": {
10116
+ "description": "Notification marked as read."
10117
+ },
10118
+ "400": {
10119
+ "$ref": "#/components/responses/InvalidRequest"
10120
+ },
10121
+ "401": {
10122
+ "$ref": "#/components/responses/Unauthorized"
10123
+ },
10124
+ "403": {
10125
+ "$ref": "#/components/responses/Forbidden"
10126
+ },
10127
+ "500": {
10128
+ "$ref": "#/components/responses/InternalServerError"
10129
+ }
10130
+ }
10131
+ }
10132
+ },
9884
10133
  "/v2/portal/notifications/entity:status": {
9885
10134
  "put": {
9886
10135
  "operationId": "updateNotificationsStatus",
@@ -10547,13 +10796,6 @@
10547
10796
  "type": "string",
10548
10797
  "description": "Email address of the partner to invite"
10549
10798
  },
10550
- "represents_contact_list": {
10551
- "type": "array",
10552
- "items": {
10553
- "$ref": "#/components/schemas/EntityId",
10554
- "description": "List of contact IDs representing the contacts / business partners the invited user should be added to.\nWhen omitted, the user is automatically added to all contacts / business partners linked to the account.\n"
10555
- }
10556
- },
10557
10799
  "contact_data": {
10558
10800
  "type": "object",
10559
10801
  "description": "Additional contact entity fields to set when creating the contact for the invited user.\nThese are mapped directly to contact entity attributes (e.g. first_name, last_name, phone).\nValues can be strings or arrays of strings (for multiselect attributes).\n",
@@ -11404,6 +11646,69 @@
11404
11646
  }
11405
11647
  },
11406
11648
  "schemas": {
11649
+ "PortalNotification": {
11650
+ "type": "object",
11651
+ "description": "A 360 notification addressed to a portal user.",
11652
+ "required": [
11653
+ "id",
11654
+ "read"
11655
+ ],
11656
+ "properties": {
11657
+ "id": {
11658
+ "type": "string",
11659
+ "description": "Stable string identifier of the notification (the numeric notification id as a string).",
11660
+ "example": "1234567890"
11661
+ },
11662
+ "notification_id": {
11663
+ "type": "number",
11664
+ "description": "Numeric id of the notification, used to mark it as read.",
11665
+ "example": 1234567890
11666
+ },
11667
+ "type": {
11668
+ "type": "string",
11669
+ "description": "Type of notification.",
11670
+ "example": "workflow_step_overdue"
11671
+ },
11672
+ "title": {
11673
+ "type": "object",
11674
+ "description": "Localized, already-rendered notification title.",
11675
+ "properties": {
11676
+ "en": {
11677
+ "type": "string"
11678
+ },
11679
+ "de": {
11680
+ "type": "string"
11681
+ }
11682
+ }
11683
+ },
11684
+ "message": {
11685
+ "type": "object",
11686
+ "description": "Localized, already-rendered notification message.",
11687
+ "properties": {
11688
+ "en": {
11689
+ "type": "string"
11690
+ },
11691
+ "de": {
11692
+ "type": "string"
11693
+ }
11694
+ }
11695
+ },
11696
+ "created_at": {
11697
+ "type": "string",
11698
+ "format": "date-time",
11699
+ "description": "When the notification was created."
11700
+ },
11701
+ "read": {
11702
+ "type": "boolean",
11703
+ "description": "Whether the notification has been read by the user.",
11704
+ "example": false
11705
+ },
11706
+ "redirect_url": {
11707
+ "type": "string",
11708
+ "description": "Optional URL the notification points to."
11709
+ }
11710
+ }
11711
+ },
11407
11712
  "MobileBuildStatus": {
11408
11713
  "type": "object",
11409
11714
  "description": "Latest build/upload status for a platform (system-written).",
@@ -12719,6 +13024,45 @@
12719
13024
  "additionalProperties": {
12720
13025
  "$ref": "#/components/schemas/Block"
12721
13026
  }
13027
+ },
13028
+ "notification_triggers": {
13029
+ "type": "array",
13030
+ "description": "Configures which 360 events generate an in-app notification for the portal user. Each enabled trigger renders the referenced notification template and creates a notification addressed to the portal user. Admin/builder-only — never exposed via the public portal config.",
13031
+ "items": {
13032
+ "$ref": "#/components/schemas/NotificationTriggerConfig"
13033
+ }
13034
+ }
13035
+ }
13036
+ },
13037
+ "NotificationTriggerConfig": {
13038
+ "type": "object",
13039
+ "required": [
13040
+ "trigger_type"
13041
+ ],
13042
+ "properties": {
13043
+ "trigger_type": {
13044
+ "type": "string",
13045
+ "description": "The 360 event that fires this notification trigger.",
13046
+ "enum": [
13047
+ "entity_created",
13048
+ "entity_assigned",
13049
+ "workflow_step_overdue"
13050
+ ]
13051
+ },
13052
+ "entity_schema": {
13053
+ "type": "string",
13054
+ "description": "For `entity_created` / `entity_assigned` triggers, the entity schema slug (e.g. `opportunity`, `order`) whose creation or assignment fires this trigger. Ignored for other trigger types.",
13055
+ "example": "opportunity"
13056
+ },
13057
+ "enabled": {
13058
+ "type": "boolean",
13059
+ "description": "Whether this trigger is active.",
13060
+ "default": true
13061
+ },
13062
+ "template_id": {
13063
+ "type": "string",
13064
+ "format": "uuid",
13065
+ "description": "Entity id of the notification_template to render for this trigger."
12722
13066
  }
12723
13067
  }
12724
13068
  },
@@ -14509,6 +14853,14 @@
14509
14853
  "is_new": {
14510
14854
  "type": "boolean",
14511
14855
  "description": "Indicate whether the user has not seen/downloaded the file before"
14856
+ },
14857
+ "custom_download_url_auth": {
14858
+ "type": "string",
14859
+ "enum": [
14860
+ "token",
14861
+ "presigned"
14862
+ ],
14863
+ "description": "Authorization mode of an externally hosted file's download url. `presigned` (the default) means `public_url` is HMAC-signed and needs no auth header; `token` means it authorizes the caller's bearer token instead and must be fetched with an `Authorization` header. Because `presigned` is the default, the absence of this property does NOT prove the file is stored in epilot — an external file may omit it."
14512
14864
  }
14513
14865
  }
14514
14866
  }
@@ -14534,6 +14886,10 @@
14534
14886
  "format": "uri",
14535
14887
  "description": "A Content-Disposition: inline URL to render in a preview viewer. Present only when kind is \"pdf\" or \"image\". Short-lived — do not cache across dialog opens."
14536
14888
  },
14889
+ "requires_auth": {
14890
+ "type": "boolean",
14891
+ "description": "When true, `url` only answers to the portal user's bearer token: fetch the bytes with an `Authorization: Bearer <token>` header and render them from an object URL. Only ever set for URLs on an allow-listed ERP file-proxy host."
14892
+ },
14537
14893
  "download_url": {
14538
14894
  "type": "string",
14539
14895
  "format": "uri",
@@ -14786,6 +15142,57 @@
14786
15142
  "link"
14787
15143
  ]
14788
15144
  },
15145
+ "OutstandingTask": {
15146
+ "type": "object",
15147
+ "required": [
15148
+ "entity_id",
15149
+ "entity_schema",
15150
+ "entity_title",
15151
+ "workflow_id",
15152
+ "workflow_name",
15153
+ "step_id",
15154
+ "step_name",
15155
+ "journey_id"
15156
+ ],
15157
+ "properties": {
15158
+ "entity_id": {
15159
+ "type": "string",
15160
+ "description": "ID of the entity the task belongs to"
15161
+ },
15162
+ "entity_schema": {
15163
+ "type": "string",
15164
+ "description": "Schema slug of the entity (opportunity, order or contract)"
15165
+ },
15166
+ "entity_title": {
15167
+ "type": "string",
15168
+ "description": "Title (_title) of the entity"
15169
+ },
15170
+ "workflow_id": {
15171
+ "type": "string",
15172
+ "description": "Workflow execution id"
15173
+ },
15174
+ "workflow_name": {
15175
+ "type": "string",
15176
+ "description": "Workflow execution / template name"
15177
+ },
15178
+ "step_id": {
15179
+ "type": "string",
15180
+ "description": "Task (step) id within the workflow execution"
15181
+ },
15182
+ "step_name": {
15183
+ "type": "string",
15184
+ "description": "Task (step) name"
15185
+ },
15186
+ "journey_id": {
15187
+ "type": "string",
15188
+ "description": "Journey id the customer needs to fill out"
15189
+ },
15190
+ "complete_task_automatically": {
15191
+ "type": "boolean",
15192
+ "description": "Whether submitting the journey from the portal should auto-complete the task. When false, an internal user completes it."
15193
+ }
15194
+ }
15195
+ },
14789
15196
  "WorkflowExecution": {
14790
15197
  "type": "object",
14791
15198
  "properties": {},
@@ -18237,7 +18644,8 @@
18237
18644
  },
18238
18645
  "token_endpoint": {
18239
18646
  "type": "string",
18240
- "description": "URL of the authorization endpoint",
18647
+ "deprecated": true,
18648
+ "description": "Deprecated and ignored; the token endpoint is derived server-side from the provider config.",
18241
18649
  "example": "https://www.facebook.com/v12.0/dialog/oauth"
18242
18650
  },
18243
18651
  "grant_type": {
@@ -585,7 +585,7 @@
585
585
  "post": {
586
586
  "operationId": "getUnreadCounts",
587
587
  "summary": "getUnreadCounts",
588
- "description": "Unread counts for several named scopes in one request.\n\nA scope is a name plus the same parameters the thread list already takes (`q`, `inbox_id`),\nso a scope's count and the list beneath it are the same predicate and agree by construction.\nThe server adds only the read-state condition; it does not re-author the caller's view.\n\nThe `organization` scope is the exception and takes no `q`: it reuses the four canonical\ncentral-inbox queries, so its numbers match `getUnread` exactly.\n\nBuckets are not symmetric, across scope types or across actors. Every scope other than\n`organization` returns `unread` alone. The `organization` scope returns all four\n(`unread`, `drafts`, `unassigned`, `spam`) for `actor: organization`, and only `unread` and\n`drafts` for `actor: user` the agent sidebar has no Spam or Unlinked folder, so those two\nnumbers have nowhere to render and each one costs a cardinality aggregation. This is a\ndeliberate divergence from `getUnread`, which computes all four for both actors.\n\nGated on the `message-unread-counts` flag, evaluated once per request against the calling\norg. With the flag off the response is `{ \"enabled\": false, \"counts\": {} }` and no\nElasticsearch query is issued.\n",
588
+ "description": "Unread counts for several named scopes in one request.\n\nA scope is a name plus the same parameters the thread list already takes (`q`, `inbox_id`),\nso a scope's count and the list beneath it are the same predicate and agree by construction.\nThe server adds only the read-state condition; it does not re-author the caller's view.\n\nThe `organization` scope is the exception and takes no `q`: it reuses the four canonical\ncentral-inbox queries, so its numbers match `getUnread` exactly.\n\nWhich buckets come back varies by scope type and actor. Every scope other than `organization`\nreturns `unread` alone. An `organization` scope returns all four (`unread`, `drafts`,\n`unassigned`, `spam`) for `actor: organization`, and `unread` and `drafts` only for\n`actor: user`. `getUnread` returns all four for both actors; this endpoint omits the two that\nno per-user surface renders, since each costs an aggregation.\n\nGated on the `message-unread-counts` flag, evaluated once per request against the calling\norg. With the flag off the response is `{ \"enabled\": false, \"counts\": {} }` and no\nElasticsearch query is issued.\n",
589
589
  "tags": [
590
590
  "Messages"
591
591
  ],
@@ -611,7 +611,7 @@
611
611
  }
612
612
  },
613
613
  "400": {
614
- "description": "The request names more scopes than the cap allows, repeats a scope name, or omits `q`\non a scope type that requires it. Over-cap requests are refused rather than truncated:\na silently dropped scope renders as a missing badge, which is indistinguishable from\nzero unread.\n"
614
+ "description": "The request names more scopes than the cap allows, repeats a scope name, or omits both\n`q` and `view` on a scope type that needs a predicate. Over-cap requests are refused rather than truncated:\na silently dropped scope renders as a missing badge, which is indistinguishable from\nzero unread.\n"
615
615
  },
616
616
  "403": {
617
617
  "description": "Forbidden"
@@ -832,7 +832,7 @@
832
832
  "post": {
833
833
  "operationId": "getAssigneeWorkload",
834
834
  "summary": "getAssigneeWorkload",
835
- "description": "Return the open-thread workload for a set of user ids.\n\nFor each requested user id, returns the number of *open* threads assigned\ndirectly to that user matching what the user sees in their central-inbox\nopen view: in inbox, not trashed, not done, and excluding notification-only\nand spam threads.\n\nOnly threads assigned directly to a user are counted; threads assigned to a\ngroup the user belongs to are not. Intended for assignment load-balancing\n(e.g. even-distribution automations) that need a consistent, inbox-aligned\nworkload per user.\n",
835
+ "description": "Return the open-thread workload for a set of user ids.\n\nFor each requested user id, returns the number of *open* threads assigned\ndirectly to that user \u2014 matching what the user sees in their central-inbox\nopen view: in inbox, not trashed, not done, and excluding notification-only\nand spam threads.\n\nOnly threads assigned directly to a user are counted; threads assigned to a\ngroup the user belongs to are not. Intended for assignment load-balancing\n(e.g. even-distribution automations) that need a consistent, inbox-aligned\nworkload per user.\n",
836
836
  "tags": [
837
837
  "Threads"
838
838
  ],
@@ -2695,6 +2695,117 @@
2695
2695
  }
2696
2696
  }
2697
2697
  },
2698
+ "ThreadView": {
2699
+ "type": "object",
2700
+ "additionalProperties": true,
2701
+ "description": "A central-inbox view, described structurally so the server compiles the query for it. Both the\nthread list and the unread count for a view are compiled from the same description, so the two\ncannot disagree about what the view means.\n\nEvery field is optional and an omitted field adds no condition, so a view narrows the whole\nmailbox rather than being a template with required holes. Unknown fields are ignored.\n",
2702
+ "properties": {
2703
+ "folder": {
2704
+ "type": "string",
2705
+ "enum": [
2706
+ "inbox",
2707
+ "favorite",
2708
+ "sent",
2709
+ "trash",
2710
+ "spam",
2711
+ "unassignable",
2712
+ "draft"
2713
+ ],
2714
+ "description": "Which sidebar folder's membership predicate to apply."
2715
+ },
2716
+ "mailbox": {
2717
+ "type": "string",
2718
+ "enum": [
2719
+ "organization",
2720
+ "agent"
2721
+ ],
2722
+ "description": "Whose mailbox this is. `agent` scopes to threads assigned to the caller or their groups;\n`organization` scopes to the org and is the only mailbox that carries address filtering.\n"
2723
+ },
2724
+ "labels": {
2725
+ "type": "array",
2726
+ "items": {
2727
+ "type": "string"
2728
+ },
2729
+ "description": "Saved-filter labels, ANDed. Matched exactly against the tag rather than against its\ntokens, so a label whose words overlap a folder tag no longer lands in that folder.\n"
2730
+ },
2731
+ "purposes": {
2732
+ "type": "array",
2733
+ "items": {
2734
+ "type": "string"
2735
+ },
2736
+ "description": "Purpose ids on linked entities, ANDed."
2737
+ },
2738
+ "filters": {
2739
+ "type": "array",
2740
+ "items": {
2741
+ "type": "string",
2742
+ "enum": [
2743
+ "unread",
2744
+ "resolved",
2745
+ "trash"
2746
+ ]
2747
+ },
2748
+ "description": "State filters, independent of the folder. `resolved` and `trash` reach the Inbox folder\nonly and are mutually exclusive there; `unread` applies anywhere.\n"
2749
+ },
2750
+ "from": {
2751
+ "type": "array",
2752
+ "items": {
2753
+ "type": "string"
2754
+ },
2755
+ "description": "Sender addresses to filter on."
2756
+ },
2757
+ "to": {
2758
+ "type": "array",
2759
+ "items": {
2760
+ "type": "string"
2761
+ },
2762
+ "description": "Recipient addresses to filter on."
2763
+ },
2764
+ "assigned_to": {
2765
+ "type": "array",
2766
+ "items": {
2767
+ "type": "string"
2768
+ },
2769
+ "description": "Assignee user ids."
2770
+ },
2771
+ "include_unassigned": {
2772
+ "type": "boolean",
2773
+ "description": "Whether threads with no assignee join the `assigned_to` set. A separate flag rather than a\nsentinel entry in that list, so `assigned_to` holds user ids and nothing else.\n"
2774
+ },
2775
+ "date_from_days_ago": {
2776
+ "type": "integer",
2777
+ "minimum": 0,
2778
+ "description": "Lower bound of the date range, in days before now. Omitted means the epoch."
2779
+ },
2780
+ "date_to_days_ago": {
2781
+ "type": "integer",
2782
+ "minimum": 0,
2783
+ "description": "Upper bound of the date range, in days before now. Omitted means now."
2784
+ },
2785
+ "email_filter": {
2786
+ "type": "array",
2787
+ "items": {
2788
+ "type": "string"
2789
+ },
2790
+ "description": "Addresses the user selected in the address filter. Absent and empty differ, and the\ndifference is a real UI state: absent is \"not filtering by address\", empty is \"every\naddress deselected\", which matches nothing.\n\nDistinct from the permission restriction, which the server derives and a caller cannot\nauthor.\n"
2791
+ },
2792
+ "text": {
2793
+ "type": "string",
2794
+ "description": "The user's search string, as typed. Expanded across the searched fields server-side and\nnever interpreted as query syntax, so a typed operator or a stray bracket cannot\nre-associate the predicate around it.\n"
2795
+ },
2796
+ "thread_ids": {
2797
+ "type": "array",
2798
+ "items": {
2799
+ "type": "string"
2800
+ },
2801
+ "description": "Restrict the view to these threads. Exists because \"would this thread appear in the view\nthe user is looking at?\" is a real question the inbox asks when a new thread arrives, and\nit is a membership test against the view rather than a different view.\n"
2802
+ },
2803
+ "pinned_by": {
2804
+ "type": "string",
2805
+ "description": "Restrict the view to threads this user pinned. The pinned strip above the list is the same\nview with this one extra condition.\n"
2806
+ }
2807
+ }
2808
+ },
2698
2809
  "UnreadCountScope": {
2699
2810
  "type": "object",
2700
2811
  "required": [
@@ -2714,13 +2825,18 @@
2714
2825
  "shared_inbox",
2715
2826
  "saved_view"
2716
2827
  ],
2717
- "description": "Decides which buckets come back, and whether `q` is required. `organization` returns all\nfour buckets from the canonical central-inbox queries and takes no `q`. `shared_inbox`\nand `saved_view` return `unread` alone and require the `q` their list uses.\n\nA `shared_inbox` scope additionally requires `actor: organization` and is refused with a\n400 otherwise. A shared inbox is an organization-level construct selecting one always\nswitches the mailbox to the organization so it has no per-user read state and the\ncombination would compute a number no surface renders. `saved_view` accepts either actor,\nbecause a view's own configuration names its mailbox.\n"
2828
+ "description": "Decides which buckets come back, and whether `q` is required. `organization` returns all\nfour buckets from the canonical central-inbox queries and takes no `q`. `shared_inbox`\nand `saved_view` return `unread` alone. A `saved_view` scope names its view with `view_id`;\na `shared_inbox` scope needs only its `inbox_id`, since the query follows from the type.\n\nA `shared_inbox` scope additionally requires `actor: organization` and is refused with a\n400 otherwise. A shared inbox is an organization-level construct \u2014 selecting one always\nswitches the mailbox to the organization \u2014 so it has no per-user read state and the\ncombination would compute a number no surface renders. `saved_view` accepts either actor,\nbecause a view's own configuration names its mailbox.\n"
2718
2829
  },
2719
2830
  "q": {
2720
2831
  "type": "string",
2721
- "description": "The scope's own list predicate, in Lucene syntax, exactly as the caller passes it to\n`threads:search`. Required for `shared_inbox` and `saved_view`, rejected for\n`organization`. The server ANDs the read-state condition onto it and nothing else, which\nis what makes the count and the list agree. Until the predicate definition moves\nserver-side, this is the caller's authored copy.\n",
2832
+ "description": "The scope's query, in Lucene syntax, as passed to `threads:search` for the same scope. The\nserver adds the read-state condition and nothing else, so the count matches that list.\n\nAccepted for `shared_inbox` and `saved_view`; rejected for `organization`.\n\nSuperseded by server-side compilation. It remains accepted for callers whose counts are\nenabled while compilation is not, and is ignored when compilation is enabled. It will be\nremoved once compilation is enabled everywhere counts are.\n",
2722
2833
  "example": "_tags.keyword:inbox AND !_tags.keyword:trash"
2723
2834
  },
2835
+ "view_id": {
2836
+ "type": "string",
2837
+ "description": "The id of the saved view this scope counts. The server reads that view and compiles the same\nquery the thread list runs for it, so the count and the list cannot describe the view\ndifferently.\n\nRequired for `saved_view` scopes unless `q` is supplied instead; rejected for the other two\ntypes. A `shared_inbox` scope needs no predicate field at all, because its query follows from\nthe type and its `inbox_id`. An `organization` scope uses the canonical folder queries.\n\nThe view's own shared-inbox filter is read from the stored view, so `inbox_id` need not be\nsent alongside this.\n\nCompilation is enabled per organization by the `message-unread-unified-predicate` feature\nflag. While it is off, a scope supplying only a `view_id` has no query to run and its name is\nreturned in `omitted` rather than counted. A named view that this organization does not have,\nor whose stored configuration cannot be read, is omitted the same way.\n",
2838
+ "example": "3f34ce73-089c-4d45-a5ee-c161234e41c3"
2839
+ },
2724
2840
  "inbox_id": {
2725
2841
  "description": "Shared inbox ids, resolved to bucket ids the same way `threads:search` resolves them.",
2726
2842
  "oneOf": [
@@ -2751,7 +2867,7 @@
2751
2867
  "organization",
2752
2868
  "user"
2753
2869
  ],
2754
- "description": "Which read state to count against the org's or the calling user's. Same meaning as\n`getUnread`'s path parameter, and unrelated to a scope's `type`.\n"
2870
+ "description": "Which read state to count against \u2014 the org's or the calling user's. Same meaning as\n`getUnread`'s path parameter, and unrelated to a scope's `type`.\n"
2755
2871
  },
2756
2872
  "email_filter": {
2757
2873
  "type": "array",
@@ -2760,6 +2876,13 @@
2760
2876
  },
2761
2877
  "description": "Restrict every scope to messages involving these addresses."
2762
2878
  },
2879
+ "user_groups": {
2880
+ "type": "array",
2881
+ "items": {
2882
+ "type": "string"
2883
+ },
2884
+ "description": "The caller's group ids, as `group_<id>`, with the same meaning and constraints as on\n`threads:search`. Read only when a scope carries a `view`. Entries not matching\n`group_<id>` are dropped. Not an authorization input.\n"
2885
+ },
2763
2886
  "scopes": {
2764
2887
  "type": "array",
2765
2888
  "minItems": 1,
@@ -2791,7 +2914,7 @@
2791
2914
  },
2792
2915
  "omitted": {
2793
2916
  "type": "array",
2794
- "description": "Names of scopes that were accepted but could not be counted today, a shared inbox whose\nids matched no bucket in this org. Listed explicitly so a caller can tell an omission apart\nfrom a mis-spelled scope name, both of which are otherwise just a missing key in `counts`.\n",
2917
+ "description": "Names of scopes that were accepted but could not be counted. Each appears here and is\nabsent from `counts`, so an omission is distinguishable from a mis-spelled scope name.\n\nCauses, not distinguishable from this field: a `shared_inbox` scope whose ids matched no\nbucket in the organization; a scope with no query to run because compilation is disabled for\nthe organization and no `q` was supplied; and a `view_id` naming a view this organization\ndoes not have or whose stored configuration cannot be read.\n",
2795
2918
  "items": {
2796
2919
  "type": "string"
2797
2920
  }
@@ -2827,9 +2950,6 @@
2827
2950
  },
2828
2951
  "SearchParamsV2": {
2829
2952
  "type": "object",
2830
- "required": [
2831
- "q"
2832
- ],
2833
2953
  "properties": {
2834
2954
  "inbox_id": {
2835
2955
  "oneOf": [
@@ -2852,10 +2972,25 @@
2852
2972
  ]
2853
2973
  },
2854
2974
  "q": {
2855
- "description": "Lucene query syntax supported with ElasticSearch",
2975
+ "description": "Lucene query syntax supported with ElasticSearch.\n\nSend this or `view`, not both. At least one is required; a request with neither is refused\nwith a 400. An empty string is accepted and returns no hits.\n",
2856
2976
  "type": "string",
2857
2977
  "example": "subject:\"Request for solar panel price\" AND _tags:INBOX"
2858
2978
  },
2979
+ "view": {
2980
+ "allOf": [
2981
+ {
2982
+ "$ref": "#/components/schemas/ThreadView"
2983
+ }
2984
+ ],
2985
+ "description": "A view for the server to compile into the query, instead of supplying `q`. When a view is\npresent and compilation is enabled for the calling organization, the compiled query runs and\n`q` is not consulted.\n\nRead by `threads:search` and `threads:searchIds` only. This schema is shared with\n`messages:search`, which compiles no view and ignores the field, so a request there must\nsupply `q`.\n\nCompilation is enabled per organization by the `message-unread-unified-predicate` feature\nflag. While it is off, `q` runs and a request supplying only a view returns no hits.\n"
2986
+ },
2987
+ "user_groups": {
2988
+ "type": "array",
2989
+ "items": {
2990
+ "type": "string"
2991
+ },
2992
+ "description": "The caller's group ids, as `group_<id>`. Read only when a `view` is compiled, where they\ndetermine the agent mailbox's assignee condition and which shared inboxes, and therefore\nwhich addresses, are reachable. Required for those conditions to be correct, because group\nmembership is not present on the id token this service parses.\n\nEntries not matching `group_<id>` are dropped.\n\nNot an authorization input, and not treated as one: naming groups the caller is not in\nwidens what the response includes, exactly as supplying a broader `q` does. Access control\nis enforced elsewhere.\n"
2993
+ },
2859
2994
  "fields": {
2860
2995
  "$ref": "#/components/schemas/FieldsParam"
2861
2996
  },
@@ -2913,6 +3048,21 @@
2913
3048
  "SearchIDParams": {
2914
3049
  "type": "object",
2915
3050
  "properties": {
3051
+ "view": {
3052
+ "allOf": [
3053
+ {
3054
+ "$ref": "#/components/schemas/ThreadView"
3055
+ }
3056
+ ],
3057
+ "description": "The view to compile, with the same meaning as on `threads:search`. Present here because\nthis endpoint returns the ordered id set *for that list*: if one compiled its view and the\nother ran an authored `q`, the two would disagree inside a single feature, which is the\ndrift this replaces.\n"
3058
+ },
3059
+ "user_groups": {
3060
+ "type": "array",
3061
+ "items": {
3062
+ "type": "string"
3063
+ },
3064
+ "description": "The caller's group ids, with the same meaning and caveats as on `threads:search`."
3065
+ },
2916
3066
  "inbox_id": {
2917
3067
  "oneOf": [
2918
3068
  {
@@ -3160,7 +3310,7 @@
3160
3310
  },
3161
3311
  "label_name": {
3162
3312
  "type": "string",
3163
- "description": "Resolved taxonomy classification display name (e.g. `Verärgert`), when the label is a classification. Absent for free-form tags."
3313
+ "description": "Resolved taxonomy classification display name (e.g. `Ver\u00e4rgert`), when the label is a classification. Absent for free-form tags."
3164
3314
  }
3165
3315
  }
3166
3316
  },
@@ -3183,7 +3333,7 @@
3183
3333
  },
3184
3334
  "label_name": {
3185
3335
  "type": "string",
3186
- "description": "Resolved taxonomy classification display name (e.g. `Verärgert`), when the label is a classification. Absent for free-form tags."
3336
+ "description": "Resolved taxonomy classification display name (e.g. `Ver\u00e4rgert`), when the label is a classification. Absent for free-form tags."
3187
3337
  }
3188
3338
  }
3189
3339
  },
@@ -3400,7 +3550,7 @@
3400
3550
  "timestamp": {
3401
3551
  "type": "string",
3402
3552
  "description": "Timestamp of the event",
3403
- "example": "2024-01-01T00:00:00Z"
3553
+ "example": "2024-01-01T00:00:00.000Z"
3404
3554
  },
3405
3555
  "message_id": {
3406
3556
  "type": "string",
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  API_LIST
4
- } from "../chunk-IKYUAORY.js";
4
+ } from "../chunk-XV6Z22GM.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.118",
14
+ version: "0.1.120",
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-CPMUSY3E.js").then((m) => m.default),
34
- upgrade: () => import("../upgrade-4B7QBPBL.js").then((m) => m.default),
33
+ completion: () => import("../completion-F6MX5VSK.js").then((m) => m.default),
34
+ upgrade: () => import("../upgrade-FXQ5SOGV.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.118" : (await null).default.version;
137
+ var VERSION = true ? "0.1.120" : (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-CPMUSY3E.js");
143
+ const { handleCompletions } = await import("../completion-F6MX5VSK.js");
144
144
  handleCompletions(args[completionsIdx + 1], args[completionsIdx + 2]);
145
145
  process.exit(0);
146
146
  }
@@ -328,7 +328,7 @@ var API_LIST = [
328
328
  kebabName: "customer-portal",
329
329
  title: "Portal API",
330
330
  serverUrl: "https://customer-portal-api.sls.epilot.io",
331
- operationCount: 162,
331
+ operationCount: 167,
332
332
  operationIds: [
333
333
  "upsertPortal",
334
334
  "createUser",
@@ -445,6 +445,7 @@ var API_LIST = [
445
445
  "getAutomationContext",
446
446
  "updateWorkflowStepAsDone",
447
447
  "getEntityWorkflows",
448
+ "getOutstandingTasks",
448
449
  "getEntityPortalWorkflows",
449
450
  "getEntityPortalWorkflowsBatch",
450
451
  "uploadMeterReadingPhoto",
@@ -472,6 +473,10 @@ var API_LIST = [
472
473
  "deletePortalPageBlock",
473
474
  "getUserEntryPoint",
474
475
  "updateCampaignPortalBlockStatus",
476
+ "listPortalNotifications",
477
+ "getPortalNotificationsUnreadCount",
478
+ "markAllPortalNotificationsRead",
479
+ "markPortalNotificationRead",
475
480
  "updateNotificationsStatus",
476
481
  "deRegisterMLoginUser",
477
482
  "notifyMLoginInterestChange",
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  API_LIST
4
- } from "./chunk-IKYUAORY.js";
4
+ } from "./chunk-XV6Z22GM.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.118";
75
+ if (true) return "0.1.120";
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.118",
3
+ "version": "0.1.120",
4
4
  "description": "CLI for epilot APIs",
5
5
  "type": "module",
6
6
  "bin": {