@epilot/cli 0.1.118 → 0.1.119

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.119 — CLI for epilot APIs
33
33
 
34
34
  USAGE
35
35
  epilot <api> <operationId> [params...] [flags]
@@ -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",
@@ -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.119",
15
15
  description: "CLI for epilot APIs"
16
16
  },
17
17
  args: {
@@ -31,7 +31,7 @@ var main = defineCommand({
31
31
  profile: () => import("../profile-OZJL5ZPT.js").then((m) => m.default),
32
32
  config: () => import("../config-DGZIMLZK.js").then((m) => m.default),
33
33
  completion: () => import("../completion-CPMUSY3E.js").then((m) => m.default),
34
- upgrade: () => import("../upgrade-4B7QBPBL.js").then((m) => m.default),
34
+ upgrade: () => import("../upgrade-LASQG4TZ.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,7 +134,7 @@ 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.119" : (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);
@@ -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.119";
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.119",
4
4
  "description": "CLI for epilot APIs",
5
5
  "type": "module",
6
6
  "bin": {