@wirecat/max-cli 0.0.0 → 0.43.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 (546) hide show
  1. package/LICENSE +204 -0
  2. package/README.md +531 -0
  3. package/dist/adapter/max-adapter.d.ts +17 -0
  4. package/dist/adapter/max-adapter.d.ts.map +1 -0
  5. package/dist/adapter/max-adapter.js +364 -0
  6. package/dist/adapter/max-adapter.js.map +1 -0
  7. package/dist/app.d.ts +3 -0
  8. package/dist/app.d.ts.map +1 -0
  9. package/dist/app.js +9 -0
  10. package/dist/app.js.map +1 -0
  11. package/dist/bin/max.d.ts +3 -0
  12. package/dist/bin/max.d.ts.map +1 -0
  13. package/dist/bin/max.js +20 -0
  14. package/dist/bin/max.js.map +1 -0
  15. package/dist/bot/adapter.d.ts +25 -0
  16. package/dist/bot/adapter.d.ts.map +1 -0
  17. package/dist/bot/adapter.js +404 -0
  18. package/dist/bot/adapter.js.map +1 -0
  19. package/dist/bot/auth.d.ts +13 -0
  20. package/dist/bot/auth.d.ts.map +1 -0
  21. package/dist/bot/auth.js +9 -0
  22. package/dist/bot/auth.js.map +1 -0
  23. package/dist/bot/client.d.ts +26 -0
  24. package/dist/bot/client.d.ts.map +1 -0
  25. package/dist/bot/client.js +105 -0
  26. package/dist/bot/client.js.map +1 -0
  27. package/dist/bot/generated/manifest.d.ts +3 -0
  28. package/dist/bot/generated/manifest.d.ts.map +1 -0
  29. package/dist/bot/generated/manifest.js +1232 -0
  30. package/dist/bot/generated/manifest.js.map +1 -0
  31. package/dist/bot/generated/schemas.d.ts +271 -0
  32. package/dist/bot/generated/schemas.d.ts.map +1 -0
  33. package/dist/bot/generated/schemas.js +869 -0
  34. package/dist/bot/generated/schemas.js.map +1 -0
  35. package/dist/bot/generated/types.d.ts +1088 -0
  36. package/dist/bot/generated/types.d.ts.map +1 -0
  37. package/dist/bot/generated/types.js +5 -0
  38. package/dist/bot/generated/types.js.map +1 -0
  39. package/dist/bot/input.d.ts +6 -0
  40. package/dist/bot/input.d.ts.map +1 -0
  41. package/dist/bot/input.js +6 -0
  42. package/dist/bot/input.js.map +1 -0
  43. package/dist/bot/joins.d.ts +26 -0
  44. package/dist/bot/joins.d.ts.map +1 -0
  45. package/dist/bot/joins.js +56 -0
  46. package/dist/bot/joins.js.map +1 -0
  47. package/dist/bot/keep.d.ts +25 -0
  48. package/dist/bot/keep.d.ts.map +1 -0
  49. package/dist/bot/keep.js +98 -0
  50. package/dist/bot/keep.js.map +1 -0
  51. package/dist/bot/map.d.ts +14 -0
  52. package/dist/bot/map.d.ts.map +1 -0
  53. package/dist/bot/map.js +101 -0
  54. package/dist/bot/map.js.map +1 -0
  55. package/dist/bot/mcp-tools.d.ts +4 -0
  56. package/dist/bot/mcp-tools.d.ts.map +1 -0
  57. package/dist/bot/mcp-tools.js +78 -0
  58. package/dist/bot/mcp-tools.js.map +1 -0
  59. package/dist/bot/permissions.d.ts +14 -0
  60. package/dist/bot/permissions.d.ts.map +1 -0
  61. package/dist/bot/permissions.js +88 -0
  62. package/dist/bot/permissions.js.map +1 -0
  63. package/dist/bot/registry.d.ts +11 -0
  64. package/dist/bot/registry.d.ts.map +1 -0
  65. package/dist/bot/registry.js +13 -0
  66. package/dist/bot/registry.js.map +1 -0
  67. package/dist/bot/russian-trusted-root.d.ts +8 -0
  68. package/dist/bot/russian-trusted-root.d.ts.map +1 -0
  69. package/dist/bot/russian-trusted-root.js +41 -0
  70. package/dist/bot/russian-trusted-root.js.map +1 -0
  71. package/dist/bot/transport.d.ts +46 -0
  72. package/dist/bot/transport.d.ts.map +1 -0
  73. package/dist/bot/transport.js +252 -0
  74. package/dist/bot/transport.js.map +1 -0
  75. package/dist/bot/uploads.d.ts +42 -0
  76. package/dist/bot/uploads.d.ts.map +1 -0
  77. package/dist/bot/uploads.js +145 -0
  78. package/dist/bot/uploads.js.map +1 -0
  79. package/dist/client.d.ts +650 -0
  80. package/dist/client.d.ts.map +1 -0
  81. package/dist/client.js +2836 -0
  82. package/dist/client.js.map +1 -0
  83. package/dist/commands/account.d.ts +3 -0
  84. package/dist/commands/account.d.ts.map +1 -0
  85. package/dist/commands/account.js +4 -0
  86. package/dist/commands/account.js.map +1 -0
  87. package/dist/commands/bot-comments.d.ts +3 -0
  88. package/dist/commands/bot-comments.d.ts.map +1 -0
  89. package/dist/commands/bot-comments.js +74 -0
  90. package/dist/commands/bot-comments.js.map +1 -0
  91. package/dist/commands/bot-context.d.ts +38 -0
  92. package/dist/commands/bot-context.d.ts.map +1 -0
  93. package/dist/commands/bot-context.js +121 -0
  94. package/dist/commands/bot-context.js.map +1 -0
  95. package/dist/commands/bot-members.d.ts +14 -0
  96. package/dist/commands/bot-members.d.ts.map +1 -0
  97. package/dist/commands/bot-members.js +64 -0
  98. package/dist/commands/bot-members.js.map +1 -0
  99. package/dist/commands/bot-messenger.d.ts +10 -0
  100. package/dist/commands/bot-messenger.d.ts.map +1 -0
  101. package/dist/commands/bot-messenger.js +101 -0
  102. package/dist/commands/bot-messenger.js.map +1 -0
  103. package/dist/commands/bot-reads.d.ts +4 -0
  104. package/dist/commands/bot-reads.d.ts.map +1 -0
  105. package/dist/commands/bot-reads.js +13 -0
  106. package/dist/commands/bot-reads.js.map +1 -0
  107. package/dist/commands/bot-sends.d.ts +13 -0
  108. package/dist/commands/bot-sends.d.ts.map +1 -0
  109. package/dist/commands/bot-sends.js +103 -0
  110. package/dist/commands/bot-sends.js.map +1 -0
  111. package/dist/commands/bot-setup.d.ts +3 -0
  112. package/dist/commands/bot-setup.d.ts.map +1 -0
  113. package/dist/commands/bot-setup.js +20 -0
  114. package/dist/commands/bot-setup.js.map +1 -0
  115. package/dist/commands/bot.d.ts +3 -0
  116. package/dist/commands/bot.d.ts.map +1 -0
  117. package/dist/commands/bot.js +60 -0
  118. package/dist/commands/bot.js.map +1 -0
  119. package/dist/commands/calls.d.ts +3 -0
  120. package/dist/commands/calls.d.ts.map +1 -0
  121. package/dist/commands/calls.js +4 -0
  122. package/dist/commands/calls.js.map +1 -0
  123. package/dist/commands/chats.d.ts +3 -0
  124. package/dist/commands/chats.d.ts.map +1 -0
  125. package/dist/commands/chats.js +46 -0
  126. package/dist/commands/chats.js.map +1 -0
  127. package/dist/commands/commands.d.ts +2 -0
  128. package/dist/commands/commands.d.ts.map +1 -0
  129. package/dist/commands/commands.js +4 -0
  130. package/dist/commands/commands.js.map +1 -0
  131. package/dist/commands/complete.d.ts +2 -0
  132. package/dist/commands/complete.d.ts.map +1 -0
  133. package/dist/commands/complete.js +34 -0
  134. package/dist/commands/complete.js.map +1 -0
  135. package/dist/commands/config.d.ts +3 -0
  136. package/dist/commands/config.d.ts.map +1 -0
  137. package/dist/commands/config.js +170 -0
  138. package/dist/commands/config.js.map +1 -0
  139. package/dist/commands/contacts.d.ts +10 -0
  140. package/dist/commands/contacts.d.ts.map +1 -0
  141. package/dist/commands/contacts.js +80 -0
  142. package/dist/commands/contacts.js.map +1 -0
  143. package/dist/commands/context.d.ts +126 -0
  144. package/dist/commands/context.d.ts.map +1 -0
  145. package/dist/commands/context.js +137 -0
  146. package/dist/commands/context.js.map +1 -0
  147. package/dist/commands/doctor.d.ts +24 -0
  148. package/dist/commands/doctor.d.ts.map +1 -0
  149. package/dist/commands/doctor.js +308 -0
  150. package/dist/commands/doctor.js.map +1 -0
  151. package/dist/commands/mcp.d.ts +36 -0
  152. package/dist/commands/mcp.d.ts.map +1 -0
  153. package/dist/commands/mcp.js +214 -0
  154. package/dist/commands/mcp.js.map +1 -0
  155. package/dist/commands/messages.d.ts +3 -0
  156. package/dist/commands/messages.d.ts.map +1 -0
  157. package/dist/commands/messages.js +105 -0
  158. package/dist/commands/messages.js.map +1 -0
  159. package/dist/commands/models.d.ts +3 -0
  160. package/dist/commands/models.d.ts.map +1 -0
  161. package/dist/commands/models.js +4 -0
  162. package/dist/commands/models.js.map +1 -0
  163. package/dist/commands/paging.d.ts +59 -0
  164. package/dist/commands/paging.d.ts.map +1 -0
  165. package/dist/commands/paging.js +77 -0
  166. package/dist/commands/paging.js.map +1 -0
  167. package/dist/commands/recipients.d.ts +9 -0
  168. package/dist/commands/recipients.d.ts.map +1 -0
  169. package/dist/commands/recipients.js +74 -0
  170. package/dist/commands/recipients.js.map +1 -0
  171. package/dist/commands/runs.d.ts +2 -0
  172. package/dist/commands/runs.d.ts.map +1 -0
  173. package/dist/commands/runs.js +4 -0
  174. package/dist/commands/runs.js.map +1 -0
  175. package/dist/commands/sends.d.ts +3 -0
  176. package/dist/commands/sends.d.ts.map +1 -0
  177. package/dist/commands/sends.js +4 -0
  178. package/dist/commands/sends.js.map +1 -0
  179. package/dist/commands/serve-members.d.ts +14 -0
  180. package/dist/commands/serve-members.d.ts.map +1 -0
  181. package/dist/commands/serve-members.js +54 -0
  182. package/dist/commands/serve-members.js.map +1 -0
  183. package/dist/commands/serve-stems.d.ts +9 -0
  184. package/dist/commands/serve-stems.d.ts.map +1 -0
  185. package/dist/commands/serve-stems.js +26 -0
  186. package/dist/commands/serve-stems.js.map +1 -0
  187. package/dist/commands/serve.d.ts +10 -0
  188. package/dist/commands/serve.d.ts.map +1 -0
  189. package/dist/commands/serve.js +79 -0
  190. package/dist/commands/serve.js.map +1 -0
  191. package/dist/commands/server.d.ts +16 -0
  192. package/dist/commands/server.d.ts.map +1 -0
  193. package/dist/commands/server.js +51 -0
  194. package/dist/commands/server.js.map +1 -0
  195. package/dist/commands/session.d.ts +15 -0
  196. package/dist/commands/session.d.ts.map +1 -0
  197. package/dist/commands/session.js +169 -0
  198. package/dist/commands/session.js.map +1 -0
  199. package/dist/commands/setup.d.ts +3 -0
  200. package/dist/commands/setup.d.ts.map +1 -0
  201. package/dist/commands/setup.js +168 -0
  202. package/dist/commands/setup.js.map +1 -0
  203. package/dist/commands/skill.d.ts +3 -0
  204. package/dist/commands/skill.d.ts.map +1 -0
  205. package/dist/commands/skill.js +7 -0
  206. package/dist/commands/skill.js.map +1 -0
  207. package/dist/commands/stickers.d.ts +3 -0
  208. package/dist/commands/stickers.d.ts.map +1 -0
  209. package/dist/commands/stickers.js +4 -0
  210. package/dist/commands/stickers.js.map +1 -0
  211. package/dist/commands/upgrade.d.ts +2 -0
  212. package/dist/commands/upgrade.d.ts.map +1 -0
  213. package/dist/commands/upgrade.js +14 -0
  214. package/dist/commands/upgrade.js.map +1 -0
  215. package/dist/commands/watch.d.ts +27 -0
  216. package/dist/commands/watch.d.ts.map +1 -0
  217. package/dist/commands/watch.js +105 -0
  218. package/dist/commands/watch.js.map +1 -0
  219. package/dist/config.d.ts +385 -0
  220. package/dist/config.d.ts.map +1 -0
  221. package/dist/config.js +372 -0
  222. package/dist/config.js.map +1 -0
  223. package/dist/deadline.d.ts +2 -0
  224. package/dist/deadline.d.ts.map +1 -0
  225. package/dist/deadline.js +2 -0
  226. package/dist/deadline.js.map +1 -0
  227. package/dist/diagnose.d.ts +143 -0
  228. package/dist/diagnose.d.ts.map +1 -0
  229. package/dist/diagnose.js +183 -0
  230. package/dist/diagnose.js.map +1 -0
  231. package/dist/domain/map.d.ts +65 -0
  232. package/dist/domain/map.d.ts.map +1 -0
  233. package/dist/domain/map.js +431 -0
  234. package/dist/domain/map.js.map +1 -0
  235. package/dist/domain/models.d.ts +238 -0
  236. package/dist/domain/models.d.ts.map +1 -0
  237. package/dist/domain/models.js +17 -0
  238. package/dist/domain/models.js.map +1 -0
  239. package/dist/download.d.ts +38 -0
  240. package/dist/download.d.ts.map +1 -0
  241. package/dist/download.js +199 -0
  242. package/dist/download.js.map +1 -0
  243. package/dist/format-markdown.d.ts +13 -0
  244. package/dist/format-markdown.d.ts.map +1 -0
  245. package/dist/format-markdown.js +241 -0
  246. package/dist/format-markdown.js.map +1 -0
  247. package/dist/generated/client.generated.d.ts +95 -0
  248. package/dist/generated/client.generated.d.ts.map +1 -0
  249. package/dist/generated/client.generated.js +91 -0
  250. package/dist/generated/client.generated.js.map +1 -0
  251. package/dist/generated/opcodes.generated.d.ts +76 -0
  252. package/dist/generated/opcodes.generated.d.ts.map +1 -0
  253. package/dist/generated/opcodes.generated.js +76 -0
  254. package/dist/generated/opcodes.generated.js.map +1 -0
  255. package/dist/generated/operations.generated.d.ts +502 -0
  256. package/dist/generated/operations.generated.d.ts.map +1 -0
  257. package/dist/generated/operations.generated.js +72 -0
  258. package/dist/generated/operations.generated.js.map +1 -0
  259. package/dist/inbox-point.d.ts +3 -0
  260. package/dist/inbox-point.d.ts.map +1 -0
  261. package/dist/inbox-point.js +17 -0
  262. package/dist/inbox-point.js.map +1 -0
  263. package/dist/install/postinstall.d.ts +8 -0
  264. package/dist/install/postinstall.d.ts.map +1 -0
  265. package/dist/install/postinstall.js +62 -0
  266. package/dist/install/postinstall.js.map +1 -0
  267. package/dist/install.d.ts +43 -0
  268. package/dist/install.d.ts.map +1 -0
  269. package/dist/install.js +142 -0
  270. package/dist/install.js.map +1 -0
  271. package/dist/markdown.d.ts +13 -0
  272. package/dist/markdown.d.ts.map +1 -0
  273. package/dist/markdown.js +6 -0
  274. package/dist/markdown.js.map +1 -0
  275. package/dist/mcp/instructions.d.ts +13 -0
  276. package/dist/mcp/instructions.d.ts.map +1 -0
  277. package/dist/mcp/instructions.js +16 -0
  278. package/dist/mcp/instructions.js.map +1 -0
  279. package/dist/mcp/legacy-check.d.ts +12 -0
  280. package/dist/mcp/legacy-check.d.ts.map +1 -0
  281. package/dist/mcp/legacy-check.js +44 -0
  282. package/dist/mcp/legacy-check.js.map +1 -0
  283. package/dist/mcp/photo.d.ts +9 -0
  284. package/dist/mcp/photo.d.ts.map +1 -0
  285. package/dist/mcp/photo.js +38 -0
  286. package/dist/mcp/photo.js.map +1 -0
  287. package/dist/mcp/prompts.d.ts +7 -0
  288. package/dist/mcp/prompts.d.ts.map +1 -0
  289. package/dist/mcp/prompts.js +100 -0
  290. package/dist/mcp/prompts.js.map +1 -0
  291. package/dist/mcp/resources.d.ts +15 -0
  292. package/dist/mcp/resources.d.ts.map +1 -0
  293. package/dist/mcp/resources.js +56 -0
  294. package/dist/mcp/resources.js.map +1 -0
  295. package/dist/mcp/server.d.ts +31 -0
  296. package/dist/mcp/server.d.ts.map +1 -0
  297. package/dist/mcp/server.js +116 -0
  298. package/dist/mcp/server.js.map +1 -0
  299. package/dist/mcp/session.d.ts +30 -0
  300. package/dist/mcp/session.d.ts.map +1 -0
  301. package/dist/mcp/session.js +109 -0
  302. package/dist/mcp/session.js.map +1 -0
  303. package/dist/mcp/shared.d.ts +14 -0
  304. package/dist/mcp/shared.d.ts.map +1 -0
  305. package/dist/mcp/shared.js +46 -0
  306. package/dist/mcp/shared.js.map +1 -0
  307. package/dist/mcp/tools.d.ts +30 -0
  308. package/dist/mcp/tools.d.ts.map +1 -0
  309. package/dist/mcp/tools.js +248 -0
  310. package/dist/mcp/tools.js.map +1 -0
  311. package/dist/messenger.d.ts +15 -0
  312. package/dist/messenger.d.ts.map +1 -0
  313. package/dist/messenger.js +149 -0
  314. package/dist/messenger.js.map +1 -0
  315. package/dist/moderation/check.d.ts +103 -0
  316. package/dist/moderation/check.d.ts.map +1 -0
  317. package/dist/moderation/check.js +273 -0
  318. package/dist/moderation/check.js.map +1 -0
  319. package/dist/moderation/points.d.ts +8 -0
  320. package/dist/moderation/points.d.ts.map +1 -0
  321. package/dist/moderation/points.js +21 -0
  322. package/dist/moderation/points.js.map +1 -0
  323. package/dist/moderation/rules.d.ts +7 -0
  324. package/dist/moderation/rules.d.ts.map +1 -0
  325. package/dist/moderation/rules.js +24 -0
  326. package/dist/moderation/rules.js.map +1 -0
  327. package/dist/online.d.ts +23 -0
  328. package/dist/online.d.ts.map +1 -0
  329. package/dist/online.js +87 -0
  330. package/dist/online.js.map +1 -0
  331. package/dist/output.d.ts +2 -0
  332. package/dist/output.d.ts.map +1 -0
  333. package/dist/output.js +2 -0
  334. package/dist/output.js.map +1 -0
  335. package/dist/permissions.d.ts +20 -0
  336. package/dist/permissions.d.ts.map +1 -0
  337. package/dist/permissions.js +76 -0
  338. package/dist/permissions.js.map +1 -0
  339. package/dist/profile.d.ts +33 -0
  340. package/dist/profile.d.ts.map +1 -0
  341. package/dist/profile.js +60 -0
  342. package/dist/profile.js.map +1 -0
  343. package/dist/program.d.ts +10 -0
  344. package/dist/program.d.ts.map +1 -0
  345. package/dist/program.js +172 -0
  346. package/dist/program.js.map +1 -0
  347. package/dist/protocol/connection.d.ts +83 -0
  348. package/dist/protocol/connection.d.ts.map +1 -0
  349. package/dist/protocol/connection.js +301 -0
  350. package/dist/protocol/connection.js.map +1 -0
  351. package/dist/protocol/frame.d.ts +55 -0
  352. package/dist/protocol/frame.d.ts.map +1 -0
  353. package/dist/protocol/frame.js +149 -0
  354. package/dist/protocol/frame.js.map +1 -0
  355. package/dist/protocol/lz4.d.ts +15 -0
  356. package/dist/protocol/lz4.d.ts.map +1 -0
  357. package/dist/protocol/lz4.js +157 -0
  358. package/dist/protocol/lz4.js.map +1 -0
  359. package/dist/record.d.ts +41 -0
  360. package/dist/record.d.ts.map +1 -0
  361. package/dist/record.js +104 -0
  362. package/dist/record.js.map +1 -0
  363. package/dist/rendering/messages.d.ts +24 -0
  364. package/dist/rendering/messages.d.ts.map +1 -0
  365. package/dist/rendering/messages.js +172 -0
  366. package/dist/rendering/messages.js.map +1 -0
  367. package/dist/report.d.ts +43 -0
  368. package/dist/report.d.ts.map +1 -0
  369. package/dist/report.js +104 -0
  370. package/dist/report.js.map +1 -0
  371. package/dist/resolve.d.ts +6 -0
  372. package/dist/resolve.d.ts.map +1 -0
  373. package/dist/resolve.js +5 -0
  374. package/dist/resolve.js.map +1 -0
  375. package/dist/sends.d.ts +17 -0
  376. package/dist/sends.d.ts.map +1 -0
  377. package/dist/sends.js +97 -0
  378. package/dist/sends.js.map +1 -0
  379. package/dist/server/lines.d.ts +23 -0
  380. package/dist/server/lines.d.ts.map +1 -0
  381. package/dist/server/lines.js +56 -0
  382. package/dist/server/lines.js.map +1 -0
  383. package/dist/server/replies.d.ts +31 -0
  384. package/dist/server/replies.d.ts.map +1 -0
  385. package/dist/server/replies.js +95 -0
  386. package/dist/server/replies.js.map +1 -0
  387. package/dist/server/server-connection.d.ts +55 -0
  388. package/dist/server/server-connection.d.ts.map +1 -0
  389. package/dist/server/server-connection.js +245 -0
  390. package/dist/server/server-connection.js.map +1 -0
  391. package/dist/server/server.d.ts +88 -0
  392. package/dist/server/server.d.ts.map +1 -0
  393. package/dist/server/server.js +634 -0
  394. package/dist/server/server.js.map +1 -0
  395. package/dist/server/start.d.ts +37 -0
  396. package/dist/server/start.d.ts.map +1 -0
  397. package/dist/server/start.js +102 -0
  398. package/dist/server/start.js.map +1 -0
  399. package/dist/server/subscribe.d.ts +9 -0
  400. package/dist/server/subscribe.d.ts.map +1 -0
  401. package/dist/server/subscribe.js +26 -0
  402. package/dist/server/subscribe.js.map +1 -0
  403. package/dist/session/adopt.d.ts +22 -0
  404. package/dist/session/adopt.d.ts.map +1 -0
  405. package/dist/session/adopt.js +34 -0
  406. package/dist/session/adopt.js.map +1 -0
  407. package/dist/session/browser.d.ts +55 -0
  408. package/dist/session/browser.d.ts.map +1 -0
  409. package/dist/session/browser.js +321 -0
  410. package/dist/session/browser.js.map +1 -0
  411. package/dist/session/handshake.d.ts +57 -0
  412. package/dist/session/handshake.d.ts.map +1 -0
  413. package/dist/session/handshake.js +40 -0
  414. package/dist/session/handshake.js.map +1 -0
  415. package/dist/session/login.d.ts +20 -0
  416. package/dist/session/login.d.ts.map +1 -0
  417. package/dist/session/login.js +66 -0
  418. package/dist/session/login.js.map +1 -0
  419. package/dist/session/prompt.d.ts +2 -0
  420. package/dist/session/prompt.d.ts.map +1 -0
  421. package/dist/session/prompt.js +2 -0
  422. package/dist/session/prompt.js.map +1 -0
  423. package/dist/session/qr-terminal.d.ts +9 -0
  424. package/dist/session/qr-terminal.d.ts.map +1 -0
  425. package/dist/session/qr-terminal.js +34 -0
  426. package/dist/session/qr-terminal.js.map +1 -0
  427. package/dist/session/store.d.ts +76 -0
  428. package/dist/session/store.d.ts.map +1 -0
  429. package/dist/session/store.js +134 -0
  430. package/dist/session/store.js.map +1 -0
  431. package/dist/skill.d.ts +7 -0
  432. package/dist/skill.d.ts.map +1 -0
  433. package/dist/skill.js +8 -0
  434. package/dist/skill.js.map +1 -0
  435. package/dist/spec/check.d.ts +16 -0
  436. package/dist/spec/check.d.ts.map +1 -0
  437. package/dist/spec/check.js +44 -0
  438. package/dist/spec/check.js.map +1 -0
  439. package/dist/spec/define.d.ts +108 -0
  440. package/dist/spec/define.d.ts.map +1 -0
  441. package/dist/spec/define.js +47 -0
  442. package/dist/spec/define.js.map +1 -0
  443. package/dist/spec/guards.d.ts +16 -0
  444. package/dist/spec/guards.d.ts.map +1 -0
  445. package/dist/spec/guards.js +30 -0
  446. package/dist/spec/guards.js.map +1 -0
  447. package/dist/spec/identity.d.ts +57 -0
  448. package/dist/spec/identity.d.ts.map +1 -0
  449. package/dist/spec/identity.js +53 -0
  450. package/dist/spec/identity.js.map +1 -0
  451. package/dist/spec/index.d.ts +15 -0
  452. package/dist/spec/index.d.ts.map +1 -0
  453. package/dist/spec/index.js +84 -0
  454. package/dist/spec/index.js.map +1 -0
  455. package/dist/spec/operations/account.d.ts +39 -0
  456. package/dist/spec/operations/account.d.ts.map +1 -0
  457. package/dist/spec/operations/account.js +103 -0
  458. package/dist/spec/operations/account.js.map +1 -0
  459. package/dist/spec/operations/assets.d.ts +17 -0
  460. package/dist/spec/operations/assets.d.ts.map +1 -0
  461. package/dist/spec/operations/assets.js +43 -0
  462. package/dist/spec/operations/assets.js.map +1 -0
  463. package/dist/spec/operations/attachments.d.ts +15 -0
  464. package/dist/spec/operations/attachments.d.ts.map +1 -0
  465. package/dist/spec/operations/attachments.js +40 -0
  466. package/dist/spec/operations/attachments.js.map +1 -0
  467. package/dist/spec/operations/banners.d.ts +7 -0
  468. package/dist/spec/operations/banners.d.ts.map +1 -0
  469. package/dist/spec/operations/banners.js +16 -0
  470. package/dist/spec/operations/banners.js.map +1 -0
  471. package/dist/spec/operations/calls.d.ts +8 -0
  472. package/dist/spec/operations/calls.d.ts.map +1 -0
  473. package/dist/spec/operations/calls.js +25 -0
  474. package/dist/spec/operations/calls.js.map +1 -0
  475. package/dist/spec/operations/chats.d.ts +115 -0
  476. package/dist/spec/operations/chats.d.ts.map +1 -0
  477. package/dist/spec/operations/chats.js +331 -0
  478. package/dist/spec/operations/chats.js.map +1 -0
  479. package/dist/spec/operations/contacts.d.ts +39 -0
  480. package/dist/spec/operations/contacts.d.ts.map +1 -0
  481. package/dist/spec/operations/contacts.js +135 -0
  482. package/dist/spec/operations/contacts.js.map +1 -0
  483. package/dist/spec/operations/folders.d.ts +31 -0
  484. package/dist/spec/operations/folders.d.ts.map +1 -0
  485. package/dist/spec/operations/folders.js +94 -0
  486. package/dist/spec/operations/folders.js.map +1 -0
  487. package/dist/spec/operations/login.d.ts +64 -0
  488. package/dist/spec/operations/login.d.ts.map +1 -0
  489. package/dist/spec/operations/login.js +105 -0
  490. package/dist/spec/operations/login.js.map +1 -0
  491. package/dist/spec/operations/messages.d.ts +142 -0
  492. package/dist/spec/operations/messages.d.ts.map +1 -0
  493. package/dist/spec/operations/messages.js +347 -0
  494. package/dist/spec/operations/messages.js.map +1 -0
  495. package/dist/spec/operations/session.d.ts +120 -0
  496. package/dist/spec/operations/session.d.ts.map +1 -0
  497. package/dist/spec/operations/session.js +202 -0
  498. package/dist/spec/operations/session.js.map +1 -0
  499. package/dist/spec/operations/uploads.d.ts +31 -0
  500. package/dist/spec/operations/uploads.d.ts.map +1 -0
  501. package/dist/spec/operations/uploads.js +59 -0
  502. package/dist/spec/operations/uploads.js.map +1 -0
  503. package/dist/spec/scalars.d.ts +17 -0
  504. package/dist/spec/scalars.d.ts.map +1 -0
  505. package/dist/spec/scalars.js +33 -0
  506. package/dist/spec/scalars.js.map +1 -0
  507. package/dist/transcribe/index.d.ts +70 -0
  508. package/dist/transcribe/index.d.ts.map +1 -0
  509. package/dist/transcribe/index.js +127 -0
  510. package/dist/transcribe/index.js.map +1 -0
  511. package/dist/transcribe/install.d.ts +2 -0
  512. package/dist/transcribe/install.d.ts.map +1 -0
  513. package/dist/transcribe/install.js +2 -0
  514. package/dist/transcribe/install.js.map +1 -0
  515. package/dist/transcribe/models.d.ts +5 -0
  516. package/dist/transcribe/models.d.ts.map +1 -0
  517. package/dist/transcribe/models.js +6 -0
  518. package/dist/transcribe/models.js.map +1 -0
  519. package/dist/transcribe/speech.d.ts +25 -0
  520. package/dist/transcribe/speech.d.ts.map +1 -0
  521. package/dist/transcribe/speech.js +107 -0
  522. package/dist/transcribe/speech.js.map +1 -0
  523. package/dist/update.d.ts +31 -0
  524. package/dist/update.d.ts.map +1 -0
  525. package/dist/update.js +69 -0
  526. package/dist/update.js.map +1 -0
  527. package/dist/upload.d.ts +15 -0
  528. package/dist/upload.d.ts.map +1 -0
  529. package/dist/upload.js +97 -0
  530. package/dist/upload.js.map +1 -0
  531. package/dist/version.d.ts +2 -0
  532. package/dist/version.d.ts.map +1 -0
  533. package/dist/version.js +2 -0
  534. package/dist/version.js.map +1 -0
  535. package/dist/voice.d.ts +9 -0
  536. package/dist/voice.d.ts.map +1 -0
  537. package/dist/voice.js +36 -0
  538. package/dist/voice.js.map +1 -0
  539. package/dist/wire-events.d.ts +23 -0
  540. package/dist/wire-events.d.ts.map +1 -0
  541. package/dist/wire-events.js +47 -0
  542. package/dist/wire-events.js.map +1 -0
  543. package/install/postinstall.mjs +3 -0
  544. package/install/windows.ps1 +160 -0
  545. package/package.json +120 -3
  546. package/skills/max-cli/SKILL.md +523 -0
@@ -0,0 +1,301 @@
1
+ import { WebSocket } from "ws";
2
+ import { Command, decodeFrame, decodeHeader, encodeFrame, HEADER_BYTES, SEQ_MODULO, } from "./frame.js";
3
+ /** Where web.max.ru connects, read off its live socket on 2026-09-25. */
4
+ export const MAX_WEBSOCKET_URL = "wss://api.oneme.ru/websocket";
5
+ /** MAX's web client sends this; we send what it sends rather than announcing ourselves (§34). */
6
+ export const WEB_ORIGIN = "https://web.max.ru";
7
+ export class ProtocolError extends Error {
8
+ opcode;
9
+ payload;
10
+ constructor(message, opcode, payload) {
11
+ super(message);
12
+ this.name = "ProtocolError";
13
+ this.opcode = opcode;
14
+ this.payload = payload;
15
+ }
16
+ }
17
+ /** MAX's keep-alive, both directions. */
18
+ const PING = 1;
19
+ /** A message arrived. The web client acknowledges each one. */
20
+ const NEW_MESSAGE = 128;
21
+ /**
22
+ * One WebSocket, one command's worth of work, then closed.
23
+ *
24
+ * **Everything that could keep the process alive is owned here**: the socket, the per-request
25
+ * timers and the listeners. `close()` clears all three, and a command that opens a connection
26
+ * closes it in a `finally` — a CLI that prints its result and then hangs is a defect, not a rough
27
+ * edge (REQUIREMENTS §18).
28
+ */
29
+ export class Connection {
30
+ #url;
31
+ #origin;
32
+ #timeoutMs;
33
+ #onEvent;
34
+ #onError;
35
+ #live;
36
+ #onClose;
37
+ #createSocket;
38
+ #pending = new Map();
39
+ #socket;
40
+ #seq = 0;
41
+ #lastPush;
42
+ #closed = false;
43
+ constructor(options = {}) {
44
+ this.#url = options.url ?? MAX_WEBSOCKET_URL;
45
+ this.#origin = options.origin ?? WEB_ORIGIN;
46
+ this.#timeoutMs = options.timeoutMs ?? 30_000;
47
+ this.#onEvent = options.onEvent;
48
+ this.#onError = options.onError;
49
+ this.#live = options.live ?? false;
50
+ this.#onClose = options.onClose;
51
+ this.#createSocket =
52
+ options.createSocket ??
53
+ ((url, origin) => new WebSocket(url, {
54
+ headers: { Origin: origin },
55
+ // A frame's body is at most 16 MiB by its header; `ws` would take 100 MiB.
56
+ maxPayload: HEADER_BYTES + 0xff_ffff,
57
+ handshakeTimeout: this.#timeoutMs,
58
+ }));
59
+ }
60
+ async open() {
61
+ if (this.#socket)
62
+ return;
63
+ const socket = this.#createSocket(this.#url, this.#origin);
64
+ this.#socket = socket;
65
+ try {
66
+ await new Promise((resolve, reject) => {
67
+ const onOpen = () => {
68
+ socket.off("error", onError);
69
+ resolve();
70
+ };
71
+ const onError = (error) => {
72
+ socket.off("open", onOpen);
73
+ reject(error);
74
+ };
75
+ socket.once("open", onOpen);
76
+ socket.once("error", onError);
77
+ });
78
+ }
79
+ catch (error) {
80
+ // Left set, the next `open()` would return at once and the request after it wait out its timeout.
81
+ if (this.#socket === socket)
82
+ this.#socket = undefined;
83
+ socket.removeAllListeners();
84
+ socket.on("error", () => { });
85
+ if (socket.readyState === socket.OPEN || socket.readyState === socket.CONNECTING)
86
+ socket.close();
87
+ throw error;
88
+ }
89
+ socket.on("message", (data) => this.#receive(asBytes(data)));
90
+ // The code and reason are all there is to tell MAX ending the session from a network drop.
91
+ socket.on("close", (code, reason) => this.#lost(new Error(closedBy(code, reason))));
92
+ socket.on("error", (error) => this.#lost(error));
93
+ }
94
+ // The web client's INIT goes out as seq 0; the header holds two bytes, so the count wraps, and
95
+ // after the wrap a request still waiting would have its answer handed to the newer one.
96
+ #nextSeq() {
97
+ for (let tried = 0; tried < SEQ_MODULO; tried++) {
98
+ const seq = this.#seq;
99
+ this.#seq = (this.#seq + 1) % SEQ_MODULO;
100
+ if (!this.#pending.has(seq))
101
+ return seq;
102
+ }
103
+ throw new Error(`all ${SEQ_MODULO} request numbers are waiting for an answer; refusing to reuse one`);
104
+ }
105
+ /**
106
+ * Sends one request and waits for the response carrying the same `seq`.
107
+ *
108
+ * MAX interleaves pushed events with responses on one socket, so the `seq` is the only thing
109
+ * tying an answer to its question — a reader that takes the next frame as its answer will
110
+ * eventually read somebody's incoming message instead.
111
+ *
112
+ * `watch` is told what left and what came back, for the caller that is keeping a diagnostic. It
113
+ * is called synchronously on the way out, so a request that never gets an answer is still on
114
+ * record — which is the run somebody actually wants to read.
115
+ */
116
+ async invoke(opcode, payload = {}, watch) {
117
+ if (!Number.isInteger(opcode)) {
118
+ // A typo in an opcode constant is otherwise a round trip to MAX that comes back
119
+ // "неизвестный opcode", which reads as the protocol's fault rather than ours.
120
+ throw new Error(`refusing to send a frame with a non-integer opcode: ${String(opcode)}`);
121
+ }
122
+ if (this.#closed)
123
+ throw new Error("the connection is closed");
124
+ if (!this.#socket)
125
+ throw new Error("the connection is not open");
126
+ const seq = this.#nextSeq();
127
+ const socket = this.#socket;
128
+ const sent = encodeFrame({ seq, opcode, payload });
129
+ const answer = await new Promise((resolve, reject) => {
130
+ const timer = setTimeout(() => {
131
+ this.#pending.delete(seq);
132
+ reject(new Error(`MAX did not answer opcode ${opcode} within ${this.#timeoutMs}ms`));
133
+ }, this.#timeoutMs);
134
+ this.#pending.set(seq, { resolve, reject, timer });
135
+ socket.send(sent);
136
+ watch?.({ phase: "sent", seq, opcode, bytes: sent.length });
137
+ });
138
+ const frame = answer.frame;
139
+ watch?.({ phase: "received", seq, opcode, bytes: answer.bytes });
140
+ if (frame.cmd === Command.ERROR) {
141
+ const reason = typeof frame.payload?.error === "string" ? frame.payload.error : "an error with no reason given";
142
+ throw new ProtocolError(`MAX refused opcode ${opcode}: ${reason}`, opcode, frame.payload);
143
+ }
144
+ return frame.payload ?? {};
145
+ }
146
+ /**
147
+ * Closes the socket and **settles anything still waiting**, rather than dropping it.
148
+ *
149
+ * ⚠ It used to clear the pending map without rejecting, which left the caller of an in-flight
150
+ * `invoke` awaiting a promise nothing could ever settle: the timers were cleared and the socket
151
+ * listeners removed in the same breath, so neither the timeout nor the close event was left to
152
+ * fire. Invisible in normal use, because `close()` runs in a `finally` once the body is done —
153
+ * and a hang the moment anything closes the connection while a request is out, which is exactly
154
+ * what a whole-command deadline does. Found by a test, not by a user.
155
+ */
156
+ async close() {
157
+ this.#closed = true;
158
+ const socket = this.#socket;
159
+ this.#socket = undefined;
160
+ this.#failAll(new Error("the connection was closed before MAX answered"));
161
+ if (!socket)
162
+ return;
163
+ socket.removeAllListeners();
164
+ // ⚠ **An error listener has to survive the close.** `ws` emits `error` when a socket is closed
165
+ // while it is still CONNECTING — measured against the real service — and an `error` event with
166
+ // no listener is how Node kills the whole process. Removing every listener and *then* closing
167
+ // turned a timeout into an unhandled event and a stack trace: exit 1 and a dump of `ws`
168
+ // internals, instead of exit 9 and one sentence.
169
+ //
170
+ // Nothing here can act on such an error anyway. The connection is being discarded; the socket
171
+ // failing to shut politely changes nothing a caller could use.
172
+ socket.on("error", () => { });
173
+ if (socket.readyState === socket.OPEN || socket.readyState === socket.CONNECTING)
174
+ socket.close();
175
+ }
176
+ #receive(raw) {
177
+ let frame;
178
+ try {
179
+ frame = decodeFrame(raw);
180
+ }
181
+ catch (error) {
182
+ // A body we cannot read still has a header naming the request it answers. Failing that
183
+ // request with the reason beats letting it wait out its timeout as "MAX did not answer".
184
+ const header = safeHeader(raw);
185
+ const answers = header && (header.cmd === Command.RESPONSE || header.cmd === Command.ERROR);
186
+ const waiting = answers ? this.#pending.get(header.seq) : undefined;
187
+ if (!header || !waiting)
188
+ return;
189
+ clearTimeout(waiting.timer);
190
+ this.#pending.delete(header.seq);
191
+ waiting.reject(error instanceof Error ? error : new Error(String(error)));
192
+ return;
193
+ }
194
+ // MAX numbers its own frames, so a push can carry the very `seq` a request is waiting on. Only
195
+ // `cmd` tells an answer from a push — a lookup by `seq` alone once resolved a request with
196
+ // somebody's incoming message.
197
+ if (frame.cmd !== Command.RESPONSE && frame.cmd !== Command.ERROR) {
198
+ // This runs inside the socket's listener, where a throw takes the whole process down.
199
+ try {
200
+ this.#pushed(frame);
201
+ }
202
+ catch (error) {
203
+ this.#onError?.(error instanceof Error ? error : new Error(String(error)));
204
+ }
205
+ return;
206
+ }
207
+ const waiting = this.#pending.get(frame.seq);
208
+ if (!waiting)
209
+ return;
210
+ clearTimeout(waiting.timer);
211
+ this.#pending.delete(frame.seq);
212
+ waiting.resolve({ frame, bytes: raw.length });
213
+ }
214
+ #pushed(frame) {
215
+ if (this.#live) {
216
+ // After a hiccup MAX sends some pushes again; the web client drops anything not newer.
217
+ // "Newer" is modular: a two-byte seq wraps, and a plain `<=` would drop every push after it.
218
+ if (this.#lastPush !== undefined && !isAfter(frame.seq, this.#lastPush))
219
+ return;
220
+ this.#lastPush = frame.seq;
221
+ if (frame.opcode === PING) {
222
+ this.#answer({ cmd: Command.RESPONSE, seq: frame.seq, opcode: PING });
223
+ return;
224
+ }
225
+ const message = frame.payload?.message;
226
+ const chatId = frame.payload?.chatId;
227
+ if (frame.opcode === NEW_MESSAGE &&
228
+ typeof message === "object" &&
229
+ message !== null &&
230
+ "id" in message &&
231
+ isId(chatId) &&
232
+ isId(message.id)) {
233
+ // As bigints, so they go back wrapped the way the web client wraps an id.
234
+ this.#answer({
235
+ cmd: Command.RESPONSE,
236
+ seq: frame.seq,
237
+ opcode: NEW_MESSAGE,
238
+ payload: { chatId: asWireId(chatId), messageId: asWireId(message.id) },
239
+ });
240
+ }
241
+ }
242
+ this.#onEvent?.(frame);
243
+ }
244
+ #answer(frame) {
245
+ const socket = this.#socket;
246
+ if (socket && !this.#closed)
247
+ socket.send(encodeFrame(frame));
248
+ }
249
+ /** MAX dropped us: every waiting request fails now, and the next `invoke` refuses at once. */
250
+ #lost(error) {
251
+ if (this.#closed)
252
+ return;
253
+ this.#closed = true;
254
+ const socket = this.#socket;
255
+ this.#socket = undefined;
256
+ if (socket) {
257
+ // A dead connection must hear nothing more, or a reconnect's frames reach it twice.
258
+ socket.removeAllListeners();
259
+ socket.on("error", () => { });
260
+ }
261
+ this.#failAll(error);
262
+ this.#onClose?.(error);
263
+ }
264
+ #failAll(error) {
265
+ for (const { reject, timer } of this.#pending.values()) {
266
+ clearTimeout(timer);
267
+ reject(error);
268
+ }
269
+ this.#pending.clear();
270
+ }
271
+ }
272
+ const asBytes = (data) => {
273
+ if (Array.isArray(data))
274
+ return Buffer.concat(data);
275
+ return data instanceof ArrayBuffer ? new Uint8Array(data) : data;
276
+ };
277
+ const safeHeader = (raw) => {
278
+ try {
279
+ return decodeHeader(raw);
280
+ }
281
+ catch {
282
+ return undefined;
283
+ }
284
+ };
285
+ const isAfter = (seq, last) => {
286
+ const distance = (seq - last + SEQ_MODULO) % SEQ_MODULO;
287
+ return distance > 0 && distance < SEQ_MODULO / 2;
288
+ };
289
+ const isId = (value) => typeof value === "string" || typeof value === "number" || typeof value === "bigint";
290
+ const asWireId = (value) => typeof value === "number" && Number.isSafeInteger(value) ? BigInt(value) : value;
291
+ const closedBy = (code, reason) => {
292
+ const said = reason
293
+ ?.toString("utf8")
294
+ .replace(/\p{Cc}/gu, " ")
295
+ .trim()
296
+ .slice(0, 120);
297
+ if (code === undefined)
298
+ return "MAX closed the connection";
299
+ return `MAX closed the connection (code ${code}${said ? `: ${said}` : ""})`;
300
+ };
301
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/protocol/connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The binary protocol web.max.ru speaks, captured from a live socket on 2026-09-25
3
+ * (`src/testing/fixtures/web-capture-2026-09-25.json`). JSON on protocol 11 was what we used to
4
+ * send, and nothing the web client sends looks like it.
5
+ */
6
+ export declare const PROTOCOL_VERSION = 10;
7
+ export declare const Command: {
8
+ readonly REQUEST: 0;
9
+ readonly RESPONSE: 1;
10
+ readonly EVENT: 2;
11
+ readonly ERROR: 3;
12
+ };
13
+ export type Command = (typeof Command)[keyof typeof Command];
14
+ export type Payload = Record<string, unknown>;
15
+ export interface OutboundFrame {
16
+ seq: number;
17
+ opcode: number;
18
+ /** Absent, or empty, goes out as a zero-length body — as the web client's ping answer does. */
19
+ payload?: Payload;
20
+ cmd?: Command;
21
+ }
22
+ export interface InboundFrame {
23
+ ver: number;
24
+ cmd: number;
25
+ seq: number;
26
+ opcode: number;
27
+ payload: Payload | null;
28
+ }
29
+ /** `ver` `cmd` `seq:u16` `opcode:u16` `flags:u8` `length:u24`, big-endian. */
30
+ export declare const HEADER_BYTES = 10;
31
+ export declare const SEQ_MODULO = 65536;
32
+ export declare const encodeFrame: (frame: OutboundFrame) => Uint8Array;
33
+ /** The header alone, so a body that cannot be read still says which request it answered. */
34
+ export declare const decodeHeader: (bytes: Uint8Array) => Omit<InboundFrame, "payload"> & {
35
+ flags: number;
36
+ length: number;
37
+ };
38
+ /**
39
+ * **Integers come back as `number` unless a number would lose digits.** MessagePack hands every
40
+ * 64-bit integer over as a `bigint`, and MAX sends times as 64-bit — a `bigint` timestamp breaks
41
+ * every `Date` and every subtraction above this layer. Message ids are 18 digits, past
42
+ * `Number.MAX_SAFE_INTEGER`, and stay `bigint`; every id leaves the domain mapper as a string.
43
+ */
44
+ export declare const decodeFrame: (bytes: Uint8Array) => InboundFrame;
45
+ /** What one frame may grow to. The header's own bound, `flags × length`, is about 2 GB of memory. */
46
+ export declare const MAX_DECOMPRESSED: number;
47
+ export declare class FrameError extends Error {
48
+ constructor(what: string);
49
+ }
50
+ /**
51
+ * Ids arrive as `number` when small and `bigint` when not, and both have to render identically.
52
+ * A domain id is a string from here on — it is an identifier, never arithmetic.
53
+ */
54
+ export declare const asId: (value: unknown) => string | undefined;
55
+ //# sourceMappingURL=frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../../src/protocol/frame.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,KAAK,CAAA;AAElC,eAAO,MAAM,OAAO;aAClB,OAAO,EAAE,CAAC;aACV,QAAQ,EAAE,CAAC;aACX,KAAK,EAAE,CAAC;aACR,KAAK,EAAE,CAAC;CACA,CAAA;AACV,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAA;AAE5D,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAE7C,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,+FAA+F;IAC/F,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,CAAC,EAAE,OAAO,CAAA;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;CACxB;AAED,8EAA8E;AAC9E,eAAO,MAAM,YAAY,KAAK,CAAA;AAS9B,eAAO,MAAM,UAAU,QAAW,CAAA;AAKlC,eAAO,MAAM,WAAW,UAAW,aAAa,KAAG,UAwBlD,CAAA;AAED,4FAA4F;AAC5F,eAAO,MAAM,YAAY,UAAW,UAAU,KAAG,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAgB/G,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,UAAW,UAAU,KAAG,YAW/C,CAAA;AAED,qGAAqG;AACrG,eAAO,MAAM,gBAAgB,QAAmB,CAAA;AAEhD,qBAAa,UAAW,SAAQ,KAAK;IACnC,YAAY,IAAI,EAAE,MAAM,EAGvB;CACF;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,UAAW,OAAO,KAAG,MAAM,GAAG,SAK9C,CAAA"}
@@ -0,0 +1,149 @@
1
+ import { decode, ExtData, ExtensionCodec, encode } from "@msgpack/msgpack";
2
+ import { compressBlock, decompressBlock } from "./lz4.js";
3
+ /**
4
+ * The binary protocol web.max.ru speaks, captured from a live socket on 2026-09-25
5
+ * (`src/testing/fixtures/web-capture-2026-09-25.json`). JSON on protocol 11 was what we used to
6
+ * send, and nothing the web client sends looks like it.
7
+ */
8
+ export const PROTOCOL_VERSION = 10;
9
+ export const Command = {
10
+ REQUEST: 0,
11
+ RESPONSE: 1,
12
+ EVENT: 2,
13
+ ERROR: 3,
14
+ };
15
+ /** `ver` `cmd` `seq:u16` `opcode:u16` `flags:u8` `length:u24`, big-endian. */
16
+ export const HEADER_BYTES = 10;
17
+ /** The web client sends 31 bytes plain and 37 compressed; where between them it switches was not seen. */
18
+ const COMPRESS_FROM = 32;
19
+ const ZSTD = 0xff;
20
+ const MAX_LZ4_FLAGS = 0x7f;
21
+ /** MAX wraps a number it means as a 64-bit id or time in extension type 1; so does the web client. */
22
+ const WRAPPED = 1;
23
+ export const SEQ_MODULO = 0x1_0000;
24
+ const wrapped = new ExtensionCodec();
25
+ wrapped.register({ type: WRAPPED, encode: () => null, decode: (data) => decodeBody(data) });
26
+ export const encodeFrame = (frame) => {
27
+ const raw = frame.payload && Object.keys(frame.payload).length > 0 ? encodeBody(frame.payload) : new Uint8Array(0);
28
+ let body = raw;
29
+ let flags = 0;
30
+ if (raw.length >= COMPRESS_FROM) {
31
+ const compressed = compressBlock(raw);
32
+ const factor = Math.ceil(raw.length / compressed.length);
33
+ if (factor <= MAX_LZ4_FLAGS) {
34
+ // Kept even when it came out larger: the web client does the same (47 bytes sent as 49).
35
+ body = compressed;
36
+ flags = factor;
37
+ }
38
+ }
39
+ const bytes = new Uint8Array(HEADER_BYTES + body.length);
40
+ const view = new DataView(bytes.buffer);
41
+ view.setUint8(0, PROTOCOL_VERSION);
42
+ view.setUint8(1, frame.cmd ?? Command.REQUEST);
43
+ view.setUint16(2, frame.seq % SEQ_MODULO);
44
+ view.setUint16(4, frame.opcode);
45
+ view.setUint32(6, ((flags << 24) | body.length) >>> 0);
46
+ bytes.set(body, HEADER_BYTES);
47
+ return bytes;
48
+ };
49
+ /** The header alone, so a body that cannot be read still says which request it answered. */
50
+ export const decodeHeader = (bytes) => {
51
+ if (bytes.length < HEADER_BYTES)
52
+ throw new FrameError(`a frame of ${bytes.length} bytes, shorter than its header`);
53
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
54
+ const packed = view.getUint32(6);
55
+ const header = {
56
+ ver: view.getUint8(0),
57
+ cmd: view.getUint8(1),
58
+ seq: view.getUint16(2),
59
+ opcode: view.getUint16(4),
60
+ flags: packed >>> 24,
61
+ length: packed & 0xff_ffff,
62
+ };
63
+ if (HEADER_BYTES + header.length > bytes.length) {
64
+ throw new FrameError(`a frame that claims ${header.length} bytes and carries ${bytes.length - HEADER_BYTES}`);
65
+ }
66
+ return header;
67
+ };
68
+ /**
69
+ * **Integers come back as `number` unless a number would lose digits.** MessagePack hands every
70
+ * 64-bit integer over as a `bigint`, and MAX sends times as 64-bit — a `bigint` timestamp breaks
71
+ * every `Date` and every subtraction above this layer. Message ids are 18 digits, past
72
+ * `Number.MAX_SAFE_INTEGER`, and stay `bigint`; every id leaves the domain mapper as a string.
73
+ */
74
+ export const decodeFrame = (bytes) => {
75
+ const { flags, length, ...header } = decodeHeader(bytes);
76
+ let body = bytes.subarray(HEADER_BYTES, HEADER_BYTES + length);
77
+ if (flags === ZSTD)
78
+ throw new FrameError("a zstd-compressed frame, which the web client was never seen receiving");
79
+ if (flags > MAX_LZ4_FLAGS)
80
+ throw new FrameError(`a frame with compression flags ${flags}`);
81
+ if (flags > 0)
82
+ body = decompressBlock(body, Math.min(flags * length, MAX_DECOMPRESSED));
83
+ if (body.length === 0)
84
+ return { ...header, payload: null };
85
+ const value = decodeBody(body);
86
+ return { ...header, payload: isRecord(value) ? value : null };
87
+ };
88
+ /** What one frame may grow to. The header's own bound, `flags × length`, is about 2 GB of memory. */
89
+ export const MAX_DECOMPRESSED = 32 * 1024 * 1024;
90
+ export class FrameError extends Error {
91
+ constructor(what) {
92
+ super(`MAX sent ${what}`);
93
+ this.name = "FrameError";
94
+ }
95
+ }
96
+ /**
97
+ * Ids arrive as `number` when small and `bigint` when not, and both have to render identically.
98
+ * A domain id is a string from here on — it is an identifier, never arithmetic.
99
+ */
100
+ export const asId = (value) => {
101
+ if (typeof value === "bigint")
102
+ return value.toString();
103
+ if (typeof value === "number" && Number.isFinite(value))
104
+ return String(value);
105
+ if (typeof value === "string" && value !== "")
106
+ return value;
107
+ return undefined;
108
+ };
109
+ /** A `bigint` is an id we built from a string (`toWireId`), and goes out wrapped the way the web client wraps ids. */
110
+ const encodeBody = (payload) => encode(wrapBigints(payload), { extensionCodec: wrapped, useBigInt64: true, ignoreUndefined: true });
111
+ const decodeBody = (bytes) => narrow(decode(bytes, { extensionCodec: wrapped, useBigInt64: true, mapKeyConverter: asKey }));
112
+ /**
113
+ * ⚠ With `useBigInt64` the library writes every `number` past 32 bits as a **float64**, and MAX
114
+ * refuses a login whose time arrives as one (`proto.payload`, measured 2026-09-25). A whole number
115
+ * that wide goes out as a bare 64-bit integer instead, as the web client sends `from` and
116
+ * `contactsSync`; only a `bigint` — an id — is wrapped.
117
+ */
118
+ const wrapBigints = (value) => {
119
+ if (typeof value === "bigint")
120
+ return new ExtData(WRAPPED, encode(value, { useBigInt64: true }));
121
+ if (typeof value === "number" && Number.isSafeInteger(value) && (value > 0xffff_ffff || value < -0x8000_0000))
122
+ return BigInt(value);
123
+ if (Array.isArray(value))
124
+ return value.map(wrapBigints);
125
+ if (isRecord(value))
126
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, wrapBigints(item)]));
127
+ return value;
128
+ };
129
+ const narrow = (value) => {
130
+ if (typeof value === "bigint")
131
+ return Number.MIN_SAFE_INTEGER <= value && value <= Number.MAX_SAFE_INTEGER ? Number(value) : value;
132
+ if (Array.isArray(value))
133
+ return value.map(narrow);
134
+ if (isRecord(value)) {
135
+ for (const key of Object.keys(value))
136
+ value[key] = narrow(value[key]);
137
+ }
138
+ return value;
139
+ };
140
+ /** Map keys are chat and message ids as often as names; ours are always strings. */
141
+ const asKey = (key) => {
142
+ if (typeof key === "string")
143
+ return key;
144
+ if (typeof key === "number" || typeof key === "bigint")
145
+ return String(key);
146
+ throw new FrameError(`a map key of type ${typeof key}`);
147
+ };
148
+ const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Uint8Array);
149
+ //# sourceMappingURL=frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.js","sourceRoot":"","sources":["../../src/protocol/frame.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * LZ4 *block* format — no frame header, no checksum — which is what MAX puts in a frame body.
3
+ *
4
+ * Hand-written because both directions are small and a native binding is what breaks under Bun
5
+ * (REQUIREMENTS §36). The decompressor mirrors the one that read all 73 frames of the 2026-09-25
6
+ * capture; the compressor keeps the format's end-of-block rules, which a lenient decoder such as
7
+ * ours would not notice being broken but MAX's might.
8
+ */
9
+ export declare class Lz4Error extends Error {
10
+ constructor(what: string);
11
+ }
12
+ export declare const compressBlock: (src: Uint8Array) => Uint8Array;
13
+ /** `maxOutput` bounds a hostile or corrupt block; the frame header gives the caller one. */
14
+ export declare const decompressBlock: (src: Uint8Array, maxOutput: number) => Uint8Array;
15
+ //# sourceMappingURL=lz4.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lz4.d.ts","sourceRoot":"","sources":["../../src/protocol/lz4.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,qBAAa,QAAS,SAAQ,KAAK;IACjC,YAAY,IAAI,EAAE,MAAM,EAGvB;CACF;AAED,eAAO,MAAM,aAAa,QAAS,UAAU,KAAG,UA4B/C,CAAA;AAED,4FAA4F;AAC5F,eAAO,MAAM,eAAe,QAAS,UAAU,aAAa,MAAM,KAAG,UA6BpE,CAAA"}