@rubytech/create-maxy-code 0.1.359 → 0.1.361
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/package.json +1 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +18 -1
- package/payload/platform/plugins/browser/PLUGIN.md +1 -1
- package/payload/platform/plugins/docs/references/graph.md +17 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/source-fetch-efficiency.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/source-fetch-efficiency.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/source-fetch-efficiency.test.js +142 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/source-fetch-efficiency.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +0 -5
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js +120 -94
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
- package/payload/platform/scripts/__tests__/vnc-cdp-liveness.test.sh +222 -0
- package/payload/platform/scripts/rss-sampler.sh +16 -0
- package/payload/platform/scripts/vnc.sh +117 -3
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +18 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/systemd-scope.d.ts +0 -4
- package/payload/platform/services/claude-session-manager/dist/systemd-scope.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/systemd-scope.js +0 -15
- package/payload/platform/services/claude-session-manager/dist/systemd-scope.js.map +1 -1
- package/payload/server/public/assets/{AdminLoginScreens-tHyAPNnQ.js → AdminLoginScreens-D6JtrY9a.js} +1 -1
- package/payload/server/public/assets/{AdminShell-Ce9izNVZ.js → AdminShell-CaVRZTmj.js} +1 -1
- package/payload/server/public/assets/{Checkbox-Cq6SJJlX.js → Checkbox-BiHO47mz.js} +1 -1
- package/payload/server/public/assets/{OperatorConversations-m2lz6Ss7.js → OperatorConversations-CzhbxFwN.js} +1 -1
- package/payload/server/public/assets/OperatorConversations-D3UBU6SM.css +1 -0
- package/payload/server/public/assets/{admin-D9iMgdbN.js → admin-BrCL9qSn.js} +1 -1
- package/payload/server/public/assets/{browser-CZWi0EAP.js → browser-DNIV6o_p.js} +1 -1
- package/payload/server/public/assets/{calendar-DUAh-_kx.js → calendar-Arx94jTH.js} +1 -1
- package/payload/server/public/assets/chat-BwShkhcz.js +1 -0
- package/payload/server/public/assets/{data-CoOcAR_2.js → data-DBInTT-w.js} +1 -1
- package/payload/server/public/assets/{graph-labels-jqagxwhW.js → graph-labels-CVZClzPb.js} +1 -1
- package/payload/server/public/assets/{graph-Dc_votDd.js → graph-z-RYpYMZ.js} +15 -15
- package/payload/server/public/assets/{operator-KYXcuQ4Y.js → operator-CoCf8Lk7.js} +1 -1
- package/payload/server/public/assets/{page-Cfsv97nq.js → page-CWnkJCxo.js} +5 -5
- package/payload/server/public/assets/{public-49guEjCh.js → public-CKMOOQiq.js} +1 -1
- package/payload/server/public/assets/{rotate-ccw-CyR5o3Nq.js → rotate-ccw-Dgw6hmsm.js} +1 -1
- package/payload/server/public/browser.html +4 -4
- package/payload/server/public/calendar.html +4 -4
- package/payload/server/public/chat.html +6 -6
- package/payload/server/public/data.html +4 -4
- package/payload/server/public/graph.html +7 -7
- package/payload/server/public/index.html +6 -6
- package/payload/server/public/operator.html +8 -8
- package/payload/server/public/public.html +6 -6
- package/payload/server/server.js +106 -0
- package/payload/server/public/assets/OperatorConversations-BERW_hUa.css +0 -1
- package/payload/server/public/assets/chat-DHuibPfc.js +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: platform-architecture
|
|
3
3
|
description: Use when grounding any documented-surface claim about what Maxy ships — plugins, skills, specialists, install/deploy flows, internals. This is the install catalogue, not evidence of what is enabled on the current account. For install state on this account, call `capabilities-here`; for documented surface, cite the `Source:` URL inline.
|
|
4
|
-
content-hash: sha256:
|
|
4
|
+
content-hash: sha256:aa31039d259f4517fbd2bcda93ca7c32c55aa794ba124b8620df32597ffa4ad3
|
|
5
5
|
brand: maxy-code
|
|
6
6
|
product-name: Maxy
|
|
7
7
|
---
|
|
@@ -2891,6 +2891,23 @@ The **Graph** admin page (`/graph`) renders a force-directed view of your
|
|
|
2891
2891
|
account's Neo4j subgraph. Labels on the canvas follow the zoom level, so you
|
|
2892
2892
|
see the most useful identity at every scale.
|
|
2893
2893
|
|
|
2894
|
+
## Default view
|
|
2895
|
+
|
|
2896
|
+
Opening `/graph` with no filter chips selected shows **all your top-level
|
|
2897
|
+
nodes** straight away, so the canvas is populated on arrival rather than
|
|
2898
|
+
blank. Top-level nodes are the operator-meaningful entry points (People,
|
|
2899
|
+
Organizations, Conversations, Tasks, Jobs, and the rest of the filter chip
|
|
2900
|
+
roster); their child and infrastructural nodes stay off this view and are
|
|
2901
|
+
reached by clicking into a node's neighbourhood.
|
|
2902
|
+
|
|
2903
|
+
This view is capped at **1000 nodes**. When your graph has more than that, the
|
|
2904
|
+
canvas shows 1000 of them and a note reads, for example, `Showing 1,000 of
|
|
2905
|
+
3,412 top-level nodes`, so you know some are not on screen. When the count is
|
|
2906
|
+
under the cap the note reads `Showing 312 of 312 top-level nodes`. Selecting
|
|
2907
|
+
one or more filter chips switches to the chip-filtered view, which returns
|
|
2908
|
+
every matching node and asks you to narrow if a single label set exceeds its
|
|
2909
|
+
own larger limit.
|
|
2910
|
+
|
|
2894
2911
|
## Search and pivot
|
|
2895
2912
|
|
|
2896
2913
|
Type a term in the search box to highlight matching nodes on the canvas. Hits get an amber border so you can pick them out of a busy view. Click any highlighted node to open its side panel and pivot into its neighbourhood — both clicks (hit and non-hit) behave identically.
|
|
@@ -111,4 +111,4 @@ All tools are admin-allowlisted; none are exposed to public chat.
|
|
|
111
111
|
|
|
112
112
|
## Observability
|
|
113
113
|
|
|
114
|
-
A successful render emits `[browser-render] url=… rendered=true domBytes=…` on the server's stderr (captured by the mcp-spawn-tee log). Every other tool returns a structured outcome: `ok`, or one of `cdp-unreachable`, `session-lost`, `selector-not-found`, `option-not-found`, `wait-timeout`, `navigate-failed`, `load-timeout`, `evaluate-failed`, `command-timeout`, `pdf-failed`, `screenshot-failed`, `unsupported-key`. On a device with no running Chromium (e.g. a laptop native-display install with no VNC browser) the tools return `cdp-unreachable` rather than hanging.
|
|
114
|
+
A successful render emits `[browser-render] url=… rendered=true domBytes=…` on the server's stderr (captured by the mcp-spawn-tee log). Every other tool returns a structured outcome: `ok`, or one of `cdp-unreachable`, `session-lost`, `selector-not-found`, `option-not-found`, `wait-timeout`, `navigate-failed`, `load-timeout`, `evaluate-failed`, `command-timeout`, `pdf-failed`, `screenshot-failed`, `unsupported-key`. On a device with no running Chromium (e.g. a laptop native-display install with no VNC browser) the tools return `cdp-unreachable` rather than hanging. In virtual-display mode a Chromium that dies while the VNC display stays up is self-healing: the brand's standing CDP-liveness check (run each `rss-sampler` cycle via `vnc.sh cdp-liveness`) relaunches it and logs `[vnc] op=cdp-liveness … reachable=<bool>` plus `[vnc] op=chromium-respawn … outcome=<ready|failed>` to the service journal, so `cdp-unreachable` is transient (recovered within the check interval, bounded against hot-looping an unlaunchable browser) rather than dead-until-restart. Native-display installs launch Chromium on-demand, so a `cdp-unreachable` there clears on the next browser call.
|
|
@@ -4,6 +4,23 @@ The **Graph** admin page (`/graph`) renders a force-directed view of your
|
|
|
4
4
|
account's Neo4j subgraph. Labels on the canvas follow the zoom level, so you
|
|
5
5
|
see the most useful identity at every scale.
|
|
6
6
|
|
|
7
|
+
## Default view
|
|
8
|
+
|
|
9
|
+
Opening `/graph` with no filter chips selected shows **all your top-level
|
|
10
|
+
nodes** straight away, so the canvas is populated on arrival rather than
|
|
11
|
+
blank. Top-level nodes are the operator-meaningful entry points (People,
|
|
12
|
+
Organizations, Conversations, Tasks, Jobs, and the rest of the filter chip
|
|
13
|
+
roster); their child and infrastructural nodes stay off this view and are
|
|
14
|
+
reached by clicking into a node's neighbourhood.
|
|
15
|
+
|
|
16
|
+
This view is capped at **1000 nodes**. When your graph has more than that, the
|
|
17
|
+
canvas shows 1000 of them and a note reads, for example, `Showing 1,000 of
|
|
18
|
+
3,412 top-level nodes`, so you know some are not on screen. When the count is
|
|
19
|
+
under the cap the note reads `Showing 312 of 312 top-level nodes`. Selecting
|
|
20
|
+
one or more filter chips switches to the chip-filtered view, which returns
|
|
21
|
+
every matching node and asks you to narrow if a single label set exceeds its
|
|
22
|
+
own larger limit.
|
|
23
|
+
|
|
7
24
|
## Search and pivot
|
|
8
25
|
|
|
9
26
|
Type a term in the search box to highlight matching nodes on the canvas. Hits get an amber border so you can pick them out of a busy view. Click any highlighted node to open its side panel and pivot into its neighbourhood — both clicks (hit and non-hit) behave identically.
|
package/payload/platform/plugins/email/mcp/dist/__tests__/source-fetch-efficiency.test.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-fetch-efficiency.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/source-fetch-efficiency.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
const fetchCalls = [];
|
|
3
|
+
let connectCount = 0;
|
|
4
|
+
let inbox = [];
|
|
5
|
+
function envelopeOf(m) {
|
|
6
|
+
return {
|
|
7
|
+
from: [{ address: m.from, name: null }],
|
|
8
|
+
to: [{ address: m.to }],
|
|
9
|
+
cc: [],
|
|
10
|
+
subject: m.subject,
|
|
11
|
+
date: new Date("2026-01-01T00:00:00Z"),
|
|
12
|
+
messageId: `<${m.uid}@x>`,
|
|
13
|
+
inReplyTo: null,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function sourceOf(m) {
|
|
17
|
+
return Buffer.from([`From: ${m.from}`, `To: ${m.to}`, `Subject: ${m.subject}`, "", `body-${m.uid}`, ""].join("\r\n"));
|
|
18
|
+
}
|
|
19
|
+
function rowFor(uid, fields) {
|
|
20
|
+
const m = inbox.find((x) => x.uid === uid);
|
|
21
|
+
if (!m)
|
|
22
|
+
return null;
|
|
23
|
+
const row = { uid };
|
|
24
|
+
if (fields.envelope)
|
|
25
|
+
row.envelope = envelopeOf(m);
|
|
26
|
+
if (fields.bodyStructure)
|
|
27
|
+
row.bodyStructure = { type: "text/plain" };
|
|
28
|
+
if (fields.source)
|
|
29
|
+
row.source = sourceOf(m);
|
|
30
|
+
return row;
|
|
31
|
+
}
|
|
32
|
+
const mockClient = {
|
|
33
|
+
connect: vi.fn(async () => {
|
|
34
|
+
connectCount++;
|
|
35
|
+
}),
|
|
36
|
+
list: vi.fn(async () => [
|
|
37
|
+
{ path: "INBOX" },
|
|
38
|
+
{ path: "Sent", specialUse: "\\Sent" },
|
|
39
|
+
]),
|
|
40
|
+
getMailboxLock: vi.fn(async () => ({ release: vi.fn() })),
|
|
41
|
+
search: vi.fn(async () => inbox.map((m) => m.uid)),
|
|
42
|
+
// async generator over the requested UID range, honouring the field set.
|
|
43
|
+
fetch: vi.fn(function (range, fields) {
|
|
44
|
+
fetchCalls.push({ range, fields });
|
|
45
|
+
const uids = range.split(",").map((s) => Number(s.trim()));
|
|
46
|
+
async function* gen() {
|
|
47
|
+
for (const uid of uids) {
|
|
48
|
+
const row = rowFor(uid, fields);
|
|
49
|
+
if (row)
|
|
50
|
+
yield row;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return gen();
|
|
54
|
+
}),
|
|
55
|
+
fetchOne: vi.fn(async (range, fields) => {
|
|
56
|
+
fetchCalls.push({ range, fields });
|
|
57
|
+
return rowFor(Number(range), fields);
|
|
58
|
+
}),
|
|
59
|
+
logout: vi.fn(async () => { }),
|
|
60
|
+
close: vi.fn(() => { }),
|
|
61
|
+
};
|
|
62
|
+
vi.mock("imapflow", () => ({
|
|
63
|
+
ImapFlow: function ImapFlow() {
|
|
64
|
+
return mockClient;
|
|
65
|
+
},
|
|
66
|
+
}));
|
|
67
|
+
import { fetchFullBody, fetchRecent, searchMessages } from "../lib/imap.js";
|
|
68
|
+
const config = {
|
|
69
|
+
email: "agent@example.com",
|
|
70
|
+
imapHost: "imap.example.com",
|
|
71
|
+
imapPort: 993,
|
|
72
|
+
imapSecurity: "tls",
|
|
73
|
+
};
|
|
74
|
+
beforeEach(() => {
|
|
75
|
+
vi.clearAllMocks();
|
|
76
|
+
fetchCalls.length = 0;
|
|
77
|
+
connectCount = 0;
|
|
78
|
+
inbox = [];
|
|
79
|
+
});
|
|
80
|
+
describe("Task 1180 — message_id full-body read uses one connection", () => {
|
|
81
|
+
it("opens a single IMAP connection for a message_id target", async () => {
|
|
82
|
+
inbox = [{ uid: 10, to: "agent@example.com", subject: "Hi", from: "a@x.com" }];
|
|
83
|
+
// search by message-id header returns the matching uid
|
|
84
|
+
mockClient.search.mockResolvedValue([10]);
|
|
85
|
+
const full = await fetchFullBody(config, "pw", { messageId: "<10@x>" });
|
|
86
|
+
expect(full?.body).toContain("body-10");
|
|
87
|
+
expect(connectCount).toBe(1);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
describe("Task 1180 — list/search fetch source only for displayed messages", () => {
|
|
91
|
+
it("fetchRecent second-pass source fetch covers only the displayed UID set", async () => {
|
|
92
|
+
// 9 messages; recipient filter keeps only those addressed to keep@x.com.
|
|
93
|
+
// limit 2 + TO over-fetch ×3 => window of 6 newest UIDs (uids 4..9).
|
|
94
|
+
inbox = [
|
|
95
|
+
{ uid: 1, to: "keep@x.com", subject: "s1", from: "a@x.com" },
|
|
96
|
+
{ uid: 2, to: "other@x.com", subject: "s2", from: "a@x.com" },
|
|
97
|
+
{ uid: 3, to: "keep@x.com", subject: "s3", from: "a@x.com" },
|
|
98
|
+
{ uid: 4, to: "other@x.com", subject: "s4", from: "a@x.com" },
|
|
99
|
+
{ uid: 5, to: "keep@x.com", subject: "s5", from: "a@x.com" },
|
|
100
|
+
{ uid: 6, to: "other@x.com", subject: "s6", from: "a@x.com" },
|
|
101
|
+
{ uid: 7, to: "keep@x.com", subject: "s7", from: "a@x.com" },
|
|
102
|
+
{ uid: 8, to: "other@x.com", subject: "s8", from: "a@x.com" },
|
|
103
|
+
{ uid: 9, to: "keep@x.com", subject: "s9", from: "a@x.com" },
|
|
104
|
+
];
|
|
105
|
+
mockClient.search.mockResolvedValue(inbox.map((m) => m.uid));
|
|
106
|
+
const res = await fetchRecent(config, "pw", { limit: 2, to: "keep@x.com" });
|
|
107
|
+
// Window is the 6 newest UIDs (4..9). The display set is the FIRST two
|
|
108
|
+
// keep@ matches in ascending window order (5, 7), returned newest-first.
|
|
109
|
+
expect(res.messages.map((m) => m.uid)).toEqual([7, 5]);
|
|
110
|
+
expect(res.messages.every((m) => m.bodyPreview.length > 0)).toBe(true);
|
|
111
|
+
const sourceFetches = fetchCalls.filter((c) => c.fields.source);
|
|
112
|
+
expect(sourceFetches.length).toBe(1);
|
|
113
|
+
const fetchedUids = sourceFetches[0].range
|
|
114
|
+
.split(",")
|
|
115
|
+
.map((s) => Number(s.trim()))
|
|
116
|
+
.sort((a, b) => a - b);
|
|
117
|
+
expect(fetchedUids).toEqual([5, 7]);
|
|
118
|
+
});
|
|
119
|
+
it("searchMessages second-pass source fetch covers only the displayed UID set", async () => {
|
|
120
|
+
inbox = [
|
|
121
|
+
{ uid: 1, to: "keep@x.com", subject: "s1", from: "a@x.com" },
|
|
122
|
+
{ uid: 2, to: "other@x.com", subject: "s2", from: "a@x.com" },
|
|
123
|
+
{ uid: 3, to: "keep@x.com", subject: "s3", from: "a@x.com" },
|
|
124
|
+
{ uid: 4, to: "other@x.com", subject: "s4", from: "a@x.com" },
|
|
125
|
+
{ uid: 5, to: "keep@x.com", subject: "s5", from: "a@x.com" },
|
|
126
|
+
{ uid: 6, to: "other@x.com", subject: "s6", from: "a@x.com" },
|
|
127
|
+
];
|
|
128
|
+
mockClient.search.mockResolvedValue(inbox.map((m) => m.uid));
|
|
129
|
+
const res = await searchMessages(config, "pw", { limit: 2, to: "keep@x.com" });
|
|
130
|
+
// Window is all 6 UIDs (1..6). Display set is the first two keep@ matches
|
|
131
|
+
// in ascending order (1, 3), returned newest-first.
|
|
132
|
+
expect(res.messages.map((m) => m.uid)).toEqual([3, 1]);
|
|
133
|
+
const sourceFetches = fetchCalls.filter((c) => c.fields.source);
|
|
134
|
+
expect(sourceFetches.length).toBe(1);
|
|
135
|
+
const fetchedUids = sourceFetches[0].range
|
|
136
|
+
.split(",")
|
|
137
|
+
.map((s) => Number(s.trim()))
|
|
138
|
+
.sort((a, b) => a - b);
|
|
139
|
+
expect(fetchedUids).toEqual([1, 3]);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
//# sourceMappingURL=source-fetch-efficiency.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-fetch-efficiency.test.js","sourceRoot":"","sources":["../../src/__tests__/source-fetch-efficiency.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -289,11 +289,6 @@ export declare function fetchSinceUid(config: EmailConfig, password: string, sin
|
|
|
289
289
|
/**
|
|
290
290
|
* Resolve an envelope by Message-ID via IMAP. Searches INBOX first, then
|
|
291
291
|
* the \Sent special-use folder. Returns null when no folder yields a hit.
|
|
292
|
-
*
|
|
293
|
-
* Uses `header: { "message-id": ... }` IMAP SEARCH — sufficient on every
|
|
294
|
-
* server that honours RFC 3501 header search. The Message-ID is sent with
|
|
295
|
-
* angle brackets restored because some servers (notably Gmail) only match
|
|
296
|
-
* the raw header value, not the bare identifier.
|
|
297
292
|
*/
|
|
298
293
|
export declare function fetchEnvelopeByMessageId(config: EmailConfig, password: string, messageId: string): Promise<{
|
|
299
294
|
uid: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imap.d.ts","sourceRoot":"","sources":["../../src/lib/imap.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"imap.d.ts","sourceRoot":"","sources":["../../src/lib/imap.ts"],"names":[],"mappings":"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"}
|
|
@@ -564,15 +564,15 @@ export async function fetchRecent(config, password, options = {}) {
|
|
|
564
564
|
let envelopeCount = 0;
|
|
565
565
|
let recipientKept = 0;
|
|
566
566
|
let recipientHidden = 0;
|
|
567
|
-
//
|
|
568
|
-
//
|
|
569
|
-
//
|
|
570
|
-
|
|
567
|
+
// Pass 1: envelopes + structure only (no source) across the whole
|
|
568
|
+
// over-fetched window, so recipient kept/hidden accounting covers every
|
|
569
|
+
// UID while costing only envelope bytes. structureType is captured per
|
|
570
|
+
// displayed message (aligned by index with `messages`) for the diag.
|
|
571
|
+
const displayStructureTypes = [];
|
|
571
572
|
for await (const msg of client.fetch(uidList, {
|
|
572
573
|
envelope: true,
|
|
573
574
|
uid: true,
|
|
574
575
|
bodyStructure: true,
|
|
575
|
-
source: true,
|
|
576
576
|
}, { uid: true })) {
|
|
577
577
|
envelopeCount++;
|
|
578
578
|
diag("fetchRecent", `envelope #${envelopeCount}`, `uid=${msg.uid} from=${msg.envelope?.from?.[0]?.address ?? "?"} at ${Date.now() - t2}ms`);
|
|
@@ -593,14 +593,10 @@ export async function fetchRecent(config, password, options = {}) {
|
|
|
593
593
|
continue;
|
|
594
594
|
// Collect up to `limit` messages for display, but keep iterating past
|
|
595
595
|
// that point so the recipient kept/hidden accounting covers the whole
|
|
596
|
-
// fetched window.
|
|
597
|
-
// (see bodySources) and only runs for the displayed messages.
|
|
596
|
+
// fetched window.
|
|
598
597
|
if (messages.length < limit) {
|
|
599
598
|
const attachments = walkAttachmentMetadata(msg.bodyStructure);
|
|
600
|
-
|
|
601
|
-
source: msg.source ?? Buffer.alloc(0),
|
|
602
|
-
structureType: msg.bodyStructure?.type ?? "?",
|
|
603
|
-
});
|
|
599
|
+
displayStructureTypes.push(msg.bodyStructure?.type ?? "?");
|
|
604
600
|
messages.push({
|
|
605
601
|
uid: msg.uid,
|
|
606
602
|
messageId,
|
|
@@ -613,11 +609,20 @@ export async function fetchRecent(config, password, options = {}) {
|
|
|
613
609
|
});
|
|
614
610
|
}
|
|
615
611
|
}
|
|
616
|
-
//
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
612
|
+
// Pass 2: download full source ONLY for the messages we display, keyed by
|
|
613
|
+
// UID, then decode previews now that the stream is closed. A heavily
|
|
614
|
+
// filtered over-fetch no longer pulls source for the UIDs it dropped.
|
|
615
|
+
if (messages.length > 0) {
|
|
616
|
+
const displayUids = messages.map((m) => m.uid);
|
|
617
|
+
const sourceByUid = new Map();
|
|
618
|
+
for await (const msg of client.fetch(displayUids.map(String).join(","), { uid: true, source: true }, { uid: true })) {
|
|
619
|
+
sourceByUid.set(msg.uid, msg.source ?? Buffer.alloc(0));
|
|
620
|
+
}
|
|
621
|
+
for (let i = 0; i < messages.length; i++) {
|
|
622
|
+
const { body, kind } = await extractBody(sourceByUid.get(messages[i].uid) ?? Buffer.alloc(0));
|
|
623
|
+
messages[i].bodyPreview = previewBody(body);
|
|
624
|
+
diag("fetchRecent", `body #${i + 1}`, `uid=${messages[i].uid} preview=${messages[i].bodyPreview.length}chars type=${displayStructureTypes[i]} bodySource=${kind}`);
|
|
625
|
+
}
|
|
621
626
|
}
|
|
622
627
|
diag("fetchRecent", "fetch done", `${envelopeCount} envelopes, ${messages.length} messages in ${Date.now() - t2}ms (total ${Date.now() - t0}ms)`);
|
|
623
628
|
if (clientSideRecipients) {
|
|
@@ -693,14 +698,14 @@ export async function searchMessages(config, password, query) {
|
|
|
693
698
|
let envelopeCount = 0;
|
|
694
699
|
let recipientKept = 0;
|
|
695
700
|
let recipientHidden = 0;
|
|
696
|
-
//
|
|
697
|
-
//
|
|
698
|
-
|
|
701
|
+
// Pass 1: envelopes + structure only (no source) across the whole
|
|
702
|
+
// over-fetched window (see fetchRecent). structureType is captured per
|
|
703
|
+
// displayed message, aligned by index with `messages`.
|
|
704
|
+
const displayStructureTypes = [];
|
|
699
705
|
for await (const msg of client.fetch(recentUids.map(String).join(","), {
|
|
700
706
|
envelope: true,
|
|
701
707
|
uid: true,
|
|
702
708
|
bodyStructure: true,
|
|
703
|
-
source: true,
|
|
704
709
|
}, { uid: true })) {
|
|
705
710
|
envelopeCount++;
|
|
706
711
|
// Client-side recipient filter (replaces IMAP SEARCH TO), with kept-vs-hidden accounting
|
|
@@ -718,13 +723,10 @@ export async function searchMessages(config, password, query) {
|
|
|
718
723
|
const inReplyTo = msg.envelope?.inReplyTo ?? null;
|
|
719
724
|
// Collect up to `limit` messages for display, but keep iterating past
|
|
720
725
|
// that point so the recipient kept/hidden accounting covers the whole
|
|
721
|
-
// fetched window.
|
|
726
|
+
// fetched window.
|
|
722
727
|
if (messages.length < limit) {
|
|
723
728
|
const attachments = walkAttachmentMetadata(msg.bodyStructure);
|
|
724
|
-
|
|
725
|
-
source: msg.source ?? Buffer.alloc(0),
|
|
726
|
-
structureType: msg.bodyStructure?.type ?? "?",
|
|
727
|
-
});
|
|
729
|
+
displayStructureTypes.push(msg.bodyStructure?.type ?? "?");
|
|
728
730
|
messages.push({
|
|
729
731
|
uid: msg.uid,
|
|
730
732
|
messageId,
|
|
@@ -737,11 +739,19 @@ export async function searchMessages(config, password, query) {
|
|
|
737
739
|
});
|
|
738
740
|
}
|
|
739
741
|
}
|
|
740
|
-
//
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
742
|
+
// Pass 2: download full source ONLY for the displayed messages, keyed by
|
|
743
|
+
// UID, then decode previews (see fetchRecent).
|
|
744
|
+
if (messages.length > 0) {
|
|
745
|
+
const displayUids = messages.map((m) => m.uid);
|
|
746
|
+
const sourceByUid = new Map();
|
|
747
|
+
for await (const msg of client.fetch(displayUids.map(String).join(","), { uid: true, source: true }, { uid: true })) {
|
|
748
|
+
sourceByUid.set(msg.uid, msg.source ?? Buffer.alloc(0));
|
|
749
|
+
}
|
|
750
|
+
for (let i = 0; i < messages.length; i++) {
|
|
751
|
+
const { body, kind } = await extractBody(sourceByUid.get(messages[i].uid) ?? Buffer.alloc(0));
|
|
752
|
+
messages[i].bodyPreview = previewBody(body);
|
|
753
|
+
diag("searchMessages", `body #${i + 1}`, `uid=${messages[i].uid} preview=${messages[i].bodyPreview.length}chars type=${displayStructureTypes[i]} bodySource=${kind}`);
|
|
754
|
+
}
|
|
745
755
|
}
|
|
746
756
|
diag("searchMessages", "fetch done", `${envelopeCount} envelopes, ${messages.length} messages in ${Date.now() - t2}ms (total ${Date.now() - t0}ms)`);
|
|
747
757
|
if (clientSideRecipients) {
|
|
@@ -881,67 +891,81 @@ export async function fetchSinceUid(config, password, sinceUid, recipients) {
|
|
|
881
891
|
}
|
|
882
892
|
}
|
|
883
893
|
/**
|
|
884
|
-
*
|
|
885
|
-
* the \Sent special-use folder
|
|
894
|
+
* Locate a message by Message-ID on an ALREADY-CONNECTED client. Searches
|
|
895
|
+
* INBOX first, then the \Sent special-use folder, returning the first hit
|
|
896
|
+
* whose envelope carries a From address. The caller owns connect/logout — this
|
|
897
|
+
* helper neither opens nor closes the connection, so one login can both resolve
|
|
898
|
+
* the message and fetch its source (see fetchFullBody's message_id path).
|
|
886
899
|
*
|
|
887
|
-
* Uses `header: { "message-id": ... }` IMAP SEARCH — sufficient on every
|
|
888
|
-
*
|
|
889
|
-
*
|
|
890
|
-
*
|
|
900
|
+
* Uses `header: { "message-id": ... }` IMAP SEARCH — sufficient on every server
|
|
901
|
+
* that honours RFC 3501 header search. The Message-ID is sent with angle
|
|
902
|
+
* brackets restored because some servers (notably Gmail) only match the raw
|
|
903
|
+
* header value, not the bare identifier.
|
|
891
904
|
*/
|
|
892
|
-
|
|
905
|
+
async function locateByMessageId(client, messageId) {
|
|
893
906
|
const cleanId = messageId.replace(/^<|>$/g, "");
|
|
894
907
|
const needle = `<${cleanId}>`;
|
|
908
|
+
const folders = ["INBOX"];
|
|
909
|
+
try {
|
|
910
|
+
const sentPath = await resolveFolderName(client, "sent");
|
|
911
|
+
folders.push(sentPath);
|
|
912
|
+
}
|
|
913
|
+
catch {
|
|
914
|
+
// No \Sent folder advertised — only search INBOX.
|
|
915
|
+
}
|
|
916
|
+
for (const folderPath of folders) {
|
|
917
|
+
const lock = await client.getMailboxLock(folderPath);
|
|
918
|
+
try {
|
|
919
|
+
const uids = await client.search({ header: { "message-id": needle } }, { uid: true });
|
|
920
|
+
if (!uids || uids.length === 0)
|
|
921
|
+
continue;
|
|
922
|
+
const uid = uids[0];
|
|
923
|
+
for await (const msg of client.fetch(String(uid), { envelope: true, uid: true }, { uid: true })) {
|
|
924
|
+
const env = msg.envelope;
|
|
925
|
+
if (!env?.from?.[0]?.address)
|
|
926
|
+
continue;
|
|
927
|
+
return { uid: msg.uid, mailbox: folderPath, envelope: env };
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
finally {
|
|
931
|
+
lock.release();
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
return null;
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Resolve an envelope by Message-ID via IMAP. Searches INBOX first, then
|
|
938
|
+
* the \Sent special-use folder. Returns null when no folder yields a hit.
|
|
939
|
+
*/
|
|
940
|
+
export async function fetchEnvelopeByMessageId(config, password, messageId) {
|
|
895
941
|
const client = createClient(config, password);
|
|
896
942
|
const t0 = Date.now();
|
|
897
|
-
diag("fetchEnvelopeByMessageId", "start", `messageId=${
|
|
943
|
+
diag("fetchEnvelopeByMessageId", "start", `messageId=${messageId.replace(/^<|>$/g, "")}`);
|
|
898
944
|
try {
|
|
899
945
|
await client.connect();
|
|
900
946
|
diag("fetchEnvelopeByMessageId", "connected", `${Date.now() - t0}ms`);
|
|
901
|
-
const
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
}
|
|
906
|
-
catch {
|
|
907
|
-
// No \Sent folder advertised — only search INBOX.
|
|
908
|
-
}
|
|
909
|
-
for (const folderPath of folders) {
|
|
910
|
-
const lock = await client.getMailboxLock(folderPath);
|
|
911
|
-
try {
|
|
912
|
-
const uids = await client.search({ header: { "message-id": needle } }, { uid: true });
|
|
913
|
-
if (!uids || uids.length === 0)
|
|
914
|
-
continue;
|
|
915
|
-
const uid = uids[0];
|
|
916
|
-
for await (const msg of client.fetch(String(uid), { envelope: true, uid: true }, { uid: true })) {
|
|
917
|
-
const env = msg.envelope ?? {};
|
|
918
|
-
const fromAddr = env.from?.[0]?.address ?? "";
|
|
919
|
-
if (!fromAddr)
|
|
920
|
-
continue;
|
|
921
|
-
diag("fetchEnvelopeByMessageId", "match", `folder=${folderPath} uid=${msg.uid} in ${Date.now() - t0}ms`);
|
|
922
|
-
return {
|
|
923
|
-
uid: msg.uid,
|
|
924
|
-
mailbox: folderPath,
|
|
925
|
-
messageId: env.messageId ?? messageId,
|
|
926
|
-
fromAddress: fromAddr,
|
|
927
|
-
fromName: env.from?.[0]?.name ?? null,
|
|
928
|
-
toAddresses: (env.to ?? [])
|
|
929
|
-
.map((a) => a.address)
|
|
930
|
-
.filter((a) => !!a),
|
|
931
|
-
ccAddresses: (env.cc ?? [])
|
|
932
|
-
.map((a) => a.address)
|
|
933
|
-
.filter((a) => !!a),
|
|
934
|
-
subject: env.subject ?? "",
|
|
935
|
-
date: env.date?.toISOString() ?? "",
|
|
936
|
-
};
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
finally {
|
|
940
|
-
lock.release();
|
|
941
|
-
}
|
|
947
|
+
const loc = await locateByMessageId(client, messageId);
|
|
948
|
+
if (!loc) {
|
|
949
|
+
diag("fetchEnvelopeByMessageId", "no-match", `in ${Date.now() - t0}ms`);
|
|
950
|
+
return null;
|
|
942
951
|
}
|
|
943
|
-
|
|
944
|
-
|
|
952
|
+
const env = loc.envelope;
|
|
953
|
+
diag("fetchEnvelopeByMessageId", "match", `folder=${loc.mailbox} uid=${loc.uid} in ${Date.now() - t0}ms`);
|
|
954
|
+
return {
|
|
955
|
+
uid: loc.uid,
|
|
956
|
+
mailbox: loc.mailbox,
|
|
957
|
+
messageId: env.messageId ?? messageId,
|
|
958
|
+
fromAddress: env.from?.[0]?.address ?? "",
|
|
959
|
+
fromName: env.from?.[0]?.name ?? null,
|
|
960
|
+
toAddresses: (env.to ?? [])
|
|
961
|
+
.map((a) => a.address)
|
|
962
|
+
.filter((a) => !!a),
|
|
963
|
+
ccAddresses: (env.cc ?? [])
|
|
964
|
+
.map((a) => a.address)
|
|
965
|
+
.filter((a) => !!a),
|
|
966
|
+
subject: env.subject ?? "",
|
|
967
|
+
date: env.date?.toISOString() ?? "",
|
|
968
|
+
};
|
|
945
969
|
}
|
|
946
970
|
catch (err) {
|
|
947
971
|
diag("fetchEnvelopeByMessageId", "FAILED", `${err instanceof Error ? err.message : String(err)} after ${Date.now() - t0}ms`);
|
|
@@ -958,18 +982,6 @@ export async function fetchEnvelopeByMessageId(config, password, messageId) {
|
|
|
958
982
|
* MIME-shape blind spot. Returns null when the message cannot be located.
|
|
959
983
|
*/
|
|
960
984
|
export async function fetchFullBody(config, password, target) {
|
|
961
|
-
let mailbox = "";
|
|
962
|
-
let uid;
|
|
963
|
-
if ("messageId" in target) {
|
|
964
|
-
const env = await fetchEnvelopeByMessageId(config, password, target.messageId);
|
|
965
|
-
if (!env)
|
|
966
|
-
return null;
|
|
967
|
-
mailbox = env.mailbox;
|
|
968
|
-
uid = env.uid;
|
|
969
|
-
}
|
|
970
|
-
else {
|
|
971
|
-
uid = target.uid;
|
|
972
|
-
}
|
|
973
985
|
const client = createClient(config, password);
|
|
974
986
|
const t0 = Date.now();
|
|
975
987
|
const label = "messageId" in target
|
|
@@ -978,8 +990,22 @@ export async function fetchFullBody(config, password, target) {
|
|
|
978
990
|
diag("fetchFullBody", "start", label);
|
|
979
991
|
try {
|
|
980
992
|
await client.connect();
|
|
981
|
-
|
|
993
|
+
// Resolve the message location on THIS connection — a message_id read no
|
|
994
|
+
// longer opens a second login just to learn its uid/mailbox.
|
|
995
|
+
let mailbox;
|
|
996
|
+
let uid;
|
|
997
|
+
if ("messageId" in target) {
|
|
998
|
+
const loc = await locateByMessageId(client, target.messageId);
|
|
999
|
+
if (!loc) {
|
|
1000
|
+
diag("fetchFullBody", "not-found", `messageId=${target.messageId} in ${Date.now() - t0}ms`);
|
|
1001
|
+
return null;
|
|
1002
|
+
}
|
|
1003
|
+
mailbox = loc.mailbox;
|
|
1004
|
+
uid = loc.uid;
|
|
1005
|
+
}
|
|
1006
|
+
else {
|
|
982
1007
|
mailbox = await resolveFolderName(client, target.folder ?? "inbox");
|
|
1008
|
+
uid = target.uid;
|
|
983
1009
|
}
|
|
984
1010
|
const lock = await client.getMailboxLock(mailbox);
|
|
985
1011
|
try {
|