@wirecat/max-cli 0.49.0 → 0.51.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 (361) hide show
  1. package/README.md +9 -9
  2. package/dist/adapter/max-adapter.d.ts +3 -3
  3. package/dist/adapter/max-adapter.d.ts.map +1 -1
  4. package/dist/adapter/max-adapter.js +2 -2
  5. package/dist/adapter/max-adapter.js.map +1 -1
  6. package/dist/app.d.ts +1 -1
  7. package/dist/app.d.ts.map +1 -1
  8. package/dist/app.js +2 -0
  9. package/dist/app.js.map +1 -1
  10. package/dist/bin/max.js +2 -2
  11. package/dist/bin/max.js.map +1 -1
  12. package/dist/bot/adapter.d.ts +2 -2
  13. package/dist/bot/adapter.d.ts.map +1 -1
  14. package/dist/bot/adapter.js +1 -1
  15. package/dist/bot/adapter.js.map +1 -1
  16. package/dist/bot/auth.d.ts +2 -2
  17. package/dist/bot/auth.d.ts.map +1 -1
  18. package/dist/bot/auth.js +2 -2
  19. package/dist/bot/auth.js.map +1 -1
  20. package/dist/bot/client.d.ts +2 -2
  21. package/dist/bot/client.d.ts.map +1 -1
  22. package/dist/bot/input.d.ts +1 -1
  23. package/dist/bot/input.d.ts.map +1 -1
  24. package/dist/bot/input.js +1 -1
  25. package/dist/bot/input.js.map +1 -1
  26. package/dist/bot/keep.d.ts +2 -2
  27. package/dist/bot/keep.d.ts.map +1 -1
  28. package/dist/bot/keep.js +1 -1
  29. package/dist/bot/keep.js.map +1 -1
  30. package/dist/bot/map.d.ts +2 -2
  31. package/dist/bot/map.d.ts.map +1 -1
  32. package/dist/bot/mcp-tools.d.ts +1 -1
  33. package/dist/bot/mcp-tools.d.ts.map +1 -1
  34. package/dist/bot/mcp-tools.js +1 -1
  35. package/dist/bot/mcp-tools.js.map +1 -1
  36. package/dist/bot/permissions.d.ts +1 -1
  37. package/dist/bot/permissions.d.ts.map +1 -1
  38. package/dist/bot/registry.d.ts +3 -3
  39. package/dist/bot/registry.d.ts.map +1 -1
  40. package/dist/bot/registry.js +2 -2
  41. package/dist/bot/registry.js.map +1 -1
  42. package/dist/bot/transport.d.ts +1 -1
  43. package/dist/bot/transport.d.ts.map +1 -1
  44. package/dist/bot/transport.js +12 -7
  45. package/dist/bot/transport.js.map +1 -1
  46. package/dist/bot/uploads.d.ts +1 -1
  47. package/dist/bot/uploads.d.ts.map +1 -1
  48. package/dist/bot/uploads.js +1 -1
  49. package/dist/bot/uploads.js.map +1 -1
  50. package/dist/client/account.d.ts +39 -0
  51. package/dist/client/account.d.ts.map +1 -0
  52. package/dist/client/account.js +92 -0
  53. package/dist/client/account.js.map +1 -0
  54. package/dist/client/chat-members.d.ts +27 -0
  55. package/dist/client/chat-members.d.ts.map +1 -0
  56. package/dist/client/chat-members.js +73 -0
  57. package/dist/client/chat-members.js.map +1 -0
  58. package/dist/client/chat-reads.d.ts +57 -0
  59. package/dist/client/chat-reads.d.ts.map +1 -0
  60. package/dist/client/chat-reads.js +160 -0
  61. package/dist/client/chat-reads.js.map +1 -0
  62. package/dist/client/chat-writes.d.ts +111 -0
  63. package/dist/client/chat-writes.d.ts.map +1 -0
  64. package/dist/client/chat-writes.js +240 -0
  65. package/dist/client/chat-writes.js.map +1 -0
  66. package/dist/client/contacts.d.ts +39 -0
  67. package/dist/client/contacts.d.ts.map +1 -0
  68. package/dist/client/contacts.js +93 -0
  69. package/dist/client/contacts.js.map +1 -0
  70. package/dist/client/delivery.d.ts +35 -0
  71. package/dist/client/delivery.d.ts.map +1 -0
  72. package/dist/client/delivery.js +62 -0
  73. package/dist/client/delivery.js.map +1 -0
  74. package/dist/client/folders.d.ts +20 -0
  75. package/dist/client/folders.d.ts.map +1 -0
  76. package/dist/client/folders.js +57 -0
  77. package/dist/client/folders.js.map +1 -0
  78. package/dist/client/history.d.ts +41 -0
  79. package/dist/client/history.d.ts.map +1 -0
  80. package/dist/client/history.js +111 -0
  81. package/dist/client/history.js.map +1 -0
  82. package/dist/client/live.d.ts +38 -0
  83. package/dist/client/live.d.ts.map +1 -0
  84. package/dist/client/live.js +182 -0
  85. package/dist/client/live.js.map +1 -0
  86. package/dist/client/login.d.ts +11 -0
  87. package/dist/client/login.d.ts.map +1 -0
  88. package/dist/client/login.js +8 -0
  89. package/dist/client/login.js.map +1 -0
  90. package/dist/client/message-reads.d.ts +53 -0
  91. package/dist/client/message-reads.d.ts.map +1 -0
  92. package/dist/client/message-reads.js +164 -0
  93. package/dist/client/message-reads.js.map +1 -0
  94. package/dist/client/message-writes.d.ts +84 -0
  95. package/dist/client/message-writes.d.ts.map +1 -0
  96. package/dist/client/message-writes.js +254 -0
  97. package/dist/client/message-writes.js.map +1 -0
  98. package/dist/client/people.d.ts +31 -0
  99. package/dist/client/people.d.ts.map +1 -0
  100. package/dist/client/people.js +130 -0
  101. package/dist/client/people.js.map +1 -0
  102. package/dist/client/polls.d.ts +53 -0
  103. package/dist/client/polls.d.ts.map +1 -0
  104. package/dist/client/polls.js +141 -0
  105. package/dist/client/polls.js.map +1 -0
  106. package/dist/client/read-policy.d.ts +2 -0
  107. package/dist/client/read-policy.d.ts.map +1 -0
  108. package/dist/client/read-policy.js +34 -0
  109. package/dist/client/read-policy.js.map +1 -0
  110. package/dist/client/request.d.ts +21 -0
  111. package/dist/client/request.d.ts.map +1 -0
  112. package/dist/client/request.js +69 -0
  113. package/dist/client/request.js.map +1 -0
  114. package/dist/client/session.d.ts +50 -0
  115. package/dist/client/session.d.ts.map +1 -0
  116. package/dist/client/session.js +293 -0
  117. package/dist/client/session.js.map +1 -0
  118. package/dist/client/stickers.d.ts +12 -0
  119. package/dist/client/stickers.d.ts.map +1 -0
  120. package/dist/client/stickers.js +29 -0
  121. package/dist/client/stickers.js.map +1 -0
  122. package/dist/client/types.d.ts +54 -0
  123. package/dist/client/types.d.ts.map +1 -0
  124. package/dist/client/types.js +2 -0
  125. package/dist/client/types.js.map +1 -0
  126. package/dist/client/upload-transport.d.ts +15 -0
  127. package/dist/client/upload-transport.d.ts.map +1 -0
  128. package/dist/client/upload-transport.js +48 -0
  129. package/dist/client/upload-transport.js.map +1 -0
  130. package/dist/client/uploads.d.ts +15 -0
  131. package/dist/client/uploads.d.ts.map +1 -0
  132. package/dist/client/uploads.js +19 -0
  133. package/dist/client/uploads.js.map +1 -0
  134. package/dist/client/values.d.ts +120 -0
  135. package/dist/client/values.d.ts.map +1 -0
  136. package/dist/client/values.js +186 -0
  137. package/dist/client/values.js.map +1 -0
  138. package/dist/client/writes.d.ts +40 -0
  139. package/dist/client/writes.d.ts.map +1 -0
  140. package/dist/client/writes.js +186 -0
  141. package/dist/client/writes.js.map +1 -0
  142. package/dist/client.d.ts +29 -644
  143. package/dist/client.d.ts.map +1 -1
  144. package/dist/client.js +267 -2828
  145. package/dist/client.js.map +1 -1
  146. package/dist/commands/account.js +1 -1
  147. package/dist/commands/account.js.map +1 -1
  148. package/dist/commands/bot-comments.d.ts.map +1 -1
  149. package/dist/commands/bot-comments.js +9 -5
  150. package/dist/commands/bot-comments.js.map +1 -1
  151. package/dist/commands/bot-context.d.ts +2 -2
  152. package/dist/commands/bot-context.d.ts.map +1 -1
  153. package/dist/commands/bot-context.js +2 -2
  154. package/dist/commands/bot-context.js.map +1 -1
  155. package/dist/commands/bot-members.d.ts +1 -1
  156. package/dist/commands/bot-members.d.ts.map +1 -1
  157. package/dist/commands/bot-members.js +14 -5
  158. package/dist/commands/bot-members.js.map +1 -1
  159. package/dist/commands/bot-messenger.d.ts +1 -1
  160. package/dist/commands/bot-messenger.d.ts.map +1 -1
  161. package/dist/commands/bot-messenger.js +2 -2
  162. package/dist/commands/bot-messenger.js.map +1 -1
  163. package/dist/commands/bot-reads.js +1 -1
  164. package/dist/commands/bot-reads.js.map +1 -1
  165. package/dist/commands/bot-sends.js +3 -3
  166. package/dist/commands/bot-sends.js.map +1 -1
  167. package/dist/commands/bot-setup.d.ts.map +1 -1
  168. package/dist/commands/bot-setup.js +2 -1
  169. package/dist/commands/bot-setup.js.map +1 -1
  170. package/dist/commands/bot.js +1 -1
  171. package/dist/commands/bot.js.map +1 -1
  172. package/dist/commands/calls.js +1 -1
  173. package/dist/commands/calls.js.map +1 -1
  174. package/dist/commands/chats.js +1 -1
  175. package/dist/commands/chats.js.map +1 -1
  176. package/dist/commands/commands.js +1 -1
  177. package/dist/commands/commands.js.map +1 -1
  178. package/dist/commands/complete.js +1 -1
  179. package/dist/commands/complete.js.map +1 -1
  180. package/dist/commands/config.d.ts.map +1 -1
  181. package/dist/commands/config.js +29 -27
  182. package/dist/commands/config.js.map +1 -1
  183. package/dist/commands/contacts.js +1 -1
  184. package/dist/commands/contacts.js.map +1 -1
  185. package/dist/commands/context.d.ts +2 -2
  186. package/dist/commands/context.d.ts.map +1 -1
  187. package/dist/commands/context.js +2 -2
  188. package/dist/commands/context.js.map +1 -1
  189. package/dist/commands/doctor.js +2 -2
  190. package/dist/commands/doctor.js.map +1 -1
  191. package/dist/commands/mcp.d.ts.map +1 -1
  192. package/dist/commands/mcp.js +9 -8
  193. package/dist/commands/mcp.js.map +1 -1
  194. package/dist/commands/messages.d.ts.map +1 -1
  195. package/dist/commands/messages.js +11 -2
  196. package/dist/commands/messages.js.map +1 -1
  197. package/dist/commands/models.js +1 -1
  198. package/dist/commands/models.js.map +1 -1
  199. package/dist/commands/paging.d.ts +6 -35
  200. package/dist/commands/paging.d.ts.map +1 -1
  201. package/dist/commands/paging.js +4 -46
  202. package/dist/commands/paging.js.map +1 -1
  203. package/dist/commands/recipients.d.ts.map +1 -1
  204. package/dist/commands/recipients.js +9 -7
  205. package/dist/commands/recipients.js.map +1 -1
  206. package/dist/commands/runs.js +1 -1
  207. package/dist/commands/runs.js.map +1 -1
  208. package/dist/commands/sends.js +1 -1
  209. package/dist/commands/sends.js.map +1 -1
  210. package/dist/commands/serve-members.js +3 -3
  211. package/dist/commands/serve-members.js.map +1 -1
  212. package/dist/commands/serve-stems.js +2 -2
  213. package/dist/commands/serve-stems.js.map +1 -1
  214. package/dist/commands/serve.d.ts.map +1 -1
  215. package/dist/commands/serve.js +12 -4
  216. package/dist/commands/serve.js.map +1 -1
  217. package/dist/commands/server.d.ts +1 -1
  218. package/dist/commands/server.d.ts.map +1 -1
  219. package/dist/commands/server.js +1 -1
  220. package/dist/commands/server.js.map +1 -1
  221. package/dist/commands/session.d.ts +1 -1
  222. package/dist/commands/setup.js +1 -1
  223. package/dist/commands/setup.js.map +1 -1
  224. package/dist/commands/skill.js +1 -1
  225. package/dist/commands/skill.js.map +1 -1
  226. package/dist/commands/stickers.js +1 -1
  227. package/dist/commands/stickers.js.map +1 -1
  228. package/dist/commands/upgrade.js +1 -1
  229. package/dist/commands/upgrade.js.map +1 -1
  230. package/dist/config.d.ts +845 -145
  231. package/dist/config.d.ts.map +1 -1
  232. package/dist/config.js +34 -34
  233. package/dist/config.js.map +1 -1
  234. package/dist/deadline.d.ts +1 -1
  235. package/dist/deadline.d.ts.map +1 -1
  236. package/dist/deadline.js +1 -1
  237. package/dist/deadline.js.map +1 -1
  238. package/dist/diagnose.d.ts +1 -1
  239. package/dist/diagnose.d.ts.map +1 -1
  240. package/dist/diagnose.js +2 -2
  241. package/dist/diagnose.js.map +1 -1
  242. package/dist/domain/models.d.ts +2 -2
  243. package/dist/domain/models.d.ts.map +1 -1
  244. package/dist/download.js +1 -1
  245. package/dist/download.js.map +1 -1
  246. package/dist/envelope.d.ts +29 -0
  247. package/dist/envelope.d.ts.map +1 -0
  248. package/dist/envelope.js +31 -0
  249. package/dist/envelope.js.map +1 -0
  250. package/dist/format-markdown.d.ts +1 -1
  251. package/dist/format-markdown.d.ts.map +1 -1
  252. package/dist/format-markdown.js +1 -1
  253. package/dist/format-markdown.js.map +1 -1
  254. package/dist/mcp/instructions.d.ts +1 -1
  255. package/dist/mcp/instructions.d.ts.map +1 -1
  256. package/dist/mcp/legacy-check.d.ts +1 -1
  257. package/dist/mcp/legacy-check.d.ts.map +1 -1
  258. package/dist/mcp/legacy-check.js +5 -3
  259. package/dist/mcp/legacy-check.js.map +1 -1
  260. package/dist/mcp/photo.d.ts +1 -1
  261. package/dist/mcp/photo.d.ts.map +1 -1
  262. package/dist/mcp/photo.js +3 -2
  263. package/dist/mcp/photo.js.map +1 -1
  264. package/dist/mcp/prompts.d.ts.map +1 -1
  265. package/dist/mcp/prompts.js +11 -9
  266. package/dist/mcp/prompts.js.map +1 -1
  267. package/dist/mcp/resources.js +2 -2
  268. package/dist/mcp/resources.js.map +1 -1
  269. package/dist/mcp/server.d.ts +1 -1
  270. package/dist/mcp/server.d.ts.map +1 -1
  271. package/dist/mcp/server.js +2 -2
  272. package/dist/mcp/server.js.map +1 -1
  273. package/dist/mcp/shared.d.ts +1 -1
  274. package/dist/mcp/shared.d.ts.map +1 -1
  275. package/dist/mcp/shared.js +3 -3
  276. package/dist/mcp/shared.js.map +1 -1
  277. package/dist/mcp/tools.d.ts +2 -2
  278. package/dist/mcp/tools.d.ts.map +1 -1
  279. package/dist/mcp/tools.js +39 -29
  280. package/dist/mcp/tools.js.map +1 -1
  281. package/dist/messenger.d.ts +3 -3
  282. package/dist/messenger.d.ts.map +1 -1
  283. package/dist/messenger.js +15 -5
  284. package/dist/messenger.js.map +1 -1
  285. package/dist/moderation/points.d.ts +1 -1
  286. package/dist/moderation/points.d.ts.map +1 -1
  287. package/dist/moderation/points.js +1 -1
  288. package/dist/moderation/points.js.map +1 -1
  289. package/dist/moderation/rules.d.ts +1 -1
  290. package/dist/moderation/rules.d.ts.map +1 -1
  291. package/dist/moderation/rules.js +2 -2
  292. package/dist/moderation/rules.js.map +1 -1
  293. package/dist/output.d.ts +1 -1
  294. package/dist/output.d.ts.map +1 -1
  295. package/dist/output.js +1 -1
  296. package/dist/output.js.map +1 -1
  297. package/dist/permissions.d.ts +1 -1
  298. package/dist/permissions.d.ts.map +1 -1
  299. package/dist/permissions.js +2 -2
  300. package/dist/permissions.js.map +1 -1
  301. package/dist/program.d.ts +1 -1
  302. package/dist/program.d.ts.map +1 -1
  303. package/dist/program.js +3 -2
  304. package/dist/program.js.map +1 -1
  305. package/dist/protocol/connection.d.ts.map +1 -1
  306. package/dist/protocol/connection.js +44 -12
  307. package/dist/protocol/connection.js.map +1 -1
  308. package/dist/record.d.ts +1 -1
  309. package/dist/record.d.ts.map +1 -1
  310. package/dist/record.js +1 -1
  311. package/dist/record.js.map +1 -1
  312. package/dist/report.d.ts +2 -2
  313. package/dist/report.d.ts.map +1 -1
  314. package/dist/report.js +1 -1
  315. package/dist/report.js.map +1 -1
  316. package/dist/resolve.d.ts +2 -2
  317. package/dist/resolve.d.ts.map +1 -1
  318. package/dist/resolve.js +2 -2
  319. package/dist/resolve.js.map +1 -1
  320. package/dist/sends.d.ts +2 -2
  321. package/dist/sends.d.ts.map +1 -1
  322. package/dist/sends.js +2 -2
  323. package/dist/sends.js.map +1 -1
  324. package/dist/server/replies.d.ts +2 -2
  325. package/dist/server/replies.d.ts.map +1 -1
  326. package/dist/server/replies.js +3 -3
  327. package/dist/server/replies.js.map +1 -1
  328. package/dist/server/server-connection.js +1 -1
  329. package/dist/server/server-connection.js.map +1 -1
  330. package/dist/server/server.d.ts +4 -2
  331. package/dist/server/server.d.ts.map +1 -1
  332. package/dist/server/server.js +39 -21
  333. package/dist/server/server.js.map +1 -1
  334. package/dist/server/subscribe.d.ts.map +1 -1
  335. package/dist/server/subscribe.js +24 -4
  336. package/dist/server/subscribe.js.map +1 -1
  337. package/dist/server/subscribers.d.ts +18 -0
  338. package/dist/server/subscribers.d.ts.map +1 -0
  339. package/dist/server/subscribers.js +146 -0
  340. package/dist/server/subscribers.js.map +1 -0
  341. package/dist/session/prompt.d.ts +1 -1
  342. package/dist/session/prompt.d.ts.map +1 -1
  343. package/dist/session/prompt.js +1 -1
  344. package/dist/session/prompt.js.map +1 -1
  345. package/dist/spec/define.d.ts +1 -1
  346. package/dist/spec/define.d.ts.map +1 -1
  347. package/dist/transcribe/install.d.ts +1 -1
  348. package/dist/transcribe/install.d.ts.map +1 -1
  349. package/dist/transcribe/install.js +1 -1
  350. package/dist/transcribe/install.js.map +1 -1
  351. package/dist/transcribe/models.d.ts +2 -2
  352. package/dist/transcribe/models.d.ts.map +1 -1
  353. package/dist/transcribe/models.js +2 -2
  354. package/dist/transcribe/models.js.map +1 -1
  355. package/dist/upload.d.ts.map +1 -1
  356. package/dist/upload.js +9 -2
  357. package/dist/upload.js.map +1 -1
  358. package/dist/version.d.ts +1 -1
  359. package/dist/version.js +1 -1
  360. package/package.json +4 -4
  361. package/skills/max-cli/SKILL.md +75 -54
@@ -0,0 +1,141 @@
1
+ import { CliError } from "@wirecat/cli-base";
2
+ import { POLL_CLOSED, pollSettings, toPoll } from "../domain/map.js";
3
+ import { asArray, asCliError, record } from "./values.js";
4
+ export const createPolls = (deps) => {
5
+ const resource = {
6
+ show: async (chatId, messageId) => {
7
+ await deps.connectOnce();
8
+ return { chatId, messageId, poll: (await deps.poll(chatId, messageId)).poll };
9
+ },
10
+ vote: async (chatId, messageId, answerIds) => {
11
+ if (deps.offline)
12
+ throw new CliError("validation_error", "`--offline` reads what was recorded; it cannot vote");
13
+ await deps.guard({ chatId, kind: "reaction", key: "polls.vote" }, messageId);
14
+ try {
15
+ await deps.connectOnce();
16
+ const { attach, poll } = await deps.poll(chatId, messageId);
17
+ const voted = poll.answers.some((answer) => answer.mine);
18
+ if (answerIds.length === 0 && !voted) {
19
+ throw new CliError("validation_error", `you have not voted in the poll of message ${messageId}`);
20
+ }
21
+ if (answerIds.length === 0 && !poll.revote) {
22
+ throw new CliError("validation_error", `the poll of message ${messageId} does not let a vote be taken back`);
23
+ }
24
+ if (answerIds.length > 0 && voted && !poll.revote) {
25
+ throw new CliError("validation_error", `you have voted in the poll of message ${messageId}, and it does not let a vote change`);
26
+ }
27
+ if (answerIds.length > 1 && !poll.multiple) {
28
+ throw new CliError("validation_error", `the poll of message ${messageId} takes one answer, not ${answerIds.length}`);
29
+ }
30
+ const unknown = answerIds.find((id) => !poll.answers.some((answer) => answer.id === id));
31
+ if (unknown !== undefined) {
32
+ throw new CliError("validation_error", `the poll of message ${messageId} has no answer ${unknown} — its answers are ${poll.answers.map((answer) => answer.id).join(", ")}`);
33
+ }
34
+ const answer = await deps.wire.messages.pollVote({
35
+ chatId,
36
+ messageId,
37
+ pollId: poll.id,
38
+ answersIds: answerIds.map(Number),
39
+ });
40
+ deps.sends?.record({ chatId, kind: "reaction", outcome: "sent", messageId });
41
+ const state = record(answer.state);
42
+ return { chatId, messageId, poll: (state && toPoll({ ...attach, state })) ?? poll };
43
+ }
44
+ catch (error) {
45
+ const failure = asCliError(error);
46
+ deps.sends?.record({
47
+ chatId,
48
+ kind: "reaction",
49
+ outcome: "failed",
50
+ messageId,
51
+ errorCode: failure.code,
52
+ });
53
+ if (answerIds.length > 0 && failure.details.provider_error === "poll.already.voted") {
54
+ throw new CliError(failure.code, `${failure.message}; if this poll allows changing votes, run \`polls vote <chat> <message> --retract\` in the same profile before voting again`, failure.details);
55
+ }
56
+ throw error;
57
+ }
58
+ },
59
+ close: async (chatId, messageId) => {
60
+ if (deps.offline)
61
+ throw new CliError("validation_error", "`--offline` reads what was recorded; it cannot close a poll");
62
+ await deps.guard({ chatId, kind: "edit", key: "polls.close" }, messageId);
63
+ try {
64
+ await deps.connectOnce();
65
+ const { attach, poll, outgoing } = await deps.poll(chatId, messageId);
66
+ if (!outgoing)
67
+ throw new CliError("validation_error", `the poll of message ${messageId} is not yours to close`);
68
+ // What the web client sends back: the answers' text only, no ids and no votes.
69
+ const closed = {
70
+ _type: "POLL",
71
+ pollId: attach.pollId,
72
+ title: attach.title,
73
+ answers: asArray(attach.answers).map((each) => ({ text: each.text })),
74
+ settings: (typeof attach.settings === "number" ? attach.settings : 0) | POLL_CLOSED,
75
+ };
76
+ const answer = await deps.wire.messages.edit({ chatId, messageId, attachments: [closed] });
77
+ deps.sends?.record({ chatId, kind: "edit", outcome: "sent", messageId });
78
+ const after = asArray(record(answer.message)?.attaches).find((each) => each._type === "POLL");
79
+ return { chatId, messageId, poll: (after && toPoll(after)) ?? { ...poll, closed: true } };
80
+ }
81
+ catch (error) {
82
+ deps.sends?.record({ chatId, kind: "edit", outcome: "failed", messageId, errorCode: asCliError(error).code });
83
+ throw error;
84
+ }
85
+ },
86
+ create: async (chatId, question, answers, options = {}) => {
87
+ if (deps.offline)
88
+ throw new CliError("validation_error", "`--offline` reads what was recorded; it cannot create a poll");
89
+ if (question.trim() === "")
90
+ throw new CliError("validation_error", "a poll needs a question");
91
+ if (answers.length < 2 || answers.some((answer) => answer.trim() === "")) {
92
+ throw new CliError("validation_error", "a poll needs at least two answers, none of them empty");
93
+ }
94
+ const cid = options.cid ?? deps.nextCid();
95
+ const sendId = String(cid);
96
+ try {
97
+ await deps.checked({ chatId, kind: "message", sendId, key: "polls.create" });
98
+ }
99
+ catch (error) {
100
+ deps.sends?.record({ chatId, kind: "message", outcome: "refused", sendId, errorCode: asCliError(error).code });
101
+ throw error;
102
+ }
103
+ const attach = {
104
+ _type: "POLL",
105
+ title: question,
106
+ answers: answers.map((text) => ({ text })),
107
+ settings: pollSettings(options),
108
+ };
109
+ try {
110
+ const sent = await deps.deliver(chatId, "", cid, {
111
+ ...options,
112
+ attaches: [attach],
113
+ repeat: `max polls create ${chatId} …`,
114
+ });
115
+ deps.sends?.record({
116
+ chatId,
117
+ kind: "message",
118
+ outcome: "sent",
119
+ messageId: sent.id,
120
+ sendId,
121
+ length: question.length,
122
+ });
123
+ deps.warn("web.max.ru does not show polls: anyone reading this chat in a browser sees «Обновите MAX…»");
124
+ return sent;
125
+ }
126
+ catch (error) {
127
+ const failure = asCliError(error);
128
+ deps.sends?.record({
129
+ chatId,
130
+ kind: "message",
131
+ outcome: failure.code === "outcome_unknown" ? "outcome_unknown" : "failed",
132
+ sendId,
133
+ errorCode: failure.code,
134
+ });
135
+ throw error;
136
+ }
137
+ },
138
+ };
139
+ return { show: resource.show, vote: resource.vote, close: resource.close, create: resource.create };
140
+ };
141
+ //# sourceMappingURL=polls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polls.js","sourceRoot":"","sources":["../../src/client/polls.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const withReadPolicy: <T extends object>(resource: string, methods: T, reads: ((key: string) => void) | undefined) => T;
2
+ //# sourceMappingURL=read-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-policy.d.ts","sourceRoot":"","sources":["../../src/client/read-policy.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,MAAM,YACnC,MAAM,WACP,CAAC,SACH,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,KACzC,CAsBF,CAAA"}
@@ -0,0 +1,34 @@
1
+ import { isId } from "../resolve.js";
2
+ const aliases = {
3
+ "account.me": "account.show",
4
+ "account.sessions": "account.sessions.list",
5
+ "account.endOtherSessions": "account.sessions.end",
6
+ "chats.markRead": "chats.mark-read",
7
+ "chats.adminIds": "chats.admins.list",
8
+ "chats.since": "messages.list",
9
+ "messages.around": "messages.context",
10
+ "messages.react": "reactions.add",
11
+ "messages.unreact": "reactions.remove",
12
+ "contacts.sync": "contacts.list",
13
+ };
14
+ export const withReadPolicy = (resource, methods, reads) => {
15
+ if (!reads || ["login", "stickers", "live"].includes(resource))
16
+ return methods;
17
+ return Object.fromEntries(Object.entries(methods).map(([key, value]) => {
18
+ const path = `${resource}.${key}`;
19
+ return [
20
+ key,
21
+ typeof value === "object" && value !== null
22
+ ? withReadPolicy(path, value, reads)
23
+ : typeof value === "function"
24
+ ? (...args) => {
25
+ if (path !== "messages.moment" &&
26
+ !(path === "chats.resolve" && typeof args[0] === "string" && isId(args[0])))
27
+ reads(path === "messages.pin" && args[1] === null ? "messages.unpin" : (aliases[path] ?? path));
28
+ return Reflect.apply(value, methods, args);
29
+ }
30
+ : value,
31
+ ];
32
+ }));
33
+ };
34
+ //# sourceMappingURL=read-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-policy.js","sourceRoot":"","sources":["../../src/client/read-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEpC,MAAM,OAAO,GAA2B;IACtC,YAAY,EAAE,cAAc;IAC5B,kBAAkB,EAAE,uBAAuB;IAC3C,0BAA0B,EAAE,sBAAsB;IAClD,gBAAgB,EAAE,iBAAiB;IACnC,gBAAgB,EAAE,mBAAmB;IACrC,aAAa,EAAE,eAAe;IAC9B,iBAAiB,EAAE,kBAAkB;IACrC,gBAAgB,EAAE,eAAe;IACjC,kBAAkB,EAAE,kBAAkB;IACtC,eAAe,EAAE,eAAe;CACjC,CAAA;AACD,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,QAAgB,EAChB,OAAU,EACV,KAA0C,EACvC,EAAE;IACL,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,OAAO,CAAA;IAC9E,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC3C,MAAM,IAAI,GAAG,GAAG,QAAQ,IAAI,GAAG,EAAE,CAAA;QACjC,OAAO;YACL,GAAG;YACH,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;gBACzC,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC;gBACpC,CAAC,CAAC,OAAO,KAAK,KAAK,UAAU;oBAC3B,CAAC,CAAC,CAAC,GAAG,IAAe,EAAE,EAAE;wBACrB,IACE,IAAI,KAAK,iBAAiB;4BAC1B,CAAC,CAAC,IAAI,KAAK,eAAe,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;4BAE3E,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA;wBACjG,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;oBAC5C,CAAC;oBACH,CAAC,CAAC,KAAK;SACZ,CAAA;IACH,CAAC,CAAC,CACE,CAAA;AACR,CAAC,CAAA"}
@@ -0,0 +1,21 @@
1
+ import type { DiagnosticEvent } from "@wirecat/cli-core/cli";
2
+ import type { Wire } from "../protocol/connection.js";
3
+ import type { Payload } from "../protocol/frame.js";
4
+ import { type Operation, type RequestOf } from "../spec/index.js";
5
+ import { type WarningCode } from "../wire-events.js";
6
+ interface Dependencies {
7
+ readonly monotonicNow: () => number;
8
+ readonly connection: Wire;
9
+ readonly warn: (message: string) => void;
10
+ readonly events: (event: DiagnosticEvent) => void;
11
+ }
12
+ export declare const createRequest: (deps: Dependencies) => {
13
+ send: <TOperation extends Operation>(operation: TOperation, request: RequestOf<TOperation>) => Promise<Payload>;
14
+ warnAbout: (code: WarningCode, message: string, extra?: {
15
+ operation?: string;
16
+ detail?: string;
17
+ }) => void;
18
+ emit: (event: DiagnosticEvent) => void;
19
+ };
20
+ export {};
21
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/client/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAA+B,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC9F,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAGrE,UAAU,YAAY;IACpB,QAAQ,CAAC,YAAY,EAAE,MAAM,MAAM,CAAA;IACnC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;CAClD;AAED,eAAO,MAAM,aAAa,SAAU,YAAY;IAqErC,IAAI,GApEc,UAAU,SAAS,SAAS,aAC1C,UAAU,WACZ,SAAS,CAAC,UAAU,CAAC,KAC7B,OAAO,CAAC,OAAO,CAAC;IAiES,SAAS,SAZZ,WAAW,WAAW,MAAM,UAAS;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAQ,IAAI;IAY/D,IAAI,UAPjC,eAAe,KAAG,IAAI;CAQ5C,CAAA"}
@@ -0,0 +1,69 @@
1
+ import { buildRequest, checkResponse } from "../spec/index.js";
2
+ import { countsIn, idsOf } from "../wire-events.js";
3
+ import { asCliError } from "./values.js";
4
+ export const createRequest = (deps) => {
5
+ async function sendRequest(operation, request) {
6
+ const payload = buildRequest(operation, request);
7
+ const started = deps.monotonicNow();
8
+ const about = { operation: operation.name, opcode: operation.opcode };
9
+ let seq = 0;
10
+ let bytes;
11
+ let answer;
12
+ try {
13
+ answer = await deps.connection.invoke(operation.opcode, payload, (wire) => {
14
+ seq = wire.seq;
15
+ if (wire.phase === "received") {
16
+ bytes = wire.bytes;
17
+ return;
18
+ }
19
+ emit({ event: "request", ...about, seq, bytes: wire.bytes, ...idsOf(request) });
20
+ });
21
+ }
22
+ catch (error) {
23
+ const failure = asCliError(error);
24
+ // The request that never came back is the one somebody is reading the log for, so it gets a
25
+ // line of its own rather than disappearing with the exception.
26
+ emit({
27
+ event: "response",
28
+ ...about,
29
+ seq,
30
+ ...(bytes === undefined ? {} : { bytes }),
31
+ durationMs: Math.round(deps.monotonicNow() - started),
32
+ outcome: "error",
33
+ errorCode: failure.code,
34
+ ...(typeof failure.details.provider_error === "string"
35
+ ? { providerError: failure.details.provider_error }
36
+ : {}),
37
+ });
38
+ throw failure;
39
+ }
40
+ const counts = countsIn(answer);
41
+ emit({
42
+ event: "response",
43
+ ...about,
44
+ seq,
45
+ ...(bytes === undefined ? {} : { bytes }),
46
+ durationMs: Math.round(deps.monotonicNow() - started),
47
+ ...(counts ? { counts } : {}),
48
+ outcome: "ok",
49
+ });
50
+ const note = checkResponse(operation, answer);
51
+ if (note)
52
+ warnAbout("response_shape", note, { operation: operation.name, detail: note });
53
+ return answer;
54
+ }
55
+ function warnAbout(code, message, extra = {}) {
56
+ deps.warn(message);
57
+ emit({ event: "warning", code, ...extra });
58
+ }
59
+ function emit(event) {
60
+ try {
61
+ deps.events(event);
62
+ }
63
+ catch {
64
+ // Whoever is keeping the log has a problem; the command does not.
65
+ }
66
+ }
67
+ return { send: sendRequest, warnAbout: warnAbout, emit: emit };
68
+ };
69
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/client/request.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { Id } from "../domain/models.js";
2
+ import type { Invoke, wireClient } from "../generated/client.generated.js";
3
+ import type { Wire } from "../protocol/connection.js";
4
+ import { type Payload } from "../protocol/frame.js";
5
+ import type { MaxRecord, SyncSummary } from "../record.js";
6
+ import { type SessionStore } from "../session/store.js";
7
+ import type { WarningCode } from "../wire-events.js";
8
+ import { type ResumeFrom } from "./values.js";
9
+ interface Dependencies {
10
+ readonly offline: boolean;
11
+ readonly store: SessionStore;
12
+ readonly fullLogin: boolean;
13
+ readonly connection: Wire;
14
+ readonly invoke: Invoke;
15
+ readonly resume: ResumeFrom | undefined;
16
+ readonly wire: Pick<ReturnType<typeof wireClient>, "chats" | "session">;
17
+ warnAbout: (code: WarningCode, message: string, extra?: {
18
+ operation?: string;
19
+ detail?: string;
20
+ }) => void;
21
+ readonly record: MaxRecord | undefined;
22
+ readonly server: {
23
+ readonly journals: boolean;
24
+ } | undefined;
25
+ readonly now: () => number;
26
+ }
27
+ export declare const createSession: (deps: Dependencies) => {
28
+ connect: (options?: {
29
+ token?: string;
30
+ }) => Promise<void>;
31
+ connectOnce: () => Promise<void>;
32
+ keep: (what: string, write: (record: MaxRecord) => Promise<void>) => Promise<void>;
33
+ participantsOf: (chat: Payload, viewerId: string | undefined) => Id[] | undefined;
34
+ logout: () => Promise<void>;
35
+ close: () => Promise<void>;
36
+ beforeLogin: (flow: () => Promise<string>) => Promise<string>;
37
+ fromEnvironment: () => boolean;
38
+ keepSettings: (sent: {
39
+ user?: Payload;
40
+ chats?: Payload;
41
+ }, answer: Payload) => void;
42
+ lastEventOf: (chatId: Id) => number;
43
+ session: () => Payload;
44
+ login: Payload | undefined;
45
+ readonly chatsCut: boolean;
46
+ readonly chatsComplete: boolean;
47
+ readonly merged: SyncSummary | undefined;
48
+ };
49
+ export {};
50
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/client/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAE1E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1D,OAAO,EAAE,KAAK,YAAY,EAAuC,MAAM,qBAAqB,CAAA;AAE5F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAML,KAAK,UAAU,EAIhB,MAAM,aAAa,CAAA;AAEpB,UAAU,YAAY;IACpB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC,CAAA;IACvE,SAAS,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IACxG,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAA;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAA;CAC3B;AAED,eAAO,MAAM,aAAa,SAAU,YAAY;wBAQpB;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAQ,OAAO,CAAC,IAAI,CAAC;uBA2GnC,OAAO,CAAC,IAAI,CAAC;iBAkGjB,MAAM,SAAS,CAAC,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC;2BAS/D,OAAO,YAAY,MAAM,GAAG,SAAS,KAAG,EAAE,EAAE,GAAG,SAAS;kBAK7D,OAAO,CAAC,IAAI,CAAC;iBAMd,OAAO,CAAC,IAAI,CAAC;wBAKJ,MAAM,OAAO,CAAC,MAAM,CAAC,KAAG,OAAO,CAAC,MAAM,CAAC;2BAU5C,OAAO;yBAQP;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,UAAU,OAAO,KAAG,IAAI;0BAW1D,EAAE,KAAG,MAAM;;WA2BrB,OAAO,GAAG,SAAS;;;;CAavC,CAAA"}
@@ -0,0 +1,293 @@
1
+ import { CliError } from "@wirecat/cli-base";
2
+ import { toChat, toContact, toProfile } from "../domain/map.js";
3
+ import { asFirstWord } from "../profile.js";
4
+ import { asId } from "../protocol/frame.js";
5
+ import { LOGIN_CHATS, startSession } from "../session/handshake.js";
6
+ import { withLoginRefused, withoutLoginPause } from "../session/store.js";
7
+ import { WEB_USER_AGENT } from "../spec/identity.js";
8
+ import { asArray, asCliError, asMarker, CHATS_PAGE_SEEN, eventTime, reasonOf, record, refuseWhilePaused, } from "./values.js";
9
+ export const createSession = (deps) => {
10
+ let login;
11
+ let chatsCut = false;
12
+ let chatsComplete = false;
13
+ let merged;
14
+ let connecting;
15
+ let closed = false;
16
+ const connect = (options = {}) => {
17
+ if (closed)
18
+ return Promise.reject(new CliError("network_error", "the client is closed"));
19
+ if (!connecting)
20
+ connecting = performConnect(options)
21
+ .catch((error) => {
22
+ login = undefined;
23
+ throw error;
24
+ })
25
+ .finally(() => {
26
+ connecting = undefined;
27
+ });
28
+ return connecting;
29
+ };
30
+ async function performConnect({ token: candidate } = {}) {
31
+ if (deps.offline)
32
+ throw new CliError("validation_error", "`--offline` reads through the shared store; it cannot connect to MAX");
33
+ const token = candidate ?? deps.store.readToken();
34
+ if (!token) {
35
+ const profile = deps.store.profile;
36
+ // cli-base swallows a keyring that will not open, so the state file is the only witness: a
37
+ // profile that has logged in lost its keyring, not its session, and another login would
38
+ // register one more device for nothing (MAX-50, measured from cron 2026-09-25).
39
+ if (deps.store.hasLoggedIn()) {
40
+ throw new CliError("authentication_error", `no token found for profile "${profile}", although it has logged in on this machine — ` +
41
+ `the keyring is probably out of reach (cron, ssh: set XDG_RUNTIME_DIR); ` +
42
+ `\`max ${asFirstWord(profile)}doctor\` shows it. Log in again only if the token was removed`);
43
+ }
44
+ if (deps.store.isBot()) {
45
+ throw new CliError("authentication_error", `profile "${profile}" is a bot — its commands are \`max ${asFirstWord(profile)}bot …\`; ` +
46
+ `\`max ${asFirstWord(profile)}session start\` would add a personal account to it`);
47
+ }
48
+ // The fix has to carry the profile, or it logs the wrong one in: a name nobody has logged
49
+ // in under is the ordinary shape of this failure now that the first word is the profile.
50
+ throw new CliError("authentication_error", `no session for profile "${profile}" — run \`max ${asFirstWord(profile)}setup\` in a local terminal; agents: read \`max skill show\``);
51
+ }
52
+ const state = deps.store.readState();
53
+ refuseWhilePaused(state);
54
+ const sync = deps.fullLogin ? undefined : await loginMarker();
55
+ try {
56
+ await deps.connection.open();
57
+ if (closed)
58
+ throw new CliError("network_error", "the client is closed");
59
+ const answer = await startSession(deps.invoke, {
60
+ token,
61
+ deviceId: state.deviceId,
62
+ ...(sync === undefined ? {} : { sync }),
63
+ ...(deps.resume ? { resume: deps.resume.login } : {}),
64
+ });
65
+ login = answer;
66
+ }
67
+ catch (error) {
68
+ const failure = asCliError(error);
69
+ if (failure.code !== "rate_limited")
70
+ throw failure;
71
+ const paused = withLoginRefused(state);
72
+ deps.store.writeState(paused);
73
+ throw new CliError("rate_limited", `${failure.message} — this profile will not log in again before ${paused.loginPausedUntil}; ` +
74
+ "logging in sooner is what keeps an account locked");
75
+ }
76
+ // MAX has counted this login by now, so its state and rotated token are kept even when the client
77
+ // closed meanwhile; dropping them would make the next run log in again.
78
+ const viewerId = toProfile(record(login.profile) ?? {}).id;
79
+ // **Before `writeState`**, so a login we are about to refuse does not count itself or move
80
+ // `lastLoginAt`. A profile is a person, not a directory name: if this token belongs to someone
81
+ // else, every later command in this process would send as them and nothing would say so.
82
+ // Switching accounts has a door already — `session end` clears the id along with the token.
83
+ if (viewerId && state.viewerId && viewerId !== state.viewerId) {
84
+ throw new CliError("authentication_error", `this token is for a different account than profile "${deps.store.profile}" was set up with — ` +
85
+ `run \`max ${asFirstWord(deps.store.profile)}session end\` first if you meant to switch`);
86
+ }
87
+ deps.store.writeState({
88
+ ...withoutLoginPause(state),
89
+ ...(viewerId ? { viewerId } : {}),
90
+ logins: state.logins + 1,
91
+ lastLoginAt: new Date(deps.now()).toISOString(),
92
+ });
93
+ keepRotatedToken(token);
94
+ // `max serve` hands this login to any process that asks its socket; none of them needs the token.
95
+ const { token: _, ...withoutToken } = login;
96
+ login = withoutToken;
97
+ if (closed)
98
+ throw new CliError("network_error", "the client is closed");
99
+ if (deps.resume)
100
+ mergeChanged(deps.resume.chats);
101
+ else
102
+ await readRestOfChats();
103
+ await mergeLogin(viewerId);
104
+ if (closed)
105
+ throw new CliError("network_error", "the client is closed");
106
+ }
107
+ async function connectOnce() {
108
+ if (closed)
109
+ throw new CliError("network_error", "the client is closed");
110
+ if (connecting)
111
+ await connecting;
112
+ else if (!login)
113
+ await connect();
114
+ }
115
+ function mergeChanged(before) {
116
+ const session = snapshot();
117
+ const changed = asArray(session.chats);
118
+ const ids = new Set(changed.map((chat) => asId(record(chat)?.id)));
119
+ const kept = before.filter((chat) => !ids.has(asId(chat.id)));
120
+ session.chats = [...changed, ...kept].sort((a, b) => eventTime(b) - eventTime(a));
121
+ }
122
+ async function readRestOfChats() {
123
+ chatsCut = false;
124
+ chatsComplete = false;
125
+ const session = snapshot();
126
+ const chats = asArray(session.chats);
127
+ const marker = record(chats.at(-1))?.lastEventTime;
128
+ if (chats.length < LOGIN_CHATS) {
129
+ chatsComplete = true;
130
+ return;
131
+ }
132
+ if (typeof marker !== "number" && typeof marker !== "bigint")
133
+ return;
134
+ try {
135
+ const answer = await deps.wire.chats.list({ marker: Number(marker) });
136
+ const known = new Set(chats.map((chat) => asId(record(chat)?.id)));
137
+ const rest = asArray(answer.chats).filter((chat) => !known.has(asId(record(chat)?.id)));
138
+ session.chats = [...chats, ...rest];
139
+ chatsCut = rest.length >= CHATS_PAGE_SEEN;
140
+ chatsComplete = !chatsCut;
141
+ }
142
+ catch (error) {
143
+ chatsCut = true;
144
+ deps.warnAbout("chats_partial", `only the newest ${chats.length} chats were read: ${reasonOf(error)}`);
145
+ }
146
+ }
147
+ function keepRotatedToken(sent) {
148
+ const rotated = snapshot().token;
149
+ if (typeof rotated !== "string" || rotated === "" || rotated === sent)
150
+ return;
151
+ if (fromEnvironment()) {
152
+ deps.warnAbout("token_not_saved", "MAX refreshed the session; the fresh token was not saved, because the one in use came from MAX_TOKEN");
153
+ return;
154
+ }
155
+ try {
156
+ deps.store.writeToken(rotated);
157
+ }
158
+ catch (error) {
159
+ deps.warnAbout("token_not_saved", `the refreshed session could not be saved, so the previous one is still in use: ${reasonOf(error)}`);
160
+ }
161
+ }
162
+ async function mergeLogin(viewerId) {
163
+ const marker = asMarker(snapshot().time);
164
+ if (!deps.record)
165
+ return;
166
+ const chats = asArray(snapshot().chats);
167
+ const members = new Map();
168
+ for (const raw of chats) {
169
+ const chat = toChat(raw);
170
+ // A channel lists four of its hundred and seventy-eight thousand subscribers, so its
171
+ // `participants` is not a membership — storing it would be storing a wrong answer.
172
+ if (!chat.id || chat.kind === "channel")
173
+ continue;
174
+ const participants = participantsOf(raw, viewerId);
175
+ if (participants !== undefined)
176
+ members.set(chat.id, participants);
177
+ }
178
+ const delta = {
179
+ chats: chats.map(toChat).filter((chat) => chat.id !== ""),
180
+ people: asArray(snapshot().contacts)
181
+ .map(toContact)
182
+ .filter((contact) => contact.id !== ""),
183
+ members,
184
+ };
185
+ // A login `max serve` made answered its own marker, not the record's: what changed before it is not in it.
186
+ const own = deps.server?.journals !== true;
187
+ await keep("login", async (record) => {
188
+ const summary = await record.applyLogin({ ...delta, ...(own && marker !== undefined ? { marker } : {}) });
189
+ merged = summary;
190
+ });
191
+ }
192
+ async function loginMarker() {
193
+ let marker;
194
+ await keep("marker", async (record) => {
195
+ marker = await record.syncMarker();
196
+ });
197
+ return marker;
198
+ }
199
+ async function keep(what, write) {
200
+ if (!deps.record)
201
+ return;
202
+ try {
203
+ await write(deps.record);
204
+ }
205
+ catch (error) {
206
+ deps.warnAbout("cache_not_written", `the local store did not take the ${what}: ${reasonOf(error)}`);
207
+ }
208
+ }
209
+ function participantsOf(chat, viewerId) {
210
+ const participants = record(chat.participants);
211
+ return participants === undefined ? undefined : Object.keys(participants).filter((id) => id !== viewerId);
212
+ }
213
+ async function logout() {
214
+ if (deps.offline)
215
+ throw new CliError("validation_error", "`--offline` cannot log out on MAX's side");
216
+ await connectOnce();
217
+ await deps.wire.session.logout({});
218
+ }
219
+ async function close() {
220
+ closed = true;
221
+ await deps.connection.close();
222
+ }
223
+ async function beforeLogin(flow) {
224
+ try {
225
+ await deps.connection.open();
226
+ }
227
+ catch (error) {
228
+ throw asCliError(error);
229
+ }
230
+ await deps.wire.session.init({ userAgent: WEB_USER_AGENT, deviceId: deps.store.readState().deviceId });
231
+ return await flow();
232
+ }
233
+ function fromEnvironment() {
234
+ try {
235
+ return deps.store.tokenSource() === "environment";
236
+ }
237
+ catch {
238
+ return false;
239
+ }
240
+ }
241
+ function keepSettings(sent, answer) {
242
+ const login = snapshot();
243
+ const config = record(login.config) ?? {};
244
+ login.config = {
245
+ ...config,
246
+ ...(typeof answer.hash === "string" ? { hash: answer.hash } : {}),
247
+ ...(sent.user ? { user: { ...(record(config.user) ?? {}), ...sent.user, ...(record(answer.user) ?? {}) } } : {}),
248
+ ...(sent.chats ? { chats: { ...(record(config.chats) ?? {}), ...sent.chats } } : {}),
249
+ };
250
+ }
251
+ function lastEventOf(chatId) {
252
+ const chat = asArray(snapshot().chats).find((one) => asId(one.id) === chatId);
253
+ return eventTime(chat) || deps.now();
254
+ }
255
+ function snapshot() {
256
+ if (!login)
257
+ throw new CliError("configuration_error", "connect() was never called");
258
+ return login;
259
+ }
260
+ return {
261
+ connect: connect,
262
+ connectOnce: connectOnce,
263
+ keep: keep,
264
+ participantsOf: participantsOf,
265
+ logout: logout,
266
+ close: close,
267
+ beforeLogin: beforeLogin,
268
+ fromEnvironment: fromEnvironment,
269
+ keepSettings: keepSettings,
270
+ lastEventOf: lastEventOf,
271
+ session: () => {
272
+ if (connecting)
273
+ throw new CliError("configuration_error", "the login is still initializing");
274
+ return snapshot();
275
+ },
276
+ get login() {
277
+ return connecting ? undefined : login;
278
+ },
279
+ set login(value) {
280
+ login = value;
281
+ },
282
+ get chatsCut() {
283
+ return chatsCut;
284
+ },
285
+ get chatsComplete() {
286
+ return chatsComplete;
287
+ },
288
+ get merged() {
289
+ return merged;
290
+ },
291
+ };
292
+ };
293
+ //# sourceMappingURL=session.js.map