@leemour/max-cli 0.5.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 (141) hide show
  1. package/README.md +14 -5
  2. package/dist/cache/store.d.ts.map +1 -1
  3. package/dist/cache/store.js +1 -0
  4. package/dist/cache/store.js.map +1 -1
  5. package/dist/client.d.ts +57 -3
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +229 -78
  8. package/dist/client.js.map +1 -1
  9. package/dist/commands/commands.d.ts +8 -0
  10. package/dist/commands/commands.d.ts.map +1 -0
  11. package/dist/commands/commands.js +36 -0
  12. package/dist/commands/commands.js.map +1 -0
  13. package/dist/commands/config.d.ts.map +1 -1
  14. package/dist/commands/config.js +2 -0
  15. package/dist/commands/config.js.map +1 -1
  16. package/dist/commands/context.d.ts +18 -0
  17. package/dist/commands/context.d.ts.map +1 -1
  18. package/dist/commands/context.js +21 -0
  19. package/dist/commands/context.js.map +1 -1
  20. package/dist/commands/inbox.d.ts +14 -0
  21. package/dist/commands/inbox.d.ts.map +1 -0
  22. package/dist/commands/inbox.js +90 -0
  23. package/dist/commands/inbox.js.map +1 -0
  24. package/dist/commands/messages.d.ts.map +1 -1
  25. package/dist/commands/messages.js +6 -2
  26. package/dist/commands/messages.js.map +1 -1
  27. package/dist/commands/reactions.d.ts +3 -0
  28. package/dist/commands/reactions.d.ts.map +1 -0
  29. package/dist/commands/reactions.js +26 -0
  30. package/dist/commands/reactions.js.map +1 -0
  31. package/dist/commands/recipients.d.ts +9 -0
  32. package/dist/commands/recipients.d.ts.map +1 -0
  33. package/dist/commands/recipients.js +68 -0
  34. package/dist/commands/recipients.js.map +1 -0
  35. package/dist/commands/sends.d.ts +4 -0
  36. package/dist/commands/sends.d.ts.map +1 -0
  37. package/dist/commands/sends.js +21 -0
  38. package/dist/commands/sends.js.map +1 -0
  39. package/dist/commands/session.d.ts.map +1 -1
  40. package/dist/commands/session.js +80 -15
  41. package/dist/commands/session.js.map +1 -1
  42. package/dist/commands/skill.d.ts.map +1 -1
  43. package/dist/commands/skill.js +2 -1
  44. package/dist/commands/skill.js.map +1 -1
  45. package/dist/config.d.ts +9 -1
  46. package/dist/config.d.ts.map +1 -1
  47. package/dist/config.js +16 -0
  48. package/dist/config.js.map +1 -1
  49. package/dist/domain/map.d.ts +3 -1
  50. package/dist/domain/map.d.ts.map +1 -1
  51. package/dist/domain/map.js +9 -0
  52. package/dist/domain/map.js.map +1 -1
  53. package/dist/domain/models.d.ts +33 -0
  54. package/dist/domain/models.d.ts.map +1 -1
  55. package/dist/domain/models.js.map +1 -1
  56. package/dist/generated/client.generated.d.ts +10 -0
  57. package/dist/generated/client.generated.d.ts.map +1 -1
  58. package/dist/generated/client.generated.js +10 -0
  59. package/dist/generated/client.generated.js.map +1 -1
  60. package/dist/generated/opcodes.generated.d.ts +13 -0
  61. package/dist/generated/opcodes.generated.d.ts.map +1 -1
  62. package/dist/generated/opcodes.generated.js +13 -0
  63. package/dist/generated/opcodes.generated.js.map +1 -1
  64. package/dist/generated/operations.generated.d.ts +86 -1
  65. package/dist/generated/operations.generated.d.ts.map +1 -1
  66. package/dist/generated/operations.generated.js +10 -1
  67. package/dist/generated/operations.generated.js.map +1 -1
  68. package/dist/markdown.d.ts +18 -0
  69. package/dist/markdown.d.ts.map +1 -0
  70. package/dist/markdown.js +52 -0
  71. package/dist/markdown.js.map +1 -0
  72. package/dist/program.d.ts.map +1 -1
  73. package/dist/program.js +10 -0
  74. package/dist/program.js.map +1 -1
  75. package/dist/rendering/messages.d.ts.map +1 -1
  76. package/dist/rendering/messages.js +6 -0
  77. package/dist/rendering/messages.js.map +1 -1
  78. package/dist/resolve.d.ts +15 -0
  79. package/dist/resolve.d.ts.map +1 -0
  80. package/dist/resolve.js +48 -0
  81. package/dist/resolve.js.map +1 -0
  82. package/dist/sends/guard.d.ts +26 -0
  83. package/dist/sends/guard.d.ts.map +1 -0
  84. package/dist/sends/guard.js +48 -0
  85. package/dist/sends/guard.js.map +1 -0
  86. package/dist/sends/journal.d.ts +29 -0
  87. package/dist/sends/journal.d.ts.map +1 -0
  88. package/dist/sends/journal.js +40 -0
  89. package/dist/sends/journal.js.map +1 -0
  90. package/dist/sends/recipients.d.ts +29 -0
  91. package/dist/sends/recipients.d.ts.map +1 -0
  92. package/dist/sends/recipients.js +62 -0
  93. package/dist/sends/recipients.js.map +1 -0
  94. package/dist/session/adopt.d.ts.map +1 -1
  95. package/dist/session/adopt.js +7 -6
  96. package/dist/session/adopt.js.map +1 -1
  97. package/dist/session/browser.d.ts +55 -0
  98. package/dist/session/browser.d.ts.map +1 -0
  99. package/dist/session/browser.js +292 -0
  100. package/dist/session/browser.js.map +1 -0
  101. package/dist/session/handshake.d.ts +2 -0
  102. package/dist/session/handshake.d.ts.map +1 -1
  103. package/dist/session/handshake.js +3 -1
  104. package/dist/session/handshake.js.map +1 -1
  105. package/dist/session/login.d.ts +20 -0
  106. package/dist/session/login.d.ts.map +1 -0
  107. package/dist/session/login.js +66 -0
  108. package/dist/session/login.js.map +1 -0
  109. package/dist/session/prompt.d.ts +3 -1
  110. package/dist/session/prompt.d.ts.map +1 -1
  111. package/dist/session/prompt.js +2 -2
  112. package/dist/session/prompt.js.map +1 -1
  113. package/dist/session/qr-terminal.d.ts +9 -0
  114. package/dist/session/qr-terminal.d.ts.map +1 -0
  115. package/dist/session/qr-terminal.js +34 -0
  116. package/dist/session/qr-terminal.js.map +1 -0
  117. package/dist/session/store.d.ts +2 -0
  118. package/dist/session/store.d.ts.map +1 -1
  119. package/dist/session/store.js +2 -0
  120. package/dist/session/store.js.map +1 -1
  121. package/dist/spec/index.d.ts.map +1 -1
  122. package/dist/spec/index.js +11 -1
  123. package/dist/spec/index.js.map +1 -1
  124. package/dist/spec/operations/login.d.ts +64 -0
  125. package/dist/spec/operations/login.d.ts.map +1 -0
  126. package/dist/spec/operations/login.js +99 -0
  127. package/dist/spec/operations/login.js.map +1 -0
  128. package/dist/spec/operations/messages.d.ts +27 -1
  129. package/dist/spec/operations/messages.d.ts.map +1 -1
  130. package/dist/spec/operations/messages.js +46 -2
  131. package/dist/spec/operations/messages.js.map +1 -1
  132. package/dist/testing/mock-max.d.ts +3 -2
  133. package/dist/testing/mock-max.d.ts.map +1 -1
  134. package/dist/testing/mock-max.js +1 -1
  135. package/dist/testing/mock-max.js.map +1 -1
  136. package/dist/testing/sandbox.js +1 -0
  137. package/dist/testing/sandbox.js.map +1 -1
  138. package/dist/version.d.ts +1 -1
  139. package/dist/version.js +1 -1
  140. package/package.json +7 -3
  141. package/skills/max-cli/SKILL.md +14 -3
@@ -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":"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"}
@@ -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;AAOhE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAE5B;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,EAAE,SAAS,KAAK,EAchC,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"}
@@ -1,7 +1,8 @@
1
1
  import { attachmentsFile, attachmentsVideo } from "./operations/attachments.js";
2
2
  import { chatMark, chatsHistory, chatsList } from "./operations/chats.js";
3
3
  import { contactsInfo, profile, unidentified36 } from "./operations/contacts.js";
4
- import { messageDelete, messagesSend } from "./operations/messages.js";
4
+ import { loginByQr, loginPassword, loginQrRequest, loginQrStatus, loginSmsCode, loginSmsRequest, qrApprove, } from "./operations/login.js";
5
+ import { messageDelete, messagesReact, messagesReactions, messagesSend } from "./operations/messages.js";
5
6
  import { logout, sessionInit, sessionLogin } from "./operations/session.js";
6
7
  export { checkResponse } from "./check.js";
7
8
  export * from "./define.js";
@@ -17,6 +18,13 @@ export const spec = [
17
18
  sessionInit,
18
19
  sessionLogin,
19
20
  logout,
21
+ loginQrRequest,
22
+ loginQrStatus,
23
+ loginByQr,
24
+ qrApprove,
25
+ loginSmsRequest,
26
+ loginSmsCode,
27
+ loginPassword,
20
28
  contactsInfo,
21
29
  profile,
22
30
  unidentified36,
@@ -24,6 +32,8 @@ export const spec = [
24
32
  chatMark,
25
33
  chatsList,
26
34
  messagesSend,
35
+ messagesReact,
36
+ messagesReactions,
27
37
  messageDelete,
28
38
  attachmentsVideo,
29
39
  attachmentsFile,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/spec/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAC/E,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACzE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACtE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAE3E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAE5B;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,IAAI,GAAqB;IACpC,WAAW;IACX,YAAY;IACZ,MAAM;IACN,YAAY;IACZ,OAAO;IACP,cAAc;IACd,YAAY;IACZ,QAAQ;IACR,SAAS;IACT,YAAY;IACZ,aAAa;IACb,gBAAgB;IAChB,eAAe;CAChB,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAyB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAsB,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,CAAA;AAEtH,MAAM,CAAC,MAAM,YAAY,GAA2B,IAAI,CAAC,MAAM,CAC7D,CAAC,KAAK,EAAwB,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,CAC9D,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/spec/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAC/E,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACzE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAChF,OAAO,EACL,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACZ,eAAe,EACf,SAAS,GACV,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACxG,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAE3E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAE5B;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,IAAI,GAAqB;IACpC,WAAW;IACX,YAAY;IACZ,MAAM;IACN,cAAc;IACd,aAAa;IACb,SAAS;IACT,SAAS;IACT,eAAe;IACf,YAAY;IACZ,aAAa;IACb,YAAY;IACZ,OAAO;IACP,cAAc;IACd,YAAY;IACZ,QAAQ;IACR,SAAS;IACT,YAAY;IACZ,aAAa;IACb,iBAAiB;IACjB,aAAa;IACb,gBAAgB;IAChB,eAAe;CAChB,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAyB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAsB,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,CAAA;AAEtH,MAAM,CAAC,MAAM,YAAY,GAA2B,IAAI,CAAC,MAAM,CAC7D,CAAC,KAAK,EAAwB,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,CAC9D,CAAA"}
@@ -0,0 +1,64 @@
1
+ import * as v from "valibot";
2
+ export declare const loginQrRequest: import("../define.js").Operation<v.StrictObjectSchema<{}, undefined>, v.LooseObjectSchema<{
3
+ readonly qrLink: v.StringSchema<undefined>;
4
+ readonly trackId: v.StringSchema<undefined>;
5
+ readonly pollingInterval: v.NumberSchema<undefined>;
6
+ readonly expiresAt: v.NumberSchema<undefined>;
7
+ }, undefined>>;
8
+ export declare const loginQrStatus: import("../define.js").Operation<v.StrictObjectSchema<{
9
+ readonly trackId: v.StringSchema<undefined>;
10
+ }, undefined>, v.LooseObjectSchema<{
11
+ readonly status: v.LooseObjectSchema<{
12
+ readonly expiresAt: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
13
+ readonly loginAvailable: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
14
+ }, undefined>;
15
+ }, undefined>>;
16
+ export declare const loginByQr: import("../define.js").Operation<v.StrictObjectSchema<{
17
+ readonly trackId: v.StringSchema<undefined>;
18
+ }, undefined>, v.LooseObjectSchema<{
19
+ tokenAttrs: v.OptionalSchema<v.LooseObjectSchema<{
20
+ readonly LOGIN: v.OptionalSchema<v.LooseObjectSchema<{
21
+ readonly token: v.StringSchema<undefined>;
22
+ }, undefined>, undefined>;
23
+ }, undefined>, undefined>;
24
+ passwordChallenge: v.OptionalSchema<v.LooseObjectSchema<{
25
+ readonly trackId: v.StringSchema<undefined>;
26
+ readonly hint: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
27
+ }, undefined>, undefined>;
28
+ }, undefined>>;
29
+ export declare const loginSmsRequest: import("../define.js").Operation<v.StrictObjectSchema<{
30
+ readonly phone: v.StringSchema<undefined>;
31
+ readonly type: v.LiteralSchema<"START_AUTH", undefined>;
32
+ readonly language: v.StringSchema<undefined>;
33
+ }, undefined>, v.LooseObjectSchema<{
34
+ readonly token: v.StringSchema<undefined>;
35
+ readonly codeLength: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
36
+ }, undefined>>;
37
+ export declare const loginSmsCode: import("../define.js").Operation<v.StrictObjectSchema<{
38
+ readonly token: v.StringSchema<undefined>;
39
+ readonly verifyCode: v.StringSchema<undefined>;
40
+ readonly authTokenType: v.LiteralSchema<"CHECK_CODE", undefined>;
41
+ }, undefined>, v.LooseObjectSchema<{
42
+ tokenAttrs: v.OptionalSchema<v.LooseObjectSchema<{
43
+ readonly LOGIN: v.OptionalSchema<v.LooseObjectSchema<{
44
+ readonly token: v.StringSchema<undefined>;
45
+ }, undefined>, undefined>;
46
+ }, undefined>, undefined>;
47
+ passwordChallenge: v.OptionalSchema<v.LooseObjectSchema<{
48
+ readonly trackId: v.StringSchema<undefined>;
49
+ readonly hint: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
50
+ }, undefined>, undefined>;
51
+ }, undefined>>;
52
+ export declare const loginPassword: import("../define.js").Operation<v.StrictObjectSchema<{
53
+ readonly trackId: v.StringSchema<undefined>;
54
+ readonly password: v.StringSchema<undefined>;
55
+ }, undefined>, v.LooseObjectSchema<{
56
+ readonly tokenAttrs: v.OptionalSchema<v.LooseObjectSchema<{
57
+ readonly LOGIN: v.OptionalSchema<v.LooseObjectSchema<{
58
+ readonly token: v.StringSchema<undefined>;
59
+ }, undefined>, undefined>;
60
+ }, undefined>, undefined>;
61
+ readonly error: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
62
+ }, undefined>>;
63
+ export declare const qrApprove: import("../define.js").Reservation;
64
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/spec/operations/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAe5B,eAAO,MAAM,cAAc;;;;;cAgBzB,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;cAexB,CAAA;AAEF,eAAO,MAAM,SAAS;;;;;;;;;;;;cAWpB,CAAA;AAEF,eAAO,MAAM,eAAe;;;;;;;cAa1B,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;cAQvB,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;cAYxB,CAAA;AAEF,eAAO,MAAM,SAAS,oCAOpB,CAAA"}
@@ -0,0 +1,99 @@
1
+ import * as v from "valibot";
2
+ import { defineOperation, reserveOpcode } from "../define.js";
3
+ /**
4
+ * How MAX hands over a token once a person has proved who they are — by QR, SMS code or password.
5
+ * ⚠ **It is a credential**: nothing prints it, logs it or puts it in a fixture.
6
+ */
7
+ const Issued = {
8
+ tokenAttrs: v.optional(v.looseObject({ LOGIN: v.optional(v.looseObject({ token: v.string() })) })),
9
+ passwordChallenge: v.optional(v.looseObject({ trackId: v.string(), hint: v.optional(v.string()) })),
10
+ };
11
+ const PYMAX = "PyMax 2.4.1 src/pymax/api/auth/service.py, GitHub 53103f0";
12
+ const DOCS = "max-api-docs/protocol/auth.md (dac4b19)";
13
+ export const loginQrRequest = defineOperation({
14
+ name: "login.qrRequest",
15
+ constant: "GET_QR",
16
+ opcode: 288,
17
+ auth: false,
18
+ request: v.strictObject({}),
19
+ response: v.looseObject({
20
+ qrLink: v.string(),
21
+ trackId: v.string(),
22
+ pollingInterval: v.number(),
23
+ expiresAt: v.number(),
24
+ }),
25
+ provenance: {
26
+ confidence: "measured",
27
+ sources: ["measured against MAX 2026-09-24: `session start qr` logged in", PYMAX, DOCS],
28
+ },
29
+ });
30
+ export const loginQrStatus = defineOperation({
31
+ name: "login.qrStatus",
32
+ constant: "GET_QR_STATUS",
33
+ opcode: 289,
34
+ auth: false,
35
+ request: v.strictObject({ trackId: v.string() }),
36
+ response: v.looseObject({
37
+ status: v.looseObject({ expiresAt: v.optional(v.number()), loginAvailable: v.optional(v.boolean()) }),
38
+ }),
39
+ provenance: {
40
+ confidence: "measured",
41
+ sources: ["measured against MAX 2026-09-24: `session start qr` logged in", PYMAX, DOCS],
42
+ notes: "`loginAvailable` is in PyMax only. The protocol notes say the token arrives as a push of opcode 18 instead.",
43
+ },
44
+ });
45
+ export const loginByQr = defineOperation({
46
+ name: "login.byQr",
47
+ constant: "LOGIN_BY_QR",
48
+ opcode: 291,
49
+ auth: false,
50
+ request: v.strictObject({ trackId: v.string() }),
51
+ response: v.looseObject(Issued),
52
+ provenance: {
53
+ confidence: "measured",
54
+ sources: ["measured against MAX 2026-09-24: `session start qr` logged in", PYMAX],
55
+ },
56
+ });
57
+ export const loginSmsRequest = defineOperation({
58
+ name: "login.smsRequest",
59
+ constant: "AUTH_REQUEST",
60
+ opcode: 17,
61
+ auth: false,
62
+ request: v.strictObject({ phone: v.string(), type: v.literal("START_AUTH"), language: v.string() }),
63
+ response: v.looseObject({ token: v.string(), codeLength: v.optional(v.number()) }),
64
+ provenance: {
65
+ confidence: "confirmed",
66
+ sources: [PYMAX, DOCS],
67
+ notes: "Measured 2026-09-24: MAX refused the first request with a captcha demand, which only the web page can solve. So `session start sms` opens web.max.ru instead of sending this; nothing sends it.",
68
+ },
69
+ });
70
+ export const loginSmsCode = defineOperation({
71
+ name: "login.smsCode",
72
+ constant: "AUTH",
73
+ opcode: 18,
74
+ auth: false,
75
+ request: v.strictObject({ token: v.string(), verifyCode: v.string(), authTokenType: v.literal("CHECK_CODE") }),
76
+ response: v.looseObject(Issued),
77
+ provenance: { confidence: "confirmed", sources: [PYMAX, DOCS] },
78
+ });
79
+ export const loginPassword = defineOperation({
80
+ name: "login.password",
81
+ constant: "AUTH_LOGIN_CHECK_PASSWORD",
82
+ opcode: 115,
83
+ auth: false,
84
+ request: v.strictObject({ trackId: v.string(), password: v.string() }),
85
+ response: v.looseObject({ tokenAttrs: Issued.tokenAttrs, error: v.optional(v.string()) }),
86
+ provenance: {
87
+ confidence: "measured",
88
+ sources: ["measured against MAX 2026-09-24: `session start qr` on an account with a cloud password", PYMAX],
89
+ notes: "A wrong password is refused as `password2fa.wrong`, and the same `trackId` takes another attempt.",
90
+ },
91
+ });
92
+ export const qrApprove = reserveOpcode({
93
+ name: "login.qrApprove",
94
+ constant: "AUTH_QR_APPROVE",
95
+ opcode: 290,
96
+ reason: "The phone's side of a QR login: it lets whoever showed the code into the owner's account. A CLI logging itself in never approves anybody.",
97
+ provenance: { confidence: "observed", sources: [PYMAX] },
98
+ });
99
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/spec/operations/login.ts"],"names":[],"mappings":"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"}
@@ -8,12 +8,38 @@ export declare const messagesSend: import("../define.js").Operation<v.StrictObje
8
8
  * never be regenerated on a retry: a fresh one means a second message in somebody's chat.
9
9
  */
10
10
  readonly cid: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>]>;
11
- readonly elements: v.ArraySchema<v.UnknownSchema, undefined>;
11
+ /** Markup in UTF-16 positions. STRONG, EMPHASIZED, STRIKETHROUGH, MONOSPACED read back from MAX 2026-09-24. */
12
+ readonly elements: v.ArraySchema<v.StrictObjectSchema<{
13
+ readonly type: v.StringSchema<undefined>;
14
+ readonly from: v.NumberSchema<undefined>;
15
+ readonly length: v.NumberSchema<undefined>;
16
+ }, undefined>, undefined>;
12
17
  readonly attaches: v.ArraySchema<v.UnknownSchema, undefined>;
18
+ /** Read back as `{type, chatId, message}` — the quoted message whole (measured 2026-09-23). */
19
+ readonly link: v.OptionalSchema<v.StrictObjectSchema<{
20
+ readonly type: v.LiteralSchema<"REPLY", undefined>;
21
+ readonly messageId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "an id is a whole number written as a string">, v.TransformAction<string, bigint>]>;
22
+ }, undefined>, undefined>;
13
23
  }, undefined>;
14
24
  readonly notify: v.BooleanSchema<undefined>;
15
25
  }, undefined>, v.LooseObjectSchema<{
16
26
  readonly message: v.OptionalSchema<v.LooseObjectSchema<{}, undefined>, undefined>;
17
27
  }, undefined>>;
28
+ export declare const messagesReactions: import("../define.js").Operation<v.StrictObjectSchema<{
29
+ readonly chatId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "an id is a whole number written as a string">, v.TransformAction<string, bigint>]>;
30
+ readonly messageIds: v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "an id is a whole number written as a string">, v.TransformAction<string, bigint>]>, undefined>;
31
+ }, undefined>, v.LooseObjectSchema<{
32
+ readonly messagesReactions: v.OptionalSchema<v.LooseObjectSchema<{}, undefined>, undefined>;
33
+ }, undefined>>;
34
+ export declare const messagesReact: import("../define.js").Operation<v.StrictObjectSchema<{
35
+ readonly chatId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "an id is a whole number written as a string">, v.TransformAction<string, bigint>]>;
36
+ readonly messageId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "an id is a whole number written as a string">, v.TransformAction<string, bigint>]>;
37
+ readonly reaction: v.StrictObjectSchema<{
38
+ readonly reactionType: v.LiteralSchema<"EMOJI", undefined>;
39
+ readonly id: v.StringSchema<undefined>;
40
+ }, undefined>;
41
+ }, undefined>, v.LooseObjectSchema<{
42
+ readonly reactionInfo: v.OptionalSchema<v.LooseObjectSchema<{}, undefined>, undefined>;
43
+ }, undefined>>;
18
44
  export declare const messageDelete: import("../define.js").Reservation;
19
45
  //# sourceMappingURL=messages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/spec/operations/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAI5B,eAAO,MAAM,YAAY;;;;QASnB;;;WAGG;;;;;;;;cAaP,CAAA;AAEF,eAAO,MAAM,aAAa,oCAOxB,CAAA"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/spec/operations/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAI5B,eAAO,MAAM,YAAY;;;;QASnB;;;WAGG;;QAEH,+GAA+G;;;;;;;QAG/G,+FAA+F;;;;;;;;;cAcnG,CAAA;AAEF,eAAO,MAAM,iBAAiB;;;;;cAiB5B,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;cAqBxB,CAAA;AAEF,eAAO,MAAM,aAAa,oCAOxB,CAAA"}
@@ -15,18 +15,62 @@ export const messagesSend = defineOperation({
15
15
  * never be regenerated on a retry: a fresh one means a second message in somebody's chat.
16
16
  */
17
17
  cid: v.pipe(v.number(), v.integer()),
18
- elements: v.array(v.unknown()),
18
+ /** Markup in UTF-16 positions. STRONG, EMPHASIZED, STRIKETHROUGH, MONOSPACED read back from MAX 2026-09-24. */
19
+ elements: v.array(v.strictObject({ type: v.string(), from: v.number(), length: v.number() })),
19
20
  attaches: v.array(v.unknown()),
21
+ /** Read back as `{type, chatId, message}` — the quoted message whole (measured 2026-09-23). */
22
+ link: v.optional(v.strictObject({ type: v.literal("REPLY"), messageId: id() })),
20
23
  }),
21
24
  notify: v.boolean(),
22
25
  }),
23
26
  response: v.looseObject({ message: v.optional(v.looseObject({})) }),
24
27
  provenance: {
25
28
  confidence: "measured",
26
- sources: ["measured against MAX 2026-09-19, including deduplication by `cid` across two connections"],
29
+ sources: [
30
+ "measured against MAX 2026-09-19, including deduplication by `cid` across two connections",
31
+ "`link` and `elements` measured 2026-09-23 in Saved messages (`pnpm probe:reply`); shapes from tsmax and PyMax",
32
+ ],
27
33
  notes: "How long MAX remembers a `cid` is still unmeasured (`PROTO-2`); the two probes were seconds apart.",
28
34
  },
29
35
  });
36
+ export const messagesReactions = defineOperation({
37
+ name: "messages.reactions",
38
+ constant: "MSG_GET_REACTIONS",
39
+ opcode: 180,
40
+ auth: true,
41
+ request: v.strictObject({ chatId: id(), messageIds: v.array(id()) }),
42
+ response: v.looseObject({ messagesReactions: v.optional(v.looseObject({})) }),
43
+ provenance: {
44
+ confidence: "measured",
45
+ sources: [
46
+ "measured against MAX 2026-09-24 in Saved messages (`pnpm probe:message-shapes`)",
47
+ "tsmax getReactions",
48
+ "PyMax get_reactions",
49
+ ],
50
+ notes: "Answers `{messagesReactions: {<message id>: {counters: [{count, reaction}], yourReaction, totalCount}}}`. History carries no reactions (measured 2026-09-23), so this is the only way to read them.",
51
+ },
52
+ });
53
+ export const messagesReact = defineOperation({
54
+ name: "messages.react",
55
+ constant: "MSG_REACTION",
56
+ opcode: 178,
57
+ auth: true,
58
+ request: v.strictObject({
59
+ chatId: id(),
60
+ messageId: id(),
61
+ reaction: v.strictObject({ reactionType: v.literal("EMOJI"), id: v.string() }),
62
+ }),
63
+ response: v.looseObject({ reactionInfo: v.optional(v.looseObject({})) }),
64
+ provenance: {
65
+ confidence: "measured",
66
+ sources: [
67
+ "measured against MAX 2026-09-23 in Saved messages (`pnpm probe:reply`)",
68
+ "tsmax addReaction",
69
+ "PyMax add_reaction",
70
+ ],
71
+ notes: "Answers `{reactionInfo: {counters: [{count, reaction}], yourReaction, totalCount}}`. Allowed by the owner (`NEED-141`).",
72
+ },
73
+ });
30
74
  export const messageDelete = reserveOpcode({
31
75
  name: "messages.delete",
32
76
  constant: "MSG_DELETE",
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/spec/operations/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAA;AAElC,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC;IAC1C,IAAI,EAAE,eAAe;IACrB,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,EAAE;IACV,IAAI,EAAE,IAAI;IACV,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC;QACtB,MAAM,EAAE,EAAE,EAAE;QACZ,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC;YACtB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB;;;eAGG;YACH,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACpC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YAC9B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SAC/B,CAAC;QACF,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;KACpB,CAAC;IACF,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACnE,UAAU,EAAE;QACV,UAAU,EAAE,UAAU;QACtB,OAAO,EAAE,CAAC,0FAA0F,CAAC;QACrG,KAAK,EAAE,oGAAoG;KAC5G;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IACzC,IAAI,EAAE,iBAAiB;IACvB,QAAQ,EAAE,YAAY;IACtB,MAAM,EAAE,EAAE;IACV,MAAM,EACJ,wJAAwJ;IAC1J,UAAU,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE;CAC3D,CAAC,CAAA"}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/spec/operations/messages.ts"],"names":[],"mappings":"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"}
@@ -4,9 +4,10 @@ export interface MockMaxOptions {
4
4
  /**
5
5
  * One answer per opcode. An opcode with no answer is an unexpected call, and the test fails.
6
6
  * A function may return `undefined` to stay silent, which is how a timeout is scripted — and
7
- * the only way a test says it means a request to go unanswered.
7
+ * the only way a test says it means a request to go unanswered. It is handed the request, so
8
+ * one answer can differ by chat.
8
9
  */
9
- answers: Record<number, Payload | (() => Payload | undefined)>;
10
+ answers: Record<number, Payload | ((request: Payload) => Payload | undefined)>;
10
11
  /** Opcodes to refuse, as MAX does: `cmd=3` with an `error` in the payload. */
11
12
  refuse?: Record<number, string>;
12
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mock-max.d.ts","sourceRoot":"","sources":["../../src/testing/mock-max.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;AACnC,OAAO,EAAqC,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAEtF,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAA;IAC9D,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,OAAO;IACtB,YAAY,EAAE,MAAM,SAAS,CAAA;IAC7B,sFAAsF;IACtF,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAC5C,8FAA8F;IAC9F,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,MAAM,EAAE,OAAO,CAAA;CAChB;AAID,+FAA+F;AAC/F,eAAO,MAAM,cAAc,QAAO,OAAO,EAAqB,CAAA;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,GAAI,qBAA0B,cAAc,KAAG,OA0DlE,CAAA"}
1
+ {"version":3,"file":"mock-max.d.ts","sourceRoot":"","sources":["../../src/testing/mock-max.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;AACnC,OAAO,EAAqC,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAEtF,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,GAAG,SAAS,CAAC,CAAC,CAAA;IAC9E,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,OAAO;IACtB,YAAY,EAAE,MAAM,SAAS,CAAA;IAC7B,sFAAsF;IACtF,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAC5C,8FAA8F;IAC9F,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,MAAM,EAAE,OAAO,CAAA;CAChB;AAID,+FAA+F;AAC/F,eAAO,MAAM,cAAc,QAAO,OAAO,EAAqB,CAAA;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,GAAI,qBAA0B,cAAc,KAAG,OA0DlE,CAAA"}
@@ -37,7 +37,7 @@ export const mockMax = ({ answers, refuse = {} }) => {
37
37
  state.unexpected.push(frame.opcode);
38
38
  return;
39
39
  }
40
- const payload = typeof answer === "function" ? answer() : answer;
40
+ const payload = typeof answer === "function" ? answer(frame.payload ?? {}) : answer;
41
41
  if (payload === undefined)
42
42
  return; // Silence: the caller will time out, as MAX sometimes does.
43
43
  this.answer({ seq: frame.seq ?? 0, opcode: frame.opcode, payload, cmd: Command.RESPONSE });
@@ -1 +1 @@
1
- {"version":3,"file":"mock-max.js","sourceRoot":"","sources":["../../src/testing/mock-max.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mock-max.js","sourceRoot":"","sources":["../../src/testing/mock-max.ts"],"names":[],"mappings":"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"}