@wirecat/cli-core 0.535.0 → 0.536.0

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/CHANGELOG.md CHANGED
@@ -7,6 +7,15 @@ shape of this file.
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ## 0.536.0 — 01.11.2026
11
+
12
+ ### Fixed
13
+
14
+ - **A server mail search that ran out of time says so.** When the server's own deadline cut a search or the read of
15
+ its finds short, `searchMailServer` reported `search.server-failed` (`provider_unavailable`), as if the server had
16
+ refused. It now reports `search.server-timeout` (`timeout`), as when `--server-time` ends it, so a caller knows to
17
+ give it more time.
18
+
10
19
  ## 0.535.0 — 01.11.2026
11
20
 
12
21
  ### Added
@@ -18,6 +18,12 @@ const refusal = {
18
18
  no_words: "--backend server needs words, people, a subject, a date or a state to send to the server",
19
19
  };
20
20
  const BOUND = Symbol("bound");
21
+ /** A call the server's own deadline cut short is the time bound's, as one cut by --server-time is. */
22
+ const failureOf = (error) => error instanceof CliError && error.code === "rate_limited"
23
+ ? "rate_limited"
24
+ : error instanceof CliError && error.code === "timeout"
25
+ ? "time_or_abort_bound"
26
+ : "search_failed";
21
27
  /** The newest first: a server's UIDs grow as mail arrives in the folder. */
22
28
  const newest = (uids, count) => [...uids].sort((one, other) => Number(other) - Number(one)).slice(0, count);
23
29
  /**
@@ -112,7 +118,7 @@ export const searchMailServer = async (store, mailbox, access, request) => {
112
118
  if (!open)
113
119
  return;
114
120
  pending.delete(call);
115
- fail(call, error instanceof CliError && error.code === "rate_limited" ? "rate_limited" : "search_failed");
121
+ fail(call, failureOf(error));
116
122
  }
117
123
  }));
118
124
  if (!open)
@@ -143,10 +149,7 @@ export const searchMailServer = async (store, mailbox, access, request) => {
143
149
  });
144
150
  let outcome;
145
151
  try {
146
- outcome = await Promise.race([
147
- run().then(() => "done", () => "failed"),
148
- bound,
149
- ]);
152
+ outcome = await Promise.race([run().then(() => "done", failureOf), bound]);
150
153
  }
151
154
  finally {
152
155
  open = false;
@@ -158,12 +161,13 @@ export const searchMailServer = async (store, mailbox, access, request) => {
158
161
  throw openFailure;
159
162
  if (unsupported)
160
163
  return skip("unsupported");
164
+ const ended = outcome === BOUND || outcome === "done" ? "time_or_abort_bound" : outcome;
161
165
  for (const call of pending)
162
- fail(call, outcome === "failed" ? "search_failed" : "time_or_abort_bound");
166
+ fail(call, ended);
163
167
  if (outcome !== "done" || (fresh.length > 0 && raws === undefined)) {
164
168
  // What was found but not read in time is the archive's to answer: none of it is claimed as the server's.
165
169
  if (pending.size === 0)
166
- fail(null, outcome === "failed" ? "search_failed" : "time_or_abort_bound");
170
+ fail(null, ended);
167
171
  for (const item of fresh)
168
172
  sources.delete(sourceKey(item.threadId, item.messageId));
169
173
  report.returned = sources.size;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wirecat/cli-core",
3
- "version": "0.535.0",
3
+ "version": "0.536.0",
4
4
  "description": "The messenger-neutral half of a messaging CLI: domain model, message locators, rendering, name resolution, the SQLite seam, the command skeleton and shared read commands, the send guard, run records and the message store",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Viacheslav Ptsarev",