@wirecat/bitrix24-cli 0.3.0 → 0.5.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 (255) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +84 -9
  3. package/dist/api-keys.d.ts +36 -9
  4. package/dist/api-keys.d.ts.map +1 -1
  5. package/dist/api-keys.js +139 -19
  6. package/dist/api-keys.js.map +1 -1
  7. package/dist/bin/b24.js +2 -2
  8. package/dist/bitrix/errors.js +1 -1
  9. package/dist/bitrix/errors.js.map +1 -1
  10. package/dist/bitrix/methods.d.ts.map +1 -1
  11. package/dist/bitrix/methods.js +7 -3
  12. package/dist/bitrix/methods.js.map +1 -1
  13. package/dist/bitrix/transport.d.ts +4 -7
  14. package/dist/bitrix/transport.d.ts.map +1 -1
  15. package/dist/bitrix/transport.js +29 -19
  16. package/dist/bitrix/transport.js.map +1 -1
  17. package/dist/body.d.ts +14 -0
  18. package/dist/body.d.ts.map +1 -0
  19. package/dist/body.js +44 -0
  20. package/dist/body.js.map +1 -0
  21. package/dist/bundle/{chunk-QIPTIUMJ.js → all-profiles-CANIDIDS.js} +12 -7
  22. package/dist/bundle/{anthropic-RHRAVHC2.js → anthropic-JUJB4DCF.js} +5 -5
  23. package/dist/bundle/{app-server-QIT6S7AZ.js → app-server-3V5Z4PTK.js} +68 -54
  24. package/dist/bundle/b24.js +18 -12
  25. package/dist/bundle/{bun-H6RSODZ3.js → bun-LKMV5TY7.js} +2 -2
  26. package/dist/bundle/{bun-sqlite-BO4LTQHX.js → bun-sqlite-S56EF74S.js} +3 -3
  27. package/dist/bundle/{chunk-D5S6QV6R.js → chunk-2I4KWS3H.js} +6 -6
  28. package/dist/bundle/chunk-36PO5NWY.js +147 -0
  29. package/dist/bundle/{chunk-ZIAQPTUS.js → chunk-42F7Q7V6.js} +3 -3
  30. package/dist/bundle/{chunk-6WY72XVQ.js → chunk-4D3K6GZW.js} +18 -4
  31. package/dist/bundle/chunk-5D4MJQ6X.js +22 -0
  32. package/dist/bundle/chunk-5JOPERVF.js +84 -0
  33. package/dist/bundle/chunk-6A4UPWDC.js +15 -0
  34. package/dist/bundle/{chunk-P33NDCDI.js → chunk-6MGWIZG4.js} +1 -1
  35. package/dist/bundle/{chunk-ZDQQCXFG.js → chunk-6YJTNZ7U.js} +13 -13
  36. package/dist/bundle/{chunk-MBDK4YXG.js → chunk-7FBFJ6B4.js} +4 -2
  37. package/dist/bundle/chunk-7VCMOTQP.js +55 -0
  38. package/dist/bundle/{chunk-P364PLIK.js → chunk-A5IMMGYU.js} +36 -34
  39. package/dist/bundle/{chunk-45AKJVKV.js → chunk-ASEHTBNK.js} +1 -1
  40. package/dist/bundle/{chunk-HGL63O5V.js → chunk-B6LPJYPQ.js} +2 -2
  41. package/dist/bundle/{chunk-LSPIOT6Z.js → chunk-BHEE2K6C.js} +7 -7
  42. package/dist/bundle/chunk-BYZQBE63.js +971 -0
  43. package/dist/bundle/{program-H3TGGRQ6.js → chunk-COKGNTDQ.js} +15761 -16685
  44. package/dist/bundle/{chunk-XJXONOB5.js → chunk-DVFYRQGE.js} +1 -1
  45. package/dist/bundle/{chunk-FLUEXJ4X.js → chunk-DVSIBZ3G.js} +1 -1
  46. package/dist/bundle/chunk-EJEIXC6Y.js +273 -0
  47. package/dist/bundle/chunk-EYTGCM44.js +130 -0
  48. package/dist/bundle/{chunk-IRV2PCQ2.js → chunk-EYYOKT23.js} +26 -26
  49. package/dist/bundle/{chunk-PH5FZX6E.js → chunk-FCWPIWSR.js} +2 -2
  50. package/dist/bundle/{chunk-YZ5LHE5Q.js → chunk-FSWRMQWX.js} +2 -2
  51. package/dist/bundle/{chunk-ADLS6FVG.js → chunk-FXBHOCJK.js} +1 -1
  52. package/dist/bundle/chunk-G5MW6RCM.js +723 -0
  53. package/dist/bundle/{chunk-VEWWAGTD.js → chunk-GLTKRLFT.js} +8 -8
  54. package/dist/bundle/chunk-GUUZQ7NE.js +581 -0
  55. package/dist/bundle/{chunk-QSNROIJL.js → chunk-H6RIPOOI.js} +42 -9
  56. package/dist/bundle/{chunk-H2ADPPSH.js → chunk-HGFNC4CR.js} +1819 -597
  57. package/dist/bundle/{chunk-7GRZAKBB.js → chunk-IERYD2N2.js} +6 -6
  58. package/dist/bundle/{chunk-N6FLBXZS.js → chunk-IGCLMEMB.js} +3 -3
  59. package/dist/bundle/{chunk-U5ACMCAQ.js → chunk-J7WCSZ2Q.js} +411 -919
  60. package/dist/bundle/{chunk-W5YAO5G5.js → chunk-JZYHQ4HB.js} +9 -4
  61. package/dist/bundle/{chunk-EVYSBZ3I.js → chunk-K4QM3X5F.js} +4 -4
  62. package/dist/bundle/{chunk-DTXERR44.js → chunk-KFSMY7SZ.js} +2 -2
  63. package/dist/bundle/{chunk-LRGYKOCP.js → chunk-KPEDH5T4.js} +1 -1
  64. package/dist/bundle/{chunk-XRFJWHY5.js → chunk-KUY7LII2.js} +4 -4
  65. package/dist/bundle/{chunk-QC53QBNC.js → chunk-LFXDHLFR.js} +3 -3
  66. package/dist/bundle/{chunk-CNNEA2M4.js → chunk-LGLT4JB6.js} +3 -3
  67. package/dist/bundle/{chunk-QGMDQ2PM.js → chunk-LM4OOBAW.js} +3 -3
  68. package/dist/bundle/chunk-M74BSKMA.js +234 -0
  69. package/dist/bundle/{chunk-2KCZ7BKW.js → chunk-MMMT6ORT.js} +11 -11
  70. package/dist/bundle/{chunk-WII44RXN.js → chunk-NGYD6QTE.js} +2 -2
  71. package/dist/bundle/{chunk-FOTREPNS.js → chunk-NO6QOPVT.js} +10 -19
  72. package/dist/bundle/chunk-O6XC7DZI.js +804 -0
  73. package/dist/bundle/chunk-OE3NFB53.js +64 -0
  74. package/dist/bundle/{chunk-XD4FRDSL.js → chunk-OUMFNB34.js} +13 -149
  75. package/dist/bundle/{chunk-ZGZT5S6B.js → chunk-P2RQTNVJ.js} +806 -850
  76. package/dist/bundle/{chunk-RRJNNPR4.js → chunk-PBIBGIZ7.js} +1 -1
  77. package/dist/bundle/{chunk-EXOOKUEA.js → chunk-Q6VQHTRW.js} +2 -2
  78. package/dist/bundle/{chunk-TE3FR6MI.js → chunk-QHBCNVUG.js} +5 -5
  79. package/dist/bundle/{chunk-SGRYYE4X.js → chunk-QNOXAQ6Y.js} +4 -4
  80. package/dist/bundle/{chunk-QQXH2OPB.js → chunk-R5F2O5GX.js} +15 -272
  81. package/dist/bundle/{chunk-SFRNX2TI.js → chunk-R5PBSKJL.js} +1 -1
  82. package/dist/bundle/{chunk-OTD2ZRXD.js → chunk-RS2BARUU.js} +4 -4
  83. package/dist/bundle/chunk-TG3DSPT5.js +14 -0
  84. package/dist/bundle/{chunk-BCF7P4FZ.js → chunk-U22JMKUO.js} +6 -125
  85. package/dist/bundle/chunk-U66Q5TVK.js +106 -0
  86. package/dist/bundle/{chunk-QMPN6WKD.js → chunk-UCHMQWON.js} +211 -89
  87. package/dist/bundle/{chunk-POC3V3AO.js → chunk-VMJS7FJZ.js} +526 -467
  88. package/dist/bundle/{chunk-FZL7F5NR.js → chunk-VMVAQHDC.js} +77 -615
  89. package/dist/bundle/{chunk-K3UIB6ZF.js → chunk-WWMCJFMT.js} +2 -2
  90. package/dist/bundle/{chunk-CXL33BFL.js → chunk-XTA5TN3H.js} +1 -1
  91. package/dist/bundle/{chunk-WTPMJYMD.js → chunk-XUHHBEA7.js} +652 -131
  92. package/dist/bundle/{chunk-WKRQ44EH.js → chunk-YDZHO4LT.js} +13 -13
  93. package/dist/bundle/{chunk-2SNUMZ7S.js → chunk-ZKINZFIT.js} +6 -6
  94. package/dist/bundle/{chunk-HAXNUIGQ.js → chunk-ZSQXSIFQ.js} +89 -39
  95. package/dist/bundle/{chunk-YYO7D2MO.js → chunk-ZZEHDIEG.js} +58 -54
  96. package/dist/bundle/command-contract-OQV6H7SR.js +36 -0
  97. package/dist/bundle/{decode-5ZPLTYV6.js → decode-QSTBX4MG.js} +3 -3
  98. package/dist/bundle/{echarts-J6LAPIX7.js → echarts-JZELFH2N.js} +2 -2
  99. package/dist/bundle/{embed-YG5LDHME.js → embed-4RIW2LVH.js} +4 -4
  100. package/dist/bundle/{embedder-7FNUA5OZ.js → embedder-SW7DTWSL.js} +7 -7
  101. package/dist/bundle/{first-run-JPZNWIJN.js → first-run-7AISOSOM.js} +8 -8
  102. package/dist/bundle/first-screen-NMHNFZ2B.js +34 -0
  103. package/dist/bundle/{instructions-AXWTQHMR.js → instructions-BZE5YUGG.js} +1 -1
  104. package/dist/bundle/{mcp-7F46P6AM.js → mcp-SDWHDJTY.js} +2 -2
  105. package/dist/bundle/{node-P4E63KXA.js → node-KM3CUABH.js} +9 -9
  106. package/dist/bundle/{node-CWKAIOEM.js → node-LTKZIO4U.js} +2 -2
  107. package/dist/bundle/{node-sqlite-LSEKVRDA.js → node-sqlite-HQ5PN2RH.js} +4 -4
  108. package/dist/bundle/{oauth-THYNLRLD.js → oauth-UH6FOZQL.js} +5 -5
  109. package/dist/bundle/{open-E47QYKFC.js → open-TSUP3XGL.js} +3 -3
  110. package/dist/bundle/{openai-EWSGC3BC.js → openai-GVEE52E3.js} +14 -14
  111. package/dist/bundle/{process-WKTEA3WE.js → process-AGXY76ZE.js} +1 -1
  112. package/dist/bundle/program-BI4A4HFJ.js +2247 -0
  113. package/dist/bundle/{prompt-CAQ7QR3U.js → prompt-NRSUY7FA.js} +3 -3
  114. package/dist/bundle/{recognize-6KGHNZC3.js → recognize-NPDPQ6PJ.js} +2 -2
  115. package/dist/bundle/{remote-3UO2WDC3.js → remote-HFASMVLB.js} +5 -5
  116. package/dist/bundle/{rerank-2JVDPZBX.js → rerank-TL6Z6F7K.js} +5 -5
  117. package/dist/bundle/{chunk-VL6SPMZV.js → serve-VB4DHDZQ.js} +8 -6
  118. package/dist/bundle/server-T5EDRPJI.js +68 -0
  119. package/dist/bundle/{chunk-ZEW4P6AH.js → server-Z6MW6C37.js} +50 -14
  120. package/dist/bundle/source-4IGO5J7E.js +237 -0
  121. package/dist/bundle/sqlite-runtime-YS4POY3W.js +17 -0
  122. package/dist/bundle/{state-7NH5G4XJ.js → state-ISZVVZGR.js} +4 -4
  123. package/dist/bundle/store-IZJBAKJV.js +58 -0
  124. package/dist/bundle/{store-7O4JQD2Z.js → store-L76MSQC3.js} +17 -12
  125. package/dist/bundle/store-PBTIB7BD.js +207 -0
  126. package/dist/bundle/store-maintenance-command-YFKII7TF.js +58 -0
  127. package/dist/bundle/writer-3O5EYMFE.js +214 -0
  128. package/dist/commands/api.d.ts.map +1 -1
  129. package/dist/commands/api.js +81 -30
  130. package/dist/commands/api.js.map +1 -1
  131. package/dist/commands/crm-shared.d.ts +4 -0
  132. package/dist/commands/crm-shared.d.ts.map +1 -0
  133. package/dist/commands/crm-shared.js +94 -0
  134. package/dist/commands/crm-shared.js.map +1 -0
  135. package/dist/commands/crm-writes.d.ts +0 -1
  136. package/dist/commands/crm-writes.d.ts.map +1 -1
  137. package/dist/commands/crm-writes.js +43 -88
  138. package/dist/commands/crm-writes.js.map +1 -1
  139. package/dist/commands/crm.d.ts.map +1 -1
  140. package/dist/commands/crm.js +30 -48
  141. package/dist/commands/crm.js.map +1 -1
  142. package/dist/commands/session.d.ts.map +1 -1
  143. package/dist/commands/session.js +1 -0
  144. package/dist/commands/session.js.map +1 -1
  145. package/dist/commands/write.d.ts +6 -6
  146. package/dist/commands/write.d.ts.map +1 -1
  147. package/dist/commands/write.js +11 -18
  148. package/dist/commands/write.js.map +1 -1
  149. package/dist/config.d.ts +0 -5
  150. package/dist/config.d.ts.map +1 -1
  151. package/dist/config.js +6 -8
  152. package/dist/config.js.map +1 -1
  153. package/dist/crm/capabilities.d.ts +7 -0
  154. package/dist/crm/capabilities.d.ts.map +1 -0
  155. package/dist/crm/capabilities.js +7 -0
  156. package/dist/crm/capabilities.js.map +1 -0
  157. package/dist/crm/conditions.d.ts +1 -1
  158. package/dist/crm/conditions.d.ts.map +1 -1
  159. package/dist/crm/conditions.js +4 -6
  160. package/dist/crm/conditions.js.map +1 -1
  161. package/dist/crm/custom-query.d.ts +19 -0
  162. package/dist/crm/custom-query.d.ts.map +1 -0
  163. package/dist/crm/custom-query.js +79 -0
  164. package/dist/crm/custom-query.js.map +1 -0
  165. package/dist/crm/deal.d.ts +4 -27
  166. package/dist/crm/deal.d.ts.map +1 -1
  167. package/dist/crm/deal.js +15 -48
  168. package/dist/crm/deal.js.map +1 -1
  169. package/dist/crm/fields.d.ts +20 -0
  170. package/dist/crm/fields.d.ts.map +1 -0
  171. package/dist/crm/fields.js +78 -0
  172. package/dist/crm/fields.js.map +1 -0
  173. package/dist/crm/items.d.ts +7 -1
  174. package/dist/crm/items.d.ts.map +1 -1
  175. package/dist/crm/items.js +21 -18
  176. package/dist/crm/items.js.map +1 -1
  177. package/dist/crm/lead.d.ts +5 -36
  178. package/dist/crm/lead.d.ts.map +1 -1
  179. package/dist/crm/lead.js +15 -61
  180. package/dist/crm/lead.js.map +1 -1
  181. package/dist/crm/organization.d.ts +1 -0
  182. package/dist/crm/organization.d.ts.map +1 -1
  183. package/dist/crm/person.d.ts +1 -0
  184. package/dist/crm/person.d.ts.map +1 -1
  185. package/dist/crm/pipelines.d.ts +5 -0
  186. package/dist/crm/pipelines.d.ts.map +1 -0
  187. package/dist/crm/pipelines.js +54 -0
  188. package/dist/crm/pipelines.js.map +1 -0
  189. package/dist/crm/product.d.ts.map +1 -1
  190. package/dist/crm/product.js +2 -2
  191. package/dist/crm/product.js.map +1 -1
  192. package/dist/crm/rest3-fields.d.ts +3 -0
  193. package/dist/crm/rest3-fields.d.ts.map +1 -0
  194. package/dist/crm/rest3-fields.js +38 -0
  195. package/dist/crm/rest3-fields.js.map +1 -0
  196. package/dist/crm/source.d.ts +15 -0
  197. package/dist/crm/source.d.ts.map +1 -0
  198. package/dist/crm/source.js +122 -0
  199. package/dist/crm/source.js.map +1 -0
  200. package/dist/crm/user.d.ts.map +1 -1
  201. package/dist/crm/user.js +2 -2
  202. package/dist/crm/user.js.map +1 -1
  203. package/dist/crm/values.d.ts +26 -5
  204. package/dist/crm/values.d.ts.map +1 -1
  205. package/dist/crm/values.js +40 -5
  206. package/dist/crm/values.js.map +1 -1
  207. package/dist/crm/writer.d.ts +9 -0
  208. package/dist/crm/writer.d.ts.map +1 -0
  209. package/dist/crm/writer.js +119 -0
  210. package/dist/crm/writer.js.map +1 -0
  211. package/dist/program.d.ts.map +1 -1
  212. package/dist/program.js +53 -5
  213. package/dist/program.js.map +1 -1
  214. package/dist/reasons.d.ts.map +1 -1
  215. package/dist/reasons.js +6 -1
  216. package/dist/reasons.js.map +1 -1
  217. package/dist/store.d.ts +15 -0
  218. package/dist/store.d.ts.map +1 -0
  219. package/dist/store.js +33 -0
  220. package/dist/store.js.map +1 -0
  221. package/dist/version.d.ts +1 -1
  222. package/dist/version.js +1 -1
  223. package/package.json +4 -6
  224. package/skills/bitrix24-cli/SKILL.md +16 -10
  225. package/dist/bundle/all-profiles-QJ444GSX.js +0 -24
  226. package/dist/bundle/chunk-XNHSPHUN.js +0 -48
  227. package/dist/bundle/command-contract-OKQOE6G4.js +0 -30
  228. package/dist/bundle/first-screen-VQM4MTS7.js +0 -28
  229. package/dist/bundle/mcp-5RSWNTHS.js +0 -160
  230. package/dist/bundle/mcp-J5R5A65I.js +0 -87
  231. package/dist/bundle/serve-ES7AG5IK.js +0 -19
  232. package/dist/bundle/server-5LE5LNUQ.js +0 -45
  233. package/dist/bundle/server-BU4VBM6S.js +0 -58
  234. package/dist/bundle/store-maintenance-command-UDVGEY2D.js +0 -47
  235. package/dist/commands/doctor.d.ts +0 -77
  236. package/dist/commands/doctor.d.ts.map +0 -1
  237. package/dist/commands/doctor.js +0 -74
  238. package/dist/commands/doctor.js.map +0 -1
  239. package/dist/commands/mcp.d.ts +0 -3
  240. package/dist/commands/mcp.d.ts.map +0 -1
  241. package/dist/commands/mcp.js +0 -97
  242. package/dist/commands/mcp.js.map +0 -1
  243. package/dist/crm/pipeline.d.ts +0 -17
  244. package/dist/crm/pipeline.d.ts.map +0 -1
  245. package/dist/crm/pipeline.js +0 -42
  246. package/dist/crm/pipeline.js.map +0 -1
  247. package/dist/crm/stage.d.ts +0 -20
  248. package/dist/crm/stage.d.ts.map +0 -1
  249. package/dist/crm/stage.js +0 -65
  250. package/dist/crm/stage.js.map +0 -1
  251. package/dist/mcp.d.ts +0 -29
  252. package/dist/mcp.d.ts.map +0 -1
  253. package/dist/mcp.js +0 -99
  254. package/dist/mcp.js.map +0 -1
  255. /package/dist/bundle/{chunk-4PDYYS5K.js → chunk-ZQ3GWKDQ.js} +0 -0
@@ -8,608 +8,72 @@ import {
8
8
  refuseLacking,
9
9
  servicesFor,
10
10
  throughWrapper
11
- } from "./chunk-POC3V3AO.js";
11
+ } from "./chunk-VMJS7FJZ.js";
12
+ import {
13
+ FloodMemory,
14
+ RecipientList,
15
+ ceilingRefusal,
16
+ floodPathFor,
17
+ guardFor,
18
+ holdEnd,
19
+ recipientsPathFor,
20
+ withFileLockAsync
21
+ } from "./chunk-GUUZQ7NE.js";
12
22
  import {
13
- LOG_ATTRIBUTES,
14
- MESSENGER_CHANGE_REFUSAL,
15
23
  asFirstWord,
16
24
  baseContext,
17
- codeOf,
18
- currentOperation,
19
- currentRun,
20
25
  environmentOf,
21
- fromLogAttributes,
22
26
  issueMessage,
23
27
  limitBatch,
24
- logAttributes,
25
28
  permissionIssues,
26
29
  publicIssue,
27
- readOnlyRefusal,
28
30
  recalledAccount,
29
31
  rememberAccount,
30
32
  rootOf2 as rootOf
31
- } from "./chunk-U5ACMCAQ.js";
33
+ } from "./chunk-J7WCSZ2Q.js";
34
+ import {
35
+ codeOf,
36
+ currentOperation
37
+ } from "./chunk-G5MW6RCM.js";
32
38
  import {
33
- isCliFailure,
34
39
  providerErrorKey
35
- } from "./chunk-FOTREPNS.js";
40
+ } from "./chunk-NO6QOPVT.js";
41
+ import {
42
+ isCliFailure
43
+ } from "./chunk-5D4MJQ6X.js";
36
44
  import {
37
45
  servingProfiles
38
- } from "./chunk-N6FLBXZS.js";
46
+ } from "./chunk-IGCLMEMB.js";
39
47
  import {
40
48
  chatReferenceOf,
41
49
  ensureAccount,
42
50
  foldName,
43
51
  isId,
44
52
  pickPerson
45
- } from "./chunk-BCF7P4FZ.js";
53
+ } from "./chunk-EYTGCM44.js";
46
54
  import {
47
55
  AUTHORITY_KEY,
48
56
  CEILING_KEY,
49
57
  DEFAULT_PERMISSIONS,
50
58
  WRITE_KEYS,
51
59
  keyForCommand,
52
- keyForWrite,
53
60
  levelFor,
54
61
  readKeysForCommand,
55
62
  skipFlagFor
56
- } from "./chunk-XD4FRDSL.js";
63
+ } from "./chunk-OUMFNB34.js";
57
64
  import {
58
65
  openStore
59
- } from "./chunk-H2ADPPSH.js";
66
+ } from "./chunk-HGFNC4CR.js";
60
67
  import {
61
68
  CliError,
62
- logRecordOf,
63
- realSleep,
64
- resolvePaths,
65
- writeSecurely
66
- } from "./chunk-IRV2PCQ2.js";
69
+ resolvePaths
70
+ } from "./chunk-EYYOKT23.js";
67
71
  import {
68
72
  __name
69
73
  } from "./chunk-ZVVMGPBJ.js";
70
74
 
71
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/sends/guard.js
72
- import { randomUUID } from "node:crypto";
73
-
74
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/sends/flood.js
75
- import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
76
- import { dirname, join } from "node:path";
77
- var MOST_DEADLINES = 50;
78
- var LIMITED_HOLD_MS = 60 * 60 * 1e3;
79
- var FROZEN_HOLD_MS = 24 * 60 * 60 * 1e3;
80
- var NO_END = "9999-12-31T23:59:59.999Z";
81
- var holdEnd = /* @__PURE__ */ __name((block, show = (iso) => iso) => block.until === null ? "until lifted" : `until ${show(block.until)}`, "holdEnd");
82
- var floodPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).state, "flood", `${profile}.json`), "floodPathFor");
83
- var FloodMemory = class {
84
- static {
85
- __name(this, "FloodMemory");
86
- }
87
- path;
88
- now;
89
- constructor(path, now = Date.now) {
90
- this.path = path;
91
- this.now = now;
92
- }
93
- /** What is still in force; anything expired is left out. */
94
- read() {
95
- const now = this.now();
96
- let raw;
97
- try {
98
- raw = JSON.parse(readFileSync(this.path, "utf8"));
99
- } catch {
100
- return { deadlines: [] };
101
- }
102
- const alive = /* @__PURE__ */ __name((until) => typeof until === "string" && Date.parse(until) > now, "alive");
103
- const deadlines = Array.isArray(raw.deadlines) ? raw.deadlines.filter((one) => typeof one?.operation === "string" && alive(one.until)) : [];
104
- const block = raw.sendBlock && (raw.sendBlock.until === NO_END ? { ...raw.sendBlock, until: null } : raw.sendBlock);
105
- const held = block && (block.until === null || alive(block.until));
106
- return { deadlines, ...held ? { sendBlock: block } : {} };
107
- }
108
- /** The deadline this call is still under: one for its chat, or one for the call in every chat. */
109
- owed(operation, chatId) {
110
- return this.read().deadlines.filter((one) => one.operation === operation && (one.chatId === void 0 || one.chatId === chatId)).sort((a, b) => b.until.localeCompare(a.until))[0];
111
- }
112
- remember(deadline) {
113
- const { waitMs, ...rest } = deadline;
114
- const kept = { ...rest, until: new Date(this.now() + waitMs).toISOString() };
115
- const state = this.read();
116
- const others = state.deadlines.filter((one) => one.operation !== kept.operation || one.chatId !== kept.chatId);
117
- const deadlines = [...others, kept].sort((a, b) => b.until.localeCompare(a.until)).slice(0, MOST_DEADLINES);
118
- this.#write({ ...state, deadlines });
119
- return kept;
120
- }
121
- sendBlock() {
122
- return this.read().sendBlock;
123
- }
124
- /** A ban the messenger gave no end for holds until lifted; a spam limit or a freeze without one, for a while. */
125
- block(block) {
126
- const now = this.now();
127
- const holdMs = { limited: LIMITED_HOLD_MS, frozen: FROZEN_HOLD_MS, banned: void 0 }[block.state];
128
- const kept = {
129
- ...block,
130
- since: new Date(now).toISOString(),
131
- until: block.until ?? (holdMs === void 0 ? null : new Date(now + holdMs).toISOString())
132
- };
133
- this.#write({ ...this.read(), sendBlock: kept });
134
- return kept;
135
- }
136
- /** Lifts only a block of this state: an account found not frozen may still be limited for spam. */
137
- unblock(state) {
138
- const { sendBlock, ...rest } = this.read();
139
- if (sendBlock?.state === state)
140
- this.#write(rest);
141
- }
142
- /** Forgets every wait and lifts the hold, and answers with what was still in force. */
143
- clear() {
144
- const cleared = this.read();
145
- this.#write({ deadlines: [] });
146
- return cleared;
147
- }
148
- #write({ sendBlock, ...rest }) {
149
- const state = sendBlock ? { ...rest, sendBlock: { ...sendBlock, until: sendBlock.until ?? NO_END } } : rest;
150
- mkdirSync(dirname(this.path), { recursive: true, mode: 448 });
151
- const temporary = `${this.path}.${process.pid}.tmp`;
152
- writeFileSync(temporary, `${JSON.stringify(state)}
153
- `, { mode: 384 });
154
- renameSync(temporary, this.path);
155
- }
156
- };
157
-
158
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/sends/journal.js
159
- import { appendFileSync, mkdirSync as mkdirSync3, readFileSync as readFileSync2 } from "node:fs";
160
- import { dirname as dirname3, join as join2 } from "node:path";
161
-
162
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/sends/file-lock.js
163
- import { closeSync, mkdirSync as mkdirSync2, openSync, statSync, unlinkSync } from "node:fs";
164
- import { dirname as dirname2 } from "node:path";
165
- var LOCK_WAIT_MS = 5e3;
166
- var LOCK_STALE_MS = 3e4;
167
- var RETRY_MS = 20;
168
- var pause = new Int32Array(new SharedArrayBuffer(4));
169
- var withFileLock = /* @__PURE__ */ __name((path, what2, body, waitMs = LOCK_WAIT_MS) => {
170
- const lock = lockFor(path);
171
- const deadline = Date.now() + waitMs;
172
- while (!taken(lock)) {
173
- if (Date.now() >= deadline)
174
- throw lockTimeout(what2, waitMs, lock);
175
- Atomics.wait(pause, 0, 0, RETRY_MS);
176
- }
177
- return holding(lock, body);
178
- }, "withFileLock");
179
- var withFileLockAsync = /* @__PURE__ */ __name(async (path, what2, body, waitMs = LOCK_WAIT_MS, sleep = realSleep) => {
180
- const lock = lockFor(path);
181
- const deadline = Date.now() + waitMs;
182
- while (!taken(lock)) {
183
- if (Date.now() >= deadline)
184
- throw lockTimeout(what2, waitMs, lock);
185
- await sleep(RETRY_MS);
186
- }
187
- return holding(lock, body);
188
- }, "withFileLockAsync");
189
- var lockFor = /* @__PURE__ */ __name((path) => {
190
- mkdirSync2(dirname2(path), { recursive: true, mode: 448 });
191
- return `${path}.lock`;
192
- }, "lockFor");
193
- var taken = /* @__PURE__ */ __name((lock) => {
194
- for (; ; ) {
195
- try {
196
- closeSync(openSync(lock, "wx", 384));
197
- return true;
198
- } catch (error) {
199
- if (error.code !== "EEXIST")
200
- throw error;
201
- if (Date.now() - lockTime(lock) <= LOCK_STALE_MS)
202
- return false;
203
- try {
204
- unlinkSync(lock);
205
- } catch {
206
- }
207
- }
208
- }
209
- }, "taken");
210
- var holding = /* @__PURE__ */ __name((lock, body) => {
211
- try {
212
- return body();
213
- } finally {
214
- try {
215
- unlinkSync(lock);
216
- } catch {
217
- }
218
- }
219
- }, "holding");
220
- var lockTimeout = /* @__PURE__ */ __name((what2, waitMs, lock) => new CliError("timeout", `${what2} stayed locked for ${waitMs / 1e3}s (${lock})`), "lockTimeout");
221
- var lockTime = /* @__PURE__ */ __name((lock) => {
222
- try {
223
- return statSync(lock).mtimeMs;
224
- } catch {
225
- return Date.now();
226
- }
227
- }, "lockTime");
228
-
229
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/sends/journal.js
230
- var sendsPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join2(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).state, "sends", `${profile}.jsonl`), "sendsPathFor");
231
- var SendJournal = class {
232
- static {
233
- __name(this, "SendJournal");
234
- }
235
- path;
236
- resource;
237
- constructor(path, resource = { service: "unknown", version: "unknown" }) {
238
- this.path = path;
239
- this.resource = resource;
240
- }
241
- /**
242
- * Runs `body` with the journal to itself, across processes: two sends at the limit must not both
243
- * read "one left". A lock file opened with `wx`, because `flock` is not there on Windows.
244
- */
245
- locked(body) {
246
- return withFileLock(this.path, "the send journal", body);
247
- }
248
- /** `locked` without blocking the thread while another process holds the journal: what `serve` uses. */
249
- lockedAsync(body) {
250
- return withFileLockAsync(this.path, "the send journal", body);
251
- }
252
- append(entry) {
253
- const { at, ...attributes } = entry;
254
- const { runId, command, traceId } = currentRun();
255
- const record = logRecordOf({
256
- severity: entry.outcome === "sent" || entry.outcome === "reserved" ? "info" : "warn",
257
- event: logAttributes({ event: "send.recorded", ...attributes }),
258
- time: at,
259
- runId,
260
- ...traceId === void 0 ? {} : { traceId },
261
- command,
262
- resource: this.resource,
263
- allow: LOG_ATTRIBUTES
264
- });
265
- mkdirSync3(dirname3(this.path), { recursive: true, mode: 448 });
266
- appendFileSync(this.path, `${JSON.stringify(record)}
267
- `, { mode: 384 });
268
- }
269
- /**
270
- * Oldest first, each reservation folded into its outcome; one with no outcome yet is in flight,
271
- * or its process died. A line that does not parse is skipped: a torn last write must not block sending.
272
- */
273
- entries(filter) {
274
- const lines = this.#lines();
275
- const settled2 = new Set(lines.filter((entry) => entry.outcome !== "reserved").map((entry) => entry.reservation));
276
- const entries = lines.filter((entry) => entry.outcome !== "reserved" || !settled2.has(entry.reservation)).map(({ reservation, ...entry }) => entry.outcome === "reserved" ? { ...entry, reservation } : entry).map(withSendId);
277
- return filter === void 0 ? entries : entries.filter((entry) => (filter.outcome === void 0 || entry.outcome === filter.outcome) && (filter.chatId === void 0 || entry.chatId === filter.chatId) && (filter.operationId === void 0 || entry.operationId === filter.operationId) && (filter.errorCode === void 0 || entry.errorCode === filter.errorCode) && (filter.key === void 0 || entry.key === filter.key));
278
- }
279
- #lines() {
280
- let text;
281
- try {
282
- text = readFileSync2(this.path, "utf8");
283
- } catch {
284
- return [];
285
- }
286
- return text.split("\n").filter((line) => line.trim() !== "").flatMap((line) => {
287
- try {
288
- return [entryOf(JSON.parse(line))];
289
- } catch {
290
- return [];
291
- }
292
- });
293
- }
294
- };
295
- var entryOf = /* @__PURE__ */ __name((line) => {
296
- if (!("attributes" in line))
297
- return line;
298
- const { event: _, ...attributes } = line.attributes;
299
- return { at: line.time, ...fromLogAttributes(attributes) };
300
- }, "entryOf");
301
- var withSendId = /* @__PURE__ */ __name((entry) => {
302
- const { cid, ...rest } = entry;
303
- return cid === void 0 || rest.sendId !== void 0 ? rest : { ...rest, sendId: String(cid) };
304
- }, "withSendId");
305
-
306
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/sends/recipients.js
307
- import { existsSync, readFileSync as readFileSync3, rmSync } from "node:fs";
308
- import { join as join3 } from "node:path";
309
- var recipientsPathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join3(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).state, "profiles", `${profile}.recipients.json`), "recipientsPathFor");
310
- var RecipientList = class {
311
- static {
312
- __name(this, "RecipientList");
313
- }
314
- path;
315
- command;
316
- lockWaitMs;
317
- /** `command` names the program in the hint that turns the list off. */
318
- constructor(path, command, lockWaitMs) {
319
- this.path = path;
320
- this.command = command;
321
- this.lockWaitMs = lockWaitMs;
322
- }
323
- /** `undefined` when the list is off. A file that cannot be read refuses rather than opening up. */
324
- read() {
325
- if (!existsSync(this.path))
326
- return void 0;
327
- try {
328
- const parsed = JSON.parse(readFileSync3(this.path, "utf8"));
329
- if (!Array.isArray(parsed.chats))
330
- throw new Error("no `chats` array");
331
- return parsed.chats;
332
- } catch (error) {
333
- throw new CliError("configuration_error", `the recipient list ${this.path} cannot be read (${error instanceof Error ? error.message : String(error)}) \u2014 fix the file or turn the list off with \`${this.command} recipients clear\``);
334
- }
335
- }
336
- list(filter = {}) {
337
- const chats = this.read();
338
- return {
339
- state: chats === void 0 ? "off" : chats.length === 0 ? "empty" : "on",
340
- items: (chats ?? []).filter((chat) => (filter.id === void 0 || chat.id === filter.id) && (filter.title === void 0 || chat.title?.toLocaleLowerCase() === filter.title.toLocaleLowerCase()))
341
- };
342
- }
343
- /** Whether it was new. Adding one again fills in a partner an older entry was stored without. */
344
- add(recipient) {
345
- return this.#locked(() => this.#added(recipient));
346
- }
347
- /** `add` waiting for the lock on timers: `recipients add` connects, so it runs inside `serve` when one holds the account. */
348
- addAsync(recipient) {
349
- return withFileLockAsync(this.path, "the recipient list", () => this.#added(recipient), this.lockWaitMs);
350
- }
351
- #added(recipient) {
352
- const chats = this.read() ?? [];
353
- const known = chats.find((chat) => chat.id === recipient.id);
354
- if (known) {
355
- if (recipient.partnerId && !known.partnerId) {
356
- this.#write(chats.map((chat) => chat === known ? { ...known, partnerId: recipient.partnerId } : chat));
357
- }
358
- return false;
359
- }
360
- this.#write([...chats, recipient]);
361
- return true;
362
- }
363
- /** The id or the title as it was stored; `undefined` when neither matched. */
364
- remove(reference) {
365
- return this.#locked(() => {
366
- const chats = this.read() ?? [];
367
- const wanted = reference.trim();
368
- const gone = chats.find((chat) => chat.id === wanted) ?? chats.find((chat) => chat.title?.toLocaleLowerCase() === wanted.toLocaleLowerCase());
369
- if (gone)
370
- this.#write(chats.filter((chat) => chat !== gone));
371
- return gone;
372
- });
373
- }
374
- /**
375
- * The chat the messenger now names `to`: its entry, and a partner of that id, follow it. Only an entry already there
376
- * changes, and no list is created, so the list never opens up. Whether anything changed.
377
- */
378
- async rekey(from, to) {
379
- if (from === to)
380
- return false;
381
- return withFileLockAsync(this.path, "the recipient list", () => {
382
- const chats = this.read();
383
- if (!chats?.some((chat) => chat.id === from || chat.partnerId === from))
384
- return false;
385
- const held = chats.some((chat) => chat.id === to);
386
- this.#write(chats.filter((chat) => !(held && chat.id === from)).map((chat) => ({
387
- ...chat,
388
- ...chat.id === from ? { id: to } : {},
389
- ...chat.partnerId === from ? { partnerId: to } : {}
390
- })));
391
- return true;
392
- }, this.lockWaitMs);
393
- }
394
- /** Whether there was a list to turn off. */
395
- off() {
396
- return this.#locked(() => {
397
- if (!existsSync(this.path))
398
- return false;
399
- rmSync(this.path);
400
- return true;
401
- });
402
- }
403
- /**
404
- * Every change reads and writes under one lock: a `serve` re-keying while the owner removes a chat must not write
405
- * the removed chat back. A lock held too long refuses the change and leaves the list as it was. Blocks the thread
406
- * while it waits: for callers that cannot be async, and `recipients remove` and `clear`, which never
407
- * connect and so never run inside `serve`.
408
- */
409
- #locked(body) {
410
- return withFileLock(this.path, "the recipient list", body, this.lockWaitMs);
411
- }
412
- #write(chats) {
413
- writeSecurely(this.path, `${JSON.stringify({ chats }, null, 2)}
414
- `, 384);
415
- }
416
- };
417
-
418
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/sends/guard.js
419
- var HOUR_MS = 60 * 60 * 1e3;
420
- var READS_UNDER_HOLD = /* @__PURE__ */ new Set([
421
- "attachments.extract",
422
- "conversations.embeddings",
423
- "conversations.links",
424
- "messages.server-search",
425
- "messages.sync-first",
426
- "stats.contacts.top.sync-first",
427
- "stats.messages.counters.sync",
428
- "stats.messages.show.sync-first",
429
- "stats.messages.top.sync-first",
430
- "store.gaps.repair"
431
- ]);
432
- var countsTowardLimit = /* @__PURE__ */ __name(({ kind = "message", action, notify }) => kind === "message" || kind === "forward" || kind === "edit" || kind === "delete" || kind === "pin" && notify === true || action === "create" || action === "members.add" || action === "requests.accept" || action === "join" || action === "contact-import", "countsTowardLimit");
433
- var weightOf = /* @__PURE__ */ __name(({ kind = "message", action, count, people }) => kind === "delete" || kind === "message" && action === void 0 ? Math.max(1, count ?? 1) : action === "create" || action === "members.add" || action === "requests.accept" || action === "contact-import" ? Math.max(1, people ?? count ?? 1) : 1, "weightOf");
434
- var timeOf = /* @__PURE__ */ __name((entry) => Date.parse(entry.scheduledFor ?? entry.at), "timeOf");
435
- var ceilingRefusal = /* @__PURE__ */ __name((key, command) => new CliError("permission_error", `${key} is not allowed: setup's answer keeps every WireCat tool read-only; the owner changes it at a terminal with \`${command} setup\``, { permission: key }), "ceilingRefusal");
436
- var levelRefusal = /* @__PURE__ */ __name((refused, fix = `${refused.command} ${refused.profile} config set permissions.${refused.key} allow`) => refused.named === CEILING_KEY ? ceilingRefusal(refused.key, refused.command) : new CliError("permission_error", `profile ${refused.profile} does not let ${refused.key} write (permissions.${refused.named} is ${refused.level}, from the ${refused.permissionSources[refused.named ?? ""] ?? "default"}); to allow it: ${fix}`, { permission: refused.key }), "levelRefusal");
437
- var sendGuard = /* @__PURE__ */ __name(({ profile, recipients, command = recipients.command, readOnlyLock, permissions, permissionSources = {}, permissionDefaults, permissionFix, ask = refuseToAsk, sendsPerHour, journal, flood, warn, now = /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "now") }) => {
438
- const currentPermissions = /* @__PURE__ */ __name(() => typeof permissions === "function" ? permissions() : permissions, "currentPermissions");
439
- let reservation;
440
- const answered = /* @__PURE__ */ new WeakSet();
441
- const refuseReadOnly = /* @__PURE__ */ __name(() => {
442
- if (readOnlyLock)
443
- throw readOnlyRefusal(readOnlyLock, MESSENGER_CHANGE_REFUSAL);
444
- }, "refuseReadOnly");
445
- const refuseHeld = /* @__PURE__ */ __name(({ key }) => {
446
- if (key !== void 0 && READS_UNDER_HOLD.has(key))
447
- return;
448
- const block = flood?.sendBlock();
449
- if (!block)
450
- return;
451
- throw new CliError("permission_error", `profile ${profile} holds its writes ${holdEnd(block)}: ${block.hint} \u2014 reads still work; do not retry: the owner checks the account with \`${command} ${profile} doctor --online\`, and lifts the hold with \`${command} ${profile} flood clear\` once it is over`, { sendBlock: block, standing: { state: block.state, hint: block.hint } });
452
- }, "refuseHeld");
453
- const permitted = /* @__PURE__ */ __name((request) => {
454
- const { chatId, kind = "message", action, personIds } = request;
455
- refuseReadOnly();
456
- const levels = currentPermissions();
457
- if (levels !== void 0) {
458
- const key = request.key ?? keyForWrite(kind, action);
459
- const { level, key: named } = levelFor(levels, key, permissionDefaults);
460
- if (level === "deny" || level === "readonly")
461
- throw levelRefusal({ profile, command, key, level, named, permissionSources }, permissionFix?.(request, key));
462
- if (level === "ask" && !answered.has(request)) {
463
- throw new CliError("confirmation_required", `${key} asks before it acts, and it was not asked`);
464
- }
465
- }
466
- const allowed = recipients.read();
467
- if (chatId !== null && allowed && !allowed.some((chat) => chat.id === chatId)) {
468
- throw new CliError("confirmation_required", `chat ${chatId} is not on the recipient list of profile ${profile} \u2014 the owner adds it with \`${command} ${profile} recipients add ${chatId}\``, { chat_id: chatId });
469
- }
470
- const strangers = allowed ? (personIds ?? []).filter((id) => !allowed.some((chat) => chat.partnerId === id)) : [];
471
- if (strangers.length > 0) {
472
- throw new CliError("confirmation_required", `${strangers.join(", ")} ${strangers.length === 1 ? "is" : "are"} not on the recipient list of profile ${profile} \u2014 the owner adds the one-to-one chat with each person (\`${command} ${profile} recipients add <chat>\`); a chat added to the list earlier is added again to be recognised`, { person_ids: strangers });
473
- }
474
- }, "permitted");
475
- const withinLimit = /* @__PURE__ */ __name((request, entries) => {
476
- const { chatId, sendId } = request;
477
- const asked = { ...request, people: request.personIds?.length ?? request.count };
478
- const count = weightOf(asked);
479
- if (count > sendsPerHour) {
480
- throw new CliError("rate_limited", `${count} at once is more than the hourly limit of profile ${profile} (sendsPerHour ${sendsPerHour}) \u2014 do fewer at a time`);
481
- }
482
- const at = request.scheduledFor ? Date.parse(request.scheduledFor) : now().getTime();
483
- const counted = entries.filter(countsTowardLimit).filter((entry) => entry.outcome === "sent" || entry.outcome === "outcome_unknown" || entry.outcome === "reserved").filter((entry) => Math.abs(timeOf(entry) - at) < HOUR_MS);
484
- const unsure = /* @__PURE__ */ __name((entry) => entry.outcome === "outcome_unknown", "unsure");
485
- const same = /* @__PURE__ */ __name((a, b) => a.sendId !== void 0 && a.sendId === b.sendId && a.chatId === b.chatId, "same");
486
- const last = [...counted].reverse().find((entry) => same(entry, { chatId, sendId }));
487
- if (sendId !== void 0 && last && unsure(last)) {
488
- if (last.sendAs !== request.sendAs) {
489
- throw new CliError("validation_error", "this send id was tried under another identity; repeat it with the same --send-as, or it may post twice", { operation_id: sendId, retryable: false });
490
- }
491
- return false;
492
- }
493
- const recent = counted.filter((entry, index) => !(unsure(entry) && counted.slice(index + 1).some((later) => same(later, entry)))).map((entry) => ({ time: timeOf(entry), weight: weightOf(entry) })).sort((a, b) => a.time - b.time);
494
- const used = recent.reduce((sum, { weight }) => sum + weight, 0);
495
- if (used + count > sendsPerHour) {
496
- let freed = 0;
497
- const opening = recent.find(({ weight }) => {
498
- freed += weight;
499
- return used - freed + count <= sendsPerHour;
500
- });
501
- const nextMs = (opening?.time ?? 0) + HOUR_MS;
502
- const next = new Date(nextMs).toISOString();
503
- throw new CliError("rate_limited", `profile ${profile} has sent ${used} messages in the hour around ${new Date(at).toISOString()}, and its limit is ${sendsPerHour} (sendsPerHour) \u2014 the next send is possible at ${next}`, { retry_after_ms: nextMs - now().getTime(), retry_at: next });
504
- }
505
- return true;
506
- }, "withinLimit");
507
- const counting = /* @__PURE__ */ __name((request) => {
508
- permitted(request);
509
- refuseHeld(request);
510
- const asked = { ...request, people: request.personIds?.length ?? request.count };
511
- const creatingTopic = request.kind === "chat" && request.action === "topic-create";
512
- if (!countsTowardLimit(asked) && !creatingTopic)
513
- return void 0;
514
- const checked = /* @__PURE__ */ __name((entries) => {
515
- if (!creatingTopic)
516
- return withinLimit(request, entries);
517
- if (request.sendId === void 0)
518
- throw new CliError("validation_error", "a topic creation needs an attempt id");
519
- if (entries.some((entry) => entry.action === "topic-create" && entry.sendId === request.sendId && ["sent", "outcome_unknown", "reserved"].includes(entry.outcome))) {
520
- throw new CliError("validation_error", "this topic creation was already attempted; check topics list and do not repeat an unknown creation", { operation_id: request.sendId, retryable: false });
521
- }
522
- return true;
523
- }, "checked");
524
- const reserving = /* @__PURE__ */ __name(() => {
525
- if (!checked(journal.entries()))
526
- return;
527
- const id = randomUUID();
528
- const { chatId, kind, action, sendId, operationId, scheduledFor, notify } = request;
529
- journal.append({
530
- at: now().toISOString(),
531
- profile,
532
- chatId,
533
- outcome: "reserved",
534
- reservation: id,
535
- ...kind ? { kind } : {},
536
- ...action ? { action } : {},
537
- ...asked.people === void 0 ? {} : kind === "delete" || kind === "message" || kind === void 0 ? { count: asked.people } : { people: asked.people },
538
- ...sendId === void 0 ? {} : { sendId },
539
- ...operationId === void 0 ? {} : { operationId },
540
- ...scheduledFor ? { scheduledFor } : {},
541
- ...notify === void 0 ? {} : { notify }
542
- });
543
- reservation = id;
544
- }, "reserving");
545
- return { checked, reserving };
546
- }, "counting");
547
- return {
548
- ask: /* @__PURE__ */ __name(async (request) => {
549
- refuseReadOnly();
550
- const levels = currentPermissions();
551
- if (levels === void 0)
552
- return;
553
- const key = request.key ?? keyForWrite(request.kind ?? "message", request.action);
554
- if (levelFor(levels, key, permissionDefaults).level !== "ask")
555
- return;
556
- refuseHeld(request);
557
- await ask(key, request);
558
- answered.add(request);
559
- }, "ask"),
560
- check: /* @__PURE__ */ __name((request, { reserve = true } = {}) => {
561
- const counted = counting(request);
562
- if (!counted)
563
- return;
564
- if (reserve)
565
- journal.locked(counted.reserving);
566
- else
567
- counted.checked(journal.entries());
568
- }, "check"),
569
- reserve: /* @__PURE__ */ __name(async (request) => {
570
- const counted = counting(request);
571
- if (counted)
572
- await journal.lockedAsync(counted.reserving);
573
- }, "reserve"),
574
- // After a send, a failure to write here must not become the command's answer: the message is
575
- // already with a person, and an error would invite the caller to send it again.
576
- record: /* @__PURE__ */ __name((entry) => {
577
- const { personIds: _, ...kept } = entry;
578
- const settles = entry.outcome === "refused" ? void 0 : reservation;
579
- reservation = void 0;
580
- try {
581
- journal.append({ at: now().toISOString(), profile, ...kept, ...settles ? { reservation: settles } : {} });
582
- } catch (error) {
583
- warn(`this send is not in the send journal: ${journalFailure(error)}`, {
584
- event: "warning",
585
- code: "send_not_journaled",
586
- operation: "sends.journal"
587
- });
588
- }
589
- }, "record")
590
- };
591
- }, "sendGuard");
592
- var refuseToAsk = /* @__PURE__ */ __name(async (key) => {
593
- throw new CliError("confirmation_required", `${key} asks before it acts (its permission level is ask), and nobody is here to answer \u2014 add ${skipFlagFor(key)} to go ahead`);
594
- }, "refuseToAsk");
595
- var guardFor = /* @__PURE__ */ __name((app, settings, warn, env = process.env, ask) => sendGuard({
596
- profile: settings.profile,
597
- command: app.command,
598
- ...settings.readOnlyLock ? { readOnlyLock: settings.readOnlyLock } : {},
599
- permissions: /* @__PURE__ */ __name(() => settings.permissions, "permissions"),
600
- permissionSources: settings.permissionSources,
601
- ...settings.permissionDefaults ? { permissionDefaults: settings.permissionDefaults } : {},
602
- ...ask ? { ask } : {},
603
- sendsPerHour: settings.sendsPerHour,
604
- journal: new SendJournal(sendsPathFor(app, settings.profile, env), { service: app.command, version: app.version }),
605
- recipients: new RecipientList(recipientsPathFor(app, settings.profile, env), app.command),
606
- flood: new FloodMemory(floodPathFor(app, settings.profile, env)),
607
- warn
608
- }), "guardFor");
609
- var journalFailure = /* @__PURE__ */ __name((error) => error?.code ?? (error instanceof Error ? error.name : "error"), "journalFailure");
610
-
611
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/ask.js
612
- import { openSync as openSync2 } from "node:fs";
75
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/ask.js
76
+ import { openSync } from "node:fs";
613
77
  import { createInterface } from "node:readline";
614
78
  import { ReadStream } from "node:tty";
615
79
  var fromTerminal = /* @__PURE__ */ __name(async (question) => {
@@ -617,7 +81,7 @@ var fromTerminal = /* @__PURE__ */ __name(async (question) => {
617
81
  return null;
618
82
  let input;
619
83
  try {
620
- input = new ReadStream(openSync2("/dev/tty", "r"));
84
+ input = new ReadStream(openSync("/dev/tty", "r"));
621
85
  } catch {
622
86
  return null;
623
87
  }
@@ -663,11 +127,11 @@ var terminalAsker = /* @__PURE__ */ __name((command) => async (key, request) =>
663
127
  throw new CliError("cancelled", `${key}: not done \u2014 the answer was no`);
664
128
  }, "terminalAsker");
665
129
 
666
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/sends/pace.js
667
- import { readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
668
- import { join as join4 } from "node:path";
130
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/sends/pace.js
131
+ import { readFileSync, renameSync, writeFileSync } from "node:fs";
132
+ import { join } from "node:path";
669
133
  var DEFAULT_PACE = { perMinute: 60, burst: 20 };
670
- var pacePathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join4(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).state, "pace", `${profile}.json`), "pacePathFor");
134
+ var pacePathFor = /* @__PURE__ */ __name((app, profile, env = process.env) => join(resolvePaths({ appName: app.appName, prefix: app.envPrefix, env }).state, "pace", `${profile}.json`), "pacePathFor");
671
135
  var Pacer = class {
672
136
  static {
673
137
  __name(this, "Pacer");
@@ -709,7 +173,7 @@ var Pacer = class {
709
173
  }
710
174
  read() {
711
175
  try {
712
- const tat = Number(JSON.parse(readFileSync4(this.path, "utf8")).tat);
176
+ const tat = Number(JSON.parse(readFileSync(this.path, "utf8")).tat);
713
177
  return Number.isFinite(tat) ? tat : 0;
714
178
  } catch {
715
179
  return 0;
@@ -717,12 +181,43 @@ var Pacer = class {
717
181
  }
718
182
  write(tat) {
719
183
  const temporary = `${this.path}.${process.pid}.tmp`;
720
- writeFileSync2(temporary, JSON.stringify({ tat }), { mode: 384 });
721
- renameSync2(temporary, this.path);
184
+ writeFileSync(temporary, JSON.stringify({ tat }), { mode: 384 });
185
+ renameSync(temporary, this.path);
722
186
  }
723
187
  };
188
+ var ANNOUNCE_WAIT_MS = 5e3;
189
+ var LONGEST_PACE_WAIT_MS = 5 * 6e4;
190
+ var waitForTurn = /* @__PURE__ */ __name(async (pacer, options) => {
191
+ const { name, operation, warn } = options;
192
+ const now = options.now ?? Date.now;
193
+ let at = now();
194
+ try {
195
+ at = await pacer.reserve();
196
+ } catch (error) {
197
+ warn?.(`could not remember ${name}'s wait (${error instanceof Error ? error.message : String(error)})`, {
198
+ event: "warning",
199
+ code: "wait_not_remembered",
200
+ operation
201
+ });
202
+ }
203
+ const waitMs = at - now();
204
+ if (waitMs <= 0)
205
+ return;
206
+ if (waitMs > LONGEST_PACE_WAIT_MS)
207
+ throw new CliError("rate_limited", `${name} asked this profile to wait, ${Math.ceil(waitMs / 1e3)} s are left \u2014 nothing was sent to ${name}`, { retry_after_ms: waitMs, retry_at: new Date(at).toISOString(), remembered: true });
208
+ if (waitMs >= ANNOUNCE_WAIT_MS) {
209
+ const seconds = Math.ceil(waitMs / 1e3);
210
+ warn?.(`waiting ${seconds} s to keep this profile's pace with ${name}`, {
211
+ event: "warning",
212
+ code: "pace_wait",
213
+ operation,
214
+ counts: { seconds }
215
+ });
216
+ }
217
+ await (options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms))))(waitMs);
218
+ }, "waitForTurn");
724
219
 
725
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/permission-keys.js
220
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/permission-keys.js
726
221
  var HOUSEKEEPING = /* @__PURE__ */ new Set([
727
222
  "help",
728
223
  "guide",
@@ -802,12 +297,10 @@ var refuseUnknownPermissionKeys = /* @__PURE__ */ __name((command, settings, too
802
297
  throw new CliError("validation_error", `--permission ${key} names no command`, { permission: key });
803
298
  }, "refuseUnknownPermissionKeys");
804
299
 
805
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/flooded.js
300
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/flooded.js
806
301
  var LONG_LIVED = /* @__PURE__ */ new Set(["self", "newSendId", "close", "formatMarkdown", "formatHtml", "storedChats"]);
807
302
  var LISTENING = /* @__PURE__ */ new Set(["watch", "feed", "listen", "listenHistory"]);
808
303
  var BLOCKING = /* @__PURE__ */ new Set(["frozen", "limited", "banned"]);
809
- var ANNOUNCE_WAIT_MS = 5e3;
810
- var LONGEST_PACE_WAIT_MS = 5 * 6e4;
811
304
  var chatOf = /* @__PURE__ */ __name((args) => typeof args[0] === "string" && /^-?\d+$/.test(args[0]) ? args[0] : void 0, "chatOf");
812
305
  var flooded = /* @__PURE__ */ __name((messenger, memory, { name, warn, pacer }) => {
813
306
  const kept = /* @__PURE__ */ __name(async (operation, what2) => {
@@ -863,28 +356,8 @@ var flooded = /* @__PURE__ */ __name((messenger, memory, { name, warn, pacer })
863
356
  await kept(operation, () => pacer.holdFor(waitMs));
864
357
  }, "noted");
865
358
  const turn = /* @__PURE__ */ __name(async (operation) => {
866
- if (!pacer)
867
- return;
868
- let at = Date.now();
869
- await kept(operation, async () => {
870
- at = await pacer.reserve();
871
- });
872
- const waitMs = at - Date.now();
873
- if (waitMs <= 0)
874
- return;
875
- if (waitMs > LONGEST_PACE_WAIT_MS) {
876
- throw new CliError("rate_limited", `${name} asked this profile to wait, ${Math.ceil(waitMs / 1e3)} s are left \u2014 nothing was sent to ${name}`, { retry_after_ms: waitMs, retry_at: new Date(at).toISOString(), remembered: true });
877
- }
878
- if (waitMs >= ANNOUNCE_WAIT_MS) {
879
- const seconds = Math.ceil(waitMs / 1e3);
880
- warn(`waiting ${seconds} s to keep this profile's pace with ${name}`, {
881
- event: "warning",
882
- code: "pace_wait",
883
- operation,
884
- counts: { seconds }
885
- });
886
- }
887
- await new Promise((resolve) => setTimeout(resolve, waitMs));
359
+ if (pacer)
360
+ await waitForTurn(pacer, { name, operation, warn });
888
361
  }, "turn");
889
362
  return throughWrapper(messenger, {}, (operation, call) => {
890
363
  if (LONG_LIVED.has(operation))
@@ -921,7 +394,7 @@ var flooded = /* @__PURE__ */ __name((messenger, memory, { name, warn, pacer })
921
394
  });
922
395
  }, "flooded");
923
396
 
924
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/observed.js
397
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/observed.js
925
398
  var observed = /* @__PURE__ */ __name((messenger, events) => {
926
399
  const timed = /* @__PURE__ */ __name(async (operation, named, work, after) => {
927
400
  const write = currentOperation();
@@ -1020,7 +493,7 @@ var byPart = /* @__PURE__ */ __name((batch, counts) => {
1020
493
  counts[part] = (counts[part] ?? 0) + items.length;
1021
494
  }, "byPart");
1022
495
 
1023
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/stored.js
496
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/stored.js
1024
497
  var REKEY_PACING = { lockMs: 50, pauseMs: 25 };
1025
498
  var stored = /* @__PURE__ */ __name((messenger, { account, store, warn, events, pending, announcing, deletedWithoutChat, profile, rekeyed, rekeyPacing = REKEY_PACING, closing, namesFromStore, recipientIds, countsUnread = false, historyLimits, command = "cli" }) => {
1026
499
  let warned = false;
@@ -1141,13 +614,13 @@ var stored = /* @__PURE__ */ __name((messenger, { account, store, warn, events,
1141
614
  }
1142
615
  if (round !== rekeyRound)
1143
616
  return;
1144
- const taken2 = pass?.taken ?? rest.length;
1145
- rekeysQueued -= taken2;
617
+ const taken = pass?.taken ?? rest.length;
618
+ rekeysQueued -= taken;
1146
619
  for (const { from, to } of pass?.applied ?? [])
1147
620
  await Promise.resolve().then(() => rekeyed?.(from, to)).catch((error) => notWritten("history.rekey", error));
1148
621
  for (const { error } of pass?.refused ?? [])
1149
622
  notWritten("history.rekey", error);
1150
- rest = rest.slice(taken2);
623
+ rest = rest.slice(taken);
1151
624
  if (rest.length > 0)
1152
625
  await new Promise((resolve) => setTimeout(resolve, rekeyPacing.pauseMs));
1153
626
  }
@@ -1596,7 +1069,7 @@ var keep = /* @__PURE__ */ __name(async (store, account, event, seenAt, among, c
1596
1069
  }
1597
1070
  }, "keep");
1598
1071
 
1599
- // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/messenger/context.js
1072
+ // node_modules/.pnpm/@wirecat+cli-core@0.601.0_@wirecat+cli-base@0.80.9_commander@15.0.0_esbuild@0.28.2_type_4fddd50439ae4e4f952967ea26554e7b/node_modules/@wirecat/cli-core/dist/cli/messenger/context.js
1600
1073
  var lazyStore = /* @__PURE__ */ __name((env, command, version) => {
1601
1074
  let opened;
1602
1075
  return {
@@ -1994,17 +1467,6 @@ var messengerContext = /* @__PURE__ */ __name((command, messenger, resolving = {
1994
1467
  }, "messengerContext");
1995
1468
 
1996
1469
  export {
1997
- holdEnd,
1998
- floodPathFor,
1999
- FloodMemory,
2000
- sendsPathFor,
2001
- SendJournal,
2002
- recipientsPathFor,
2003
- RecipientList,
2004
- ceilingRefusal,
2005
- levelRefusal,
2006
- sendGuard,
2007
- guardFor,
2008
1470
  commandPathKey,
2009
1471
  commandPermissions,
2010
1472
  knownPermissionKeys,