@leemour/max-cli 0.4.0 → 0.6.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.
Files changed (190) hide show
  1. package/README.md +14 -5
  2. package/dist/bin/max.js +0 -0
  3. package/dist/cache/store.d.ts +14 -8
  4. package/dist/cache/store.d.ts.map +1 -1
  5. package/dist/cache/store.js +30 -5
  6. package/dist/cache/store.js.map +1 -1
  7. package/dist/client.d.ts +93 -5
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +347 -59
  10. package/dist/client.js.map +1 -1
  11. package/dist/commands/chats.d.ts.map +1 -1
  12. package/dist/commands/chats.js +20 -0
  13. package/dist/commands/chats.js.map +1 -1
  14. package/dist/commands/commands.d.ts +8 -0
  15. package/dist/commands/commands.d.ts.map +1 -0
  16. package/dist/commands/commands.js +36 -0
  17. package/dist/commands/commands.js.map +1 -0
  18. package/dist/commands/config.d.ts.map +1 -1
  19. package/dist/commands/config.js +29 -0
  20. package/dist/commands/config.js.map +1 -1
  21. package/dist/commands/contacts.d.ts.map +1 -1
  22. package/dist/commands/contacts.js +18 -0
  23. package/dist/commands/contacts.js.map +1 -1
  24. package/dist/commands/context.d.ts +18 -0
  25. package/dist/commands/context.d.ts.map +1 -1
  26. package/dist/commands/context.js +22 -0
  27. package/dist/commands/context.js.map +1 -1
  28. package/dist/commands/inbox.d.ts +14 -0
  29. package/dist/commands/inbox.d.ts.map +1 -0
  30. package/dist/commands/inbox.js +90 -0
  31. package/dist/commands/inbox.js.map +1 -0
  32. package/dist/commands/messages.d.ts.map +1 -1
  33. package/dist/commands/messages.js +55 -4
  34. package/dist/commands/messages.js.map +1 -1
  35. package/dist/commands/reactions.d.ts +3 -0
  36. package/dist/commands/reactions.d.ts.map +1 -0
  37. package/dist/commands/reactions.js +26 -0
  38. package/dist/commands/reactions.js.map +1 -0
  39. package/dist/commands/recipients.d.ts +9 -0
  40. package/dist/commands/recipients.d.ts.map +1 -0
  41. package/dist/commands/recipients.js +68 -0
  42. package/dist/commands/recipients.js.map +1 -0
  43. package/dist/commands/sends.d.ts +4 -0
  44. package/dist/commands/sends.d.ts.map +1 -0
  45. package/dist/commands/sends.js +21 -0
  46. package/dist/commands/sends.js.map +1 -0
  47. package/dist/commands/session.d.ts.map +1 -1
  48. package/dist/commands/session.js +80 -15
  49. package/dist/commands/session.js.map +1 -1
  50. package/dist/commands/skill.d.ts.map +1 -1
  51. package/dist/commands/skill.js +2 -1
  52. package/dist/commands/skill.js.map +1 -1
  53. package/dist/config.d.ts +54 -13
  54. package/dist/config.d.ts.map +1 -1
  55. package/dist/config.js +98 -16
  56. package/dist/config.js.map +1 -1
  57. package/dist/domain/map.d.ts +3 -1
  58. package/dist/domain/map.d.ts.map +1 -1
  59. package/dist/domain/map.js +15 -1
  60. package/dist/domain/map.js.map +1 -1
  61. package/dist/domain/models.d.ts +55 -1
  62. package/dist/domain/models.d.ts.map +1 -1
  63. package/dist/domain/models.js.map +1 -1
  64. package/dist/download.d.ts +15 -0
  65. package/dist/download.d.ts.map +1 -0
  66. package/dist/download.js +60 -0
  67. package/dist/download.js.map +1 -0
  68. package/dist/generated/client.generated.d.ts +14 -0
  69. package/dist/generated/client.generated.d.ts.map +1 -1
  70. package/dist/generated/client.generated.js +14 -0
  71. package/dist/generated/client.generated.js.map +1 -1
  72. package/dist/generated/opcodes.generated.d.ts +15 -0
  73. package/dist/generated/opcodes.generated.d.ts.map +1 -1
  74. package/dist/generated/opcodes.generated.js +15 -0
  75. package/dist/generated/opcodes.generated.js.map +1 -1
  76. package/dist/generated/operations.generated.d.ts +99 -1
  77. package/dist/generated/operations.generated.d.ts.map +1 -1
  78. package/dist/generated/operations.generated.js +13 -1
  79. package/dist/generated/operations.generated.js.map +1 -1
  80. package/dist/markdown.d.ts +18 -0
  81. package/dist/markdown.d.ts.map +1 -0
  82. package/dist/markdown.js +52 -0
  83. package/dist/markdown.js.map +1 -0
  84. package/dist/program.d.ts.map +1 -1
  85. package/dist/program.js +10 -0
  86. package/dist/program.js.map +1 -1
  87. package/dist/rendering/messages.d.ts.map +1 -1
  88. package/dist/rendering/messages.js +6 -0
  89. package/dist/rendering/messages.js.map +1 -1
  90. package/dist/resolve.d.ts +15 -0
  91. package/dist/resolve.d.ts.map +1 -0
  92. package/dist/resolve.js +48 -0
  93. package/dist/resolve.js.map +1 -0
  94. package/dist/runs/recording.d.ts.map +1 -1
  95. package/dist/runs/recording.js +7 -0
  96. package/dist/runs/recording.js.map +1 -1
  97. package/dist/runs/run.d.ts +2 -0
  98. package/dist/runs/run.d.ts.map +1 -1
  99. package/dist/runs/run.js +1 -0
  100. package/dist/runs/run.js.map +1 -1
  101. package/dist/sends/guard.d.ts +26 -0
  102. package/dist/sends/guard.d.ts.map +1 -0
  103. package/dist/sends/guard.js +48 -0
  104. package/dist/sends/guard.js.map +1 -0
  105. package/dist/sends/journal.d.ts +29 -0
  106. package/dist/sends/journal.d.ts.map +1 -0
  107. package/dist/sends/journal.js +40 -0
  108. package/dist/sends/journal.js.map +1 -0
  109. package/dist/sends/recipients.d.ts +29 -0
  110. package/dist/sends/recipients.d.ts.map +1 -0
  111. package/dist/sends/recipients.js +62 -0
  112. package/dist/sends/recipients.js.map +1 -0
  113. package/dist/session/adopt.d.ts.map +1 -1
  114. package/dist/session/adopt.js +7 -6
  115. package/dist/session/adopt.js.map +1 -1
  116. package/dist/session/browser.d.ts +55 -0
  117. package/dist/session/browser.d.ts.map +1 -0
  118. package/dist/session/browser.js +292 -0
  119. package/dist/session/browser.js.map +1 -0
  120. package/dist/session/handshake.d.ts +3 -1
  121. package/dist/session/handshake.d.ts.map +1 -1
  122. package/dist/session/handshake.js +3 -1
  123. package/dist/session/handshake.js.map +1 -1
  124. package/dist/session/login.d.ts +20 -0
  125. package/dist/session/login.d.ts.map +1 -0
  126. package/dist/session/login.js +66 -0
  127. package/dist/session/login.js.map +1 -0
  128. package/dist/session/prompt.d.ts +3 -1
  129. package/dist/session/prompt.d.ts.map +1 -1
  130. package/dist/session/prompt.js +2 -2
  131. package/dist/session/prompt.js.map +1 -1
  132. package/dist/session/qr-terminal.d.ts +9 -0
  133. package/dist/session/qr-terminal.d.ts.map +1 -0
  134. package/dist/session/qr-terminal.js +34 -0
  135. package/dist/session/qr-terminal.js.map +1 -0
  136. package/dist/session/store.d.ts +2 -0
  137. package/dist/session/store.d.ts.map +1 -1
  138. package/dist/session/store.js +2 -0
  139. package/dist/session/store.js.map +1 -1
  140. package/dist/spec/index.d.ts.map +1 -1
  141. package/dist/spec/index.js +14 -1
  142. package/dist/spec/index.js.map +1 -1
  143. package/dist/spec/operations/attachments.d.ts +15 -0
  144. package/dist/spec/operations/attachments.d.ts.map +1 -0
  145. package/dist/spec/operations/attachments.js +38 -0
  146. package/dist/spec/operations/attachments.js.map +1 -0
  147. package/dist/spec/operations/login.d.ts +64 -0
  148. package/dist/spec/operations/login.d.ts.map +1 -0
  149. package/dist/spec/operations/login.js +99 -0
  150. package/dist/spec/operations/login.js.map +1 -0
  151. package/dist/spec/operations/messages.d.ts +27 -1
  152. package/dist/spec/operations/messages.d.ts.map +1 -1
  153. package/dist/spec/operations/messages.js +46 -2
  154. package/dist/spec/operations/messages.js.map +1 -1
  155. package/dist/testing/mock-max.d.ts +10 -4
  156. package/dist/testing/mock-max.d.ts.map +1 -1
  157. package/dist/testing/mock-max.js +5 -1
  158. package/dist/testing/mock-max.js.map +1 -1
  159. package/dist/testing/sandbox.js +3 -0
  160. package/dist/testing/sandbox.js.map +1 -1
  161. package/dist/testing/unscripted.d.ts +2 -0
  162. package/dist/testing/unscripted.d.ts.map +1 -0
  163. package/dist/testing/unscripted.js +18 -0
  164. package/dist/testing/unscripted.js.map +1 -0
  165. package/dist/version.d.ts +1 -1
  166. package/dist/version.js +1 -1
  167. package/package.json +31 -22
  168. package/skills/max-cli/SKILL.md +25 -6
  169. package/dist/commands/login.d.ts +0 -15
  170. package/dist/commands/login.d.ts.map +0 -1
  171. package/dist/commands/login.js +0 -43
  172. package/dist/commands/login.js.map +0 -1
  173. package/dist/commands/logout.d.ts +0 -10
  174. package/dist/commands/logout.d.ts.map +0 -1
  175. package/dist/commands/logout.js +0 -22
  176. package/dist/commands/logout.js.map +0 -1
  177. package/dist/commands/me.d.ts +0 -3
  178. package/dist/commands/me.d.ts.map +0 -1
  179. package/dist/commands/me.js +0 -18
  180. package/dist/commands/me.js.map +0 -1
  181. package/dist/commands/send.d.ts +0 -10
  182. package/dist/commands/send.d.ts.map +0 -1
  183. package/dist/commands/send.js +0 -30
  184. package/dist/commands/send.js.map +0 -1
  185. package/dist/protocol/session.d.ts +0 -54
  186. package/dist/protocol/session.d.ts.map +0 -1
  187. package/dist/protocol/session.js +0 -57
  188. package/dist/protocol/session.js.map +0 -1
  189. package/dist/spec/operations/auth.d.ts +0 -42
  190. package/dist/spec/operations/auth.d.ts.map +0 -1
@@ -0,0 +1,292 @@
1
+ import { spawn } from "node:child_process";
2
+ import { randomBytes } from "node:crypto";
3
+ import { existsSync, mkdtempSync, realpathSync, rmSync } from "node:fs";
4
+ import { createServer } from "node:http";
5
+ import { createServer as createTcpServer } from "node:net";
6
+ import { tmpdir } from "node:os";
7
+ import { delimiter, join } from "node:path";
8
+ import { setTimeout as delay } from "node:timers/promises";
9
+ import { CliError } from "@leemour/cli-core";
10
+ import qrcode from "qrcode-generator";
11
+ import { WebSocket } from "ws";
12
+ export const realBrowser = {
13
+ open: (url) => openUrl(url),
14
+ chromiumToken: (options) => tokenFromChromium(options),
15
+ };
16
+ const WEB_MAX = "https://web.max.ru/";
17
+ const AUTH_KEY = "__oneme_auth";
18
+ /**
19
+ * The QR page, served from `127.0.0.1` rather than written to a file: a browser installed as a
20
+ * snap cannot read our temporary directory, and a file would leave the link on disk. The path is
21
+ * random, so another local user guessing the port finds nothing.
22
+ */
23
+ export const serveQrPage = async (link) => {
24
+ const path = `/${randomBytes(16).toString("hex")}`;
25
+ const code = qrcode(0, "M");
26
+ code.addData(link);
27
+ code.make();
28
+ const page = qrHtml(code.createSvgTag({ cellSize: 8, margin: 4, scalable: true }));
29
+ const server = createServer((request, response) => {
30
+ if (request.url !== path) {
31
+ response.writeHead(404).end();
32
+ return;
33
+ }
34
+ response
35
+ .writeHead(200, {
36
+ "content-type": "text/html; charset=utf-8",
37
+ "cache-control": "no-store",
38
+ "referrer-policy": "no-referrer",
39
+ })
40
+ .end(page);
41
+ });
42
+ await new Promise((resolve, reject) => {
43
+ server.once("error", reject);
44
+ server.listen(0, "127.0.0.1", resolve);
45
+ });
46
+ const { port } = server.address();
47
+ return {
48
+ url: `http://127.0.0.1:${port}${path}`,
49
+ close: () => new Promise((resolve) => {
50
+ server.closeAllConnections();
51
+ server.close(() => resolve());
52
+ }),
53
+ };
54
+ };
55
+ const qrHtml = (svg) => `<!doctype html>
56
+ <html lang="ru"><head><meta charset="utf-8"><title>MAX — вход</title>
57
+ <style>body{font-family:system-ui,sans-serif;display:grid;place-items:center;min-height:100vh;margin:0;background:#fff;color:#111}
58
+ main{text-align:center;max-width:22rem}svg{width:18rem;height:18rem}</style></head>
59
+ <body><main>${svg}<p>Отсканируйте код приложением MAX на телефоне. Код действует около двух минут.</p>
60
+ <p>После входа эту вкладку можно закрыть.</p></main></body></html>`;
61
+ export const openUrl = async (url) => {
62
+ refuseInTests();
63
+ const [command, args] = process.platform === "darwin"
64
+ ? ["open", [url]]
65
+ : process.platform === "win32"
66
+ ? ["cmd", ["/c", "start", "", url]]
67
+ : ["xdg-open", [url]];
68
+ await new Promise((resolve, reject) => {
69
+ const child = spawn(command, args, { stdio: "ignore", detached: true, windowsHide: true });
70
+ child.once("error", () => reject(new CliError("configuration_error", "no browser could be opened here — use `session start token`")));
71
+ child.once("spawn", () => {
72
+ child.unref();
73
+ resolve();
74
+ });
75
+ });
76
+ };
77
+ /**
78
+ * Chrome, Chromium, Edge or Brave — any browser that speaks the DevTools protocol. `MAX_BROWSER`
79
+ * names another. A snap build is skipped: it keeps its own `/tmp`, so the profile we hand it would
80
+ * land where we cannot delete it.
81
+ */
82
+ export const findChromium = () => {
83
+ const named = process.env.MAX_BROWSER;
84
+ if (named)
85
+ return named;
86
+ if (process.platform === "darwin") {
87
+ return [
88
+ "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
89
+ "/Applications/Chromium.app/Contents/MacOS/Chromium",
90
+ "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
91
+ "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
92
+ ].find((path) => existsSync(path));
93
+ }
94
+ if (process.platform === "win32") {
95
+ const roots = [process.env.PROGRAMFILES, process.env["PROGRAMFILES(X86)"], process.env.LOCALAPPDATA];
96
+ const apps = [
97
+ "Google\\Chrome\\Application\\chrome.exe",
98
+ "Microsoft\\Edge\\Application\\msedge.exe",
99
+ "BraveSoftware\\Brave-Browser\\Application\\brave.exe",
100
+ ];
101
+ return apps
102
+ .flatMap((app) => roots.filter((root) => root !== undefined).map((root) => join(root, app)))
103
+ .find(existsSync);
104
+ }
105
+ const names = [
106
+ "google-chrome",
107
+ "google-chrome-stable",
108
+ "chromium",
109
+ "chromium-browser",
110
+ "microsoft-edge",
111
+ "microsoft-edge-stable",
112
+ "brave-browser",
113
+ ];
114
+ const dirs = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
115
+ for (const name of names) {
116
+ for (const dir of dirs) {
117
+ const path = join(dir, name);
118
+ if (existsSync(path) && !realpathSync(path).startsWith("/snap/"))
119
+ return path;
120
+ }
121
+ }
122
+ return undefined;
123
+ };
124
+ /**
125
+ * web.max.ru logs itself in — it asks MAX for the QR code, or sends the SMS — in a real browser with
126
+ * a profile of its own, and we read the token it stores once it has one. MAX sees its own web
127
+ * client do the login, not our socket.
128
+ *
129
+ * ⚠ The profile holds a live session, so it is deleted on every way out: success, a closed window,
130
+ * `--timeout`, Ctrl-C.
131
+ */
132
+ export const tokenFromChromium = async ({ track, waitMs, }) => {
133
+ refuseInTests();
134
+ const binary = findChromium();
135
+ if (!binary) {
136
+ throw new CliError("configuration_error", "no Chrome, Chromium, Edge or Brave found — set MAX_BROWSER to one, or use `session start qr`");
137
+ }
138
+ const profile = mkdtempSync(join(tmpdir(), "max-login-"));
139
+ const port = await freePort();
140
+ const child = spawn(binary, [
141
+ `--user-data-dir=${profile}`,
142
+ `--remote-debugging-port=${port}`,
143
+ "--no-first-run",
144
+ "--no-default-browser-check",
145
+ WEB_MAX,
146
+ ], { stdio: "ignore" });
147
+ const browser = new ChromiumSession(child, profile, port);
148
+ track(browser);
149
+ const stopSignals = closeOnSignal(browser);
150
+ try {
151
+ return await browser.waitForToken(waitMs);
152
+ }
153
+ finally {
154
+ stopSignals();
155
+ await browser.close();
156
+ }
157
+ };
158
+ export class ChromiumSession {
159
+ #child;
160
+ #profile;
161
+ #port;
162
+ #exited;
163
+ #graceMs;
164
+ #closing;
165
+ constructor(child, profile, port, graceMs = 5_000) {
166
+ this.#child = child;
167
+ this.#graceMs = graceMs;
168
+ this.#profile = profile;
169
+ this.#port = port;
170
+ this.#exited = new Promise((resolve) => {
171
+ child.once("exit", () => resolve());
172
+ child.once("error", () => resolve());
173
+ });
174
+ }
175
+ async waitForToken(waitMs) {
176
+ const deadline = Date.now() + waitMs;
177
+ let running = true;
178
+ void this.#exited.then(() => {
179
+ running = false;
180
+ });
181
+ while (Date.now() < deadline) {
182
+ if (!running)
183
+ throw new CliError("cancelled", "the browser was closed before the login finished");
184
+ const token = await this.#storedToken().catch(() => undefined);
185
+ if (token)
186
+ return token;
187
+ await delay(1_000);
188
+ }
189
+ throw new CliError("timeout", `nobody logged in within ${Math.round(waitMs / 60_000)} minutes`);
190
+ }
191
+ close() {
192
+ this.#closing ??= this.#shutdown();
193
+ return this.#closing;
194
+ }
195
+ async #shutdown() {
196
+ // Chrome writes to the profile while it shuts down; removing it first leaves half of it behind.
197
+ const version = await this.#json("/json/version").catch(() => undefined);
198
+ const endpoint = typeof version?.webSocketDebuggerUrl === "string" ? version.webSocketDebuggerUrl : undefined;
199
+ if (endpoint)
200
+ await evaluateOver(endpoint, "Browser.close", {}).catch(() => undefined);
201
+ const exited = await Promise.race([this.#exited.then(() => true), delay(this.#graceMs).then(() => false)]);
202
+ if (!exited && this.#child.pid !== undefined) {
203
+ this.#child.kill();
204
+ await Promise.race([this.#exited, delay(2_000)]);
205
+ }
206
+ rmSync(this.#profile, { recursive: true, force: true, maxRetries: 3 });
207
+ }
208
+ async #storedToken() {
209
+ const targets = await this.#json("/json/list");
210
+ const page = (Array.isArray(targets) ? targets : []).find((target) => target?.type === "page" && typeof target.url === "string" && target.url.startsWith(WEB_MAX));
211
+ if (typeof page?.webSocketDebuggerUrl !== "string")
212
+ return undefined;
213
+ const result = await evaluateOver(page.webSocketDebuggerUrl, "Runtime.evaluate", {
214
+ expression: `localStorage.getItem(${JSON.stringify(AUTH_KEY)})`,
215
+ returnByValue: true,
216
+ });
217
+ const stored = result?.result?.value;
218
+ return typeof stored === "string" ? tokenIn(stored) : undefined;
219
+ }
220
+ // biome-ignore lint/suspicious/noExplicitAny: the DevTools answers are read defensively, field by field.
221
+ async #json(path) {
222
+ const response = await fetch(`http://127.0.0.1:${this.#port}${path}`, { signal: AbortSignal.timeout(2_000) });
223
+ return await response.json();
224
+ }
225
+ }
226
+ /**
227
+ * The stored value is JSON holding the token, or the token itself — which one is not measured yet.
228
+ * Either way nothing here prints it.
229
+ */
230
+ export const tokenIn = (stored) => {
231
+ try {
232
+ const parsed = JSON.parse(stored);
233
+ if (typeof parsed === "object" && parsed !== null && "token" in parsed) {
234
+ const token = parsed.token;
235
+ return typeof token === "string" && token !== "" ? token : undefined;
236
+ }
237
+ return typeof parsed === "string" && parsed !== "" ? parsed : undefined;
238
+ }
239
+ catch {
240
+ return stored === "" ? undefined : stored;
241
+ }
242
+ };
243
+ // biome-ignore lint/suspicious/noExplicitAny: see #json.
244
+ const evaluateOver = (endpoint, method, params) => new Promise((resolve, reject) => {
245
+ const socket = new WebSocket(endpoint);
246
+ const timer = setTimeout(() => {
247
+ socket.terminate();
248
+ reject(new Error("the browser did not answer"));
249
+ }, 5_000);
250
+ socket.once("error", (error) => {
251
+ clearTimeout(timer);
252
+ reject(error);
253
+ });
254
+ socket.once("open", () => socket.send(JSON.stringify({ id: 1, method, params })));
255
+ socket.on("message", (data) => {
256
+ const message = JSON.parse(String(data));
257
+ if (message.id !== 1)
258
+ return;
259
+ clearTimeout(timer);
260
+ socket.close();
261
+ resolve(message.result);
262
+ });
263
+ });
264
+ /**
265
+ * Node's default Ctrl-C exits without running a `finally`, which would leave the browser open and
266
+ * its logged-in profile on disk. Returns the function that removes the handlers again.
267
+ */
268
+ const closeOnSignal = (closeable) => {
269
+ const onSignal = () => {
270
+ void closeable.close().finally(() => process.exit(130));
271
+ };
272
+ // `on`, not `once`: a second Ctrl-C during the shutdown would otherwise exit before the profile goes.
273
+ process.on("SIGINT", onSignal);
274
+ process.on("SIGTERM", onSignal);
275
+ return () => {
276
+ process.off("SIGINT", onSignal);
277
+ process.off("SIGTERM", onSignal);
278
+ };
279
+ };
280
+ const freePort = () => new Promise((resolve, reject) => {
281
+ const probe = createTcpServer();
282
+ probe.once("error", reject);
283
+ probe.listen(0, "127.0.0.1", () => {
284
+ const { port } = probe.address();
285
+ probe.close(() => resolve(port));
286
+ });
287
+ });
288
+ const refuseInTests = () => {
289
+ if (process.env.MAX_TEST_SANDBOX)
290
+ throw new Error("a test reached the real browser — inject BrowserDoors");
291
+ };
292
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/session/browser.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@ export interface SessionOptions {
12
12
  * changed in each collection since the one given, so a stored marker is the difference between
13
13
  * re-fetching every chat and every contact on every invocation and receiving the handful that
14
14
  * moved. Where it is kept, and why the merge and the marker share a transaction, is
15
- * `ARCHITECTURE.md`.
15
+ * `docs/architecture/session.md`.
16
16
  *
17
17
  * All four carry the same value: nothing reads presence or drafts, and sending the marker in
18
18
  * those two as well was measured harmless on the real account (`NEED-103`).
@@ -35,5 +35,7 @@ export interface SessionOptions {
35
35
  * diagnostic hook in `MaxClient` saw nothing of the two requests every single invocation makes,
36
36
  * and `max chats list` answers from the LOGIN response without sending anything else.
37
37
  */
38
+ /** How many chats LOGIN is asked for. MAX answers the newest that many, newest first (`FIND-80`). */
39
+ export declare const LOGIN_CHATS = 40;
38
40
  export declare const startSession: (invoke: Invoke, { token, deviceId, chatsCount, sync }: SessionOptions) => Promise<Payload>;
39
41
  //# sourceMappingURL=handshake.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handshake.d.ts","sourceRoot":"","sources":["../../src/session/handshake.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAA;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAInD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY,GACvB,QAAQ,MAAM,EACd,uCAAgD,cAAc,KAC7D,OAAO,CAAC,OAAO,CAajB,CAAA"}
1
+ {"version":3,"file":"handshake.d.ts","sourceRoot":"","sources":["../../src/session/handshake.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAA;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAInD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;;;;;;;GAeG;AACH,qGAAqG;AACrG,eAAO,MAAM,WAAW,KAAK,CAAA;AAE7B,eAAO,MAAM,YAAY,GACvB,QAAQ,MAAM,EACd,uCAAyD,cAAc,KACtE,OAAO,CAAC,OAAO,CAajB,CAAA"}
@@ -16,7 +16,9 @@ import { sessionInit, sessionLogin } from "../spec/operations/session.js";
16
16
  * diagnostic hook in `MaxClient` saw nothing of the two requests every single invocation makes,
17
17
  * and `max chats list` answers from the LOGIN response without sending anything else.
18
18
  */
19
- export const startSession = async (invoke, { token, deviceId, chatsCount = 40, sync = 0 }) => {
19
+ /** How many chats LOGIN is asked for. MAX answers the newest that many, newest first (`FIND-80`). */
20
+ export const LOGIN_CHATS = 40;
21
+ export const startSession = async (invoke, { token, deviceId, chatsCount = LOGIN_CHATS, sync = 0 }) => {
20
22
  await invoke(sessionInit, { userAgent: WEB_USER_AGENT, deviceId });
21
23
  return await invoke(sessionLogin, {
22
24
  token,
@@ -1 +1 @@
1
- {"version":3,"file":"handshake.js","sourceRoot":"","sources":["../../src/session/handshake.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAsBzE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,MAAc,EACd,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,GAAG,EAAE,EAAE,IAAI,GAAG,CAAC,EAAkB,EAC5C,EAAE;IACpB,MAAM,MAAM,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAA;IAElE,OAAO,MAAM,MAAM,CAAC,YAAY,EAAE;QAChC,KAAK;QACL,8FAA8F;QAC9F,WAAW,EAAE,KAAK;QAClB,UAAU;QACV,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,IAAI;QAClB,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,IAAI;KACjB,CAAC,CAAA;AACJ,CAAC,CAAA"}
1
+ {"version":3,"file":"handshake.js","sourceRoot":"","sources":["../../src/session/handshake.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAsBzE;;;;;;;;;;;;;;;GAeG;AACH,qGAAqG;AACrG,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAA;AAE7B,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,MAAc,EACd,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,GAAG,WAAW,EAAE,IAAI,GAAG,CAAC,EAAkB,EACrD,EAAE;IACpB,MAAM,MAAM,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAA;IAElE,OAAO,MAAM,MAAM,CAAC,YAAY,EAAE;QAChC,KAAK;QACL,8FAA8F;QAC9F,WAAW,EAAE,KAAK;QAClB,UAAU;QACV,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,IAAI;QAClB,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,IAAI;KACjB,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -0,0 +1,20 @@
1
+ import type { WireClient } from "../generated/client.generated.js";
2
+ export interface SecondFactor {
3
+ /** Asked only when the account has a cloud password; `again` after a wrong one. */
4
+ askPassword: (hint: string | undefined, again: boolean) => Promise<string>;
5
+ }
6
+ export interface QrLogin extends SecondFactor {
7
+ /** Put the code where a phone can scan it. Resolves once it is shown, not once it is scanned. */
8
+ show: (link: string) => Promise<void>;
9
+ now?: () => number;
10
+ sleep?: (ms: number) => Promise<void>;
11
+ }
12
+ /**
13
+ * The login MAX's web client does itself when it shows a QR code: ask for a code, wait until a phone
14
+ * approves it, then exchange it for a token. Shapes from PyMax 2.4.1 (`auth/qr.py`), not measured.
15
+ *
16
+ * One code per run: an expired one is an error rather than a fresh code, so a person who walked
17
+ * away does not come back to a loop that has been asking MAX for codes all along.
18
+ */
19
+ export declare const tokenByQr: (wire: WireClient, { show, askPassword, now, sleep }: QrLogin) => Promise<string>;
20
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/session/login.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAGlE,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAC3E;AAED,MAAM,WAAW,OAAQ,SAAQ,YAAY;IAC3C,iGAAiG;IACjG,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GACpB,MAAM,UAAU,EAChB,mCAAsD,OAAO,KAC5D,OAAO,CAAC,MAAM,CAiBhB,CAAA"}
@@ -0,0 +1,66 @@
1
+ import { setTimeout as delay } from "node:timers/promises";
2
+ import { CliError } from "@leemour/cli-core";
3
+ /**
4
+ * The login MAX's web client does itself when it shows a QR code: ask for a code, wait until a phone
5
+ * approves it, then exchange it for a token. Shapes from PyMax 2.4.1 (`auth/qr.py`), not measured.
6
+ *
7
+ * One code per run: an expired one is an error rather than a fresh code, so a person who walked
8
+ * away does not come back to a loop that has been asking MAX for codes all along.
9
+ */
10
+ export const tokenByQr = async (wire, { show, askPassword, now = Date.now, sleep = delay }) => {
11
+ const code = await wire.login.qrRequest({});
12
+ const trackId = text(code.trackId, "trackId");
13
+ const expiresAt = typeof code.expiresAt === "number" ? code.expiresAt : now() + 120_000;
14
+ const interval = typeof code.pollingInterval === "number" ? code.pollingInterval : 5_000;
15
+ await show(text(code.qrLink, "qrLink"));
16
+ while (now() < expiresAt) {
17
+ const answer = await wire.login.qrStatus({ trackId });
18
+ if (record(answer.status)?.loginAvailable === true) {
19
+ return await tokenFrom(wire, await wire.login.byQr({ trackId }), askPassword);
20
+ }
21
+ await sleep(interval);
22
+ }
23
+ throw new CliError("timeout", "the QR code expired before it was scanned — run the command again");
24
+ };
25
+ /**
26
+ * A few attempts, not PyMax's endless loop, and not one: a mistyped password would otherwise cost a
27
+ * fresh QR code. Only a person at a terminal gets here, so asking again cannot hang a script.
28
+ */
29
+ const tokenFrom = async (wire, answer, askPassword) => {
30
+ const issued = loginToken(answer);
31
+ if (issued)
32
+ return issued;
33
+ const challenge = record(answer.passwordChallenge);
34
+ if (!challenge)
35
+ throw new CliError("authentication_error", "MAX confirmed the login but sent no token");
36
+ const trackId = text(challenge.trackId, "trackId");
37
+ const hint = typeof challenge.hint === "string" && challenge.hint !== "" ? challenge.hint : undefined;
38
+ for (let attempt = 1; attempt <= PASSWORD_ATTEMPTS; attempt++) {
39
+ const password = await askPassword(hint, attempt > 1);
40
+ if (!password)
41
+ throw new CliError("validation_error", "no password given");
42
+ const checked = await wire.login.password({ trackId, password }).catch((error) => {
43
+ if (wrongPassword(error))
44
+ return undefined;
45
+ throw error;
46
+ });
47
+ const token = checked && loginToken(checked);
48
+ if (token)
49
+ return token;
50
+ }
51
+ throw new CliError("authentication_error", `the password was wrong ${PASSWORD_ATTEMPTS} times — run the command again`);
52
+ };
53
+ const PASSWORD_ATTEMPTS = 3;
54
+ // Measured 2026-09-24: a wrong cloud password is refused as `password2fa.wrong`.
55
+ const wrongPassword = (error) => error instanceof CliError && /password2fa\.wrong/.test(error.message);
56
+ const loginToken = (answer) => {
57
+ const token = record(record(answer.tokenAttrs)?.LOGIN)?.token;
58
+ return typeof token === "string" && token !== "" ? token : undefined;
59
+ };
60
+ const text = (value, field) => {
61
+ if (typeof value === "string" && value !== "")
62
+ return value;
63
+ throw new CliError("provider_error", `MAX's answer had no ${field}`);
64
+ };
65
+ const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
66
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/session/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAgB5C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,IAAgB,EAChB,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG,KAAK,EAAW,EAC5C,EAAE;IACnB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IAC7C,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,OAAO,CAAA;IACvF,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAA;IAExF,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;IAEvC,OAAO,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;QACrD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,cAAc,KAAK,IAAI,EAAE,CAAC;YACnD,OAAO,MAAM,SAAS,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,CAAC,CAAA;QAC/E,CAAC;QACD,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAA;IACvB,CAAC;IAED,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE,mEAAmE,CAAC,CAAA;AACpG,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,SAAS,GAAG,KAAK,EAAE,IAAgB,EAAE,MAAe,EAAE,WAAwC,EAAE,EAAE;IACtG,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;IACjC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAA;IAEzB,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAA;IAClD,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,QAAQ,CAAC,sBAAsB,EAAE,2CAA2C,CAAC,CAAA;IAEvG,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IAClD,MAAM,IAAI,GAAG,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;IAErG,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,iBAAiB,EAAE,OAAO,EAAE,EAAE,CAAC;QAC9D,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,CAAC,CAAC,CAAA;QACrD,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,CAAA;QAE1E,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACxF,IAAI,aAAa,CAAC,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAA;YAC1C,MAAM,KAAK,CAAA;QACb,CAAC,CAAC,CAAA;QACF,MAAM,KAAK,GAAG,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;QAC5C,IAAI,KAAK;YAAE,OAAO,KAAK,CAAA;IACzB,CAAC;IACD,MAAM,IAAI,QAAQ,CAChB,sBAAsB,EACtB,0BAA0B,iBAAiB,gCAAgC,CAC5E,CAAA;AACH,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,CAAC,CAAA;AAE3B,iFAAiF;AACjF,MAAM,aAAa,GAAG,CAAC,KAAc,EAAW,EAAE,CAAC,KAAK,YAAY,QAAQ,IAAI,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AAExH,MAAM,UAAU,GAAG,CAAC,MAAe,EAAsB,EAAE;IACzD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,CAAA;IAC7D,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACtE,CAAC,CAAA;AAED,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,KAAa,EAAU,EAAE;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,KAAK,CAAA;IAC3D,MAAM,IAAI,QAAQ,CAAC,gBAAgB,EAAE,uBAAuB,KAAK,EAAE,CAAC,CAAA;AACtE,CAAC,CAAA;AAED,MAAM,MAAM,GAAG,CAAC,KAAc,EAAuB,EAAE,CACrD,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAiB,CAAC,CAAC,CAAC,SAAS,CAAA"}
@@ -3,6 +3,8 @@ export interface SecretInput {
3
3
  isTTY?: boolean;
4
4
  };
5
5
  output?: NodeJS.WritableStream;
6
+ /** For a phone number or an SMS code, which a person needs to see while typing. */
7
+ echo?: boolean;
6
8
  }
7
9
  /**
8
10
  * One line of secret, taken without a file and without argv.
@@ -14,5 +16,5 @@ export interface SecretInput {
14
16
  * The prompt goes to **stderr**, not stdout, so that `max session start --json` still writes one JSON
15
17
  * value and nothing else.
16
18
  */
17
- export declare const readSecret: (prompt: string, { input, output }?: SecretInput) => Promise<string>;
19
+ export declare const readSecret: (prompt: string, { input, output, echo }?: SecretInput) => Promise<string>;
18
20
  //# sourceMappingURL=prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/session/prompt.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAA;CAC/B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,GACrB,QAAQ,MAAM,EACd,oBAAoD,WAAgB,KACnE,OAAO,CAAC,MAAM,CA0BhB,CAAA"}
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/session/prompt.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAA;IAC9B,mFAAmF;IACnF,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,GACrB,QAAQ,MAAM,EACd,0BAAkE,WAAgB,KACjF,OAAO,CAAC,MAAM,CA0BhB,CAAA"}
@@ -10,7 +10,7 @@ import { Writable } from "node:stream";
10
10
  * The prompt goes to **stderr**, not stdout, so that `max session start --json` still writes one JSON
11
11
  * value and nothing else.
12
12
  */
13
- export const readSecret = async (prompt, { input = process.stdin, output = process.stderr } = {}) => {
13
+ export const readSecret = async (prompt, { input = process.stdin, output = process.stderr, echo = false } = {}) => {
14
14
  if (!input.isTTY) {
15
15
  const chunks = [];
16
16
  for await (const chunk of input)
@@ -29,7 +29,7 @@ export const readSecret = async (prompt, { input = process.stdin, output = proce
29
29
  try {
30
30
  const answer = await new Promise((resolve) => {
31
31
  reader.question(prompt, resolve);
32
- muted = true;
32
+ muted = !echo;
33
33
  });
34
34
  return answer.trim();
35
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/session/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAOtC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC7B,MAAc,EACd,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,KAAkB,EAAE,EACnD,EAAE;IACnB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAChE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;IACtD,CAAC;IAED,IAAI,KAAK,GAAG,KAAK,CAAA;IACjB,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC;QACxB,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI;YAC1B,IAAI,CAAC,KAAK;gBAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YAC/B,IAAI,EAAE,CAAA;QACR,CAAC;KACF,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IACvE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YACnD,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;YAChC,KAAK,GAAG,IAAI,CAAA;QACd,CAAC,CAAC,CAAA;QACF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;IACtB,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,KAAK,EAAE,CAAA;QACd,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACpB,CAAC;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/session/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAStC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAC7B,MAAc,EACd,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,GAAG,KAAK,KAAkB,EAAE,EACjE,EAAE;IACnB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAChE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;IACtD,CAAC;IAED,IAAI,KAAK,GAAG,KAAK,CAAA;IACjB,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC;QACxB,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI;YAC1B,IAAI,CAAC,KAAK;gBAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YAC/B,IAAI,EAAE,CAAA;QACR,CAAC;KACF,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IACvE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YACnD,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;YAChC,KAAK,GAAG,CAAC,IAAI,CAAA;QACf,CAAC,CAAC,CAAA;QACF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;IACtB,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,KAAK,EAAE,CAAA;QACd,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACpB,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * A QR code as text, two modules per character cell with half blocks, so it fits a terminal
3
+ * without being twice as tall as it is wide. `width` is in columns, for deciding whether it fits.
4
+ */
5
+ export declare const terminalQr: (link: string) => {
6
+ text: string;
7
+ width: number;
8
+ };
9
+ //# sourceMappingURL=qr-terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr-terminal.d.ts","sourceRoot":"","sources":["../../src/session/qr-terminal.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAwBtE,CAAA"}
@@ -0,0 +1,34 @@
1
+ import qrcode from "qrcode-generator";
2
+ const QUIET_ZONE = 4;
3
+ // Dark modules on a light ground whatever the terminal's theme: a phone camera reads an inverted
4
+ // code unreliably, so the colours are forced even under NO_COLOR.
5
+ const BLACK_ON_WHITE = "\x1b[30;107m";
6
+ const RESET = "\x1b[0m";
7
+ /**
8
+ * A QR code as text, two modules per character cell with half blocks, so it fits a terminal
9
+ * without being twice as tall as it is wide. `width` is in columns, for deciding whether it fits.
10
+ */
11
+ export const terminalQr = (link) => {
12
+ const code = qrcode(0, "M");
13
+ code.addData(link);
14
+ code.make();
15
+ const count = code.getModuleCount();
16
+ const size = count + QUIET_ZONE * 2;
17
+ const dark = (row, col) => {
18
+ const r = row - QUIET_ZONE;
19
+ const c = col - QUIET_ZONE;
20
+ return r >= 0 && c >= 0 && r < count && c < count && code.isDark(r, c);
21
+ };
22
+ const lines = [];
23
+ for (let row = 0; row < size; row += 2) {
24
+ let line = "";
25
+ for (let col = 0; col < size; col++) {
26
+ const top = dark(row, col);
27
+ const bottom = row + 1 < size && dark(row + 1, col);
28
+ line += top && bottom ? "█" : top ? "▀" : bottom ? "▄" : " ";
29
+ }
30
+ lines.push(`${BLACK_ON_WHITE}${line}${RESET}`);
31
+ }
32
+ return { text: lines.join("\n"), width: size };
33
+ };
34
+ //# sourceMappingURL=qr-terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr-terminal.js","sourceRoot":"","sources":["../../src/session/qr-terminal.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,kBAAkB,CAAA;AAErC,MAAM,UAAU,GAAG,CAAC,CAAA;AACpB,iGAAiG;AACjG,kEAAkE;AAClE,MAAM,cAAc,GAAG,cAAc,CAAA;AACrC,MAAM,KAAK,GAAG,SAAS,CAAA;AAEvB;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAmC,EAAE;IAC1E,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAClB,IAAI,CAAC,IAAI,EAAE,CAAA;IAEX,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAA;IACnC,MAAM,IAAI,GAAG,KAAK,GAAG,UAAU,GAAG,CAAC,CAAA;IACnC,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE;QACxC,MAAM,CAAC,GAAG,GAAG,GAAG,UAAU,CAAA;QAC1B,MAAM,CAAC,GAAG,GAAG,GAAG,UAAU,CAAA;QAC1B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACxE,CAAC,CAAA;IAED,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QACvC,IAAI,IAAI,GAAG,EAAE,CAAA;QACb,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;YAC1B,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;YACnD,IAAI,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;QAC9D,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,GAAG,cAAc,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC,CAAA;IAChD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;AAChD,CAAC,CAAA"}
@@ -14,6 +14,8 @@ export interface SessionState {
14
14
  /** Counts logins so a token that stops working can be explained rather than guessed at (NEED-8). */
15
15
  logins: number;
16
16
  lastLoginAt?: string;
17
+ /** Where `max inbox` starts next time: the newest message it has read (`NEED-162`). */
18
+ lastCheckAt?: string;
17
19
  }
18
20
  export interface SessionStoreOptions {
19
21
  profile?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/session/store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAe,KAAK,YAAY,EAAmD,MAAM,mBAAmB,CAAA;AAEnH;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oGAAoG;IACpG,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAID,qBAAa,YAAY;;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAIZ,EAAE,OAAmB,EAAE,GAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAE,mBAAwB;IAe9G,8DAA8D;IAC9D,SAAS,IAAI,MAAM,GAAG,SAAS;IAI/B,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B;;;;;;;OAOG;IACH,SAAS,IAAI,YAAY;IAezB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAIrC,0FAA0F;IAC1F,MAAM,IAAI,OAAO;CAclB"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/session/store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAe,KAAK,YAAY,EAAmD,MAAM,mBAAmB,CAAA;AAEnH;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oGAAoG;IACpG,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uFAAuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAID,qBAAa,YAAY;;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAIZ,EAAE,OAAmB,EAAE,GAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAE,mBAAwB;IAe9G,8DAA8D;IAC9D,SAAS,IAAI,MAAM,GAAG,SAAS;IAI/B,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B;;;;;;;OAOG;IACH,SAAS,IAAI,YAAY;IAezB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAIrC,0FAA0F;IAC1F,MAAM,IAAI,OAAO;CAclB"}
@@ -75,6 +75,8 @@ const pick = (state) => {
75
75
  extra.viewerId = state.viewerId;
76
76
  if (typeof state.lastLoginAt === "string")
77
77
  extra.lastLoginAt = state.lastLoginAt;
78
+ if (typeof state.lastCheckAt === "string")
79
+ extra.lastCheckAt = state.lastCheckAt;
78
80
  return extra;
79
81
  };
80
82
  //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/session/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/session/store.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/spec/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAMhE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAE5B;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,EAAE,SAAS,KAAK,EAYhC,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EAA2E,CAAA;AAEtH,eAAO,MAAM,YAAY,EAAE,SAAS,WAAW,EAE9C,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/spec/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAgBhE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAE5B;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,EAAE,SAAS,KAAK,EAuBhC,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EAA2E,CAAA;AAEtH,eAAO,MAAM,YAAY,EAAE,SAAS,WAAW,EAE9C,CAAA"}