@leemour/max-cli 0.5.0 → 0.7.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 (261) hide show
  1. package/README.md +22 -5
  2. package/dist/cache/index.d.ts +1 -0
  3. package/dist/cache/index.d.ts.map +1 -1
  4. package/dist/cache/index.js +4 -4
  5. package/dist/cache/index.js.map +1 -1
  6. package/dist/cache/store.d.ts.map +1 -1
  7. package/dist/cache/store.js +1 -0
  8. package/dist/cache/store.js.map +1 -1
  9. package/dist/client.d.ts +230 -7
  10. package/dist/client.d.ts.map +1 -1
  11. package/dist/client.js +959 -78
  12. package/dist/client.js.map +1 -1
  13. package/dist/commands/account.d.ts.map +1 -1
  14. package/dist/commands/account.js +71 -3
  15. package/dist/commands/account.js.map +1 -1
  16. package/dist/commands/chats.d.ts.map +1 -1
  17. package/dist/commands/chats.js +159 -0
  18. package/dist/commands/chats.js.map +1 -1
  19. package/dist/commands/commands.d.ts +8 -0
  20. package/dist/commands/commands.d.ts.map +1 -0
  21. package/dist/commands/commands.js +36 -0
  22. package/dist/commands/commands.js.map +1 -0
  23. package/dist/commands/complete.d.ts +10 -0
  24. package/dist/commands/complete.d.ts.map +1 -0
  25. package/dist/commands/complete.js +89 -0
  26. package/dist/commands/complete.js.map +1 -0
  27. package/dist/commands/config.d.ts.map +1 -1
  28. package/dist/commands/config.js +6 -2
  29. package/dist/commands/config.js.map +1 -1
  30. package/dist/commands/contacts.d.ts +3 -0
  31. package/dist/commands/contacts.d.ts.map +1 -1
  32. package/dist/commands/contacts.js +85 -0
  33. package/dist/commands/contacts.js.map +1 -1
  34. package/dist/commands/context.d.ts +26 -1
  35. package/dist/commands/context.d.ts.map +1 -1
  36. package/dist/commands/context.js +47 -6
  37. package/dist/commands/context.js.map +1 -1
  38. package/dist/commands/folders.d.ts +4 -0
  39. package/dist/commands/folders.d.ts.map +1 -0
  40. package/dist/commands/folders.js +76 -0
  41. package/dist/commands/folders.js.map +1 -0
  42. package/dist/commands/inbox.d.ts +14 -0
  43. package/dist/commands/inbox.d.ts.map +1 -0
  44. package/dist/commands/inbox.js +90 -0
  45. package/dist/commands/inbox.js.map +1 -0
  46. package/dist/commands/mcp.d.ts +3 -0
  47. package/dist/commands/mcp.d.ts.map +1 -0
  48. package/dist/commands/mcp.js +17 -0
  49. package/dist/commands/mcp.js.map +1 -0
  50. package/dist/commands/messages.d.ts.map +1 -1
  51. package/dist/commands/messages.js +90 -4
  52. package/dist/commands/messages.js.map +1 -1
  53. package/dist/commands/reactions.d.ts +3 -0
  54. package/dist/commands/reactions.d.ts.map +1 -0
  55. package/dist/commands/reactions.js +43 -0
  56. package/dist/commands/reactions.js.map +1 -0
  57. package/dist/commands/recipients.d.ts +9 -0
  58. package/dist/commands/recipients.d.ts.map +1 -0
  59. package/dist/commands/recipients.js +68 -0
  60. package/dist/commands/recipients.js.map +1 -0
  61. package/dist/commands/sends.d.ts +4 -0
  62. package/dist/commands/sends.d.ts.map +1 -0
  63. package/dist/commands/sends.js +21 -0
  64. package/dist/commands/sends.js.map +1 -0
  65. package/dist/commands/serve.d.ts +10 -0
  66. package/dist/commands/serve.d.ts.map +1 -0
  67. package/dist/commands/serve.js +50 -0
  68. package/dist/commands/serve.js.map +1 -0
  69. package/dist/commands/session.d.ts.map +1 -1
  70. package/dist/commands/session.js +84 -16
  71. package/dist/commands/session.js.map +1 -1
  72. package/dist/commands/skill.d.ts.map +1 -1
  73. package/dist/commands/skill.js +2 -1
  74. package/dist/commands/skill.js.map +1 -1
  75. package/dist/commands/update.d.ts +7 -0
  76. package/dist/commands/update.d.ts.map +1 -0
  77. package/dist/commands/update.js +53 -0
  78. package/dist/commands/update.js.map +1 -0
  79. package/dist/commands/watch.d.ts +9 -0
  80. package/dist/commands/watch.d.ts.map +1 -0
  81. package/dist/commands/watch.js +68 -0
  82. package/dist/commands/watch.js.map +1 -0
  83. package/dist/config.d.ts +24 -1
  84. package/dist/config.d.ts.map +1 -1
  85. package/dist/config.js +43 -4
  86. package/dist/config.js.map +1 -1
  87. package/dist/domain/map.d.ts +10 -1
  88. package/dist/domain/map.d.ts.map +1 -1
  89. package/dist/domain/map.js +51 -1
  90. package/dist/domain/map.js.map +1 -1
  91. package/dist/domain/models.d.ts +80 -0
  92. package/dist/domain/models.d.ts.map +1 -1
  93. package/dist/domain/models.js.map +1 -1
  94. package/dist/generated/client.generated.d.ts +36 -0
  95. package/dist/generated/client.generated.d.ts.map +1 -1
  96. package/dist/generated/client.generated.js +36 -0
  97. package/dist/generated/client.generated.js.map +1 -1
  98. package/dist/generated/opcodes.generated.d.ts +37 -5
  99. package/dist/generated/opcodes.generated.d.ts.map +1 -1
  100. package/dist/generated/opcodes.generated.js +37 -5
  101. package/dist/generated/opcodes.generated.js.map +1 -1
  102. package/dist/generated/operations.generated.d.ts +245 -3
  103. package/dist/generated/operations.generated.d.ts.map +1 -1
  104. package/dist/generated/operations.generated.js +36 -4
  105. package/dist/generated/operations.generated.js.map +1 -1
  106. package/dist/markdown.d.ts +18 -0
  107. package/dist/markdown.d.ts.map +1 -0
  108. package/dist/markdown.js +52 -0
  109. package/dist/markdown.js.map +1 -0
  110. package/dist/mcp/confirm.d.ts +24 -0
  111. package/dist/mcp/confirm.d.ts.map +1 -0
  112. package/dist/mcp/confirm.js +53 -0
  113. package/dist/mcp/confirm.js.map +1 -0
  114. package/dist/mcp/instructions.d.ts +10 -0
  115. package/dist/mcp/instructions.d.ts.map +1 -0
  116. package/dist/mcp/instructions.js +25 -0
  117. package/dist/mcp/instructions.js.map +1 -0
  118. package/dist/mcp/server.d.ts +23 -0
  119. package/dist/mcp/server.d.ts.map +1 -0
  120. package/dist/mcp/server.js +38 -0
  121. package/dist/mcp/server.js.map +1 -0
  122. package/dist/mcp/session.d.ts +28 -0
  123. package/dist/mcp/session.d.ts.map +1 -0
  124. package/dist/mcp/session.js +91 -0
  125. package/dist/mcp/session.js.map +1 -0
  126. package/dist/mcp/tools.d.ts +8 -0
  127. package/dist/mcp/tools.d.ts.map +1 -0
  128. package/dist/mcp/tools.js +274 -0
  129. package/dist/mcp/tools.js.map +1 -0
  130. package/dist/program.d.ts.map +1 -1
  131. package/dist/program.js +27 -0
  132. package/dist/program.js.map +1 -1
  133. package/dist/protocol/connection.d.ts +10 -8
  134. package/dist/protocol/connection.d.ts.map +1 -1
  135. package/dist/protocol/connection.js +64 -7
  136. package/dist/protocol/connection.js.map +1 -1
  137. package/dist/protocol/frame.d.ts +2 -1
  138. package/dist/protocol/frame.d.ts.map +1 -1
  139. package/dist/protocol/frame.js.map +1 -1
  140. package/dist/rendering/messages.d.ts.map +1 -1
  141. package/dist/rendering/messages.js +21 -7
  142. package/dist/rendering/messages.js.map +1 -1
  143. package/dist/resolve.d.ts +15 -0
  144. package/dist/resolve.d.ts.map +1 -0
  145. package/dist/resolve.js +48 -0
  146. package/dist/resolve.js.map +1 -0
  147. package/dist/sends/guard.d.ts +27 -0
  148. package/dist/sends/guard.d.ts.map +1 -0
  149. package/dist/sends/guard.js +52 -0
  150. package/dist/sends/guard.js.map +1 -0
  151. package/dist/sends/journal.d.ts +42 -0
  152. package/dist/sends/journal.d.ts.map +1 -0
  153. package/dist/sends/journal.js +40 -0
  154. package/dist/sends/journal.js.map +1 -0
  155. package/dist/sends/recipients.d.ts +29 -0
  156. package/dist/sends/recipients.d.ts.map +1 -0
  157. package/dist/sends/recipients.js +62 -0
  158. package/dist/sends/recipients.js.map +1 -0
  159. package/dist/server/lines.d.ts +9 -0
  160. package/dist/server/lines.d.ts.map +1 -0
  161. package/dist/server/lines.js +25 -0
  162. package/dist/server/lines.js.map +1 -0
  163. package/dist/server/server-connection.d.ts +35 -0
  164. package/dist/server/server-connection.d.ts.map +1 -0
  165. package/dist/server/server-connection.js +195 -0
  166. package/dist/server/server-connection.js.map +1 -0
  167. package/dist/server/server.d.ts +62 -0
  168. package/dist/server/server.d.ts.map +1 -0
  169. package/dist/server/server.js +297 -0
  170. package/dist/server/server.js.map +1 -0
  171. package/dist/server/start.d.ts +12 -0
  172. package/dist/server/start.d.ts.map +1 -0
  173. package/dist/server/start.js +41 -0
  174. package/dist/server/start.js.map +1 -0
  175. package/dist/server/subscribe.d.ts +9 -0
  176. package/dist/server/subscribe.d.ts.map +1 -0
  177. package/dist/server/subscribe.js +26 -0
  178. package/dist/server/subscribe.js.map +1 -0
  179. package/dist/session/adopt.d.ts.map +1 -1
  180. package/dist/session/adopt.js +7 -6
  181. package/dist/session/adopt.js.map +1 -1
  182. package/dist/session/browser.d.ts +55 -0
  183. package/dist/session/browser.d.ts.map +1 -0
  184. package/dist/session/browser.js +319 -0
  185. package/dist/session/browser.js.map +1 -0
  186. package/dist/session/handshake.d.ts +2 -0
  187. package/dist/session/handshake.d.ts.map +1 -1
  188. package/dist/session/handshake.js +3 -1
  189. package/dist/session/handshake.js.map +1 -1
  190. package/dist/session/login.d.ts +20 -0
  191. package/dist/session/login.d.ts.map +1 -0
  192. package/dist/session/login.js +66 -0
  193. package/dist/session/login.js.map +1 -0
  194. package/dist/session/prompt.d.ts +3 -1
  195. package/dist/session/prompt.d.ts.map +1 -1
  196. package/dist/session/prompt.js +2 -2
  197. package/dist/session/prompt.js.map +1 -1
  198. package/dist/session/qr-terminal.d.ts +9 -0
  199. package/dist/session/qr-terminal.d.ts.map +1 -0
  200. package/dist/session/qr-terminal.js +34 -0
  201. package/dist/session/qr-terminal.js.map +1 -0
  202. package/dist/session/store.d.ts +4 -0
  203. package/dist/session/store.d.ts.map +1 -1
  204. package/dist/session/store.js +6 -0
  205. package/dist/session/store.js.map +1 -1
  206. package/dist/spec/define.d.ts.map +1 -1
  207. package/dist/spec/define.js +14 -1
  208. package/dist/spec/define.js.map +1 -1
  209. package/dist/spec/index.d.ts.map +1 -1
  210. package/dist/spec/index.js +38 -5
  211. package/dist/spec/index.js.map +1 -1
  212. package/dist/spec/operations/account.d.ts +20 -0
  213. package/dist/spec/operations/account.d.ts.map +1 -0
  214. package/dist/spec/operations/account.js +62 -0
  215. package/dist/spec/operations/account.js.map +1 -0
  216. package/dist/spec/operations/chats.d.ts +54 -0
  217. package/dist/spec/operations/chats.d.ts.map +1 -1
  218. package/dist/spec/operations/chats.js +121 -0
  219. package/dist/spec/operations/chats.js.map +1 -1
  220. package/dist/spec/operations/contacts.d.ts +19 -1
  221. package/dist/spec/operations/contacts.d.ts.map +1 -1
  222. package/dist/spec/operations/contacts.js +49 -6
  223. package/dist/spec/operations/contacts.js.map +1 -1
  224. package/dist/spec/operations/folders.d.ts +24 -0
  225. package/dist/spec/operations/folders.d.ts.map +1 -0
  226. package/dist/spec/operations/folders.js +64 -0
  227. package/dist/spec/operations/folders.js.map +1 -0
  228. package/dist/spec/operations/login.d.ts +64 -0
  229. package/dist/spec/operations/login.d.ts.map +1 -0
  230. package/dist/spec/operations/login.js +99 -0
  231. package/dist/spec/operations/login.js.map +1 -0
  232. package/dist/spec/operations/messages.d.ts +67 -3
  233. package/dist/spec/operations/messages.d.ts.map +1 -1
  234. package/dist/spec/operations/messages.js +126 -13
  235. package/dist/spec/operations/messages.js.map +1 -1
  236. package/dist/spec/operations/session.d.ts +7 -0
  237. package/dist/spec/operations/session.d.ts.map +1 -1
  238. package/dist/spec/operations/session.js +17 -0
  239. package/dist/spec/operations/session.js.map +1 -1
  240. package/dist/spec/operations/uploads.d.ts +18 -0
  241. package/dist/spec/operations/uploads.d.ts.map +1 -0
  242. package/dist/spec/operations/uploads.js +35 -0
  243. package/dist/spec/operations/uploads.js.map +1 -0
  244. package/dist/testing/mock-max.d.ts +15 -4
  245. package/dist/testing/mock-max.d.ts.map +1 -1
  246. package/dist/testing/mock-max.js +16 -3
  247. package/dist/testing/mock-max.js.map +1 -1
  248. package/dist/testing/sandbox.js +3 -0
  249. package/dist/testing/sandbox.js.map +1 -1
  250. package/dist/update.d.ts +36 -0
  251. package/dist/update.d.ts.map +1 -0
  252. package/dist/update.js +70 -0
  253. package/dist/update.js.map +1 -0
  254. package/dist/upload.d.ts +10 -0
  255. package/dist/upload.d.ts.map +1 -0
  256. package/dist/upload.js +61 -0
  257. package/dist/upload.js.map +1 -0
  258. package/dist/version.d.ts +1 -1
  259. package/dist/version.js +1 -1
  260. package/package.json +16 -3
  261. package/skills/max-cli/SKILL.md +23 -3
@@ -0,0 +1,64 @@
1
+ import * as v from "valibot";
2
+ import { defineOperation } from "../define.js";
3
+ import { id } from "../scalars.js";
4
+ const webClient = "web.max.ru chunk `_app/immutable/chunks/5oCuRT0F.js`, read 2026-09-24";
5
+ const Folder = {
6
+ id: v.pipe(v.string(), v.minLength(1)),
7
+ title: v.string(),
8
+ include: v.optional(v.array(id())),
9
+ /** Sent back as they came: nobody has described what they hold. */
10
+ filters: v.array(v.unknown()),
11
+ options: v.array(v.unknown()),
12
+ favorites: v.optional(v.array(v.unknown())),
13
+ };
14
+ export const foldersList = defineOperation({
15
+ name: "folders.list",
16
+ constant: "FOLDERS_GET",
17
+ opcode: 272,
18
+ auth: true,
19
+ request: v.strictObject({ folderSync: v.number() }),
20
+ response: v.looseObject({
21
+ folders: v.optional(v.array(v.looseObject({}))),
22
+ foldersOrder: v.optional(v.array(v.unknown())),
23
+ folderSync: v.optional(v.number()),
24
+ }),
25
+ provenance: {
26
+ confidence: "measured",
27
+ sources: [
28
+ "measured against MAX 2026-09-24 (`pnpm probe:account`): no folder of the owner's carries `include`",
29
+ webClient,
30
+ "PyMax 53103f0 `get_folders`",
31
+ ],
32
+ },
33
+ });
34
+ export const foldersUpdate = defineOperation({
35
+ name: "folders.update",
36
+ constant: "FOLDERS_UPDATE",
37
+ opcode: 274,
38
+ auth: true,
39
+ request: v.strictObject(Folder),
40
+ response: v.looseObject({ folder: v.optional(v.looseObject({})), folderSync: v.optional(v.number()) }),
41
+ provenance: {
42
+ confidence: "measured",
43
+ sources: [
44
+ "measured against MAX 2026-09-24 (`pnpm probe:account`): created, renamed and deleted a folder; a 21-character title came back `folder.validation.title.too-long`, 15 was taken",
45
+ webClient,
46
+ "PyMax 53103f0 `create_folder`, `update_folder`",
47
+ ],
48
+ notes: "Creates a folder under an id it has not seen, replaces one it has. **The whole folder**: the web client sends every field back, and PyMax's `include or []` would empty a folder whose title changed.",
49
+ },
50
+ });
51
+ export const foldersDelete = defineOperation({
52
+ name: "folders.delete",
53
+ constant: "FOLDERS_DELETE",
54
+ opcode: 276,
55
+ auth: true,
56
+ request: v.strictObject({ folderIds: v.array(v.pipe(v.string(), v.minLength(1))) }),
57
+ response: v.looseObject({}),
58
+ provenance: {
59
+ confidence: "measured",
60
+ sources: ["measured against MAX 2026-09-24 (`pnpm probe:account`)", webClient, "PyMax 53103f0 `delete_folder`"],
61
+ notes: "Deletes the folder, not the chats in it.",
62
+ },
63
+ });
64
+ //# sourceMappingURL=folders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folders.js","sourceRoot":"","sources":["../../../src/spec/operations/folders.ts"],"names":[],"mappings":"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"}
@@ -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":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE7D;;;GAGG;AACH,MAAM,MAAM,GAAG;IACb,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAClG,iBAAiB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;CACpG,CAAA;AAED,MAAM,KAAK,GAAG,2DAA2D,CAAA;AACzE,MAAM,IAAI,GAAG,yCAAyC,CAAA;AAEtD,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAC;IAC5C,IAAI,EAAE,iBAAiB;IACvB,QAAQ,EAAE,QAAQ;IAClB,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC;IAC3B,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC;QACtB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;QAC3B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;KACtB,CAAC;IACF,UAAU,EAAE;QACV,UAAU,EAAE,UAAU;QACtB,OAAO,EAAE,CAAC,+DAA+D,EAAE,KAAK,EAAE,IAAI,CAAC;KACxF;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;IAC3C,IAAI,EAAE,gBAAgB;IACtB,QAAQ,EAAE,eAAe;IACzB,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IAChD,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC;QACtB,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;KACtG,CAAC;IACF,UAAU,EAAE;QACV,UAAU,EAAE,UAAU;QACtB,OAAO,EAAE,CAAC,+DAA+D,EAAE,KAAK,EAAE,IAAI,CAAC;QACvF,KAAK,EACH,6GAA6G;KAChH;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,eAAe,CAAC;IACvC,IAAI,EAAE,YAAY;IAClB,QAAQ,EAAE,aAAa;IACvB,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IAChD,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC;IAC/B,UAAU,EAAE;QACV,UAAU,EAAE,UAAU;QACtB,OAAO,EAAE,CAAC,+DAA+D,EAAE,KAAK,CAAC;KAClF;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC;IAC7C,IAAI,EAAE,kBAAkB;IACxB,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,EAAE;IACV,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IACnG,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;IAClF,UAAU,EAAE;QACV,UAAU,EAAE,WAAW;QACvB,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC;QACtB,KAAK,EACH,iMAAiM;KACpM;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC;IAC1C,IAAI,EAAE,eAAe;IACrB,QAAQ,EAAE,MAAM;IAChB,MAAM,EAAE,EAAE;IACV,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;IAC9G,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC;IAC/B,UAAU,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE;CAChE,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;IAC3C,IAAI,EAAE,gBAAgB;IACtB,QAAQ,EAAE,2BAA2B;IACrC,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IACtE,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;IACzF,UAAU,EAAE;QACV,UAAU,EAAE,UAAU;QACtB,OAAO,EAAE,CAAC,yFAAyF,EAAE,KAAK,CAAC;QAC3G,KAAK,EAAE,mGAAmG;KAC3G;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC;IACrC,IAAI,EAAE,iBAAiB;IACvB,QAAQ,EAAE,iBAAiB;IAC3B,MAAM,EAAE,GAAG;IACX,MAAM,EACJ,2IAA2I;IAC7I,UAAU,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE;CACzD,CAAC,CAAA"}
@@ -1,19 +1,83 @@
1
1
  import * as v from "valibot";
2
- export declare const messagesSend: import("../define.js").Operation<v.StrictObjectSchema<{
2
+ export declare const messagesSend: import("../define.js").Operation<v.UnionSchema<[v.StrictObjectSchema<{
3
3
  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>]>;
4
4
  readonly message: v.StrictObjectSchema<{
5
- readonly text: v.StringSchema<undefined>;
5
+ /** Left out on a forward, as the web client does: the forwarded message is the content. */
6
+ readonly text: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
6
7
  /**
7
8
  * The client id MAX deduplicates by — measured, and it is what makes one retry safe. It must
8
9
  * never be regenerated on a retry: a fresh one means a second message in somebody's chat.
9
10
  */
10
11
  readonly cid: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>]>;
11
- readonly elements: v.ArraySchema<v.UnknownSchema, undefined>;
12
+ /** Markup in UTF-16 positions. STRONG, EMPHASIZED, STRIKETHROUGH, MONOSPACED read back from MAX 2026-09-24. */
13
+ readonly elements: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
14
+ readonly type: v.StringSchema<undefined>;
15
+ readonly from: v.NumberSchema<undefined>;
16
+ readonly length: v.NumberSchema<undefined>;
17
+ }, undefined>, undefined>, undefined>;
12
18
  readonly attaches: v.ArraySchema<v.UnknownSchema, undefined>;
19
+ /** Read back as `{type, chatId, message}` — the quoted message whole (measured 2026-09-23). */
20
+ readonly link: v.OptionalSchema<v.VariantSchema<"type", [v.StrictObjectSchema<{
21
+ readonly type: v.LiteralSchema<"REPLY", undefined>;
22
+ 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>]>;
23
+ }, undefined>, v.StrictObjectSchema<{
24
+ readonly type: v.LiteralSchema<"FORWARD", undefined>;
25
+ 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>]>;
26
+ 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>]>;
27
+ }, undefined>], undefined>, undefined>;
13
28
  }, undefined>;
14
29
  readonly notify: v.BooleanSchema<undefined>;
30
+ }, undefined>, v.StrictObjectSchema<{
31
+ readonly message: v.StrictObjectSchema<{
32
+ readonly cid: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>]>;
33
+ readonly attaches: v.TupleSchema<[v.StrictObjectSchema<{
34
+ readonly _type: v.LiteralSchema<"CONTROL", undefined>;
35
+ readonly event: v.LiteralSchema<"new", undefined>;
36
+ readonly chatType: v.LiteralSchema<"CHAT", undefined>;
37
+ readonly title: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
38
+ readonly userIds: 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>;
39
+ }, undefined>], undefined>;
40
+ }, undefined>;
41
+ readonly notify: v.BooleanSchema<undefined>;
42
+ }, undefined>], undefined>, v.LooseObjectSchema<{
43
+ readonly message: v.OptionalSchema<v.LooseObjectSchema<{}, undefined>, undefined>;
44
+ readonly chat: v.OptionalSchema<v.LooseObjectSchema<{}, undefined>, undefined>;
45
+ }, undefined>>;
46
+ export declare const messagesEdit: import("../define.js").Operation<v.StrictObjectSchema<{
47
+ 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>]>;
48
+ 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>]>;
49
+ readonly text: v.StringSchema<undefined>;
50
+ readonly elements: v.ArraySchema<v.StrictObjectSchema<{
51
+ readonly type: v.StringSchema<undefined>;
52
+ readonly from: v.NumberSchema<undefined>;
53
+ readonly length: v.NumberSchema<undefined>;
54
+ }, undefined>, undefined>;
55
+ /** `attachments`, not `attaches` as in MSG_SEND — every source spells them differently. */
56
+ readonly attachments: v.ArraySchema<v.UnknownSchema, undefined>;
15
57
  }, undefined>, v.LooseObjectSchema<{
16
58
  readonly message: v.OptionalSchema<v.LooseObjectSchema<{}, undefined>, undefined>;
17
59
  }, undefined>>;
60
+ export declare const messagesReactions: import("../define.js").Operation<v.StrictObjectSchema<{
61
+ 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>]>;
62
+ 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>;
63
+ }, undefined>, v.LooseObjectSchema<{
64
+ readonly messagesReactions: v.OptionalSchema<v.LooseObjectSchema<{}, undefined>, undefined>;
65
+ }, undefined>>;
66
+ export declare const messagesReact: import("../define.js").Operation<v.StrictObjectSchema<{
67
+ 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>]>;
68
+ 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>]>;
69
+ readonly reaction: v.StrictObjectSchema<{
70
+ readonly reactionType: v.LiteralSchema<"EMOJI", undefined>;
71
+ readonly id: v.StringSchema<undefined>;
72
+ }, undefined>;
73
+ }, undefined>, v.LooseObjectSchema<{
74
+ readonly reactionInfo: v.OptionalSchema<v.LooseObjectSchema<{}, undefined>, undefined>;
75
+ }, undefined>>;
76
+ export declare const messagesUnreact: import("../define.js").Operation<v.StrictObjectSchema<{
77
+ 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>]>;
78
+ 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>]>;
79
+ }, undefined>, v.LooseObjectSchema<{
80
+ readonly reactionInfo: v.OptionalSchema<v.LooseObjectSchema<{}, undefined>, undefined>;
81
+ }, undefined>>;
18
82
  export declare const messageDelete: import("../define.js").Reservation;
19
83
  //# 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;;;QASjB,2FAA2F;;QAE3F;;;WAGG;;QAEH,+GAA+G;;;;;;;QAG/G,+FAA+F;;;;;;;;;;;;;;;;;;;;;;;;;;cA6CrG,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;;IAUrB,2FAA2F;;;;cAgB7F,CAAA;AAEF,eAAO,MAAM,iBAAiB;;;;;cAiB5B,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;cAqBxB,CAAA;AAEF,eAAO,MAAM,eAAe;;;;;cAY1B,CAAA;AAEF,eAAO,MAAM,aAAa,oCAOxB,CAAA"}
@@ -6,25 +6,138 @@ export const messagesSend = defineOperation({
6
6
  constant: "MSG_SEND",
7
7
  opcode: 64,
8
8
  auth: true,
9
+ request: v.union([
10
+ v.strictObject({
11
+ chatId: id(),
12
+ message: v.strictObject({
13
+ /** Left out on a forward, as the web client does: the forwarded message is the content. */
14
+ text: v.optional(v.string()),
15
+ /**
16
+ * The client id MAX deduplicates by — measured, and it is what makes one retry safe. It must
17
+ * never be regenerated on a retry: a fresh one means a second message in somebody's chat.
18
+ */
19
+ cid: v.pipe(v.number(), v.integer()),
20
+ /** Markup in UTF-16 positions. STRONG, EMPHASIZED, STRIKETHROUGH, MONOSPACED read back from MAX 2026-09-24. */
21
+ elements: v.optional(v.array(v.strictObject({ type: v.string(), from: v.number(), length: v.number() }))),
22
+ attaches: v.array(v.unknown()),
23
+ /** Read back as `{type, chatId, message}` — the quoted message whole (measured 2026-09-23). */
24
+ link: v.optional(v.variant("type", [
25
+ v.strictObject({ type: v.literal("REPLY"), messageId: id() }),
26
+ /** `chatId` is the chat the message is forwarded **from** (web.max.ru, PyMax). */
27
+ v.strictObject({ type: v.literal("FORWARD"), messageId: id(), chatId: id() }),
28
+ ])),
29
+ }),
30
+ notify: v.boolean(),
31
+ }),
32
+ /**
33
+ * Creating a group is a message too: a CONTROL attachment with no chat to send it to. Measured
34
+ * 2026-09-24 with nobody invited (`pnpm probe:groups`); the answer adds `chat` and `chatId`.
35
+ */
36
+ v.strictObject({
37
+ message: v.strictObject({
38
+ cid: v.pipe(v.number(), v.integer()),
39
+ attaches: v.tuple([
40
+ v.strictObject({
41
+ _type: v.literal("CONTROL"),
42
+ event: v.literal("new"),
43
+ chatType: v.literal("CHAT"),
44
+ title: v.pipe(v.string(), v.minLength(1)),
45
+ userIds: v.array(id()),
46
+ }),
47
+ ]),
48
+ }),
49
+ notify: v.boolean(),
50
+ }),
51
+ ]),
52
+ response: v.looseObject({ message: v.optional(v.looseObject({})), chat: v.optional(v.looseObject({})) }),
53
+ provenance: {
54
+ confidence: "measured",
55
+ sources: [
56
+ "measured against MAX 2026-09-19, including deduplication by `cid` across two connections",
57
+ "`link` and `elements` measured 2026-09-23 in Saved messages (`pnpm probe:reply`); shapes from tsmax and PyMax",
58
+ "the FORWARD link: web.max.ru `_app/immutable/chunks/5oCuRT0F.js` (2026-09-24), PyMax `api/messages/payloads.py:56-73`",
59
+ "a forward with no `text` and no `elements` measured 2026-09-24 in Saved messages (`pnpm probe:edit-pin-forward`)",
60
+ "group creation measured 2026-09-24 (`pnpm probe:groups`); shape from PyMax create_group",
61
+ ],
62
+ notes: "How long MAX remembers a `cid` is still unmeasured (`PROTO-2`); the two probes were seconds apart. " +
63
+ "The forward was measured from chat 0 to chat 0, so that `link.chatId` is the source rests on the two clients.",
64
+ },
65
+ });
66
+ export const messagesEdit = defineOperation({
67
+ name: "messages.edit",
68
+ constant: "MSG_EDIT",
69
+ opcode: 67,
70
+ auth: true,
9
71
  request: v.strictObject({
10
72
  chatId: id(),
11
- message: v.strictObject({
12
- text: v.string(),
13
- /**
14
- * The client id MAX deduplicates by — measured, and it is what makes one retry safe. It must
15
- * never be regenerated on a retry: a fresh one means a second message in somebody's chat.
16
- */
17
- cid: v.pipe(v.number(), v.integer()),
18
- elements: v.array(v.unknown()),
19
- attaches: v.array(v.unknown()),
20
- }),
21
- notify: v.boolean(),
73
+ messageId: id(),
74
+ text: v.string(),
75
+ elements: v.array(v.strictObject({ type: v.string(), from: v.number(), length: v.number() })),
76
+ /** `attachments`, not `attaches` as in MSG_SEND — every source spells them differently. */
77
+ attachments: v.array(v.unknown()),
22
78
  }),
23
79
  response: v.looseObject({ message: v.optional(v.looseObject({})) }),
24
80
  provenance: {
25
81
  confidence: "measured",
26
- sources: ["measured against MAX 2026-09-19, including deduplication by `cid` across two connections"],
27
- notes: "How long MAX remembers a `cid` is still unmeasured (`PROTO-2`); the two probes were seconds apart.",
82
+ sources: [
83
+ "measured against MAX 2026-09-24 in Saved messages (`pnpm probe:edit-pin-forward`)",
84
+ "web.max.ru `_app/immutable/chunks/5oCuRT0F.js` (2026-09-24)",
85
+ "PyMax `api/messages/payloads.py:21-28` (53103f0)",
86
+ ],
87
+ notes: 'Answers `{message}` with `status: "EDITED"`. `attachments: []` removes a photo; the ones history gives, sent back ' +
88
+ "as they are, keep it. LOGIN's `config.server.edit-timeout` was 604800 s. The web client edits only your own " +
89
+ "messages, and never a forward.",
90
+ },
91
+ });
92
+ export const messagesReactions = defineOperation({
93
+ name: "messages.reactions",
94
+ constant: "MSG_GET_REACTIONS",
95
+ opcode: 180,
96
+ auth: true,
97
+ request: v.strictObject({ chatId: id(), messageIds: v.array(id()) }),
98
+ response: v.looseObject({ messagesReactions: v.optional(v.looseObject({})) }),
99
+ provenance: {
100
+ confidence: "measured",
101
+ sources: [
102
+ "measured against MAX 2026-09-24 in Saved messages (`pnpm probe:message-shapes`)",
103
+ "tsmax getReactions",
104
+ "PyMax get_reactions",
105
+ ],
106
+ 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.",
107
+ },
108
+ });
109
+ export const messagesReact = defineOperation({
110
+ name: "messages.react",
111
+ constant: "MSG_REACTION",
112
+ opcode: 178,
113
+ auth: true,
114
+ request: v.strictObject({
115
+ chatId: id(),
116
+ messageId: id(),
117
+ reaction: v.strictObject({ reactionType: v.literal("EMOJI"), id: v.string() }),
118
+ }),
119
+ response: v.looseObject({ reactionInfo: v.optional(v.looseObject({})) }),
120
+ provenance: {
121
+ confidence: "measured",
122
+ sources: [
123
+ "measured against MAX 2026-09-23 in Saved messages (`pnpm probe:reply`)",
124
+ "tsmax addReaction",
125
+ "PyMax add_reaction",
126
+ ],
127
+ notes: "Answers `{reactionInfo: {counters: [{count, reaction}], yourReaction, totalCount}}`. Allowed by the owner (`NEED-141`).",
128
+ },
129
+ });
130
+ export const messagesUnreact = defineOperation({
131
+ name: "messages.unreact",
132
+ constant: "MSG_CANCEL_REACTION",
133
+ opcode: 179,
134
+ auth: true,
135
+ request: v.strictObject({ chatId: id(), messageId: id() }),
136
+ response: v.looseObject({ reactionInfo: v.optional(v.looseObject({})) }),
137
+ provenance: {
138
+ confidence: "measured",
139
+ sources: ["measured against MAX 2026-09-24 in Saved messages", "tsmax removeReaction", "PyMax remove_reaction"],
140
+ notes: "Answers the reactions left, `{reactionInfo: {}}` when none. A second call is answered the same.",
28
141
  },
29
142
  });
30
143
  export const messageDelete = reserveOpcode({
@@ -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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"}
@@ -1,4 +1,11 @@
1
1
  import * as v from "valibot";
2
+ /**
3
+ * **The keep-alive, which only `max serve` sends** — a one-shot command is gone long before it
4
+ * would matter. `interactive` is whether the tab is visible; ours is never, as LOGIN's is.
5
+ */
6
+ export declare const sessionPing: import("../define.js").Operation<v.StrictObjectSchema<{
7
+ readonly interactive: v.BooleanSchema<undefined>;
8
+ }, undefined>, v.LooseObjectSchema<{}, undefined>>;
2
9
  export declare const sessionInit: import("../define.js").Operation<v.StrictObjectSchema<{
3
10
  readonly userAgent: v.StrictObjectSchema<{
4
11
  readonly deviceType: v.LiteralSchema<"WEB", undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/spec/operations/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAsB5B,eAAO,MAAM,WAAW;;;;;;;;;;;;;;kDAYtB,CAAA;AAEF,eAAO,MAAM,YAAY;;IAOrB;;;;OAIG;;;IAKH;;;;;;;;;;;OAWG;;;;;;;;;IAUH;;;;;;;;;;;;;;OAcG;;IAEH;;;;;;;;;;;;;;OAcG;;;;;;;cAkBL,CAAA;AAEF,eAAO,MAAM,MAAM,oCAOjB,CAAA"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/spec/operations/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAsB5B;;;GAGG;AACH,eAAO,MAAM,WAAW;;kDAYtB,CAAA;AAEF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;kDAYtB,CAAA;AAEF,eAAO,MAAM,YAAY;;IAOrB;;;;OAIG;;;IAKH;;;;;;;;;;;OAWG;;;;;;;;;IAUH;;;;;;;;;;;;;;OAcG;;IAEH;;;;;;;;;;;;;;OAcG;;;;;;;cAkBL,CAAA;AAEF,eAAO,MAAM,MAAM,oCAOjB,CAAA"}
@@ -18,6 +18,23 @@ const WebUserAgent = v.strictObject({
18
18
  screen: v.string(),
19
19
  timezone: v.string(),
20
20
  });
21
+ /**
22
+ * **The keep-alive, which only `max serve` sends** — a one-shot command is gone long before it
23
+ * would matter. `interactive` is whether the tab is visible; ours is never, as LOGIN's is.
24
+ */
25
+ export const sessionPing = defineOperation({
26
+ name: "session.ping",
27
+ constant: "PING",
28
+ opcode: 1,
29
+ auth: true,
30
+ request: v.strictObject({ interactive: v.boolean() }),
31
+ response: v.looseObject({}),
32
+ provenance: {
33
+ confidence: "confirmed",
34
+ sources: ["web.max.ru bundle read 2026-09-24: `cmd(1, {interactive})` every 30 s", "PyMax Opcode.PING = 1"],
35
+ notes: "MAX pings too; `Connection` answers those itself when it is live.",
36
+ },
37
+ });
21
38
  export const sessionInit = defineOperation({
22
39
  name: "session.init",
23
40
  constant: "SESSION_INIT",
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/spec/operations/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/spec/operations/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import * as v from "valibot";
2
+ export declare const uploadsPhoto: import("../define.js").Operation<v.StrictObjectSchema<{
3
+ readonly count: v.LiteralSchema<1, undefined>;
4
+ readonly type: v.LiteralSchema<0, undefined>;
5
+ readonly uploaderType: v.LiteralSchema<0, undefined>;
6
+ readonly profile: v.LiteralSchema<false, undefined>;
7
+ }, undefined>, v.LooseObjectSchema<{
8
+ readonly url: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
9
+ }, undefined>>;
10
+ export declare const uploadsFile: import("../define.js").Operation<v.StrictObjectSchema<{
11
+ readonly count: v.LiteralSchema<1, undefined>;
12
+ readonly type: v.LiteralSchema<0, undefined>;
13
+ readonly uploaderType: v.LiteralSchema<0, undefined>;
14
+ readonly profile: v.LiteralSchema<false, undefined>;
15
+ }, undefined>, v.LooseObjectSchema<{
16
+ readonly info: v.OptionalSchema<v.ArraySchema<v.LooseObjectSchema<{}, undefined>, undefined>, undefined>;
17
+ }, undefined>>;
18
+ //# sourceMappingURL=uploads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploads.d.ts","sourceRoot":"","sources":["../../../src/spec/operations/uploads.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAU5B,eAAO,MAAM,YAAY;;;;;;;cAavB,CAAA;AAEF,eAAO,MAAM,WAAW;;;;;;;cAatB,CAAA"}
@@ -0,0 +1,35 @@
1
+ import * as v from "valibot";
2
+ import { defineOperation } from "../define.js";
3
+ const uploadRequest = v.strictObject({
4
+ count: v.literal(1),
5
+ type: v.literal(0),
6
+ uploaderType: v.literal(0),
7
+ profile: v.literal(false),
8
+ });
9
+ export const uploadsPhoto = defineOperation({
10
+ name: "uploads.photo",
11
+ constant: "PHOTO_UPLOAD",
12
+ opcode: 80,
13
+ auth: true,
14
+ request: uploadRequest,
15
+ response: v.looseObject({ url: v.optional(v.string()) }),
16
+ provenance: {
17
+ confidence: "measured",
18
+ sources: ["measured against MAX 2026-09-24 in Saved messages (`pnpm probe:upload`)", "PyMax upload_photo"],
19
+ notes: 'Answers `{url}`. A multipart POST of the image, field `file`, answers `{photos: {<key>: {token}}}`; the message attaches `{_type: "PHOTO", photoToken}`.',
20
+ },
21
+ });
22
+ export const uploadsFile = defineOperation({
23
+ name: "uploads.file",
24
+ constant: "FILE_UPLOAD",
25
+ opcode: 87,
26
+ auth: true,
27
+ request: uploadRequest,
28
+ response: v.looseObject({ info: v.optional(v.array(v.looseObject({}))) }),
29
+ provenance: {
30
+ confidence: "measured",
31
+ sources: ["measured against MAX 2026-09-24 in Saved messages (`pnpm probe:upload`)", "PyMax upload_file"],
32
+ notes: 'Answers `{info: [{url, fileId, token}]}`. The bytes are POSTed raw with `Content-Range: 0-<end>/<size>`; MAX then pushes 136 `{fileId}`, and a send before that is refused `attachment.not.ready`. The message attaches `{_type: "FILE", fileId}`.',
33
+ },
34
+ });
35
+ //# sourceMappingURL=uploads.js.map