@wirecat/bitrix24-cli 0.4.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 (248) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/README.md +84 -9
  3. package/dist/api-keys.d.ts +18 -13
  4. package/dist/api-keys.d.ts.map +1 -1
  5. package/dist/api-keys.js +79 -22
  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/transport.d.ts +1 -1
  11. package/dist/bitrix/transport.d.ts.map +1 -1
  12. package/dist/bitrix/transport.js +20 -6
  13. package/dist/bitrix/transport.js.map +1 -1
  14. package/dist/body.d.ts +14 -0
  15. package/dist/body.d.ts.map +1 -0
  16. package/dist/body.js +44 -0
  17. package/dist/body.js.map +1 -0
  18. package/dist/bundle/{chunk-JAS3OZSP.js → all-profiles-CANIDIDS.js} +12 -7
  19. package/dist/bundle/{anthropic-QCYLKSJJ.js → anthropic-JUJB4DCF.js} +5 -5
  20. package/dist/bundle/{app-server-FSLZ2Y6N.js → app-server-3V5Z4PTK.js} +68 -54
  21. package/dist/bundle/b24.js +18 -12
  22. package/dist/bundle/{bun-UYRQXF33.js → bun-LKMV5TY7.js} +2 -2
  23. package/dist/bundle/{bun-sqlite-GXME7EMT.js → bun-sqlite-S56EF74S.js} +3 -3
  24. package/dist/bundle/{chunk-D2IRPC5I.js → chunk-2I4KWS3H.js} +6 -6
  25. package/dist/bundle/chunk-36PO5NWY.js +147 -0
  26. package/dist/bundle/{chunk-COOOXDKZ.js → chunk-42F7Q7V6.js} +3 -3
  27. package/dist/bundle/{chunk-POUSZWMP.js → chunk-4D3K6GZW.js} +18 -4
  28. package/dist/bundle/chunk-5D4MJQ6X.js +22 -0
  29. package/dist/bundle/chunk-5JOPERVF.js +84 -0
  30. package/dist/bundle/chunk-6A4UPWDC.js +15 -0
  31. package/dist/bundle/{chunk-O7FVOICH.js → chunk-6MGWIZG4.js} +1 -1
  32. package/dist/bundle/{chunk-B252WFK7.js → chunk-6YJTNZ7U.js} +13 -13
  33. package/dist/bundle/{chunk-2D5W4LWL.js → chunk-7FBFJ6B4.js} +4 -2
  34. package/dist/bundle/chunk-7VCMOTQP.js +55 -0
  35. package/dist/bundle/{chunk-6BLVBGRK.js → chunk-A5IMMGYU.js} +36 -34
  36. package/dist/bundle/{chunk-66QLBRIT.js → chunk-ASEHTBNK.js} +1 -1
  37. package/dist/bundle/{chunk-MY6FAZRA.js → chunk-B6LPJYPQ.js} +2 -2
  38. package/dist/bundle/{chunk-EQLWU6ZB.js → chunk-BHEE2K6C.js} +7 -7
  39. package/dist/bundle/chunk-BYZQBE63.js +971 -0
  40. package/dist/bundle/{chunk-J7OMY6EO.js → chunk-COKGNTDQ.js} +1477 -723
  41. package/dist/bundle/{chunk-QVZSLBR6.js → chunk-DVFYRQGE.js} +1 -1
  42. package/dist/bundle/{chunk-Q7Z5IMVY.js → chunk-DVSIBZ3G.js} +1 -1
  43. package/dist/bundle/chunk-EJEIXC6Y.js +273 -0
  44. package/dist/bundle/chunk-EYTGCM44.js +130 -0
  45. package/dist/bundle/{chunk-SBW2Y7AZ.js → chunk-EYYOKT23.js} +26 -26
  46. package/dist/bundle/{chunk-Y5PPMGCS.js → chunk-FCWPIWSR.js} +2 -2
  47. package/dist/bundle/{chunk-AOUNT22U.js → chunk-FSWRMQWX.js} +2 -2
  48. package/dist/bundle/{chunk-ADLS6FVG.js → chunk-FXBHOCJK.js} +1 -1
  49. package/dist/bundle/chunk-G5MW6RCM.js +723 -0
  50. package/dist/bundle/{chunk-4OVK5XW2.js → chunk-GLTKRLFT.js} +8 -8
  51. package/dist/bundle/chunk-GUUZQ7NE.js +581 -0
  52. package/dist/bundle/{chunk-XOPMSWFC.js → chunk-H6RIPOOI.js} +36 -3
  53. package/dist/bundle/{chunk-GTMCLOYY.js → chunk-HGFNC4CR.js} +1447 -430
  54. package/dist/bundle/{chunk-IF27EQN6.js → chunk-IERYD2N2.js} +6 -6
  55. package/dist/bundle/{chunk-Q4ILKTV4.js → chunk-IGCLMEMB.js} +3 -3
  56. package/dist/bundle/{chunk-2IZ6GGU2.js → chunk-J7WCSZ2Q.js} +410 -918
  57. package/dist/bundle/{chunk-CR3TLGM4.js → chunk-JZYHQ4HB.js} +3 -3
  58. package/dist/bundle/{chunk-XR5SUCAC.js → chunk-K4QM3X5F.js} +4 -4
  59. package/dist/bundle/{chunk-OWILUBCI.js → chunk-KFSMY7SZ.js} +2 -2
  60. package/dist/bundle/{chunk-AMVRNYD6.js → chunk-KPEDH5T4.js} +1 -1
  61. package/dist/bundle/{chunk-NEK7LKC6.js → chunk-KUY7LII2.js} +4 -4
  62. package/dist/bundle/{chunk-NDSOBIR3.js → chunk-LFXDHLFR.js} +3 -3
  63. package/dist/bundle/{chunk-ZU4HXKEW.js → chunk-LGLT4JB6.js} +3 -3
  64. package/dist/bundle/{chunk-EIGPMMGC.js → chunk-LM4OOBAW.js} +3 -3
  65. package/dist/bundle/chunk-M74BSKMA.js +234 -0
  66. package/dist/bundle/{chunk-MPI2FDJ4.js → chunk-MMMT6ORT.js} +11 -11
  67. package/dist/bundle/{chunk-F5NH3UJQ.js → chunk-NGYD6QTE.js} +2 -2
  68. package/dist/bundle/{chunk-6ERX33NC.js → chunk-NO6QOPVT.js} +10 -19
  69. package/dist/bundle/chunk-O6XC7DZI.js +804 -0
  70. package/dist/bundle/chunk-OE3NFB53.js +64 -0
  71. package/dist/bundle/{chunk-VTIUWHZ3.js → chunk-OUMFNB34.js} +13 -149
  72. package/dist/bundle/{chunk-VMQL4GNH.js → chunk-P2RQTNVJ.js} +806 -850
  73. package/dist/bundle/{chunk-XKQZLR2X.js → chunk-PBIBGIZ7.js} +1 -1
  74. package/dist/bundle/{chunk-YFZXI3NN.js → chunk-Q6VQHTRW.js} +2 -2
  75. package/dist/bundle/{chunk-OKDC6CLH.js → chunk-QHBCNVUG.js} +5 -5
  76. package/dist/bundle/{chunk-WJRBX5QB.js → chunk-QNOXAQ6Y.js} +4 -4
  77. package/dist/bundle/{chunk-GTFRSYYJ.js → chunk-R5F2O5GX.js} +7 -269
  78. package/dist/bundle/{chunk-OCRCVLZQ.js → chunk-R5PBSKJL.js} +1 -1
  79. package/dist/bundle/{chunk-JB7OXYAU.js → chunk-RS2BARUU.js} +4 -4
  80. package/dist/bundle/chunk-TG3DSPT5.js +14 -0
  81. package/dist/bundle/{chunk-UH56WLDS.js → chunk-U22JMKUO.js} +6 -125
  82. package/dist/bundle/chunk-U66Q5TVK.js +106 -0
  83. package/dist/bundle/{chunk-NWKXMMON.js → chunk-UCHMQWON.js} +136 -33
  84. package/dist/bundle/{chunk-DQIQIZQS.js → chunk-VMJS7FJZ.js} +451 -433
  85. package/dist/bundle/{chunk-IWEWDVZ6.js → chunk-VMVAQHDC.js} +77 -615
  86. package/dist/bundle/{chunk-M5XMAUGZ.js → chunk-WWMCJFMT.js} +2 -2
  87. package/dist/bundle/{chunk-OYLJHX74.js → chunk-XTA5TN3H.js} +1 -1
  88. package/dist/bundle/{chunk-ELBOQHJA.js → chunk-XUHHBEA7.js} +652 -131
  89. package/dist/bundle/{chunk-BHZ5VDDY.js → chunk-YDZHO4LT.js} +13 -13
  90. package/dist/bundle/{chunk-NKLLI4B2.js → chunk-ZKINZFIT.js} +6 -6
  91. package/dist/bundle/{chunk-GTDOUP6L.js → chunk-ZSQXSIFQ.js} +85 -38
  92. package/dist/bundle/{chunk-LAYH344Y.js → chunk-ZZEHDIEG.js} +58 -54
  93. package/dist/bundle/command-contract-OQV6H7SR.js +36 -0
  94. package/dist/bundle/{decode-IF2F2SFC.js → decode-QSTBX4MG.js} +3 -3
  95. package/dist/bundle/{echarts-WDDVEJO2.js → echarts-JZELFH2N.js} +2 -2
  96. package/dist/bundle/{embed-VDUGYEAR.js → embed-4RIW2LVH.js} +4 -4
  97. package/dist/bundle/{embedder-DUN62H3Z.js → embedder-SW7DTWSL.js} +7 -7
  98. package/dist/bundle/{first-run-NDGYBQEN.js → first-run-7AISOSOM.js} +8 -8
  99. package/dist/bundle/first-screen-NMHNFZ2B.js +34 -0
  100. package/dist/bundle/{instructions-JIIKWS7X.js → instructions-BZE5YUGG.js} +1 -1
  101. package/dist/bundle/{mcp-33JX6KP4.js → mcp-SDWHDJTY.js} +2 -2
  102. package/dist/bundle/{node-P4E63KXA.js → node-KM3CUABH.js} +9 -9
  103. package/dist/bundle/{node-K57WT42O.js → node-LTKZIO4U.js} +2 -2
  104. package/dist/bundle/{node-sqlite-KS6ORRIG.js → node-sqlite-HQ5PN2RH.js} +4 -4
  105. package/dist/bundle/{oauth-SLSANN37.js → oauth-UH6FOZQL.js} +5 -5
  106. package/dist/bundle/{open-WJPHADEX.js → open-TSUP3XGL.js} +3 -3
  107. package/dist/bundle/{openai-HXB3GTOD.js → openai-GVEE52E3.js} +14 -14
  108. package/dist/bundle/{process-P73TFAXT.js → process-AGXY76ZE.js} +1 -1
  109. package/dist/bundle/{program-7BMG5NIN.js → program-BI4A4HFJ.js} +1045 -1048
  110. package/dist/bundle/{prompt-WDPV37R4.js → prompt-NRSUY7FA.js} +3 -3
  111. package/dist/bundle/{recognize-CXIFL6IV.js → recognize-NPDPQ6PJ.js} +2 -2
  112. package/dist/bundle/{remote-Q4VJ4OQW.js → remote-HFASMVLB.js} +5 -5
  113. package/dist/bundle/{rerank-SUFYK63I.js → rerank-TL6Z6F7K.js} +5 -5
  114. package/dist/bundle/{chunk-XG6QKS7L.js → serve-VB4DHDZQ.js} +8 -6
  115. package/dist/bundle/server-T5EDRPJI.js +68 -0
  116. package/dist/bundle/{chunk-K7XWCZF6.js → server-Z6MW6C37.js} +50 -14
  117. package/dist/bundle/source-4IGO5J7E.js +237 -0
  118. package/dist/bundle/sqlite-runtime-YS4POY3W.js +17 -0
  119. package/dist/bundle/{state-EZCCXQV7.js → state-ISZVVZGR.js} +4 -4
  120. package/dist/bundle/store-IZJBAKJV.js +58 -0
  121. package/dist/bundle/{store-MZ7JBYR6.js → store-L76MSQC3.js} +17 -12
  122. package/dist/bundle/store-PBTIB7BD.js +207 -0
  123. package/dist/bundle/store-maintenance-command-YFKII7TF.js +58 -0
  124. package/dist/bundle/writer-3O5EYMFE.js +214 -0
  125. package/dist/commands/api.d.ts.map +1 -1
  126. package/dist/commands/api.js +34 -33
  127. package/dist/commands/api.js.map +1 -1
  128. package/dist/commands/crm-shared.d.ts +4 -0
  129. package/dist/commands/crm-shared.d.ts.map +1 -0
  130. package/dist/commands/crm-shared.js +94 -0
  131. package/dist/commands/crm-shared.js.map +1 -0
  132. package/dist/commands/crm-writes.d.ts +0 -1
  133. package/dist/commands/crm-writes.d.ts.map +1 -1
  134. package/dist/commands/crm-writes.js +31 -92
  135. package/dist/commands/crm-writes.js.map +1 -1
  136. package/dist/commands/crm.d.ts.map +1 -1
  137. package/dist/commands/crm.js +1 -45
  138. package/dist/commands/crm.js.map +1 -1
  139. package/dist/commands/session.d.ts.map +1 -1
  140. package/dist/commands/session.js +1 -0
  141. package/dist/commands/session.js.map +1 -1
  142. package/dist/commands/write.d.ts +1 -6
  143. package/dist/commands/write.d.ts.map +1 -1
  144. package/dist/commands/write.js +7 -16
  145. package/dist/commands/write.js.map +1 -1
  146. package/dist/config.d.ts +0 -5
  147. package/dist/config.d.ts.map +1 -1
  148. package/dist/config.js +6 -9
  149. package/dist/config.js.map +1 -1
  150. package/dist/crm/capabilities.d.ts +7 -0
  151. package/dist/crm/capabilities.d.ts.map +1 -0
  152. package/dist/crm/capabilities.js +7 -0
  153. package/dist/crm/capabilities.js.map +1 -0
  154. package/dist/crm/conditions.d.ts +1 -1
  155. package/dist/crm/conditions.d.ts.map +1 -1
  156. package/dist/crm/conditions.js +3 -5
  157. package/dist/crm/conditions.js.map +1 -1
  158. package/dist/crm/custom-query.d.ts +1 -1
  159. package/dist/crm/custom-query.d.ts.map +1 -1
  160. package/dist/crm/custom-query.js +2 -2
  161. package/dist/crm/custom-query.js.map +1 -1
  162. package/dist/crm/deal.d.ts +4 -28
  163. package/dist/crm/deal.d.ts.map +1 -1
  164. package/dist/crm/deal.js +15 -48
  165. package/dist/crm/deal.js.map +1 -1
  166. package/dist/crm/fields.d.ts +2 -26
  167. package/dist/crm/fields.d.ts.map +1 -1
  168. package/dist/crm/fields.js +2 -67
  169. package/dist/crm/fields.js.map +1 -1
  170. package/dist/crm/items.d.ts.map +1 -1
  171. package/dist/crm/items.js +6 -5
  172. package/dist/crm/items.js.map +1 -1
  173. package/dist/crm/lead.d.ts +5 -37
  174. package/dist/crm/lead.d.ts.map +1 -1
  175. package/dist/crm/lead.js +15 -61
  176. package/dist/crm/lead.js.map +1 -1
  177. package/dist/crm/pipelines.d.ts +5 -0
  178. package/dist/crm/pipelines.d.ts.map +1 -0
  179. package/dist/crm/pipelines.js +54 -0
  180. package/dist/crm/pipelines.js.map +1 -0
  181. package/dist/crm/product.d.ts.map +1 -1
  182. package/dist/crm/product.js +2 -2
  183. package/dist/crm/product.js.map +1 -1
  184. package/dist/crm/rest3-fields.d.ts +3 -0
  185. package/dist/crm/rest3-fields.d.ts.map +1 -0
  186. package/dist/crm/rest3-fields.js +38 -0
  187. package/dist/crm/rest3-fields.js.map +1 -0
  188. package/dist/crm/source.d.ts +15 -0
  189. package/dist/crm/source.d.ts.map +1 -0
  190. package/dist/crm/source.js +122 -0
  191. package/dist/crm/source.js.map +1 -0
  192. package/dist/crm/user.d.ts.map +1 -1
  193. package/dist/crm/user.js +2 -2
  194. package/dist/crm/user.js.map +1 -1
  195. package/dist/crm/values.d.ts +19 -4
  196. package/dist/crm/values.d.ts.map +1 -1
  197. package/dist/crm/values.js +28 -2
  198. package/dist/crm/values.js.map +1 -1
  199. package/dist/crm/writer.d.ts +9 -0
  200. package/dist/crm/writer.d.ts.map +1 -0
  201. package/dist/crm/writer.js +119 -0
  202. package/dist/crm/writer.js.map +1 -0
  203. package/dist/program.d.ts.map +1 -1
  204. package/dist/program.js +51 -6
  205. package/dist/program.js.map +1 -1
  206. package/dist/store.d.ts +15 -0
  207. package/dist/store.d.ts.map +1 -0
  208. package/dist/store.js +33 -0
  209. package/dist/store.js.map +1 -0
  210. package/dist/version.d.ts +1 -1
  211. package/dist/version.js +1 -1
  212. package/package.json +4 -6
  213. package/skills/bitrix24-cli/SKILL.md +16 -15
  214. package/dist/bundle/all-profiles-MBQZCOVK.js +0 -24
  215. package/dist/bundle/chunk-UCLWWSQK.js +0 -48
  216. package/dist/bundle/command-contract-UON4EIC4.js +0 -30
  217. package/dist/bundle/first-screen-QAVKP5RF.js +0 -28
  218. package/dist/bundle/mcp-57EQ6QJO.js +0 -171
  219. package/dist/bundle/mcp-PFJER2DE.js +0 -87
  220. package/dist/bundle/serve-B7PGFOC2.js +0 -19
  221. package/dist/bundle/server-4DBNJWW6.js +0 -58
  222. package/dist/bundle/server-OKE7SXJ2.js +0 -45
  223. package/dist/bundle/store-maintenance-command-T5QZMENJ.js +0 -47
  224. package/dist/commands/doctor.d.ts +0 -77
  225. package/dist/commands/doctor.d.ts.map +0 -1
  226. package/dist/commands/doctor.js +0 -74
  227. package/dist/commands/doctor.js.map +0 -1
  228. package/dist/commands/fields.d.ts +0 -3
  229. package/dist/commands/fields.d.ts.map +0 -1
  230. package/dist/commands/fields.js +0 -45
  231. package/dist/commands/fields.js.map +0 -1
  232. package/dist/commands/mcp.d.ts +0 -3
  233. package/dist/commands/mcp.d.ts.map +0 -1
  234. package/dist/commands/mcp.js +0 -97
  235. package/dist/commands/mcp.js.map +0 -1
  236. package/dist/crm/pipeline.d.ts +0 -17
  237. package/dist/crm/pipeline.d.ts.map +0 -1
  238. package/dist/crm/pipeline.js +0 -42
  239. package/dist/crm/pipeline.js.map +0 -1
  240. package/dist/crm/stage.d.ts +0 -20
  241. package/dist/crm/stage.d.ts.map +0 -1
  242. package/dist/crm/stage.js +0 -65
  243. package/dist/crm/stage.js.map +0 -1
  244. package/dist/mcp.d.ts +0 -29
  245. package/dist/mcp.d.ts.map +0 -1
  246. package/dist/mcp.js +0 -102
  247. package/dist/mcp.js.map +0 -1
  248. /package/dist/bundle/{chunk-NDTJE6JQ.js → chunk-ZQ3GWKDQ.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,84 @@
2
2
 
3
3
  Notable changes to `@wirecat/bitrix24-cli`. One section per version, newest first.
4
4
 
5
+ ## 0.5.0 — 07.11.2026
6
+
7
+ ### Added
8
+
9
+ - `sync` copies the portal's pipelines, companies, contacts, deals and leads into the local WireCat store: what changed
10
+ since the last sync, or everything with `--rescan`; once a day it also finds what the portal deleted. `store status`
11
+ says how far each kind is. A sync stops before its deadline or `--max-pages`, and the next one goes on from there.
12
+ - `deals close <ref> won|lost` and `leads close`, to the first won or lost stage of the record's pipeline, and
13
+ `deals delete` and `leads delete`, which ask first.
14
+ - `deals create` and `update` take `--pipeline`, `--stage`, `--amount` with `--currency`, `--close-date` and
15
+ `--owner`; leads take the same but `--close-date`. A stage checks the move key, a won or lost one the close key too.
16
+ - `search all` finds stored deals and leads beside the other WireCat tools' messages, notes and events. Under
17
+ `deals.list: deny` it leaves deals out and names them in `missing` and on stderr, and the same for leads; with every
18
+ kind it was asked for denied, it is refused (`search.all-denied`).
19
+ - `b24 --help` and a bare `b24` open with what `b24` is for, what to try first, and where to start.
20
+
21
+ ### Changed — may break callers
22
+
23
+ - `deals`, `leads`, `pipelines` and `stages` are cli-core's shared CRM commands, the same in every WireCat CRM tool.
24
+ Their lists and `show` read the local store, so run `sync` first; `--offline` works for them now.
25
+ - A deal or lead is named by its ref, `deal:12` or `lead:7`, as a list prints it, not by its Bitrix24 id or title.
26
+ - A deal or lead answers `ref`, `pipeline` and `pipeline_name`, `stage` (its name), `status` (`open`, `won` or `lost`),
27
+ `close_date`, `amount` as a decimal string in `currency`, both `null` with no amount, `assignee` as
28
+ `<portal>/user/<id>`, and the portal's own fields in `provider_metadata` by code. `stage_id`, `pipeline_id`,
29
+ `outcome`, `closes_on`, `assigned_to` and `person_ids` are gone from them; contacts are in `people`, the company in
30
+ `organization`.
31
+ - Their list query takes `status`, `stage`, `pipeline` and `organization`; the free word, the time windows and the
32
+ portal's own fields are gone from it. `--all` is gone from those lists.
33
+ - `deals move <ref> <stage>` takes the stage as an argument, not `--stage`.
34
+ - Deal and lead writes have no `--body`. `--field <label or code>=<value>` sets a custom field by the definitions the
35
+ last `sync` stored: a list field takes its option's label or id, a multiple field one `--field` per value, and an
36
+ empty value clears it. A code that names a standard field (`stageId`, `categoryId`, `assignedById`, a lead's
37
+ `STATUS_ID`) is refused, and so is a `--field` with no key before its `=`.
38
+ - A custom field's label and a list option's label are matched as cli-core matches names, for every `--field` and
39
+ query: `е` finds `ё`, and a letter typed as two code points finds the same letter typed as one. `people show` and
40
+ `organizations show` compare a name with the portal's matches the same way. A label that matched one field may now
41
+ match two, which is refused with both.
42
+ - `fields list <deals|leads|people|organizations>` is cli-core's: it reads the definitions `sync` stored, so run
43
+ `sync` first, and each field names its `untrusted` parts.
44
+ - `api.crm.deal.update` (and the other deal and lead `api.*` keys) at `ask` now asks on `deals update`, `move` and
45
+ `close` too, not only on `api call`. `--dry-run` of a deal or lead write names every key it may check: the
46
+ `api.*` key, and the move, close and `crm.assign-others` keys with the option that would make each apply.
47
+ - `sync` reads the portal's field definitions of each kind, one more request per kind, so `--max-pages` reaches the
48
+ records later. A webhook without the rights to read them still syncs; any other failure there fails the sync.
49
+ - Leads stand in one pipeline named `Leads`, since Bitrix24's leads have none.
50
+ - `deals.delete` and `leads.delete` default to `ask`; `api call` that sets a stage checks `deals.close` (or
51
+ `leads.close`) as well as `deals.move`.
52
+ - `mcp` and `doctor` are cli-core's shared commands: `mcp` adds `config`, `add` and `check`, and `--profiles` and
53
+ `--permission` on `serve`; `doctor` adds `--online`.
54
+ - A `--body` or `api call` method that could be read in more than one way is refused before anything is sent: a
55
+ body that names one field twice in any spelling, an `entityTypeId` that is not a plain number, a `fields` that is
56
+ not an object, a method with any suffix but one `.json`, and a `crm.item` method without `entityTypeId`. Send each
57
+ field once, under one spelling.
58
+ - `--operation-id` is gone from every write. On a live portal a create repeated with the same id made a second
59
+ record, so a repeat is never safe: after `outcome_unknown`, `sync` and `show` the record and write it again only if
60
+ it is not there. A deal or lead write given `--operation-id` is refused before anything is sent.
61
+
62
+ ### Fixed
63
+
64
+ - A `sync` after the first one works. It asked the portal for what changed with a time the portal refuses, so
65
+ every kind failed and nothing new was copied. Times in a filter now go in whole seconds with an offset, which also
66
+ fixes `updated_at:` and `created_at:` in `people list` and `organizations list`.
67
+ - A write answered with a server or gateway failure (500, 502, 504) is `outcome_unknown`, not `provider_unavailable`:
68
+ the portal may have made it. A write a cancel cuts is `outcome_unknown` too, never `cancelled`.
69
+ - Stages are read page by page: a directory past REST 2's first 50 rows lost its later stages.
70
+ - An id or owner that is not a number is refused before anything is sent; it went out empty before.
71
+ - `--body` keeps integers past 2^53 as typed; `api call --body -` reads the body from stdin.
72
+ - A request that gets no answer is cut after 10 seconds, not 30, so a read can be tried again before a one-shot
73
+ command's own 30 s run out.
74
+ - `show` for people and organizations fails when the portal's field labels fail for a reason other than missing
75
+ rights, instead of showing the record without its labels.
76
+
77
+ ### Security
78
+
79
+ - Permission checks on `api call` and on `people` and `organizations` writes read a body exactly as it is sent, so
80
+ the key they check is the key the write needs.
81
+ - `api call` reads check the same keys as the commands that read those records, as its writes already did.
82
+
5
83
  ## 0.4.0 — 06.11.2026
6
84
 
7
85
  ### Added
package/README.md CHANGED
@@ -1,18 +1,93 @@
1
- # b24
1
+ # b24 — Bitrix24 CRM CLI for AI agents
2
2
 
3
3
  `b24` reads and changes a Bitrix24 portal's sales data from the terminal, from scripts and from AI agents: deals,
4
4
  leads, contacts, companies, pipelines and their stages, products and employees. It signs in with one of the portal's
5
- incoming webhooks and acts with the rights of the employee who made it.
5
+ incoming webhooks and acts with the rights of the employee who made it. Deals and leads are copied into the local
6
+ [WireCat](https://wirecat.dev) store, so lists and search work offline, beside your other WireCat tools' data.
7
+
8
+ ## Quick start
6
9
 
7
10
  ```sh
8
11
  npm install -g @wirecat/bitrix24-cli
12
+ b24 skill install # the agent skill, for Claude Code, Codex, Gemini CLI and OpenClaw
9
13
  b24 work session start # paste the webhook address; it is kept in the keyring
10
- b24 work deals list outcome:open
11
- b24 work leads list updated_at>=7d --json
12
- b24 work deals move 42 --stage "Contract signed"
14
+ b24 work sync # copies pipelines, companies, contacts, deals and leads into the local store
15
+ b24 work deals list status:open
16
+ ```
17
+
18
+ `work` is a profile: a name you choose for one portal. It is the first word of every command that uses an account,
19
+ and none is ever assumed. Make the webhook in Bitrix24 under Developer resources → Other → Incoming webhook, with the
20
+ scopes `crm` and `user`. You need Node.js 22.16 or a later 22.x, or Node.js 24 or later. `b24 doctor` needs no
21
+ network and shows what is set up.
22
+
23
+ More: [installation](docs/installation.md), [usage](docs/usage.md).
24
+
25
+ ## What you can do
26
+
27
+ ```sh
28
+ b24 work leads list stage:"In progress" --json # from the store, offline too
29
+ b24 work deals move deal:42 "Contract signed" # checks deals.move, and deals.close for a won or lost stage
30
+ b24 work search all kitchen # stored deals and leads beside your other WireCat data
31
+ b24 work people update 4 --body '{"post":"Buyer"}' # a contact, in Bitrix24's own field names
32
+ b24 work api call crm.deal.fields --dry-run # any REST method, with every permission it checks
13
33
  ```
14
34
 
15
- Every command answers JSON with `--json`, every write answers an `operation_id` and can be previewed with
16
- `--dry-run`, and `b24 work mcp serve` gives the same commands to an agent. Start with
17
- [installation](docs/installation.md), then [usage](docs/usage.md). The design is in
18
- [docs/dev/DESIGN.md](docs/dev/DESIGN.md).
35
+ Every write answers an `operation_id` and can be previewed with `--dry-run`. More: [usage](docs/usage.md) and the
36
+ [command reference](docs/commands.md).
37
+
38
+ ## For AI agents
39
+
40
+ - **An agent with a terminal** (Claude Code, Codex, Gemini CLI, OpenClaw): `b24 skill install` writes the skill, the
41
+ agent's instruction sheet.
42
+ - **An MCP client**: `b24 work mcp serve`, or `b24 work mcp add claude-code`. `mcp serve --permission deals=deny`
43
+ tightens the levels for one server; an agent can never loosen them.
44
+ - **ChatGPT or Claude in a browser**: `b24 work mcp serve --http` behind your own tunnel.
45
+
46
+ Text from the portal is marked `untrusted` in MCP answers: it is data for the agent, never instructions. `api call`
47
+ and `session start`/`end` are never offered over MCP. With `--json`, every command prints one JSON value, and an error
48
+ comes as JSON with a code to branch on.
49
+
50
+ More: [agents](docs/usage.md#agents).
51
+
52
+ ## Settings and permissions
53
+
54
+ Each profile has a permission level for every command and every REST method: `allow`, `ask`, `readonly` or `deny`.
55
+ Assigning a record to another employee is denied until you allow it, a delete asks first, and methods that message
56
+ people, publish or start the portal's automation are denied, reads too. A stage change can start the portal's own
57
+ robots, which may write to your clients: set `permissions.deals.move` to `ask` if your portal has such robots.
58
+ `B24_READ_ONLY=1` refuses every write.
59
+
60
+ More: [settings](docs/configuration.md#permissions), [security](docs/security.md).
61
+
62
+ ## Limits
63
+
64
+ - The portal allows about 2 requests a second for all its apps together; `b24` keeps to that pace.
65
+ - `people`, `organizations`, `products`, `users` and `fields` still ask the portal on every read and refuse
66
+ `--offline`.
67
+ - Bitrix24 does a repeated write again: on a live portal, a create repeated with the same `Idempotency-Key` made a
68
+ second record. After an `outcome_unknown`, look at the record before you write it again.
69
+
70
+ ## Security
71
+
72
+ The webhook address is the password: anyone who has it can do what its employee can. `b24` keeps it in the system
73
+ keyring and never prints it, in output, errors or run records. Report a vulnerability as [SECURITY.md](SECURITY.md)
74
+ says.
75
+
76
+ ## When it does not work
77
+
78
+ Start with `b24 doctor`, then [troubleshooting](docs/troubleshooting.md).
79
+
80
+ ## Documentation
81
+
82
+ - [Install](docs/installation.md) · [Use it](docs/usage.md) · [Settings](docs/configuration.md) ·
83
+ [Security](docs/security.md) · [Commands](docs/commands.md) · [Troubleshooting](docs/troubleshooting.md)
84
+ - The design: [docs/dev/DESIGN.md](docs/dev/DESIGN.md).
85
+
86
+ ## Part of WireCat
87
+
88
+ `b24` is one of the [WireCat](https://wirecat.dev) tools. They share one local store, so `search all` and an agent see
89
+ your CRM beside your messages, mail, notes and meetings.
90
+
91
+ ## License
92
+
93
+ [Apache-2.0](LICENSE).
@@ -1,5 +1,8 @@
1
+ import type { DealKind } from "@wirecat/cli-core";
2
+ import type { CrmVerb } from "@wirecat/cli-core/crm";
1
3
  import type { Level } from "@wirecat/cli-core/sends";
2
4
  import { type Effect } from "./bitrix/methods.js";
5
+ import { type Body } from "./body.js";
3
6
  export declare const apiKey: (method: string) => string;
4
7
  /**
5
8
  * Families whose writes reach people, publish, or start the portal's own automation: messages and notifications (im,
@@ -11,31 +14,33 @@ export declare const apiKey: (method: string) => string;
11
14
  export declare const DENIED_FAMILIES: string[];
12
15
  /** Bitrix24 takes a method in any letter case and with a `.json` suffix; one name keeps the keys from being dodged. */
13
16
  export declare const normalMethod: (raw: string) => string;
14
- /** A field in any letter case, with or without underscores: Bitrix24 takes both `stageId` and `STAGE_ID`. */
15
- export declare const fieldOf: (record: Record<string, unknown>, name: string) => unknown;
16
- export declare const fieldsOf: (body: Record<string, unknown>) => Record<string, unknown>;
17
+ /** A field in any letter case, with or without underscores: `parseBody` has refused a body that spells one twice. */
18
+ export declare const fieldOf: (record: Body, name: string) => unknown;
19
+ export declare const fieldsOf: (body: Body) => Record<string, unknown>;
17
20
  /** The employee a write assigns the record to, by any spelling of `assignedById`. */
18
- export declare const assigneeOf: (fields: Record<string, unknown>) => string | undefined;
21
+ export declare const assigneeOf: (fields: Body) => string | undefined;
19
22
  /** Whether a write changes a deal's or a lead's stage: `stageId`, or a lead's REST 2 `STATUS_ID`. */
20
23
  export declare const setsStage: (type: string, fields: Record<string, unknown>) => boolean;
24
+ /** What `api call` sends, checked once: the body `parseBody` gave, its `fields` an object and its type a number. */
25
+ export declare const checkCall: (method: string, body: Body) => void;
21
26
  /**
22
- * The command keys a raw call does the same as, so `api call` cannot get round `deals.update: deny` (gcal-cli's
23
- * `WRITE_METHODS`). A create or update that sets a stage is a move too.
27
+ * The command keys a raw call does the same as, so `api call` cannot get round `deals: deny` (gcal-cli's
28
+ * `WRITE_METHODS`, WC-PERM-22). A create or update that sets a stage is a move too.
24
29
  */
25
- export declare const commandKeysOf: (method: string, body?: Record<string, unknown>) => string[];
26
- /** The command keys a CRM write command checks beside its own: `.move` when its fields set a stage. */
27
- export declare const stageKeysOf: (noun: string, fields: Record<string, unknown>) => string[];
30
+ export declare const commandKeysOf: (method: string, body?: Body) => string[];
28
31
  /**
29
32
  * A method's default, as WC-PERM-22 has it, from an allow list: the reads `b24` makes and the CRM writes the command
30
33
  * keys govern are allowed, a delete and anything else asks, and the families that reach people are denied, reads too.
31
34
  */
32
- export declare const apiDefault: (method: string, effect?: Effect, body?: Record<string, unknown>) => Level;
35
+ export declare const apiDefault: (method: string, effect?: Effect, body?: Body) => Level;
33
36
  /** The built-in levels with this call's own key, which the static table cannot list for every method. */
34
- export declare const callDefaults: (method: string, effect: Effect, body: Record<string, unknown>, defaults: Readonly<Record<string, Level>>) => Record<string, Level>;
37
+ export declare const callDefaults: (method: string, effect: Effect, body: Body, defaults: Readonly<Record<string, Level>>) => Record<string, Level>;
35
38
  /**
36
- * The other way round: the `api.*` key a CRM write command's own request checks, so `api.crm.deal.update: deny` holds
37
- * on `deals update` too. Both the run and its `--dry-run` preview read it.
39
+ * The `api.*` key a deal's or lead's write sends its request under, so `api.crm.deal.update: deny` holds on `deals
40
+ * update` too: core's `CrmWrites.alsoChecks` and, through `crmAlsoChecks`, its `--dry-run`.
38
41
  */
42
+ export declare const crmApiKeys: (kind: DealKind, verb: CrmVerb) => string[];
43
+ /** The same for b24's own `people` and `organizations` writes, by command path. */
39
44
  export declare const apiKeysOf: (path: readonly string[]) => string[];
40
45
  /** The keys `permissions` may name for `api`: the known methods and the denied families. */
41
46
  export declare const API_KEYS: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"api-keys.d.ts","sourceRoot":"","sources":["../src/api-keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,KAAK,MAAM,EAA2B,MAAM,qBAAqB,CAAA;AAE1E,eAAO,MAAM,MAAM,WAAY,MAAM,KAAG,MAAyB,CAAA;AAEjE;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,UAoB3B,CAAA;AAQD,uHAAuH;AACvH,eAAO,MAAM,YAAY,QAAS,MAAM,KAAG,MAAkD,CAAA;AAE7F,6GAA6G;AAC7G,eAAO,MAAM,OAAO,WAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,MAAM,KAAG,OAIvE,CAAA;AAED,eAAO,MAAM,QAAQ,SAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAG9E,CAAA;AAED,qFAAqF;AACrF,eAAO,MAAM,UAAU,WAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,GAAG,SAGrE,CAAA;AAED,qGAAqG;AACrG,eAAO,MAAM,SAAS,SAAU,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,OAEoC,CAAA;AAgB9G;;;GAGG;AACH,eAAO,MAAM,aAAa,WAAY,MAAM,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAQ,MAAM,EAOxF,CAAA;AAED,uGAAuG;AACvG,eAAO,MAAM,WAAW,SAAU,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,EAGjF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,WACb,MAAM,WACN,MAAM,SACR,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,KAKF,CAAA;AAED,yGAAyG;AACzG,eAAO,MAAM,YAAY,WACf,MAAM,UACN,MAAM,QACR,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YACnB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,KACxC,MAAM,CAAC,MAAM,EAAE,KAAK,CAA0E,CAAA;AAIjG;;;GAGG;AACH,eAAO,MAAM,SAAS,SAAU,SAAS,MAAM,EAAE,KAAG,MAAM,EAKzD,CAAA;AAED,4FAA4F;AAC5F,eAAO,MAAM,QAAQ,UAAoF,CAAA;AAEzG,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAQ9C,CAAA"}
1
+ {"version":3,"file":"api-keys.d.ts","sourceRoot":"","sources":["../src/api-keys.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,KAAK,MAAM,EAA2B,MAAM,qBAAqB,CAAA;AAC1E,OAAO,EAAE,KAAK,IAAI,EAAkC,MAAM,WAAW,CAAA;AAErE,eAAO,MAAM,MAAM,WAAY,MAAM,KAAG,MAAyB,CAAA;AAEjE;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,UAoB3B,CAAA;AAQD,uHAAuH;AACvH,eAAO,MAAM,YAAY,QAAS,MAAM,KAAG,MAAkD,CAAA;AAE7F,qHAAqH;AACrH,eAAO,MAAM,OAAO,WAAY,IAAI,QAAQ,MAAM,KAAG,OAIpD,CAAA;AAED,eAAO,MAAM,QAAQ,SAAU,IAAI,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAG3D,CAAA;AAED,qFAAqF;AACrF,eAAO,MAAM,UAAU,WAAY,IAAI,KAAG,MAAM,GAAG,SAGlD,CAAA;AAED,qGAAqG;AACrG,eAAO,MAAM,SAAS,SAAU,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,OAEoC,CAAA;AAoB9G,oHAAoH;AACpH,eAAO,MAAM,SAAS,WAAY,MAAM,QAAQ,IAAI,KAAG,IAMtD,CAAA;AAoCD;;;GAGG;AACH,eAAO,MAAM,aAAa,WAAY,MAAM,SAAQ,IAAI,KAAQ,MAAM,EASrE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,WAAY,MAAM,WAAU,MAAM,SAAkC,IAAI,KAAQ,KAKtG,CAAA;AAED,yGAAyG;AACzG,eAAO,MAAM,YAAY,WACf,MAAM,UACN,MAAM,QACR,IAAI,YACA,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,KACxC,MAAM,CAAC,MAAM,EAAE,KAAK,CAA0E,CAAA;AAUjG;;;GAGG;AACH,eAAO,MAAM,UAAU,SAAU,QAAQ,QAAQ,OAAO,KAAG,MAAM,EAA8C,CAAA;AAI/G,mFAAmF;AACnF,eAAO,MAAM,SAAS,SAAU,SAAS,MAAM,EAAE,KAAG,MAAM,EAKzD,CAAA;AAED,4FAA4F;AAC5F,eAAO,MAAM,QAAQ,UAAoF,CAAA;AAEzG,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAQ9C,CAAA"}
package/dist/api-keys.js CHANGED
@@ -1,4 +1,6 @@
1
+ import { CliError } from "@wirecat/cli-base";
1
2
  import { KNOWN_METHODS, methodOf } from "./bitrix/methods.js";
3
+ import { foldCode, isRecord, jsonNumber } from "./body.js";
2
4
  export const apiKey = (method) => `api.${method}`;
3
5
  /**
4
6
  * Families whose writes reach people, publish, or start the portal's own automation: messages and notifications (im,
@@ -33,15 +35,15 @@ const READ_FAMILIES = ["crm", "catalog", "user", "profile", "methods", "method",
33
35
  const inFamily = (families, method) => families.some((family) => method === family || method.startsWith(`${family}.`));
34
36
  /** Bitrix24 takes a method in any letter case and with a `.json` suffix; one name keeps the keys from being dodged. */
35
37
  export const normalMethod = (raw) => raw.toLowerCase().replace(/\.json$/, "");
36
- /** A field in any letter case, with or without underscores: Bitrix24 takes both `stageId` and `STAGE_ID`. */
38
+ /** A field in any letter case, with or without underscores: `parseBody` has refused a body that spells one twice. */
37
39
  export const fieldOf = (record, name) => {
38
- const wanted = name.toLowerCase();
39
- const found = Object.keys(record).find((one) => one.replaceAll("_", "").toLowerCase() === wanted);
40
+ const wanted = foldCode(name);
41
+ const found = Object.keys(record).find((one) => foldCode(one) === wanted);
40
42
  return found === undefined ? undefined : record[found];
41
43
  };
42
44
  export const fieldsOf = (body) => {
43
45
  const fields = fieldOf(body, "fields");
44
- return typeof fields === "object" && fields !== null ? fields : {};
46
+ return isRecord(fields) ? fields : {};
45
47
  };
46
48
  /** The employee a write assigns the record to, by any spelling of `assignedById`. */
47
49
  export const assigneeOf = (fields) => {
@@ -55,34 +57,80 @@ const NOUNS = { deal: "deals", lead: "leads", contact: "people", company: "organ
55
57
  const ACTIONS = { add: "create", update: "update", delete: "delete" };
56
58
  /** `crm.item.*`'s `entityTypeId` for the four types the commands cover (apidocs "crm.item.add"). */
57
59
  const ENTITY_TYPES = { "1": "lead", "2": "deal", "3": "contact", "4": "company" };
58
- /** The CRM type and action a raw write does, whether named `crm.deal.update` or `crm.item.update` with its type id. */
59
- const crmWriteOf = (method, body) => {
60
- const named = /^crm\.(deal|lead|contact|company)\.(add|update|delete)$/.exec(method);
60
+ const refused = (message) => new CliError("validation_error", message, { param: "--body", reason: "body.invalid", sent: false });
61
+ /** `"02"`, `" 2"` or `"2.0"` would name no type here while the portal may read them as deals: only digits pass. */
62
+ const entityTypeOf = (body) => {
63
+ const given = fieldOf(body, "entityTypeId");
64
+ if (given === undefined)
65
+ return undefined;
66
+ const digits = jsonNumber(given) ?? (typeof given === "string" ? given : typeof given === "number" ? String(given) : "");
67
+ if (!/^(0|[1-9][0-9]*)$/.test(digits))
68
+ throw refused("entityTypeId takes the type's number, such as 2 for deals");
69
+ return digits;
70
+ };
71
+ /** What `api call` sends, checked once: the body `parseBody` gave, its `fields` an object and its type a number. */
72
+ export const checkCall = (method, body) => {
73
+ entityTypeOf(body);
74
+ const fields = fieldOf(body, "fields");
75
+ if (fields !== undefined && !isRecord(fields))
76
+ throw refused("fields takes a JSON object of field names and values");
77
+ if (/^crm\.item\.(add|update|delete|get|list|fields)$/.test(method) && fieldOf(body, "entityTypeId") === undefined)
78
+ throw refused(`${method} needs entityTypeId, the record type's number`);
79
+ };
80
+ const typeOf = (method, body) => {
81
+ const named = /^crm\.(deal|lead|contact|company)\.(.+)$/.exec(method);
61
82
  if (named?.[1] && named[2])
62
83
  return { type: named[1], action: named[2] };
63
- const item = /^crm\.item\.(add|update|delete)$/.exec(method);
64
- const type = ENTITY_TYPES[String(fieldOf(body, "entityTypeId"))];
84
+ const item = /^crm\.item\.(.+)$/.exec(method);
85
+ const type = ENTITY_TYPES[entityTypeOf(body) ?? ""];
65
86
  return item?.[1] && type ? { type, action: item[1] } : undefined;
66
87
  };
88
+ /** The CRM type and action a raw write does, whether named `crm.deal.update` or `crm.item.update` with its type id. */
89
+ const crmWriteOf = (method, body) => {
90
+ const found = typeOf(method, body);
91
+ return found && Object.hasOwn(ACTIONS, found.action) ? found : undefined;
92
+ };
93
+ /** The command a raw read reads the same as; any other read of a type, such as its product rows, is its list. */
94
+ const readKeysOf = (method, body) => {
95
+ const crm = typeOf(method, body);
96
+ if (crm) {
97
+ const noun = NOUNS[crm.type];
98
+ if (crm.action === "get")
99
+ return [`${noun}.show`];
100
+ return /^(fields$|field\.|userfield\.)/.test(crm.action) ? ["fields.list"] : [`${noun}.list`];
101
+ }
102
+ // `crm.item.productrow.*` names its record by ownerType in the filter, not entityTypeId (apidocs).
103
+ if (method.startsWith("crm.item.") && fieldOf(body, "entityTypeId") === undefined)
104
+ return Object.values(NOUNS).map((noun) => `${noun}.list`);
105
+ const product = /^(?:crm|catalog)\.product\.(.+)$/.exec(method);
106
+ if (product)
107
+ return [product[1] === "get" ? "products.show" : "products.list"];
108
+ // `users list` and `users show` both read through user.get.
109
+ if (method === "user.get" || method === "user.search")
110
+ return ["users.list", "users.show"];
111
+ if (method.startsWith("crm.category."))
112
+ return ["pipelines.list"];
113
+ if (method.startsWith("crm.status."))
114
+ return ["stages.list"];
115
+ return [];
116
+ };
67
117
  /**
68
- * The command keys a raw call does the same as, so `api call` cannot get round `deals.update: deny` (gcal-cli's
69
- * `WRITE_METHODS`). A create or update that sets a stage is a move too.
118
+ * The command keys a raw call does the same as, so `api call` cannot get round `deals: deny` (gcal-cli's
119
+ * `WRITE_METHODS`, WC-PERM-22). A create or update that sets a stage is a move too.
70
120
  */
71
121
  export const commandKeysOf = (method, body = {}) => {
122
+ if (methodOf(method).effect === "read")
123
+ return readKeysOf(method, body);
72
124
  const write = crmWriteOf(method, body);
73
125
  if (!write)
74
126
  return [];
75
127
  const noun = NOUNS[write.type];
76
128
  const keys = [`${noun}.${ACTIONS[write.action]}`];
129
+ // Without a lookup a stage may be a won or lost one, so both the move and the close key are checked.
77
130
  if (write.action !== "delete" && setsStage(write.type, fieldsOf(body)))
78
- keys.push(`${noun}.move`);
131
+ keys.push(`${noun}.move`, `${noun}.close`);
79
132
  return keys;
80
133
  };
81
- /** The command keys a CRM write command checks beside its own: `.move` when its fields set a stage. */
82
- export const stageKeysOf = (noun, fields) => {
83
- const type = Object.keys(NOUNS).find((one) => NOUNS[one] === noun) ?? "";
84
- return setsStage(type, fields) ? [`${noun}.move`] : [];
85
- };
86
134
  /**
87
135
  * A method's default, as WC-PERM-22 has it, from an allow list: the reads `b24` makes and the CRM writes the command
88
136
  * keys govern are allowed, a delete and anything else asks, and the families that reach people are denied, reads too.
@@ -98,15 +146,24 @@ export const apiDefault = (method, effect = methodOf(method).effect, body = {})
98
146
  };
99
147
  /** The built-in levels with this call's own key, which the static table cannot list for every method. */
100
148
  export const callDefaults = (method, effect, body, defaults) => ({ ...defaults, [apiKey(method)]: apiDefault(method, effect, body) });
101
- const METHODS_OF_COMMANDS = { create: "add", update: "update", move: "update" };
149
+ const METHODS = {
150
+ create: "add",
151
+ update: "update",
152
+ move: "update",
153
+ close: "update",
154
+ remove: "delete",
155
+ };
102
156
  /**
103
- * The other way round: the `api.*` key a CRM write command's own request checks, so `api.crm.deal.update: deny` holds
104
- * on `deals update` too. Both the run and its `--dry-run` preview read it.
157
+ * The `api.*` key a deal's or lead's write sends its request under, so `api.crm.deal.update: deny` holds on `deals
158
+ * update` too: core's `CrmWrites.alsoChecks` and, through `crmAlsoChecks`, its `--dry-run`.
105
159
  */
160
+ export const crmApiKeys = (kind, verb) => [apiKey(`crm.${kind}.${METHODS[verb]}`)];
161
+ const OWN_WRITES = { people: "contact", organizations: "company" };
162
+ /** The same for b24's own `people` and `organizations` writes, by command path. */
106
163
  export const apiKeysOf = (path) => {
107
164
  const [noun, command, ...rest] = path;
108
- const type = Object.keys(NOUNS).find((one) => NOUNS[one] === noun);
109
- const method = METHODS_OF_COMMANDS[command ?? ""];
165
+ const type = OWN_WRITES[noun ?? ""];
166
+ const method = command === "create" ? "add" : command === "update" ? "update" : undefined;
110
167
  return type && method && rest.length === 0 ? [apiKey(`crm.${type}.${method}`)] : [];
111
168
  };
112
169
  /** The keys `permissions` may name for `api`: the known methods and the denied families. */
@@ -1 +1 @@
1
- {"version":3,"file":"api-keys.js","sourceRoot":"","sources":["../src/api-keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-keys.js","sourceRoot":"","sources":["../src/api-keys.ts"],"names":[],"mappings":"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"}
package/dist/bin/b24.js CHANGED
@@ -9,7 +9,7 @@ if (
9
9
  (words[0] === "--version" || words[0] === "-V") &&
10
10
  !Object.keys(process.env).some((key) => key.endsWith("_TEST_ARGV_LOG"))
11
11
  ) {
12
- process.stdout.write("0.4.0\n")
12
+ process.stdout.write("0.5.0\n")
13
13
  } else {
14
14
  // Before the bundle compiles: the bundle's own call comes after its chunks.
15
15
  module.enableCompileCache()
@@ -28,7 +28,7 @@ if (
28
28
  : next(specifier, context),
29
29
  })
30
30
  }
31
- const chunks = ["../bundle/all-profiles-MBQZCOVK.js","../bundle/anthropic-QCYLKSJJ.js","../bundle/app-server-FSLZ2Y6N.js","../bundle/bun-UYRQXF33.js","../bundle/bun-sqlite-GXME7EMT.js","../bundle/decode-IF2F2SFC.js","../bundle/dist-6Y64DTOE.js","../bundle/echarts-WDDVEJO2.js","../bundle/embed-VDUGYEAR.js","../bundle/embedder-DUN62H3Z.js","../bundle/first-screen-QAVKP5RF.js","../bundle/instructions-JIIKWS7X.js","../bundle/mcp-33JX6KP4.js","../bundle/mcp-57EQ6QJO.js","../bundle/mcp-PFJER2DE.js","../bundle/node-K57WT42O.js","../bundle/node-P4E63KXA.js","../bundle/node-TLZSIHIJ.js","../bundle/node-sqlite-KS6ORRIG.js","../bundle/oauth-SLSANN37.js","../bundle/open-WJPHADEX.js","../bundle/openai-HXB3GTOD.js","../bundle/process-P73TFAXT.js","../bundle/program-7BMG5NIN.js","../bundle/prompt-WDPV37R4.js","../bundle/recognize-CXIFL6IV.js","../bundle/remote-Q4VJ4OQW.js","../bundle/rerank-SUFYK63I.js","../bundle/serve-B7PGFOC2.js","../bundle/server-4DBNJWW6.js","../bundle/server-OKE7SXJ2.js","../bundle/state-EZCCXQV7.js","../bundle/store-MZ7JBYR6.js","../bundle/store-maintenance-command-T5QZMENJ.js"]
31
+ const chunks = ["../bundle/all-profiles-CANIDIDS.js","../bundle/anthropic-JUJB4DCF.js","../bundle/app-server-3V5Z4PTK.js","../bundle/bun-LKMV5TY7.js","../bundle/bun-sqlite-S56EF74S.js","../bundle/decode-QSTBX4MG.js","../bundle/dist-6Y64DTOE.js","../bundle/echarts-JZELFH2N.js","../bundle/embed-4RIW2LVH.js","../bundle/embedder-SW7DTWSL.js","../bundle/first-screen-NMHNFZ2B.js","../bundle/instructions-BZE5YUGG.js","../bundle/mcp-SDWHDJTY.js","../bundle/node-KM3CUABH.js","../bundle/node-LTKZIO4U.js","../bundle/node-TLZSIHIJ.js","../bundle/node-sqlite-HQ5PN2RH.js","../bundle/oauth-UH6FOZQL.js","../bundle/open-TSUP3XGL.js","../bundle/openai-GVEE52E3.js","../bundle/process-AGXY76ZE.js","../bundle/program-BI4A4HFJ.js","../bundle/prompt-NRSUY7FA.js","../bundle/recognize-NPDPQ6PJ.js","../bundle/remote-HFASMVLB.js","../bundle/rerank-TL6Z6F7K.js","../bundle/serve-VB4DHDZQ.js","../bundle/server-T5EDRPJI.js","../bundle/server-Z6MW6C37.js","../bundle/source-4IGO5J7E.js","../bundle/sqlite-runtime-YS4POY3W.js","../bundle/state-ISZVVZGR.js","../bundle/store-IZJBAKJV.js","../bundle/store-L76MSQC3.js","../bundle/store-PBTIB7BD.js","../bundle/store-maintenance-command-YFKII7TF.js","../bundle/writer-3O5EYMFE.js"]
32
32
  if (((words) => words
33
33
  .filter((word) => !word.startsWith("-"))
34
34
  .slice(0, 2)
@@ -65,7 +65,7 @@ export const bitrixError = (method, status, body, { now = Date.now(), waitMs } =
65
65
  if (code && NOT_FOUND.has(code))
66
66
  return as("not_found", `${method}: Bitrix24 has no such record${named}`);
67
67
  if (code === "BITRIX_REST_V3_EXCEPTION_IDEMPOTENCYKEYREUSEDEXCEPTION")
68
- return as("conflict", `${method}: this --operation-id was already used for a different request; leave it out for a new write`, { reason: "operation.reused" });
68
+ return as("conflict", `${method}: Bitrix24 refused this write's operation id as already used for a different request`, { reason: "operation.reused" });
69
69
  const fields = fieldsOf(body);
70
70
  if (status === 400 || code?.startsWith("BITRIX_REST_V3_EXCEPTION_"))
71
71
  return as("validation_error", `Bitrix24 refused ${method}${named}${fields.length ? `; check ${fields.join(", ")}` : ""}`, fields.length ? { fields } : {});
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/bitrix/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/bitrix/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAwC,MAAM,mBAAmB,CAAA;AAClF,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAEtE,4FAA4F;AAC5F,MAAM,mBAAmB,GAAG,KAAK,CAAA;AACjC,sGAAsG;AACtG,MAAM,iBAAiB,GAAG,MAAM,CAAA;AAEhC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,qBAAqB,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC,CAAA;AACtH,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,oBAAoB,EAAE,qDAAqD,CAAC,CAAC,CAAA;AACpG,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,mBAAmB,EAAE,gDAAgD,CAAC,CAAC,CAAA;AAChH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,kDAAkD,CAAC,CAAC,CAAA;AAS5F,MAAM,IAAI,GAAG,uBAAuB,CAAA;AAEpC,8GAA8G;AAC9G,MAAM,MAAM,GAAG,CAAC,IAA+B,EAAsB,EAAE;IACrE,MAAM,GAAG,GAAG,OAAO,IAAI,EAAE,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAA;IAClG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC,WAAW,EAAE,CAAA;IACvE,sEAAsE;IACtE,IAAI,GAAG,KAAK,EAAE,IAAI,OAAO,IAAI,EAAE,iBAAiB,KAAK,QAAQ,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;QACjH,OAAO,WAAW,CAAA;IACpB,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,CAAC,IAA+B,EAAY,EAAE;IAC7D,MAAM,UAAU,GAAG,OAAO,IAAI,EAAE,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAA;IAC7G,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAA;IACzC,OAAO,UAAU;SACd,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAE,GAA2B,EAAE,KAAK,CAAC;SACjD,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;AAC1G,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,CAAC,IAA+B,EAAE,GAAW,EAAE,EAAE;IACvE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAA;IACpD,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,iBAAiB,CAAA;AAC9F,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,MAAc,EACd,MAAc,EACd,IAA+B,EAC/B,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,GAAkD,EAAE,EACtE,EAAE;IACZ,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;IACzB,MAAM,OAAO,GAAoB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;IACzG,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IACtC,MAAM,EAAE,GAAG,CAAC,SAAoB,EAAE,OAAe,EAAE,IAAI,GAAoB,EAAE,EAAE,EAAE,CAC/E,IAAI,QAAQ,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC,CAAA;IAE3D,IAAI,IAAI,KAAK,sBAAsB;QACjC,OAAO,EAAE,CAAC,cAAc,EAAE,qCAAqC,MAAM,yCAAyC,EAAE;YAC9G,cAAc,EAAE,MAAM,IAAI,mBAAmB;YAC7C,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;IACJ,IAAI,IAAI,KAAK,sBAAsB;QACjC,OAAO,EAAE,CAAC,cAAc,EAAE,kBAAkB,MAAM,4DAA4D,EAAE;YAC9G,cAAc,EAAE,MAAM,IAAI,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC;YACpD,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;IACJ,IAAI,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QACzB,OAAO,EAAE,CAAC,kBAAkB,EAAE,iCAAiC,MAAM,GAAG,KAAK,sBAAsB,EAAE;YACnG,MAAM,EAAE,uBAAuB;SAChC,CAAC,CAAA;IACJ,IAAI,IAAI,KAAK,gBAAgB;QAAE,OAAO,EAAE,CAAC,sBAAsB,EAAE,kCAAkC,CAAC,CAAA;IACpG,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,MAAM,KAAK,GAAG;QAC9C,OAAO,EAAE,CAAC,kBAAkB,EAAE,iCAAiC,MAAM,GAAG,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC,CAAA;IACtH,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,MAAM,KAAK,GAAG;QAC/C,OAAO,EAAE,CACP,sBAAsB,EACtB,gCAAgC,KAAK,0DAA0D,EAC/F,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAC9B,CAAA;IACH,IAAI,IAAI,KAAK,wBAAwB;QACnC,OAAO,EAAE,CACP,WAAW,EACX,0BAA0B,MAAM,+DAA+D,EAC/F,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAC7B,CAAA;IACH,IAAI,IAAI,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC,WAAW,EAAE,GAAG,MAAM,gCAAgC,KAAK,EAAE,CAAC,CAAA;IACzG,IAAI,IAAI,KAAK,wDAAwD;QACnE,OAAO,EAAE,CACP,UAAU,EACV,GAAG,MAAM,sFAAsF,EAC/F,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAC/B,CAAA;IACH,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC7B,IAAI,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,UAAU,CAAC,2BAA2B,CAAC;QACjE,OAAO,EAAE,CACP,kBAAkB,EAClB,oBAAoB,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAC1F,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAChC,CAAA;IACH,IAAI,MAAM,IAAI,GAAG;QACf,OAAO,EAAE,CAAC,sBAAsB,EAAE,sBAAsB,MAAM,GAAG,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACnH,OAAO,EAAE,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE,oBAAoB,MAAM,GAAG,KAAK,EAAE,CAAC,CAAA;AAC1G,CAAC,CAAA"}
@@ -16,7 +16,7 @@ export interface BitrixTransportOptions {
16
16
  random?: () => number;
17
17
  }
18
18
  export interface CallOptions {
19
- /** A write's operation id, sent as REST 3.0's `Idempotency-Key`, so the owner can repeat it by hand. */
19
+ /** A write's operation id, sent as REST 3.0's `Idempotency-Key`; a live portal still did a repeat again. */
20
20
  idempotencyKey?: string;
21
21
  }
22
22
  /** REST 2 lists carry `total` and `next` beside `result`; REST 3.0 answers carry neither. */
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/bitrix/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EAEf,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAA2B,KAAK,SAAS,EAAkC,MAAM,uBAAuB,CAAA;AAC/G,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAGpD,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAQtD,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE7E,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,uGAAuG;IACvG,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,wGAAwG;IACxG,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,6FAA6F;AAC7F,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;GAMG;AACH,qBAAa,eAAe;;IAW1B,YAAY,OAAO,EAAE,sBAAsB,EAU1C;IAED,wCAAwC;IACxC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;;OAIG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAqBjH;CA0HF"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/bitrix/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EAEf,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAA2B,KAAK,SAAS,EAAkC,MAAM,uBAAuB,CAAA;AAC/G,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAGpD,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAYtD,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE7E,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,uGAAuG;IACvG,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,4GAA4G;IAC5G,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,6FAA6F;AAC7F,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;GAMG;AACH,qBAAa,eAAe;;IAW1B,YAAY,OAAO,EAAE,sBAAsB,EAU1C;IAED,wCAAwC;IACxC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;;OAIG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAqBjH;CAoIF"}
@@ -4,7 +4,11 @@ import { apiJson, currentAttempt, providerEvent, providerRequest } from "@wireca
4
4
  import { bitrixError } from "./errors.js";
5
5
  import { methodOf } from "./methods.js";
6
6
  import { methodUrl } from "./webhook.js";
7
- const DEFAULT_TIMEOUT_MS = 30_000;
7
+ /**
8
+ * A third of a one-shot command's 30 s deadline (cli-core `DEFAULT_COMMAND_MS`), so a read that timed out can still be
9
+ * tried again before the command ends. cli-core does not hand the run's remaining time to a transport.
10
+ */
11
+ const DEFAULT_TIMEOUT_MS = 10_000;
8
12
  const LARGEST_ANSWER = 16 * 1024 * 1024;
9
13
  const RETRY = { retries: 3, baseDelayMs: 1_000, maxDelayMs: 10_000, maxRetryAfterMs: 30_000 };
10
14
  /** A pace wait longer than this ends the run instead of sitting in it, as cli-core's messenger pacing does. */
@@ -142,7 +146,7 @@ export class BitrixTransport {
142
146
  }
143
147
  end({ status: response.status, errorCode: "invalid_response" });
144
148
  if (!response.ok)
145
- throw bitrixError(method, response.status, undefined);
149
+ throw this.#refused(method, bitrixError(method, response.status, undefined), run.reads);
146
150
  throw new CliError("invalid_response", `Bitrix24 answered ${method} with something that is not JSON`, {
147
151
  operation: method,
148
152
  status: response.status,
@@ -159,7 +163,7 @@ export class BitrixTransport {
159
163
  errorCode: refusal.code,
160
164
  providerError: String(refusal.details.provider_error ?? ""),
161
165
  });
162
- throw refusal;
166
+ throw this.#refused(method, refusal, run.reads);
163
167
  }
164
168
  end({ status: response.status });
165
169
  return {
@@ -172,12 +176,22 @@ export class BitrixTransport {
172
176
  clearTimeout(timer);
173
177
  }
174
178
  }
179
+ /** A gateway or server failure may come after a write was made; only a refusal says it was not. */
180
+ #refused(method, refusal, reads) {
181
+ if (reads || refusal.code !== "provider_unavailable")
182
+ return refusal;
183
+ return new CliError("outcome_unknown", `Bitrix24 failed on ${method}; it may or may not have carried it out`, {
184
+ ...refusal.details,
185
+ retryable: false,
186
+ });
187
+ }
175
188
  #unanswered(method, error, run) {
176
- if (this.#signal?.aborted && this.#signal.reason?.name !== "TimeoutError")
177
- return new CliError("cancelled", `${method} was cancelled`, { operation: method });
178
- // A keyed write's caller names how to repeat it; a REST 2 write has no key to repeat it safely with.
189
+ // A cut write may have reached the portal: never "cancelled", which a caller would repeat (WC-LIFE-9). A keyed
190
+ // write's caller names how to repeat it; a REST 2 write has no key to repeat it safely with.
179
191
  if (!run.reads)
180
192
  return new CliError("outcome_unknown", `${method} got no answer; Bitrix24 may or may not have carried it out${run.key ? "" : " — check before repeating it"}`, { operation: method, retryable: false });
193
+ if (this.#signal?.aborted && this.#signal.reason?.name !== "TimeoutError")
194
+ return new CliError("cancelled", `${method} was cancelled`, { operation: method });
181
195
  const timedOut = error?.name === "TimeoutError";
182
196
  return new CliError(timedOut ? "timeout" : "network_error", timedOut ? `${method} got no answer within ${this.#timeoutMs} ms` : `${method} could not reach Bitrix24`, { operation: method, retryable: true });
183
197
  }