pi-session-mail 0.6.0 → 0.6.1

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
@@ -6,6 +6,16 @@ follows [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.6.1] - 2026-10-31
10
+
11
+ ### Changed
12
+
13
+ - The label on the answer to an ask now calls it an ask: "It is a reply to your
14
+ ask …" and "[mailbox] Your ask …, quoted from …" (and "Ask cut at 2 KiB").
15
+ It said "request" before, which now names a different kind of mail. A reply
16
+ to a request, or to an id with no copy in `sent/`, keeps the request wording.
17
+ The test that pinned the old wording for an ask's answer is updated.
18
+
9
19
  ## [0.6.0] - 2026-10-31
10
20
 
11
21
  ### Added
@@ -240,7 +250,8 @@ author's dotfiles; the changes below are against that copy.
240
250
  - CI on Node 22.19 and 24: lint, typecheck, tests, and a check of the
241
251
  published file list.
242
252
 
243
- [Unreleased]: https://github.com/gvanderclay/pi-session-mail/compare/v0.6.0...HEAD
253
+ [Unreleased]: https://github.com/gvanderclay/pi-session-mail/compare/v0.6.1...HEAD
254
+ [0.6.1]: https://github.com/gvanderclay/pi-session-mail/compare/v0.6.0...v0.6.1
244
255
  [0.6.0]: https://github.com/gvanderclay/pi-session-mail/compare/v0.5.0...v0.6.0
245
256
  [0.5.0]: https://github.com/gvanderclay/pi-session-mail/compare/v0.4.0...v0.5.0
246
257
  [0.4.0]: https://github.com/gvanderclay/pi-session-mail/compare/v0.3.0...v0.4.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-session-mail",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "A file mailbox between Pi sessions on the same machine",
5
5
  "keywords": [
6
6
  "pi-package",
package/src/index.ts CHANGED
@@ -75,14 +75,15 @@ function cap(text: string, max: number): string | undefined {
75
75
  */
76
76
  const plain = (text: string): string => text.replace(/[\p{Cc}\u2028\u2029]/gu, " ");
77
77
 
78
- /** A reply quotes each request it answers: the id, the copy's path, then the capped body. */
78
+ /** A reply quotes each request or ask it answers: the id, the copy's path, then the capped body. */
79
79
  function quoteRequest(request: SentCopy): string {
80
+ const ask = request.envelope.kind === "ask";
80
81
  const cut = cap(request.envelope.body, QUOTE_CAP);
81
82
  const body =
82
83
  cut === undefined
83
84
  ? request.envelope.body
84
- : `${cut}\n[mailbox] Request cut at 2 KiB; the full copy is ${plain(request.path)}`;
85
- return `[mailbox] Your request ${plain(request.envelope.id)}, quoted from ${plain(request.path)}:\n${body
85
+ : `${cut}\n[mailbox] ${ask ? "Ask" : "Request"} cut at 2 KiB; the full copy is ${plain(request.path)}`;
86
+ return `[mailbox] Your ${ask ? "ask" : "request"} ${plain(request.envelope.id)}, quoted from ${plain(request.path)}:\n${body
86
87
  .split("\n")
87
88
  .map((line) => `> ${line}`)
88
89
  .join("\n")}`;
@@ -136,10 +137,10 @@ function inboundText(
136
137
  envelope: Envelope,
137
138
  path: string,
138
139
  quotes: readonly string[],
139
- opts: { lateAnswer: boolean; byUser: boolean },
140
+ opts: { lateAnswer: boolean; byUser: boolean; answersAsks: boolean },
140
141
  senderRecord: RunningRecord | undefined,
141
142
  ): string {
142
- const { lateAnswer, byUser } = opts;
143
+ const { lateAnswer, byUser, answersAsks } = opts;
143
144
  const sender = senderLine(envelope.from, senderRecord);
144
145
  const id = plain(envelope.id);
145
146
  const replyIds = envelope.in_reply_to.map(plain);
@@ -152,7 +153,9 @@ function inboundText(
152
153
  if (envelope.kind === "message")
153
154
  header.push(`It expects no answer; if one is wanted, send it with session_mail_send to ${envelope.from}.`);
154
155
  if (envelope.in_reply_to.length > 0)
155
- header.push(`It is a reply to your request${envelope.in_reply_to.length > 1 ? "s" : ""} ${replyIds.join(", ")}.`);
156
+ header.push(
157
+ `It is a reply to your ${answersAsks ? "ask" : "request"}${envelope.in_reply_to.length > 1 ? "s" : ""} ${replyIds.join(", ")}.`,
158
+ );
156
159
  if (byUser)
157
160
  header.push("The user made that request, typing it with /mailbox or through an extension such as delegate.");
158
161
  if (envelope.in_reply_to.length > 0 && envelope.status !== "done")
@@ -395,6 +398,9 @@ export default function mailbox(pi: ExtensionAPI) {
395
398
  const lateAnswer = envelope.kind === "reply" && requests.some((copy) => copy.envelope.kind === "ask");
396
399
  const wakes = envelope.kind !== "reply" || lateAnswer;
397
400
  const byUser = envelope.kind === "reply" && requests.some((copy) => copy.envelope.kind === "request");
401
+ // The label says "ask" only when every id it answers is a known ask; otherwise "request", as before.
402
+ const answersAsks =
403
+ requests.length === envelope.in_reply_to.length && requests.every((copy) => copy.envelope.kind === "ask");
398
404
  // Listeners run synchronously inside emit, so `handled` is final when it returns.
399
405
  const inbound: InboundPayload = { envelope, path, requests, handled: false };
400
406
  pi.events.emit(INBOUND, inbound);
@@ -415,7 +421,7 @@ export default function mailbox(pi: ExtensionAPI) {
415
421
  envelope,
416
422
  path,
417
423
  quotes,
418
- { lateAnswer, byUser },
424
+ { lateAnswer, byUser, answersAsks },
419
425
  listRunning().find((r) => r.address === envelope.from),
420
426
  ),
421
427
  display: true,