charness 3.6.1 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (578) hide show
  1. package/CHANGELOG.md +267 -0
  2. package/DEVELOPMENT.md +31 -5
  3. package/MIGRATION_RENAME_TO_CHARNESS.md +3 -2
  4. package/README.md +84 -782
  5. package/SETUP.md +37 -10
  6. package/agent-plugin/.claude-plugin/plugin.json +7 -0
  7. package/agent-plugin/README.md +35 -0
  8. package/agent-plugin/skills/charness-delegate-claude/SKILL.md +85 -0
  9. package/agent-plugin/skills/charness-delegate-claude/summarize-events.py +90 -0
  10. package/agent-plugin/skills/charness-delegate-opencode/SKILL.md +68 -0
  11. package/agent-plugin/skills/charness-manager/SKILL.md +152 -0
  12. package/dist/adapters/adapterNames.d.ts +6 -0
  13. package/dist/adapters/adapterNames.d.ts.map +1 -1
  14. package/dist/adapters/adapterNames.js +8 -2
  15. package/dist/adapters/adapterNames.js.map +1 -1
  16. package/dist/adapters/claudeCliAdapter.d.ts +8 -0
  17. package/dist/adapters/claudeCliAdapter.d.ts.map +1 -1
  18. package/dist/adapters/claudeCliAdapter.js +42 -5
  19. package/dist/adapters/claudeCliAdapter.js.map +1 -1
  20. package/dist/adapters/claudeJsonStreamAdapter.d.ts +10 -9
  21. package/dist/adapters/claudeJsonStreamAdapter.d.ts.map +1 -1
  22. package/dist/adapters/claudeJsonStreamAdapter.js +53 -55
  23. package/dist/adapters/claudeJsonStreamAdapter.js.map +1 -1
  24. package/dist/adapters/createAdapter.d.ts +8 -0
  25. package/dist/adapters/createAdapter.d.ts.map +1 -1
  26. package/dist/adapters/createAdapter.js +14 -2
  27. package/dist/adapters/createAdapter.js.map +1 -1
  28. package/dist/adapters/openCodeAdapter.d.ts +43 -6
  29. package/dist/adapters/openCodeAdapter.d.ts.map +1 -1
  30. package/dist/adapters/openCodeAdapter.js +95 -6
  31. package/dist/adapters/openCodeAdapter.js.map +1 -1
  32. package/dist/agentLogin/agentLogin.d.ts +1 -1
  33. package/dist/agentLogin/agentLogin.d.ts.map +1 -1
  34. package/dist/apiRetryKick.d.ts +4 -3
  35. package/dist/apiRetryKick.d.ts.map +1 -1
  36. package/dist/apiRetryKick.js +16 -9
  37. package/dist/apiRetryKick.js.map +1 -1
  38. package/dist/bot.d.ts.map +1 -1
  39. package/dist/bot.js +1313 -381
  40. package/dist/bot.js.map +1 -1
  41. package/dist/cli/claudeProfiles.d.ts +11 -6
  42. package/dist/cli/claudeProfiles.d.ts.map +1 -1
  43. package/dist/cli/claudeProfiles.js +50 -22
  44. package/dist/cli/claudeProfiles.js.map +1 -1
  45. package/dist/cli/hot.d.ts +5 -0
  46. package/dist/cli/hot.d.ts.map +1 -1
  47. package/dist/cli/hot.js +71 -25
  48. package/dist/cli/hot.js.map +1 -1
  49. package/dist/cli/tscWatchGuard.d.ts +95 -0
  50. package/dist/cli/tscWatchGuard.d.ts.map +1 -0
  51. package/dist/cli/tscWatchGuard.js +295 -0
  52. package/dist/cli/tscWatchGuard.js.map +1 -0
  53. package/dist/cli.js +12 -1
  54. package/dist/cli.js.map +1 -1
  55. package/dist/connectors/jira/answerSink.d.ts +10 -0
  56. package/dist/connectors/jira/answerSink.d.ts.map +1 -1
  57. package/dist/connectors/jira/answerSink.js +13 -0
  58. package/dist/connectors/jira/answerSink.js.map +1 -1
  59. package/dist/connectors/jira/config.d.ts +2 -0
  60. package/dist/connectors/jira/config.d.ts.map +1 -1
  61. package/dist/connectors/jira/config.js +9 -1
  62. package/dist/connectors/jira/config.js.map +1 -1
  63. package/dist/connectors/jira/connector.d.ts +11 -1
  64. package/dist/connectors/jira/connector.d.ts.map +1 -1
  65. package/dist/connectors/jira/connector.js +7 -0
  66. package/dist/connectors/jira/connector.js.map +1 -1
  67. package/dist/connectors/jira/inbound.d.ts +27 -4
  68. package/dist/connectors/jira/inbound.d.ts.map +1 -1
  69. package/dist/connectors/jira/inbound.js +69 -8
  70. package/dist/connectors/jira/inbound.js.map +1 -1
  71. package/dist/connectors/jira/issueBlocks.d.ts +5 -0
  72. package/dist/connectors/jira/issueBlocks.d.ts.map +1 -1
  73. package/dist/connectors/jira/issueBlocks.js +11 -0
  74. package/dist/connectors/jira/issueBlocks.js.map +1 -1
  75. package/dist/connectors/telegram/bindPicker.d.ts +5 -0
  76. package/dist/connectors/telegram/bindPicker.d.ts.map +1 -1
  77. package/dist/connectors/telegram/bindPicker.js +18 -1
  78. package/dist/connectors/telegram/bindPicker.js.map +1 -1
  79. package/dist/connectors/telegram/bindPickerClaims.d.ts +46 -0
  80. package/dist/connectors/telegram/bindPickerClaims.d.ts.map +1 -0
  81. package/dist/connectors/telegram/bindPickerClaims.js +83 -0
  82. package/dist/connectors/telegram/bindPickerClaims.js.map +1 -0
  83. package/dist/connectors/telegram/bindSweep.d.ts +32 -0
  84. package/dist/connectors/telegram/bindSweep.d.ts.map +1 -0
  85. package/dist/connectors/telegram/bindSweep.js +47 -0
  86. package/dist/connectors/telegram/bindSweep.js.map +1 -0
  87. package/dist/connectors/telegram/bindingWelcome.d.ts +23 -0
  88. package/dist/connectors/telegram/bindingWelcome.d.ts.map +1 -0
  89. package/dist/connectors/telegram/bindingWelcome.js +26 -0
  90. package/dist/connectors/telegram/bindingWelcome.js.map +1 -0
  91. package/dist/connectors/telegram/botApiConnection.d.ts +74 -0
  92. package/dist/connectors/telegram/botApiConnection.d.ts.map +1 -0
  93. package/dist/connectors/telegram/botApiConnection.js +201 -0
  94. package/dist/connectors/telegram/botApiConnection.js.map +1 -0
  95. package/dist/connectors/telegram/commands/botCore.d.ts +8 -2
  96. package/dist/connectors/telegram/commands/botCore.d.ts.map +1 -1
  97. package/dist/connectors/telegram/commands/botSkills.d.ts +21 -0
  98. package/dist/connectors/telegram/commands/botSkills.d.ts.map +1 -0
  99. package/dist/connectors/telegram/commands/botSkills.js +133 -0
  100. package/dist/connectors/telegram/commands/botSkills.js.map +1 -0
  101. package/dist/connectors/telegram/commands/callbackMessage.d.ts +5 -0
  102. package/dist/connectors/telegram/commands/callbackMessage.d.ts.map +1 -1
  103. package/dist/connectors/telegram/commands/callbackMessage.js +9 -0
  104. package/dist/connectors/telegram/commands/callbackMessage.js.map +1 -1
  105. package/dist/connectors/telegram/commands/compaction.d.ts +65 -3
  106. package/dist/connectors/telegram/commands/compaction.d.ts.map +1 -1
  107. package/dist/connectors/telegram/commands/compaction.js +512 -94
  108. package/dist/connectors/telegram/commands/compaction.js.map +1 -1
  109. package/dist/connectors/telegram/commands/displayModes.d.ts +1 -1
  110. package/dist/connectors/telegram/commands/displayModes.d.ts.map +1 -1
  111. package/dist/connectors/telegram/commands/displayModes.js +6 -18
  112. package/dist/connectors/telegram/commands/displayModes.js.map +1 -1
  113. package/dist/connectors/telegram/commands/fallbackChain.js +5 -5
  114. package/dist/connectors/telegram/commands/fallbackChain.js.map +1 -1
  115. package/dist/connectors/telegram/commands/reminders.d.ts +1 -1
  116. package/dist/connectors/telegram/commands/reminders.d.ts.map +1 -1
  117. package/dist/connectors/telegram/commands/reminders.js +4 -15
  118. package/dist/connectors/telegram/commands/reminders.js.map +1 -1
  119. package/dist/connectors/telegram/commands/selfUpdate.d.ts.map +1 -1
  120. package/dist/connectors/telegram/commands/selfUpdate.js +1 -11
  121. package/dist/connectors/telegram/commands/selfUpdate.js.map +1 -1
  122. package/dist/connectors/telegram/commands/taskAgents.d.ts +22 -0
  123. package/dist/connectors/telegram/commands/taskAgents.d.ts.map +1 -0
  124. package/dist/connectors/telegram/commands/taskAgents.js +104 -0
  125. package/dist/connectors/telegram/commands/taskAgents.js.map +1 -0
  126. package/dist/connectors/telegram/commands/todo.d.ts +82 -0
  127. package/dist/connectors/telegram/commands/todo.d.ts.map +1 -0
  128. package/dist/connectors/telegram/commands/todo.js +384 -0
  129. package/dist/connectors/telegram/commands/todo.js.map +1 -0
  130. package/dist/connectors/telegram/commands/topicCommand.d.ts +6 -2
  131. package/dist/connectors/telegram/commands/topicCommand.d.ts.map +1 -1
  132. package/dist/connectors/telegram/commands/topicCommand.js +6 -9
  133. package/dist/connectors/telegram/commands/topicCommand.js.map +1 -1
  134. package/dist/connectors/telegram/openBindMessages.d.ts +45 -0
  135. package/dist/connectors/telegram/openBindMessages.d.ts.map +1 -0
  136. package/dist/connectors/telegram/openBindMessages.js +67 -0
  137. package/dist/connectors/telegram/openBindMessages.js.map +1 -0
  138. package/dist/connectors/telegram/outputFlushPlan.d.ts +49 -0
  139. package/dist/connectors/telegram/outputFlushPlan.d.ts.map +1 -1
  140. package/dist/connectors/telegram/outputFlushPlan.js +46 -0
  141. package/dist/connectors/telegram/outputFlushPlan.js.map +1 -1
  142. package/dist/connectors/telegram/pendingTopicName.d.ts +26 -0
  143. package/dist/connectors/telegram/pendingTopicName.d.ts.map +1 -0
  144. package/dist/connectors/telegram/pendingTopicName.js +27 -0
  145. package/dist/connectors/telegram/pendingTopicName.js.map +1 -0
  146. package/dist/connectors/test/connector.d.ts.map +1 -1
  147. package/dist/connectors/test/connector.js +6 -1
  148. package/dist/connectors/test/connector.js.map +1 -1
  149. package/dist/i18n/de.d.ts.map +1 -1
  150. package/dist/i18n/de.js +90 -7
  151. package/dist/i18n/de.js.map +1 -1
  152. package/dist/i18n/en.d.ts.map +1 -1
  153. package/dist/i18n/en.js +90 -7
  154. package/dist/i18n/en.js.map +1 -1
  155. package/dist/i18n/es.d.ts.map +1 -1
  156. package/dist/i18n/es.js +90 -7
  157. package/dist/i18n/es.js.map +1 -1
  158. package/dist/i18n/fr.d.ts.map +1 -1
  159. package/dist/i18n/fr.js +90 -7
  160. package/dist/i18n/fr.js.map +1 -1
  161. package/dist/i18n/hi.d.ts.map +1 -1
  162. package/dist/i18n/hi.js +90 -7
  163. package/dist/i18n/hi.js.map +1 -1
  164. package/dist/i18n/ja.d.ts.map +1 -1
  165. package/dist/i18n/ja.js +90 -7
  166. package/dist/i18n/ja.js.map +1 -1
  167. package/dist/i18n/ka.d.ts.map +1 -1
  168. package/dist/i18n/ka.js +90 -7
  169. package/dist/i18n/ka.js.map +1 -1
  170. package/dist/i18n/pt.d.ts.map +1 -1
  171. package/dist/i18n/pt.js +90 -7
  172. package/dist/i18n/pt.js.map +1 -1
  173. package/dist/i18n/ru.d.ts.map +1 -1
  174. package/dist/i18n/ru.js +90 -7
  175. package/dist/i18n/ru.js.map +1 -1
  176. package/dist/i18n/uk.d.ts.map +1 -1
  177. package/dist/i18n/uk.js +90 -7
  178. package/dist/i18n/uk.js.map +1 -1
  179. package/dist/i18n/uz.d.ts.map +1 -1
  180. package/dist/i18n/uz.js +90 -7
  181. package/dist/i18n/uz.js.map +1 -1
  182. package/dist/i18n/zh.d.ts.map +1 -1
  183. package/dist/i18n/zh.js +90 -7
  184. package/dist/i18n/zh.js.map +1 -1
  185. package/dist/i18n.d.ts +1 -1
  186. package/dist/i18n.js +1 -1
  187. package/dist/installManager.d.ts +13 -0
  188. package/dist/installManager.d.ts.map +1 -1
  189. package/dist/installManager.js +38 -4
  190. package/dist/installManager.js.map +1 -1
  191. package/dist/instanceSettings.d.ts +40 -1
  192. package/dist/instanceSettings.d.ts.map +1 -1
  193. package/dist/instanceSettings.js +105 -26
  194. package/dist/instanceSettings.js.map +1 -1
  195. package/dist/openCodeQuestionFlow.d.ts +30 -0
  196. package/dist/openCodeQuestionFlow.d.ts.map +1 -1
  197. package/dist/openCodeQuestionFlow.js +43 -0
  198. package/dist/openCodeQuestionFlow.js.map +1 -1
  199. package/dist/postToSession.d.ts +20 -5
  200. package/dist/postToSession.d.ts.map +1 -1
  201. package/dist/postToSession.js +38 -7
  202. package/dist/postToSession.js.map +1 -1
  203. package/dist/remoteRun/cliArgs.d.ts +73 -0
  204. package/dist/remoteRun/cliArgs.d.ts.map +1 -0
  205. package/dist/remoteRun/cliArgs.js +197 -0
  206. package/dist/remoteRun/cliArgs.js.map +1 -0
  207. package/dist/remoteRun/commands.d.ts +56 -0
  208. package/dist/remoteRun/commands.d.ts.map +1 -0
  209. package/dist/remoteRun/commands.js +306 -0
  210. package/dist/remoteRun/commands.js.map +1 -0
  211. package/dist/remoteRun/depsPlan.d.ts +16 -0
  212. package/dist/remoteRun/depsPlan.d.ts.map +1 -0
  213. package/dist/remoteRun/depsPlan.js +82 -0
  214. package/dist/remoteRun/depsPlan.js.map +1 -0
  215. package/dist/remoteRun/exitCodes.d.ts +34 -0
  216. package/dist/remoteRun/exitCodes.d.ts.map +1 -0
  217. package/dist/remoteRun/exitCodes.js +38 -0
  218. package/dist/remoteRun/exitCodes.js.map +1 -0
  219. package/dist/remoteRun/foreground.d.ts +29 -0
  220. package/dist/remoteRun/foreground.d.ts.map +1 -0
  221. package/dist/remoteRun/foreground.js +159 -0
  222. package/dist/remoteRun/foreground.js.map +1 -0
  223. package/dist/remoteRun/interrupts.d.ts +17 -0
  224. package/dist/remoteRun/interrupts.d.ts.map +1 -0
  225. package/dist/remoteRun/interrupts.js +41 -0
  226. package/dist/remoteRun/interrupts.js.map +1 -0
  227. package/dist/remoteRun/jobFiles.d.ts +31 -0
  228. package/dist/remoteRun/jobFiles.d.ts.map +1 -0
  229. package/dist/remoteRun/jobFiles.js +84 -0
  230. package/dist/remoteRun/jobFiles.js.map +1 -0
  231. package/dist/remoteRun/jobFormat.d.ts +16 -0
  232. package/dist/remoteRun/jobFormat.d.ts.map +1 -0
  233. package/dist/remoteRun/jobFormat.js +130 -0
  234. package/dist/remoteRun/jobFormat.js.map +1 -0
  235. package/dist/remoteRun/jobId.d.ts +15 -0
  236. package/dist/remoteRun/jobId.d.ts.map +1 -0
  237. package/dist/remoteRun/jobId.js +85 -0
  238. package/dist/remoteRun/jobId.js.map +1 -0
  239. package/dist/remoteRun/jobMeta.d.ts +18 -0
  240. package/dist/remoteRun/jobMeta.d.ts.map +1 -0
  241. package/dist/remoteRun/jobMeta.js +33 -0
  242. package/dist/remoteRun/jobMeta.js.map +1 -0
  243. package/dist/remoteRun/jobQuery.d.ts +12 -0
  244. package/dist/remoteRun/jobQuery.d.ts.map +1 -0
  245. package/dist/remoteRun/jobQuery.js +22 -0
  246. package/dist/remoteRun/jobQuery.js.map +1 -0
  247. package/dist/remoteRun/jobRecords.d.ts +22 -0
  248. package/dist/remoteRun/jobRecords.d.ts.map +1 -0
  249. package/dist/remoteRun/jobRecords.js +145 -0
  250. package/dist/remoteRun/jobRecords.js.map +1 -0
  251. package/dist/remoteRun/jobState.d.ts +62 -0
  252. package/dist/remoteRun/jobState.d.ts.map +1 -0
  253. package/dist/remoteRun/jobState.js +132 -0
  254. package/dist/remoteRun/jobState.js.map +1 -0
  255. package/dist/remoteRun/leaseTiming.d.ts +18 -0
  256. package/dist/remoteRun/leaseTiming.d.ts.map +1 -0
  257. package/dist/remoteRun/leaseTiming.js +43 -0
  258. package/dist/remoteRun/leaseTiming.js.map +1 -0
  259. package/dist/remoteRun/output.d.ts +35 -0
  260. package/dist/remoteRun/output.d.ts.map +1 -0
  261. package/dist/remoteRun/output.js +82 -0
  262. package/dist/remoteRun/output.js.map +1 -0
  263. package/dist/remoteRun/pathPatterns.d.ts +33 -0
  264. package/dist/remoteRun/pathPatterns.d.ts.map +1 -0
  265. package/dist/remoteRun/pathPatterns.js +115 -0
  266. package/dist/remoteRun/pathPatterns.js.map +1 -0
  267. package/dist/remoteRun/probe.d.ts +56 -0
  268. package/dist/remoteRun/probe.d.ts.map +1 -0
  269. package/dist/remoteRun/probe.js +123 -0
  270. package/dist/remoteRun/probe.js.map +1 -0
  271. package/dist/remoteRun/project.d.ts +26 -0
  272. package/dist/remoteRun/project.d.ts.map +1 -0
  273. package/dist/remoteRun/project.js +159 -0
  274. package/dist/remoteRun/project.js.map +1 -0
  275. package/dist/remoteRun/projectConfig.d.ts +38 -0
  276. package/dist/remoteRun/projectConfig.d.ts.map +1 -0
  277. package/dist/remoteRun/projectConfig.js +87 -0
  278. package/dist/remoteRun/projectConfig.js.map +1 -0
  279. package/dist/remoteRun/remoteRunCli.d.ts +15 -0
  280. package/dist/remoteRun/remoteRunCli.d.ts.map +1 -0
  281. package/dist/remoteRun/remoteRunCli.js +144 -0
  282. package/dist/remoteRun/remoteRunCli.js.map +1 -0
  283. package/dist/remoteRun/remoteRunError.d.ts +14 -0
  284. package/dist/remoteRun/remoteRunError.d.ts.map +1 -0
  285. package/dist/remoteRun/remoteRunError.js +28 -0
  286. package/dist/remoteRun/remoteRunError.js.map +1 -0
  287. package/dist/remoteRun/rsync.d.ts +17 -0
  288. package/dist/remoteRun/rsync.d.ts.map +1 -0
  289. package/dist/remoteRun/rsync.js +39 -0
  290. package/dist/remoteRun/rsync.js.map +1 -0
  291. package/dist/remoteRun/runnerClient.d.ts +50 -0
  292. package/dist/remoteRun/runnerClient.d.ts.map +1 -0
  293. package/dist/remoteRun/runnerClient.js +139 -0
  294. package/dist/remoteRun/runnerClient.js.map +1 -0
  295. package/dist/remoteRun/runners.d.ts +57 -0
  296. package/dist/remoteRun/runners.d.ts.map +1 -0
  297. package/dist/remoteRun/runners.js +181 -0
  298. package/dist/remoteRun/runners.js.map +1 -0
  299. package/dist/remoteRun/runnersConfig.d.ts +44 -0
  300. package/dist/remoteRun/runnersConfig.d.ts.map +1 -0
  301. package/dist/remoteRun/runnersConfig.js +107 -0
  302. package/dist/remoteRun/runnersConfig.js.map +1 -0
  303. package/dist/remoteRun/safeCopy.d.ts +31 -0
  304. package/dist/remoteRun/safeCopy.d.ts.map +1 -0
  305. package/dist/remoteRun/safeCopy.js +137 -0
  306. package/dist/remoteRun/safeCopy.js.map +1 -0
  307. package/dist/remoteRun/sendPlan.d.ts +67 -0
  308. package/dist/remoteRun/sendPlan.d.ts.map +1 -0
  309. package/dist/remoteRun/sendPlan.js +139 -0
  310. package/dist/remoteRun/sendPlan.js.map +1 -0
  311. package/dist/remoteRun/ssh.d.ts +62 -0
  312. package/dist/remoteRun/ssh.d.ts.map +1 -0
  313. package/dist/remoteRun/ssh.js +202 -0
  314. package/dist/remoteRun/ssh.js.map +1 -0
  315. package/dist/remoteRun/submit.d.ts +29 -0
  316. package/dist/remoteRun/submit.d.ts.map +1 -0
  317. package/dist/remoteRun/submit.js +142 -0
  318. package/dist/remoteRun/submit.js.map +1 -0
  319. package/dist/requests/answerRequest.d.ts +5 -0
  320. package/dist/requests/answerRequest.d.ts.map +1 -1
  321. package/dist/requests/answerRequest.js +16 -1
  322. package/dist/requests/answerRequest.js.map +1 -1
  323. package/dist/requests/requestLedger.d.ts +13 -0
  324. package/dist/requests/requestLedger.d.ts.map +1 -1
  325. package/dist/requests/requestLedger.js +9 -0
  326. package/dist/requests/requestLedger.js.map +1 -1
  327. package/dist/requests/topicRequestSettle.d.ts +30 -0
  328. package/dist/requests/topicRequestSettle.d.ts.map +1 -0
  329. package/dist/requests/topicRequestSettle.js +23 -0
  330. package/dist/requests/topicRequestSettle.js.map +1 -0
  331. package/dist/requests/wakeUpEngine.d.ts +4 -0
  332. package/dist/requests/wakeUpEngine.d.ts.map +1 -1
  333. package/dist/requests/wakeUpEngine.js +5 -1
  334. package/dist/requests/wakeUpEngine.js.map +1 -1
  335. package/dist/scheduler/delivery.d.ts +2 -0
  336. package/dist/scheduler/delivery.d.ts.map +1 -1
  337. package/dist/scheduler/delivery.js +8 -4
  338. package/dist/scheduler/delivery.js.map +1 -1
  339. package/dist/scheduler/mcpSurface.d.ts +59 -10
  340. package/dist/scheduler/mcpSurface.d.ts.map +1 -1
  341. package/dist/scheduler/mcpSurface.js +276 -79
  342. package/dist/scheduler/mcpSurface.js.map +1 -1
  343. package/dist/scheduler/recurrence.d.ts +5 -0
  344. package/dist/scheduler/recurrence.d.ts.map +1 -1
  345. package/dist/scheduler/recurrence.js +12 -2
  346. package/dist/scheduler/recurrence.js.map +1 -1
  347. package/dist/scheduler/strictToolInput.d.ts +45 -0
  348. package/dist/scheduler/strictToolInput.d.ts.map +1 -0
  349. package/dist/scheduler/strictToolInput.js +155 -0
  350. package/dist/scheduler/strictToolInput.js.map +1 -0
  351. package/dist/scheduler/types.d.ts +5 -0
  352. package/dist/scheduler/types.d.ts.map +1 -1
  353. package/dist/scheduler/workerWatch.d.ts +23 -0
  354. package/dist/scheduler/workerWatch.d.ts.map +1 -0
  355. package/dist/scheduler/workerWatch.js +26 -0
  356. package/dist/scheduler/workerWatch.js.map +1 -0
  357. package/dist/selfUpdate/emittedSource.d.ts +11 -0
  358. package/dist/selfUpdate/emittedSource.d.ts.map +1 -0
  359. package/dist/selfUpdate/emittedSource.js +24 -0
  360. package/dist/selfUpdate/emittedSource.js.map +1 -0
  361. package/dist/selfUpdate/gitSource.d.ts +0 -6
  362. package/dist/selfUpdate/gitSource.d.ts.map +1 -1
  363. package/dist/selfUpdate/gitSource.js +2 -18
  364. package/dist/selfUpdate/gitSource.js.map +1 -1
  365. package/dist/selfUpdate/updatePending.d.ts +1 -1
  366. package/dist/sendErrorClassifier.d.ts +10 -0
  367. package/dist/sendErrorClassifier.d.ts.map +1 -1
  368. package/dist/sendErrorClassifier.js +22 -0
  369. package/dist/sendErrorClassifier.js.map +1 -1
  370. package/dist/state.d.ts +78 -7
  371. package/dist/state.d.ts.map +1 -1
  372. package/dist/state.js +125 -8
  373. package/dist/state.js.map +1 -1
  374. package/dist/stateFile.d.ts +9 -0
  375. package/dist/stateFile.d.ts.map +1 -0
  376. package/dist/stateFile.js +57 -0
  377. package/dist/stateFile.js.map +1 -0
  378. package/dist/stt/sttInstall.d.ts +7 -3
  379. package/dist/stt/sttInstall.d.ts.map +1 -1
  380. package/dist/stt/sttInstall.js +8 -4
  381. package/dist/stt/sttInstall.js.map +1 -1
  382. package/dist/stt/sttSettings.d.ts +2 -1
  383. package/dist/stt/sttSettings.d.ts.map +1 -1
  384. package/dist/stt/sttSettings.js +3 -2
  385. package/dist/stt/sttSettings.js.map +1 -1
  386. package/dist/stt/transcribeChain.js +2 -0
  387. package/dist/stt/transcribeChain.js.map +1 -1
  388. package/dist/testTimings.d.ts +13 -3
  389. package/dist/testTimings.d.ts.map +1 -1
  390. package/dist/testTimings.js +26 -2
  391. package/dist/testTimings.js.map +1 -1
  392. package/dist/todos/board.d.ts +83 -0
  393. package/dist/todos/board.d.ts.map +1 -0
  394. package/dist/todos/board.js +227 -0
  395. package/dist/todos/board.js.map +1 -0
  396. package/dist/todos/format.d.ts +33 -0
  397. package/dist/todos/format.d.ts.map +1 -0
  398. package/dist/todos/format.js +90 -0
  399. package/dist/todos/format.js.map +1 -0
  400. package/dist/todos/merge.d.ts +46 -0
  401. package/dist/todos/merge.d.ts.map +1 -0
  402. package/dist/todos/merge.js +137 -0
  403. package/dist/todos/merge.js.map +1 -0
  404. package/dist/todos/midTurn.d.ts +75 -0
  405. package/dist/todos/midTurn.d.ts.map +1 -0
  406. package/dist/todos/midTurn.js +214 -0
  407. package/dist/todos/midTurn.js.map +1 -0
  408. package/dist/todos/nag.d.ts +85 -0
  409. package/dist/todos/nag.d.ts.map +1 -0
  410. package/dist/todos/nag.js +103 -0
  411. package/dist/todos/nag.js.map +1 -0
  412. package/dist/todos/order.d.ts +25 -0
  413. package/dist/todos/order.d.ts.map +1 -0
  414. package/dist/todos/order.js +61 -0
  415. package/dist/todos/order.js.map +1 -0
  416. package/dist/todos/projects.d.ts +102 -0
  417. package/dist/todos/projects.d.ts.map +1 -0
  418. package/dist/todos/projects.js +342 -0
  419. package/dist/todos/projects.js.map +1 -0
  420. package/dist/todos/registry.d.ts +64 -0
  421. package/dist/todos/registry.d.ts.map +1 -0
  422. package/dist/todos/registry.js +116 -0
  423. package/dist/todos/registry.js.map +1 -0
  424. package/dist/todos/reminderEngine.d.ts +78 -0
  425. package/dist/todos/reminderEngine.d.ts.map +1 -0
  426. package/dist/todos/reminderEngine.js +162 -0
  427. package/dist/todos/reminderEngine.js.map +1 -0
  428. package/dist/todos/store.d.ts +34 -0
  429. package/dist/todos/store.d.ts.map +1 -0
  430. package/dist/todos/store.js +208 -0
  431. package/dist/todos/store.js.map +1 -0
  432. package/dist/todos/tools.d.ts +26 -0
  433. package/dist/todos/tools.d.ts.map +1 -0
  434. package/dist/todos/tools.js +25 -0
  435. package/dist/todos/tools.js.map +1 -0
  436. package/dist/todos/types.d.ts +85 -0
  437. package/dist/todos/types.d.ts.map +1 -0
  438. package/dist/todos/types.js +30 -0
  439. package/dist/todos/types.js.map +1 -0
  440. package/dist/trackers/taskAgentLimit.d.ts +58 -0
  441. package/dist/trackers/taskAgentLimit.d.ts.map +1 -0
  442. package/dist/trackers/taskAgentLimit.js +62 -0
  443. package/dist/trackers/taskAgentLimit.js.map +1 -0
  444. package/dist/trackers/taskAgentSlots.d.ts +109 -0
  445. package/dist/trackers/taskAgentSlots.d.ts.map +1 -0
  446. package/dist/trackers/taskAgentSlots.js +227 -0
  447. package/dist/trackers/taskAgentSlots.js.map +1 -0
  448. package/dist/trackers/types.d.ts +14 -0
  449. package/dist/trackers/types.d.ts.map +1 -0
  450. package/dist/trackers/types.js +3 -0
  451. package/dist/trackers/types.js.map +1 -0
  452. package/dist/types.d.ts +80 -4
  453. package/dist/types.d.ts.map +1 -1
  454. package/dist/utils/adoptReplayGate.d.ts +16 -0
  455. package/dist/utils/adoptReplayGate.d.ts.map +1 -0
  456. package/dist/utils/adoptReplayGate.js +35 -0
  457. package/dist/utils/adoptReplayGate.js.map +1 -0
  458. package/dist/utils/agentPlugin.d.ts +113 -0
  459. package/dist/utils/agentPlugin.d.ts.map +1 -0
  460. package/dist/utils/agentPlugin.js +192 -0
  461. package/dist/utils/agentPlugin.js.map +1 -0
  462. package/dist/utils/autoContinueOnLimit.d.ts +7 -4
  463. package/dist/utils/autoContinueOnLimit.d.ts.map +1 -1
  464. package/dist/utils/autoContinueOnLimit.js +8 -5
  465. package/dist/utils/autoContinueOnLimit.js.map +1 -1
  466. package/dist/utils/botSkills.d.ts +62 -0
  467. package/dist/utils/botSkills.d.ts.map +1 -0
  468. package/dist/utils/botSkills.js +53 -0
  469. package/dist/utils/botSkills.js.map +1 -0
  470. package/dist/utils/botSkillsSetting.d.ts +7 -0
  471. package/dist/utils/botSkillsSetting.d.ts.map +1 -0
  472. package/dist/utils/botSkillsSetting.js +9 -0
  473. package/dist/utils/botSkillsSetting.js.map +1 -0
  474. package/dist/utils/claudeCodeVersion.d.ts +7 -0
  475. package/dist/utils/claudeCodeVersion.d.ts.map +1 -1
  476. package/dist/utils/claudeCodeVersion.js +14 -1
  477. package/dist/utils/claudeCodeVersion.js.map +1 -1
  478. package/dist/utils/claudeCompactHook.d.ts +33 -15
  479. package/dist/utils/claudeCompactHook.d.ts.map +1 -1
  480. package/dist/utils/claudeCompactHook.js +36 -17
  481. package/dist/utils/claudeCompactHook.js.map +1 -1
  482. package/dist/utils/claudeCompactSummary.d.ts +15 -0
  483. package/dist/utils/claudeCompactSummary.d.ts.map +1 -0
  484. package/dist/utils/claudeCompactSummary.js +96 -0
  485. package/dist/utils/claudeCompactSummary.js.map +1 -0
  486. package/dist/utils/claudeLimitSwitch.d.ts +11 -9
  487. package/dist/utils/claudeLimitSwitch.d.ts.map +1 -1
  488. package/dist/utils/claudeLimitSwitch.js +18 -16
  489. package/dist/utils/claudeLimitSwitch.js.map +1 -1
  490. package/dist/utils/claudeProfiles.d.ts +5 -0
  491. package/dist/utils/claudeProfiles.d.ts.map +1 -1
  492. package/dist/utils/claudeProfiles.js +14 -0
  493. package/dist/utils/claudeProfiles.js.map +1 -1
  494. package/dist/utils/claudeSessionTitle.d.ts +2 -1
  495. package/dist/utils/claudeSessionTitle.d.ts.map +1 -1
  496. package/dist/utils/claudeSessionTitle.js +14 -14
  497. package/dist/utils/claudeSessionTitle.js.map +1 -1
  498. package/dist/utils/claudeUsage.d.ts +95 -15
  499. package/dist/utils/claudeUsage.d.ts.map +1 -1
  500. package/dist/utils/claudeUsage.js +241 -41
  501. package/dist/utils/claudeUsage.js.map +1 -1
  502. package/dist/utils/claudeUsageRefresher.d.ts +10 -0
  503. package/dist/utils/claudeUsageRefresher.d.ts.map +1 -1
  504. package/dist/utils/claudeUsageRefresher.js +11 -0
  505. package/dist/utils/claudeUsageRefresher.js.map +1 -1
  506. package/dist/utils/claudeUserEntry.d.ts +50 -0
  507. package/dist/utils/claudeUserEntry.d.ts.map +1 -0
  508. package/dist/utils/claudeUserEntry.js +120 -0
  509. package/dist/utils/claudeUserEntry.js.map +1 -0
  510. package/dist/utils/clearThreadOutputQueues.d.ts +4 -3
  511. package/dist/utils/clearThreadOutputQueues.d.ts.map +1 -1
  512. package/dist/utils/clearThreadOutputQueues.js +1 -1
  513. package/dist/utils/clearThreadOutputQueues.js.map +1 -1
  514. package/dist/utils/compactOnIdle.d.ts +33 -13
  515. package/dist/utils/compactOnIdle.d.ts.map +1 -1
  516. package/dist/utils/compactOnIdle.js +35 -15
  517. package/dist/utils/compactOnIdle.js.map +1 -1
  518. package/dist/utils/fallbackBridge.d.ts +5 -0
  519. package/dist/utils/fallbackBridge.d.ts.map +1 -1
  520. package/dist/utils/fallbackBridge.js +19 -3
  521. package/dist/utils/fallbackBridge.js.map +1 -1
  522. package/dist/utils/fallbackChain.d.ts +9 -3
  523. package/dist/utils/fallbackChain.d.ts.map +1 -1
  524. package/dist/utils/fallbackChain.js +21 -3
  525. package/dist/utils/fallbackChain.js.map +1 -1
  526. package/dist/utils/fileSendPlan.d.ts +6 -0
  527. package/dist/utils/fileSendPlan.d.ts.map +1 -1
  528. package/dist/utils/fileSendPlan.js +11 -0
  529. package/dist/utils/fileSendPlan.js.map +1 -1
  530. package/dist/utils/fileSendService.d.ts +7 -1
  531. package/dist/utils/fileSendService.d.ts.map +1 -1
  532. package/dist/utils/fileSendService.js +6 -2
  533. package/dist/utils/fileSendService.js.map +1 -1
  534. package/dist/utils/groupFinalizePlan.d.ts +8 -10
  535. package/dist/utils/groupFinalizePlan.d.ts.map +1 -1
  536. package/dist/utils/groupFinalizePlan.js +8 -12
  537. package/dist/utils/groupFinalizePlan.js.map +1 -1
  538. package/dist/utils/jsonStreamHost.d.ts +13 -0
  539. package/dist/utils/jsonStreamHost.d.ts.map +1 -1
  540. package/dist/utils/jsonStreamHost.js +13 -0
  541. package/dist/utils/jsonStreamHost.js.map +1 -1
  542. package/dist/utils/messageSendService.d.ts +5 -3
  543. package/dist/utils/messageSendService.d.ts.map +1 -1
  544. package/dist/utils/messageSendService.js +12 -5
  545. package/dist/utils/messageSendService.js.map +1 -1
  546. package/dist/utils/openCodeCompactPlugin.d.ts +39 -14
  547. package/dist/utils/openCodeCompactPlugin.d.ts.map +1 -1
  548. package/dist/utils/openCodeCompactPlugin.js +106 -38
  549. package/dist/utils/openCodeCompactPlugin.js.map +1 -1
  550. package/dist/utils/promptDelivery.d.ts +29 -12
  551. package/dist/utils/promptDelivery.d.ts.map +1 -1
  552. package/dist/utils/promptDelivery.js +13 -5
  553. package/dist/utils/promptDelivery.js.map +1 -1
  554. package/dist/utils/sentKindsSummary.d.ts +10 -0
  555. package/dist/utils/sentKindsSummary.d.ts.map +1 -0
  556. package/dist/utils/sentKindsSummary.js +18 -0
  557. package/dist/utils/sentKindsSummary.js.map +1 -0
  558. package/dist/utils/telegramError.d.ts +6 -0
  559. package/dist/utils/telegramError.d.ts.map +1 -1
  560. package/dist/utils/telegramError.js +12 -0
  561. package/dist/utils/telegramError.js.map +1 -1
  562. package/dist/utils/topicView.d.ts +1 -1
  563. package/dist/utils/topicView.js +1 -1
  564. package/dist/utils/transcribeAudio.d.ts +10 -0
  565. package/dist/utils/transcribeAudio.d.ts.map +1 -1
  566. package/dist/utils/transcribeAudio.js +22 -3
  567. package/dist/utils/transcribeAudio.js.map +1 -1
  568. package/dist/utils/transcriptErrorTime.d.ts +8 -0
  569. package/dist/utils/transcriptErrorTime.d.ts.map +1 -0
  570. package/dist/utils/transcriptErrorTime.js +56 -0
  571. package/dist/utils/transcriptErrorTime.js.map +1 -0
  572. package/dist/utils/wedgeRecovery.d.ts +2 -0
  573. package/dist/utils/wedgeRecovery.d.ts.map +1 -1
  574. package/dist/utils/wedgeRecovery.js +1 -1
  575. package/dist/utils/wedgeRecovery.js.map +1 -1
  576. package/package.json +11 -3
  577. package/remoteRun/runner.sh +1242 -0
  578. package/stt/gigaam_sidecar.py +555 -50
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.bindPickerCallbacks = exports.bindPageNoopCallback = exports.bindLeaveCurrentCallback = exports.bindCreateFolderCallback = exports.BIND_PAGE_SIZE = void 0;
4
+ exports.checkIsBindPickerExtra = checkIsBindPickerExtra;
4
5
  exports.buildBindKeyboard = buildBindKeyboard;
5
6
  /**
6
7
  * The folder picker of `/bind` — and of `/topic`, which shows the same keyboard with its buttons pointing at a
@@ -30,6 +31,19 @@ exports.bindPickerCallbacks = {
30
31
  getPageCallback: (page) => `bind_page_${page}`,
31
32
  createFolderCallback: exports.bindCreateFolderCallback,
32
33
  };
34
+ /**
35
+ * The keyboards {@link buildBindKeyboard} built with `/bind`'s own callbacks, by identity of their `reply_markup`: a copy of
36
+ * the extra that carries one (a larger object spread from it) still holds the same markup, so a send is recognised as a
37
+ * `/bind` picker wherever it was composed.
38
+ */
39
+ const bindPickerMarkups = new WeakSet();
40
+ /**
41
+ * @description Whether a send's `extra` carries a `/bind` picker — the keyboard of `/bind`, of the «not bound» replies and of
42
+ * the topic-created welcome — and not another keyboard, nor the `/topic` wizard's re-targeted copy of the same layout.
43
+ */
44
+ function checkIsBindPickerExtra(extra) {
45
+ return 'reply_markup' in extra && typeof extra.reply_markup === 'object' && extra.reply_markup !== null && bindPickerMarkups.has(extra.reply_markup);
46
+ }
33
47
  /**
34
48
  * @description Build a `subdir`-suggestion keyboard for `/bind` and friends.
35
49
  *
@@ -92,6 +106,9 @@ function buildBindKeyboard(subdirs, page = 0, pageSize = exports.BIND_PAGE_SIZE,
92
106
  if (callbacks.cancelButton) {
93
107
  rows.push([telegraf_1.Markup.button.callback(callbacks.cancelButton.label, callbacks.cancelButton.callback)]);
94
108
  }
95
- return telegraf_1.Markup.inlineKeyboard(rows);
109
+ const keyboard = telegraf_1.Markup.inlineKeyboard(rows);
110
+ if (callbacks === exports.bindPickerCallbacks)
111
+ bindPickerMarkups.add(keyboard.reply_markup);
112
+ return keyboard;
96
113
  }
97
114
  //# sourceMappingURL=bindPicker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bindPicker.js","sourceRoot":"","sources":["../../../src/connectors/telegram/bindPicker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bindPicker.js","sourceRoot":"","sources":["../../../src/connectors/telegram/bindPicker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Which `/bind` picker messages a bind has already claimed. A leaf module (no `bot.ts`, no environment), so a test can
3
+ * reach it.
4
+ */
5
+ import type { SessionKey } from '../../sessionKey';
6
+ /** How many claims are kept: the oldest is dropped past it, as a keyboard that old has long been out of reach. */
7
+ export declare const bindPickerClaimLimit = 200;
8
+ /**
9
+ * The `/bind` picker is spent by the bind (or the leave) it leads to, and a bind takes seconds (the folder's facts are probed, the sends
10
+ * are paced): a second tap on the same keyboard inside that time must not bind again. A handler claims the picker message
11
+ * in the same synchronous step that decides to act, before its first await, so of two taps landing together exactly one wins;
12
+ * a bind that is refused gives the claim back, and the picker works on.
13
+ */
14
+ export declare class BindPickerClaims {
15
+ private readonly limit;
16
+ private readonly claimed;
17
+ /** The messages {@link retire} holds until {@link unretire}; not subject to the limit. */
18
+ private readonly retired;
19
+ constructor(limit?: number);
20
+ /** @description Claim the picker message; `false` when a bind already holds it. */
21
+ claim(key: SessionKey, messageId: number): boolean;
22
+ /** @description Whether a bind (or a leave) holds the picker message: nothing else may act on it. */
23
+ has(key: SessionKey, messageId: number): boolean;
24
+ /**
25
+ * @description Hold the picker message outside the limit, until {@link unretire}: the sweep that closes a topic's open pickers
26
+ * takes dozens at once, which must neither push a tap's claim out of the limited list (a second tap would then bind again)
27
+ * nor be pushed out by newer claims (a picker that keeps its buttons — too old to delete, past the strip bound — has nothing
28
+ * else between a stale tap and a rebind). The hold lasts as long as the process: a restart forgets it, and a picker still
29
+ * carrying buttons then works again.
30
+ */
31
+ retire(key: SessionKey, messageId: number): void;
32
+ /** @description Let go of a {@link retire}d message that has nothing left to tap — deleted, or its buttons removed: the hold would only grow. */
33
+ unretire(key: SessionKey, messageId: number): void;
34
+ /** @description Give a claim back: the bind it was for was refused, so the picker stays usable. */
35
+ release(key: SessionKey, messageId: number): void;
36
+ /**
37
+ * @description Run `work` holding the picker message. `'busy'`: a bind already holds it, `work` did not run. `'done'`: `work`
38
+ * resolved `true` — it did what the tap asked, and the picker stays claimed (it is spent). `'undone'`: it resolved `false`
39
+ * (a refused bind), or threw — the claim goes back and the picker works on, so nothing between the claim and a finished
40
+ * bind can leave it held for a bind that never happened. The claim is taken before the first await: call this straight
41
+ * from the handler, with no await in front of it. `messageId` is `null` for a tap Telegram attached no message to: the
42
+ * work runs, with nothing to claim.
43
+ */
44
+ runClaimed(key: SessionKey, messageId: number | null, work: () => Promise<boolean>): Promise<'busy' | 'done' | 'undone'>;
45
+ }
46
+ //# sourceMappingURL=bindPickerClaims.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindPickerClaims.d.ts","sourceRoot":"","sources":["../../../src/connectors/telegram/bindPickerClaims.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,kHAAkH;AAClH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;;;GAKG;AACH,qBAAa,gBAAgB;IAKf,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJlC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,0FAA0F;IAC1F,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEhB,KAAK,GAAE,MAA6B;IAEjE,mFAAmF;IACnF,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAYlD,qGAAqG;IACrG,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAKhD;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAIhD,iJAAiJ;IACjJ,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAIlD,mGAAmG;IACnG,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAIjD;;;;;;;OAOG;IACG,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;CAW/H"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BindPickerClaims = exports.bindPickerClaimLimit = void 0;
4
+ const callbackMessage_1 = require("./commands/callbackMessage");
5
+ /** How many claims are kept: the oldest is dropped past it, as a keyboard that old has long been out of reach. */
6
+ exports.bindPickerClaimLimit = 200;
7
+ /**
8
+ * The `/bind` picker is spent by the bind (or the leave) it leads to, and a bind takes seconds (the folder's facts are probed, the sends
9
+ * are paced): a second tap on the same keyboard inside that time must not bind again. A handler claims the picker message
10
+ * in the same synchronous step that decides to act, before its first await, so of two taps landing together exactly one wins;
11
+ * a bind that is refused gives the claim back, and the picker works on.
12
+ */
13
+ class BindPickerClaims {
14
+ limit;
15
+ claimed = new Set();
16
+ /** The messages {@link retire} holds until {@link unretire}; not subject to the limit. */
17
+ retired = new Set();
18
+ constructor(limit = exports.bindPickerClaimLimit) {
19
+ this.limit = limit;
20
+ }
21
+ /** @description Claim the picker message; `false` when a bind already holds it. */
22
+ claim(key, messageId) {
23
+ const claimKey = (0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId);
24
+ if (this.claimed.has(claimKey) || this.retired.has(claimKey))
25
+ return false;
26
+ this.claimed.add(claimKey);
27
+ while (this.claimed.size > this.limit) {
28
+ const oldest = this.claimed.values().next().value;
29
+ if (oldest === undefined)
30
+ break;
31
+ this.claimed.delete(oldest);
32
+ }
33
+ return true;
34
+ }
35
+ /** @description Whether a bind (or a leave) holds the picker message: nothing else may act on it. */
36
+ has(key, messageId) {
37
+ const claimKey = (0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId);
38
+ return this.claimed.has(claimKey) || this.retired.has(claimKey);
39
+ }
40
+ /**
41
+ * @description Hold the picker message outside the limit, until {@link unretire}: the sweep that closes a topic's open pickers
42
+ * takes dozens at once, which must neither push a tap's claim out of the limited list (a second tap would then bind again)
43
+ * nor be pushed out by newer claims (a picker that keeps its buttons — too old to delete, past the strip bound — has nothing
44
+ * else between a stale tap and a rebind). The hold lasts as long as the process: a restart forgets it, and a picker still
45
+ * carrying buttons then works again.
46
+ */
47
+ retire(key, messageId) {
48
+ this.retired.add((0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId));
49
+ }
50
+ /** @description Let go of a {@link retire}d message that has nothing left to tap — deleted, or its buttons removed: the hold would only grow. */
51
+ unretire(key, messageId) {
52
+ this.retired.delete((0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId));
53
+ }
54
+ /** @description Give a claim back: the bind it was for was refused, so the picker stays usable. */
55
+ release(key, messageId) {
56
+ this.claimed.delete((0, callbackMessage_1.buildMessageSnapshotKey)(key, messageId));
57
+ }
58
+ /**
59
+ * @description Run `work` holding the picker message. `'busy'`: a bind already holds it, `work` did not run. `'done'`: `work`
60
+ * resolved `true` — it did what the tap asked, and the picker stays claimed (it is spent). `'undone'`: it resolved `false`
61
+ * (a refused bind), or threw — the claim goes back and the picker works on, so nothing between the claim and a finished
62
+ * bind can leave it held for a bind that never happened. The claim is taken before the first await: call this straight
63
+ * from the handler, with no await in front of it. `messageId` is `null` for a tap Telegram attached no message to: the
64
+ * work runs, with nothing to claim.
65
+ */
66
+ async runClaimed(key, messageId, work) {
67
+ if (messageId === null)
68
+ return (await work()) ? 'done' : 'undone';
69
+ if (!this.claim(key, messageId))
70
+ return 'busy';
71
+ let isDone = false;
72
+ try {
73
+ isDone = await work();
74
+ return isDone ? 'done' : 'undone';
75
+ }
76
+ finally {
77
+ if (!isDone)
78
+ this.release(key, messageId);
79
+ }
80
+ }
81
+ }
82
+ exports.BindPickerClaims = BindPickerClaims;
83
+ //# sourceMappingURL=bindPickerClaims.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindPickerClaims.js","sourceRoot":"","sources":["../../../src/connectors/telegram/bindPickerClaims.ts"],"names":[],"mappings":";;;AAKA,gEAAqE;AAErE,kHAAkH;AACrG,QAAA,oBAAoB,GAAG,GAAG,CAAC;AAExC;;;;;GAKG;AACH,MAAa,gBAAgB;IAKE;IAJZ,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAC7C,0FAA0F;IACzE,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAE7C,YAA6B,QAAgB,4BAAoB;QAApC,UAAK,GAAL,KAAK,CAA+B;IAAG,CAAC;IAErE,mFAAmF;IACnF,KAAK,CAAC,GAAe,EAAE,SAAiB;QACtC,MAAM,QAAQ,GAAG,IAAA,yCAAuB,EAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACzD,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAClD,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM;YAChC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qGAAqG;IACrG,GAAG,CAAC,GAAe,EAAE,SAAiB;QACpC,MAAM,QAAQ,GAAG,IAAA,yCAAuB,EAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClE,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,GAAe,EAAE,SAAiB;QACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAA,yCAAuB,EAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,iJAAiJ;IACjJ,QAAQ,CAAC,GAAe,EAAE,SAAiB;QACzC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAA,yCAAuB,EAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,mGAAmG;IACnG,OAAO,CAAC,GAAe,EAAE,SAAiB;QACxC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAA,yCAAuB,EAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,UAAU,CAAC,GAAe,EAAE,SAAwB,EAAE,IAA4B;QACtF,IAAI,SAAS,KAAK,IAAI;YAAE,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;QAClE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC;YAAE,OAAO,MAAM,CAAC;QAC/C,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;YACtB,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM;gBAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;CACF;AAlED,4CAkEC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The sweep that closes the open `/bind` messages of a topic once it is bound or has left its folder, written over ports so a
3
+ * test can reach it: the Telegram calls and the claim list are the caller's. A leaf module (no `bot.ts`, no environment).
4
+ */
5
+ import { type OpenBindMessage } from './openBindMessages';
6
+ /** What a sweep does to the messages of ONE topic. */
7
+ export interface BindSweepPorts {
8
+ /** Hold a picker message: a tap on it is refused until {@link BindSweepPorts.unretire} (`BindPickerClaims.retire`). */
9
+ retire: (messageId: number) => void;
10
+ /** Let go of a message that has nothing left to tap (`BindPickerClaims.unretire`). */
11
+ unretire: (messageId: number) => void;
12
+ /** ONE bulk delete; `false` when Telegram refused the call. */
13
+ deleteMessages: (messageIds: readonly number[]) => Promise<boolean>;
14
+ /** Remove one message's keyboard; `false` when the edit failed. */
15
+ removeKeyboard: (messageId: number) => Promise<boolean>;
16
+ }
17
+ /**
18
+ * @description Remove the keyboards of messages that can no longer be deleted or must stay as history, the newest
19
+ * `keyboardStripsPerSweepLimit` of them (`messageIds` oldest first: the newest sit nearest the bottom of the topic): each strip
20
+ * is a paced send of the bot's one global gate. Resolves the ids whose keyboard is gone — the older rest and every failed edit
21
+ * still carry theirs.
22
+ */
23
+ export declare function stripStaleKeyboards(messageIds: readonly number[], removeKeyboard: (messageId: number) => Promise<boolean>): Promise<number[]>;
24
+ /**
25
+ * @description Close `entries`, the messages a topic had open. Every one is held FIRST, before the first await, so a tap on it is
26
+ * refused whatever becomes of its message; the hold is let go of for the ones with nothing left to tap — deleted by the bulk
27
+ * call, or stripped of their buttons. A message too old for Telegram to delete loses its buttons instead, and so does every one
28
+ * of a bulk call Telegram refused (no delete per picker: two paced sends each) — only the newest
29
+ * `keyboardStripsPerSweepLimit` of them; the older rest and any failed edit keep their buttons, and with them the hold.
30
+ */
31
+ export declare function sweepOpenBindMessages(entries: readonly OpenBindMessage[], nowMs: number, ports: BindSweepPorts): Promise<void>;
32
+ //# sourceMappingURL=bindSweep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindSweep.d.ts","sourceRoot":"","sources":["../../../src/connectors/telegram/bindSweep.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAoD,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE5G,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,uHAAuH;IACvH,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,sFAAsF;IACtF,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,+DAA+D;IAC/D,cAAc,EAAE,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpE,mEAAmE;IACnE,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACzD;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GACtD,OAAO,CAAC,MAAM,EAAE,CAAC,CAMnB;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAWpI"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stripStaleKeyboards = stripStaleKeyboards;
4
+ exports.sweepOpenBindMessages = sweepOpenBindMessages;
5
+ /**
6
+ * The sweep that closes the open `/bind` messages of a topic once it is bound or has left its folder, written over ports so a
7
+ * test can reach it: the Telegram calls and the claim list are the caller's. A leaf module (no `bot.ts`, no environment).
8
+ */
9
+ const openBindMessages_1 = require("./openBindMessages");
10
+ /**
11
+ * @description Remove the keyboards of messages that can no longer be deleted or must stay as history, the newest
12
+ * `keyboardStripsPerSweepLimit` of them (`messageIds` oldest first: the newest sit nearest the bottom of the topic): each strip
13
+ * is a paced send of the bot's one global gate. Resolves the ids whose keyboard is gone — the older rest and every failed edit
14
+ * still carry theirs.
15
+ */
16
+ async function stripStaleKeyboards(messageIds, removeKeyboard) {
17
+ const strippedMessageIds = [];
18
+ for (const messageId of messageIds.slice(-openBindMessages_1.keyboardStripsPerSweepLimit)) {
19
+ if (await removeKeyboard(messageId))
20
+ strippedMessageIds.push(messageId);
21
+ }
22
+ return strippedMessageIds;
23
+ }
24
+ /**
25
+ * @description Close `entries`, the messages a topic had open. Every one is held FIRST, before the first await, so a tap on it is
26
+ * refused whatever becomes of its message; the hold is let go of for the ones with nothing left to tap — deleted by the bulk
27
+ * call, or stripped of their buttons. A message too old for Telegram to delete loses its buttons instead, and so does every one
28
+ * of a bulk call Telegram refused (no delete per picker: two paced sends each) — only the newest
29
+ * `keyboardStripsPerSweepLimit` of them; the older rest and any failed edit keep their buttons, and with them the hold.
30
+ */
31
+ async function sweepOpenBindMessages(entries, nowMs, ports) {
32
+ for (const { messageId } of entries)
33
+ ports.retire(messageId);
34
+ const releaseAll = (messageIds) => {
35
+ for (const messageId of messageIds)
36
+ ports.unretire(messageId);
37
+ };
38
+ const { deletable, tooOld } = (0, openBindMessages_1.splitByDeleteWindow)(entries, nowMs);
39
+ if (deletable.length > 0) {
40
+ if (await ports.deleteMessages(deletable))
41
+ releaseAll(deletable);
42
+ else
43
+ releaseAll(await stripStaleKeyboards(deletable, ports.removeKeyboard));
44
+ }
45
+ releaseAll(await stripStaleKeyboards(tooOld, ports.removeKeyboard));
46
+ }
47
+ //# sourceMappingURL=bindSweep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindSweep.js","sourceRoot":"","sources":["../../../src/connectors/telegram/bindSweep.ts"],"names":[],"mappings":";;AAwBA,kDASC;AASD,sDAWC;AArDD;;;GAGG;AACH,yDAA4G;AAc5G;;;;;GAKG;AACI,KAAK,UAAU,mBAAmB,CACvC,UAA6B,EAC7B,cAAuD;IAEvD,MAAM,kBAAkB,GAAa,EAAE,CAAC;IACxC,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,8CAA2B,CAAC,EAAE,CAAC;QACvE,IAAI,MAAM,cAAc,CAAC,SAAS,CAAC;YAAE,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,qBAAqB,CAAC,OAAmC,EAAE,KAAa,EAAE,KAAqB;IACnH,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,OAAO;QAAE,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,CAAC,UAA6B,EAAQ,EAAE;QACzD,KAAK,MAAM,SAAS,IAAI,UAAU;YAAE,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC,CAAC;IACF,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAA,sCAAmB,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAClE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,IAAI,MAAM,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC;YAAE,UAAU,CAAC,SAAS,CAAC,CAAC;;YAC5D,UAAU,CAAC,MAAM,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;IAC9E,CAAC;IACD,UAAU,CAAC,MAAM,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The pure parts of a binding's welcome that name OTHER topics: how a topic that shares the folder is written in the
3
+ * welcome's «also used by» row. A leaf module (no `bot.ts`, no environment), so a test can reach it.
4
+ */
5
+ /**
6
+ * A topic bound to the same folder. `name`: what the bot saw the topic made with (or renamed to by an admin), when it
7
+ * saw it. `link`: the link that opens the topic, which a person can always follow.
8
+ */
9
+ export interface SharedTopic {
10
+ name: string | undefined;
11
+ link: string;
12
+ }
13
+ /**
14
+ * @description The row's list, comma-separated: a topic with a name is that name as inline code, one without is its bare
15
+ * link (Telegram makes it tappable; it is digits and slashes only, so Markdown has nothing to mangle). `moreLabel` —
16
+ * the count of the topics that are only counted, already worded (`+2 more`) — is the last item: those of OTHER chats, and any
17
+ * of this chat that has neither a name nor a link to show; a
18
+ * member of one chat is not told the names, the links or the ids of another's. The welcome is sent as Markdown, where
19
+ * nothing inside a code span can be escaped, so a backtick in a name (a name is free text) would end the span early — it
20
+ * becomes an apostrophe instead.
21
+ */
22
+ export declare function formatSharedTopicList(topics: readonly SharedTopic[], moreLabel?: string | null): string;
23
+ //# sourceMappingURL=bindingWelcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindingWelcome.d.ts","sourceRoot":"","sources":["../../../src/connectors/telegram/bindingWelcome.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,EAAE,SAAS,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM,CAO7G"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /**
3
+ * The pure parts of a binding's welcome that name OTHER topics: how a topic that shares the folder is written in the
4
+ * welcome's «also used by» row. A leaf module (no `bot.ts`, no environment), so a test can reach it.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.formatSharedTopicList = formatSharedTopicList;
8
+ /**
9
+ * @description The row's list, comma-separated: a topic with a name is that name as inline code, one without is its bare
10
+ * link (Telegram makes it tappable; it is digits and slashes only, so Markdown has nothing to mangle). `moreLabel` —
11
+ * the count of the topics that are only counted, already worded (`+2 more`) — is the last item: those of OTHER chats, and any
12
+ * of this chat that has neither a name nor a link to show; a
13
+ * member of one chat is not told the names, the links or the ids of another's. The welcome is sent as Markdown, where
14
+ * nothing inside a code span can be escaped, so a backtick in a name (a name is free text) would end the span early — it
15
+ * becomes an apostrophe instead.
16
+ */
17
+ function formatSharedTopicList(topics, moreLabel = null) {
18
+ const items = topics.map(({ name, link }) => {
19
+ const label = name?.trim();
20
+ return label ? `\`${label.replaceAll('`', "'")}\`` : link;
21
+ });
22
+ if (moreLabel !== null)
23
+ items.push(moreLabel);
24
+ return items.join(', ');
25
+ }
26
+ //# sourceMappingURL=bindingWelcome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindingWelcome.js","sourceRoot":"","sources":["../../../src/connectors/telegram/bindingWelcome.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAoBH,sDAOC;AAhBD;;;;;;;;GAQG;AACH,SAAgB,qBAAqB,CAAC,MAA8B,EAAE,YAA2B,IAAI;IACnG,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,CAAC,CAAC,CAAC;IACH,IAAI,SAAS,KAAK,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @description The connections the bot keeps pooled to the Bot API, and what happens when the server closed one the bot
3
+ * still held.
4
+ *
5
+ * The bot keeps its connections alive and reuses them. A server closes an idle one after a while; a client that learns
6
+ * of it only when it writes its next request (a process starved of CPU, whose event loop has not yet read the close)
7
+ * gets «socket hang up» / `ECONNRESET` / `EPIPE` for a request the closed connection never delivered. Two layers:
8
+ *
9
+ * 1. The agent closes a connection that sat idle in the pool for {@link botApiFreeSocketTimeoutMs} itself, long before
10
+ * the server's own idle limit (api.telegram.org kept an idle HTTP/1.1 connection for more than 130 s when measured),
11
+ * so an ordinary pause between two sends never meets a connection the server closed. A client stalled past the
12
+ * server's limit cannot be helped that way: its timers do not run either, and the stale connection is still in the
13
+ * pool when the next request starts. What it meets then depends on the Node: since 22.23.4 the http agent looks for
14
+ * what the server already sent on an idle socket before it reuses it («http: ensure agent data guard works without I/O»,
15
+ * CVE-2026-105481) and opens a fresh connection; an older Node (`engines` allows 22.12) writes onto the closed one.
16
+ * 2. {@link wireBotApiClient} makes a client send such a request again ONCE, on a fresh connection — the case of those older
17
+ * agents, and on every Node the one of a server that closes the connection as the request is on its way, which no
18
+ * client sees coming. It does so only when
19
+ * the request rode a REUSED connection (`ClientRequest.reusedSocket`, the signal Node documents for exactly this) and
20
+ * the connection failed at once ({@link staleConnectionFailureWindowMs}) with the socket having read not a single byte
21
+ * since the reuse: no answer began, not even a partial one, and the server did not sit on the request. A timeout, an
22
+ * abort, an answer that began, a failure that came late and a first-time connection are never retried.
23
+ *
24
+ * This is a heuristic, not a guarantee. A server that took the request and dropped the connection at once, before a byte of
25
+ * its answer, looks the same to the client, and there the retry posts the message twice. That case is rare; the alternative
26
+ * is losing the message every time a pooled connection had been closed.
27
+ */
28
+ import * as http from 'http';
29
+ import * as https from 'https';
30
+ import type { CallApiHost } from '../../outputTrace';
31
+ /**
32
+ * @description How long a connection may idle in the pool before the agent closes it. Well under the server's own limit
33
+ * (the real Bot API held an idle HTTP/1.1 connection for more than 130 s when measured, and sends no `Keep-Alive` hint),
34
+ * long enough to span the pauses between a topic's sends and the typing indicator, so a streaming reply keeps its warm
35
+ * connection.
36
+ *
37
+ * It is a socket idle timeout, applied by Node only to FREE sockets (`http.Agent` destroys a socket on `timeout` only if
38
+ * it sits in the free list): a long poll that waits 50 s for an update is not cut.
39
+ */
40
+ export declare const botApiFreeSocketTimeoutMs = 30000;
41
+ /**
42
+ * @description How soon after a pooled connection was handed to a request its failure still counts as "the server had
43
+ * closed it". A closed connection fails within one turn of the event loop of the write — milliseconds, a second on a host
44
+ * that is starved of CPU —, while a server that took the request, worked on it for long and then dropped the connection
45
+ * (a slow send under load, a media group, a middlebox) fails later: that request is not retried.
46
+ */
47
+ export declare const staleConnectionFailureWindowMs = 1000;
48
+ /** The log line of a retry: `<prefix> (<method>): …`. Never carries the bot token. */
49
+ export declare const reusedConnectionRetryLogPrefix = "[telegram] pooled connection was closed by the server, retrying once on a fresh one";
50
+ /**
51
+ * @description The keep-alive, IPv4-pinned `https.Agent` the Bot API client and the file downloads ride: a warm
52
+ * connection avoids the cold-handshake stall.
53
+ */
54
+ export declare function createBotApiHttpsAgent(freeSocketTimeoutMs?: number): https.Agent;
55
+ /**
56
+ * @description The same pooling for an `http://` API root (the process-level tests' fake on loopback): Telegraf drops its
57
+ * agent for such a root and node-fetch then falls back to the global agent, which has other limits.
58
+ */
59
+ export declare function createBotApiHttpAgent(freeSocketTimeoutMs?: number): http.Agent;
60
+ /** A Telegraf `Telegram` client, as far as the wiring needs it. */
61
+ export interface BotApiClient extends CallApiHost {
62
+ readonly options: {
63
+ agent?: http.Agent;
64
+ };
65
+ }
66
+ /**
67
+ * @description Put the bot's pooling on a Telegraf client: its agent (Telegraf drops the agent of an `http://` root, and
68
+ * builds every client from options that already lack it) and the retry of a request that met a closed pooled connection.
69
+ * Telegraf builds a NEW client for every update (`ctx.telegram`, behind `ctx.reply` / `ctx.answerCbQuery` /
70
+ * `ctx.editMessageText`), so this runs once for `bot.telegram` and once per update for `ctx.telegram`. For `bot.telegram`
71
+ * call it AFTER the output trace wrap, so the trace records both attempts of a retried request.
72
+ */
73
+ export declare function wireBotApiClient(telegram: BotApiClient, agent: http.Agent): void;
74
+ //# sourceMappingURL=botApiConnection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"botApiConnection.d.ts","sourceRoot":"","sources":["../../../src/connectors/telegram/botApiConnection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAKhD;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,OAAO,CAAC;AAEnD,sFAAsF;AACtF,eAAO,MAAM,8BAA8B,wFAAwF,CAAC;AAkDpI;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,mBAAmB,GAAE,MAAkC,GAAG,KAAK,CAAC,KAAK,CAE3G;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,mBAAmB,GAAE,MAAkC,GAAG,IAAI,CAAC,KAAK,CAEzG;AA0CD,mEAAmE;AACnE,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,QAAQ,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAA;KAAE,CAAC;CAC1C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAGhF"}
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ /**
3
+ * @description The connections the bot keeps pooled to the Bot API, and what happens when the server closed one the bot
4
+ * still held.
5
+ *
6
+ * The bot keeps its connections alive and reuses them. A server closes an idle one after a while; a client that learns
7
+ * of it only when it writes its next request (a process starved of CPU, whose event loop has not yet read the close)
8
+ * gets «socket hang up» / `ECONNRESET` / `EPIPE` for a request the closed connection never delivered. Two layers:
9
+ *
10
+ * 1. The agent closes a connection that sat idle in the pool for {@link botApiFreeSocketTimeoutMs} itself, long before
11
+ * the server's own idle limit (api.telegram.org kept an idle HTTP/1.1 connection for more than 130 s when measured),
12
+ * so an ordinary pause between two sends never meets a connection the server closed. A client stalled past the
13
+ * server's limit cannot be helped that way: its timers do not run either, and the stale connection is still in the
14
+ * pool when the next request starts. What it meets then depends on the Node: since 22.23.4 the http agent looks for
15
+ * what the server already sent on an idle socket before it reuses it («http: ensure agent data guard works without I/O»,
16
+ * CVE-2026-105481) and opens a fresh connection; an older Node (`engines` allows 22.12) writes onto the closed one.
17
+ * 2. {@link wireBotApiClient} makes a client send such a request again ONCE, on a fresh connection — the case of those older
18
+ * agents, and on every Node the one of a server that closes the connection as the request is on its way, which no
19
+ * client sees coming. It does so only when
20
+ * the request rode a REUSED connection (`ClientRequest.reusedSocket`, the signal Node documents for exactly this) and
21
+ * the connection failed at once ({@link staleConnectionFailureWindowMs}) with the socket having read not a single byte
22
+ * since the reuse: no answer began, not even a partial one, and the server did not sit on the request. A timeout, an
23
+ * abort, an answer that began, a failure that came late and a first-time connection are never retried.
24
+ *
25
+ * This is a heuristic, not a guarantee. A server that took the request and dropped the connection at once, before a byte of
26
+ * its answer, looks the same to the client, and there the retry posts the message twice. That case is rare; the alternative
27
+ * is losing the message every time a pooled connection had been closed.
28
+ */
29
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
30
+ if (k2 === undefined) k2 = k;
31
+ var desc = Object.getOwnPropertyDescriptor(m, k);
32
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
33
+ desc = { enumerable: true, get: function() { return m[k]; } };
34
+ }
35
+ Object.defineProperty(o, k2, desc);
36
+ }) : (function(o, m, k, k2) {
37
+ if (k2 === undefined) k2 = k;
38
+ o[k2] = m[k];
39
+ }));
40
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
41
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
42
+ }) : function(o, v) {
43
+ o["default"] = v;
44
+ });
45
+ var __importStar = (this && this.__importStar) || (function () {
46
+ var ownKeys = function(o) {
47
+ ownKeys = Object.getOwnPropertyNames || function (o) {
48
+ var ar = [];
49
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
50
+ return ar;
51
+ };
52
+ return ownKeys(o);
53
+ };
54
+ return function (mod) {
55
+ if (mod && mod.__esModule) return mod;
56
+ var result = {};
57
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
58
+ __setModuleDefault(result, mod);
59
+ return result;
60
+ };
61
+ })();
62
+ Object.defineProperty(exports, "__esModule", { value: true });
63
+ exports.reusedConnectionRetryLogPrefix = exports.staleConnectionFailureWindowMs = exports.botApiFreeSocketTimeoutMs = void 0;
64
+ exports.createBotApiHttpsAgent = createBotApiHttpsAgent;
65
+ exports.createBotApiHttpAgent = createBotApiHttpAgent;
66
+ exports.wireBotApiClient = wireBotApiClient;
67
+ const http = __importStar(require("http"));
68
+ const https = __importStar(require("https"));
69
+ const async_hooks_1 = require("async_hooks");
70
+ const net_1 = require("net");
71
+ const perf_hooks_1 = require("perf_hooks");
72
+ const stream_1 = require("stream");
73
+ const sendErrorClassifier_1 = require("../../sendErrorClassifier");
74
+ /**
75
+ * @description How long a connection may idle in the pool before the agent closes it. Well under the server's own limit
76
+ * (the real Bot API held an idle HTTP/1.1 connection for more than 130 s when measured, and sends no `Keep-Alive` hint),
77
+ * long enough to span the pauses between a topic's sends and the typing indicator, so a streaming reply keeps its warm
78
+ * connection.
79
+ *
80
+ * It is a socket idle timeout, applied by Node only to FREE sockets (`http.Agent` destroys a socket on `timeout` only if
81
+ * it sits in the free list): a long poll that waits 50 s for an update is not cut.
82
+ */
83
+ exports.botApiFreeSocketTimeoutMs = 30_000;
84
+ /** The initial delay of the TCP keep-alive probes on a pooled connection. */
85
+ const tcpKeepAliveInitialDelayMs = 10_000;
86
+ /**
87
+ * @description How soon after a pooled connection was handed to a request its failure still counts as "the server had
88
+ * closed it". A closed connection fails within one turn of the event loop of the write — milliseconds, a second on a host
89
+ * that is starved of CPU —, while a server that took the request, worked on it for long and then dropped the connection
90
+ * (a slow send under load, a media group, a middlebox) fails later: that request is not retried.
91
+ */
92
+ exports.staleConnectionFailureWindowMs = 1000;
93
+ /** The log line of a retry: `<prefix> (<method>): …`. Never carries the bot token. */
94
+ exports.reusedConnectionRetryLogPrefix = '[telegram] pooled connection was closed by the server, retrying once on a fresh one';
95
+ /** How deep a payload is searched for a one-shot stream (`{ media: [{ media: { source: stream } }] }` is the deepest shape). */
96
+ const maxPayloadDepth = 5;
97
+ /**
98
+ * The probe of the `callApi` that is running, handed to the agent through the async context: node-fetch sits between the
99
+ * two and keeps nothing of the request on the error it throws.
100
+ */
101
+ const reuseProbeStorage = new async_hooks_1.AsyncLocalStorage();
102
+ /**
103
+ * Mark the running `callApi`'s probe when this reused request fails at once ({@link staleConnectionFailureWindowMs}) with the
104
+ * socket having read nothing since the reuse. The socket's byte count, not the request's `response` event, is the test for
105
+ * "nothing": that event fires only once a whole response head is parsed, so a connection that delivered half a head — an
106
+ * answer that began — would pass for a closed one. `bytesRead` is the bytes of the application stream on a TLS socket too (a
107
+ * `close_notify` alert is not counted).
108
+ */
109
+ function watchReusedRequest(socket, request) {
110
+ const probe = reuseProbeStorage.getStore();
111
+ if (!probe || !(socket instanceof net_1.Socket))
112
+ return;
113
+ const bytesReadAtReuse = socket.bytesRead;
114
+ const reusedAtMs = perf_hooks_1.performance.now();
115
+ request.once('error', () => {
116
+ const isAtOnce = perf_hooks_1.performance.now() - reusedAtMs <= exports.staleConnectionFailureWindowMs;
117
+ if (isAtOnce && socket.bytesRead === bytesReadAtReuse)
118
+ probe.isPooledConnectionLost = true;
119
+ });
120
+ }
121
+ /** `agent.reuseSocket` is called by Node, synchronously inside `http.request`, when a pooled socket is handed to a request. */
122
+ function trackReusedConnections(agent) {
123
+ const reuseSocket = agent.reuseSocket.bind(agent);
124
+ agent.reuseSocket = (socket, request) => {
125
+ reuseSocket(socket, request);
126
+ watchReusedRequest(socket, request);
127
+ };
128
+ return agent;
129
+ }
130
+ /** The pooling both agents share. `freeSocketTimeoutMs` is a test seam; production keeps {@link botApiFreeSocketTimeoutMs}. */
131
+ function getBotApiAgentOptions(freeSocketTimeoutMs) {
132
+ return { keepAlive: true, keepAliveMsecs: tcpKeepAliveInitialDelayMs, family: 4, timeout: freeSocketTimeoutMs };
133
+ }
134
+ /**
135
+ * @description The keep-alive, IPv4-pinned `https.Agent` the Bot API client and the file downloads ride: a warm
136
+ * connection avoids the cold-handshake stall.
137
+ */
138
+ function createBotApiHttpsAgent(freeSocketTimeoutMs = exports.botApiFreeSocketTimeoutMs) {
139
+ return trackReusedConnections(new https.Agent(getBotApiAgentOptions(freeSocketTimeoutMs)));
140
+ }
141
+ /**
142
+ * @description The same pooling for an `http://` API root (the process-level tests' fake on loopback): Telegraf drops its
143
+ * agent for such a root and node-fetch then falls back to the global agent, which has other limits.
144
+ */
145
+ function createBotApiHttpAgent(freeSocketTimeoutMs = exports.botApiFreeSocketTimeoutMs) {
146
+ return trackReusedConnections(new http.Agent(getBotApiAgentOptions(freeSocketTimeoutMs)));
147
+ }
148
+ /**
149
+ * A file handed to Telegraf as a stream can be read once: sending the payload again would upload what is left of it. Also
150
+ * skips a Buffer (its bytes are not walked) and bounds the walk.
151
+ */
152
+ function checkIsPayloadReplayable(payload, depth = 0) {
153
+ if (payload instanceof stream_1.Readable)
154
+ return false;
155
+ if (ArrayBuffer.isView(payload) || depth >= maxPayloadDepth)
156
+ return true;
157
+ return Object.values(payload).every((value) => typeof value !== 'object' || value === null || checkIsPayloadReplayable(value, depth + 1));
158
+ }
159
+ /** Close every idle pooled connection: one that went stale was idle just as long as its siblings, so a retry must not meet another. */
160
+ function destroyFreeSockets(agent) {
161
+ for (const sockets of Object.values(agent.freeSockets)) {
162
+ for (const socket of [...(sockets ?? [])])
163
+ socket.destroy();
164
+ }
165
+ }
166
+ /**
167
+ * Wrap `host.callApi` so a request that rode a reused connection and was dropped before any byte of an answer is sent again
168
+ * ONCE on a fresh connection (see the module description for what that does and does not guarantee). A second failure is the
169
+ * caller's, as before. `agent` is the one `host` sends through. Sits BELOW the send queue, the global pacer and the 429
170
+ * retry — the retry takes no permit, the thread's order is kept — and above the output trace, which therefore shows both
171
+ * attempts.
172
+ */
173
+ function installReusedConnectionRetry(host, agent) {
174
+ const originalCallApi = host.callApi.bind(host);
175
+ host.callApi = async (method, payload, options) => {
176
+ const probe = { isPooledConnectionLost: false };
177
+ try {
178
+ return await reuseProbeStorage.run(probe, () => originalCallApi(method, payload, options));
179
+ }
180
+ catch (error) {
181
+ const isRetryable = probe.isPooledConnectionLost && (0, sendErrorClassifier_1.checkIsConnectionResetError)(error) && checkIsPayloadReplayable(payload);
182
+ if (!isRetryable)
183
+ throw error;
184
+ console.warn(`${exports.reusedConnectionRetryLogPrefix} (${method})`);
185
+ destroyFreeSockets(agent);
186
+ return originalCallApi(method, payload, options);
187
+ }
188
+ };
189
+ }
190
+ /**
191
+ * @description Put the bot's pooling on a Telegraf client: its agent (Telegraf drops the agent of an `http://` root, and
192
+ * builds every client from options that already lack it) and the retry of a request that met a closed pooled connection.
193
+ * Telegraf builds a NEW client for every update (`ctx.telegram`, behind `ctx.reply` / `ctx.answerCbQuery` /
194
+ * `ctx.editMessageText`), so this runs once for `bot.telegram` and once per update for `ctx.telegram`. For `bot.telegram`
195
+ * call it AFTER the output trace wrap, so the trace records both attempts of a retried request.
196
+ */
197
+ function wireBotApiClient(telegram, agent) {
198
+ telegram.options.agent = agent;
199
+ installReusedConnectionRetry(telegram, agent);
200
+ }
201
+ //# sourceMappingURL=botApiConnection.js.map