@animalabs/agent-framework 0.22.1 → 0.22.3

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 (946) hide show
  1. package/README.md +4 -2
  2. package/dist/src/agent.d.ts +266 -28
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +539 -104
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/mcp-server-core.d.ts +41 -0
  7. package/dist/src/api/mcp-server-core.d.ts.map +1 -0
  8. package/dist/src/api/mcp-server-core.js +593 -0
  9. package/dist/src/api/mcp-server-core.js.map +1 -0
  10. package/dist/src/api/mcp-server.d.ts +2 -36
  11. package/dist/src/api/mcp-server.d.ts.map +1 -1
  12. package/dist/src/api/mcp-server.js +15 -595
  13. package/dist/src/api/mcp-server.js.map +1 -1
  14. package/dist/src/api/server.d.ts +9 -1
  15. package/dist/src/api/server.d.ts.map +1 -1
  16. package/dist/src/api/server.js +55 -27
  17. package/dist/src/api/server.js.map +1 -1
  18. package/dist/src/api/types.d.ts +10 -2
  19. package/dist/src/api/types.d.ts.map +1 -1
  20. package/dist/src/branch-names.d.ts +14 -0
  21. package/dist/src/branch-names.d.ts.map +1 -0
  22. package/dist/src/branch-names.js +22 -0
  23. package/dist/src/branch-names.js.map +1 -0
  24. package/dist/src/closest-names.d.ts +28 -0
  25. package/dist/src/closest-names.d.ts.map +1 -0
  26. package/dist/src/closest-names.js +98 -0
  27. package/dist/src/closest-names.js.map +1 -0
  28. package/dist/src/code-execution/py-runner.d.ts +16 -5
  29. package/dist/src/code-execution/py-runner.d.ts.map +1 -1
  30. package/dist/src/code-execution/py-runner.js +186 -74
  31. package/dist/src/code-execution/py-runner.js.map +1 -1
  32. package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
  33. package/dist/src/code-execution/runtime-py.js +49 -3
  34. package/dist/src/code-execution/runtime-py.js.map +1 -1
  35. package/dist/src/code-execution/tool-definition.d.ts +12 -1
  36. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  37. package/dist/src/code-execution/tool-definition.js +21 -3
  38. package/dist/src/code-execution/tool-definition.js.map +1 -1
  39. package/dist/src/config-checks.d.ts +28 -0
  40. package/dist/src/config-checks.d.ts.map +1 -0
  41. package/dist/src/config-checks.js +52 -0
  42. package/dist/src/config-checks.js.map +1 -0
  43. package/dist/src/deadline-timer.d.ts +21 -0
  44. package/dist/src/deadline-timer.d.ts.map +1 -0
  45. package/dist/src/deadline-timer.js +43 -0
  46. package/dist/src/deadline-timer.js.map +1 -0
  47. package/dist/src/error-message.d.ts +30 -0
  48. package/dist/src/error-message.d.ts.map +1 -0
  49. package/dist/src/error-message.js +50 -0
  50. package/dist/src/error-message.js.map +1 -0
  51. package/dist/src/framework.d.ts +1212 -192
  52. package/dist/src/framework.d.ts.map +1 -1
  53. package/dist/src/framework.js +6686 -1835
  54. package/dist/src/framework.js.map +1 -1
  55. package/dist/src/gate/event-gate.d.ts +8 -0
  56. package/dist/src/gate/event-gate.d.ts.map +1 -1
  57. package/dist/src/gate/event-gate.js +27 -3
  58. package/dist/src/gate/event-gate.js.map +1 -1
  59. package/dist/src/gate/gate-script.d.ts.map +1 -1
  60. package/dist/src/gate/gate-script.js.map +1 -1
  61. package/dist/src/index.d.ts +5 -3
  62. package/dist/src/index.d.ts.map +1 -1
  63. package/dist/src/index.js +5 -3
  64. package/dist/src/index.js.map +1 -1
  65. package/dist/src/mcpl/capability-grant.d.ts.map +1 -1
  66. package/dist/src/mcpl/channel-registry.d.ts +170 -13
  67. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  68. package/dist/src/mcpl/channel-registry.js +499 -258
  69. package/dist/src/mcpl/channel-registry.js.map +1 -1
  70. package/dist/src/mcpl/checkpoint-manager.d.ts +21 -1
  71. package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
  72. package/dist/src/mcpl/checkpoint-manager.js +91 -30
  73. package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
  74. package/dist/src/mcpl/conversation-router.d.ts +19 -3
  75. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  76. package/dist/src/mcpl/conversation-router.js +23 -8
  77. package/dist/src/mcpl/conversation-router.js.map +1 -1
  78. package/dist/src/mcpl/convert-block.d.ts +20 -0
  79. package/dist/src/mcpl/convert-block.d.ts.map +1 -0
  80. package/dist/src/mcpl/convert-block.js +89 -0
  81. package/dist/src/mcpl/convert-block.js.map +1 -0
  82. package/dist/src/mcpl/errors.d.ts +13 -0
  83. package/dist/src/mcpl/errors.d.ts.map +1 -1
  84. package/dist/src/mcpl/errors.js +28 -0
  85. package/dist/src/mcpl/errors.js.map +1 -1
  86. package/dist/src/mcpl/feature-set-manager.d.ts.map +1 -1
  87. package/dist/src/mcpl/feature-set-manager.js +4 -3
  88. package/dist/src/mcpl/feature-set-manager.js.map +1 -1
  89. package/dist/src/mcpl/hook-orchestrator.d.ts +23 -0
  90. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
  91. package/dist/src/mcpl/hook-orchestrator.js +83 -72
  92. package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
  93. package/dist/src/mcpl/inbound-source.d.ts +114 -0
  94. package/dist/src/mcpl/inbound-source.d.ts.map +1 -0
  95. package/dist/src/mcpl/inbound-source.js +83 -0
  96. package/dist/src/mcpl/inbound-source.js.map +1 -0
  97. package/dist/src/mcpl/index.d.ts +3 -1
  98. package/dist/src/mcpl/index.d.ts.map +1 -1
  99. package/dist/src/mcpl/index.js +3 -1
  100. package/dist/src/mcpl/index.js.map +1 -1
  101. package/dist/src/mcpl/inference-router.d.ts +15 -11
  102. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  103. package/dist/src/mcpl/inference-router.js +153 -84
  104. package/dist/src/mcpl/inference-router.js.map +1 -1
  105. package/dist/src/mcpl/log-value.d.ts +54 -0
  106. package/dist/src/mcpl/log-value.d.ts.map +1 -0
  107. package/dist/src/mcpl/log-value.js +109 -0
  108. package/dist/src/mcpl/log-value.js.map +1 -0
  109. package/dist/src/mcpl/prose-stream-router.d.ts +6 -6
  110. package/dist/src/mcpl/prose-stream-router.d.ts.map +1 -1
  111. package/dist/src/mcpl/prose-stream-router.js +4 -4
  112. package/dist/src/mcpl/prose-stream-router.js.map +1 -1
  113. package/dist/src/mcpl/push-coalescer.d.ts +64 -7
  114. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  115. package/dist/src/mcpl/push-coalescer.js +121 -24
  116. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  117. package/dist/src/mcpl/push-handler.d.ts +38 -8
  118. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  119. package/dist/src/mcpl/push-handler.js +77 -78
  120. package/dist/src/mcpl/push-handler.js.map +1 -1
  121. package/dist/src/mcpl/reference-fetcher.d.ts +14 -2
  122. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  123. package/dist/src/mcpl/reference-fetcher.js +72 -30
  124. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  125. package/dist/src/mcpl/references.d.ts +49 -14
  126. package/dist/src/mcpl/references.d.ts.map +1 -1
  127. package/dist/src/mcpl/references.js +74 -21
  128. package/dist/src/mcpl/references.js.map +1 -1
  129. package/dist/src/mcpl/refusal-lines.d.ts +37 -0
  130. package/dist/src/mcpl/refusal-lines.d.ts.map +1 -0
  131. package/dist/src/mcpl/refusal-lines.js +61 -0
  132. package/dist/src/mcpl/refusal-lines.js.map +1 -0
  133. package/dist/src/mcpl/scope-manager.d.ts.map +1 -1
  134. package/dist/src/mcpl/server-connection.d.ts +107 -12
  135. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  136. package/dist/src/mcpl/server-connection.js +470 -139
  137. package/dist/src/mcpl/server-connection.js.map +1 -1
  138. package/dist/src/mcpl/server-registry.d.ts +10 -1
  139. package/dist/src/mcpl/server-registry.d.ts.map +1 -1
  140. package/dist/src/mcpl/server-registry.js +14 -3
  141. package/dist/src/mcpl/server-registry.js.map +1 -1
  142. package/dist/src/mcpl/skip-reply-wake.d.ts +36 -0
  143. package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -0
  144. package/dist/src/mcpl/skip-reply-wake.js +55 -0
  145. package/dist/src/mcpl/skip-reply-wake.js.map +1 -0
  146. package/dist/src/mcpl/tool-classes.d.ts +1 -1
  147. package/dist/src/mcpl/tool-classes.d.ts.map +1 -1
  148. package/dist/src/mcpl/tool-classes.js +3 -2
  149. package/dist/src/mcpl/tool-classes.js.map +1 -1
  150. package/dist/src/mcpl/tool-lifecycle.d.ts.map +1 -1
  151. package/dist/src/mcpl/tool-lifecycle.js.map +1 -1
  152. package/dist/src/mcpl/transport.d.ts +74 -7
  153. package/dist/src/mcpl/transport.d.ts.map +1 -1
  154. package/dist/src/mcpl/transport.js +209 -22
  155. package/dist/src/mcpl/transport.js.map +1 -1
  156. package/dist/src/mcpl/types.d.ts +43 -28
  157. package/dist/src/mcpl/types.d.ts.map +1 -1
  158. package/dist/src/mcpl/types.js.map +1 -1
  159. package/dist/src/mcpl/visible-content.d.ts +15 -0
  160. package/dist/src/mcpl/visible-content.d.ts.map +1 -1
  161. package/dist/src/mcpl/visible-content.js +25 -0
  162. package/dist/src/mcpl/visible-content.js.map +1 -1
  163. package/dist/src/module-registry.d.ts +19 -1
  164. package/dist/src/module-registry.d.ts.map +1 -1
  165. package/dist/src/module-registry.js +54 -25
  166. package/dist/src/module-registry.js.map +1 -1
  167. package/dist/src/modules/api/index.d.ts.map +1 -1
  168. package/dist/src/modules/api/index.js +1 -1
  169. package/dist/src/modules/api/index.js.map +1 -1
  170. package/dist/src/modules/discord/discord-js-client.d.ts +1 -0
  171. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  172. package/dist/src/modules/discord/discord-js-client.js +25 -9
  173. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  174. package/dist/src/modules/discord/index.d.ts +29 -3
  175. package/dist/src/modules/discord/index.d.ts.map +1 -1
  176. package/dist/src/modules/discord/index.js +383 -145
  177. package/dist/src/modules/discord/index.js.map +1 -1
  178. package/dist/src/modules/discord/types.d.ts +14 -1
  179. package/dist/src/modules/discord/types.d.ts.map +1 -1
  180. package/dist/src/modules/health/index.d.ts.map +1 -1
  181. package/dist/src/modules/health/index.js +2 -1
  182. package/dist/src/modules/health/index.js.map +1 -1
  183. package/dist/src/modules/history/index.d.ts +3 -1
  184. package/dist/src/modules/history/index.d.ts.map +1 -1
  185. package/dist/src/modules/history/index.js +359 -127
  186. package/dist/src/modules/history/index.js.map +1 -1
  187. package/dist/src/modules/history/semantic.d.ts +28 -1
  188. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  189. package/dist/src/modules/history/semantic.js +177 -32
  190. package/dist/src/modules/history/semantic.js.map +1 -1
  191. package/dist/src/modules/unknown-tool.d.ts +10 -0
  192. package/dist/src/modules/unknown-tool.d.ts.map +1 -0
  193. package/dist/src/modules/unknown-tool.js +17 -0
  194. package/dist/src/modules/unknown-tool.js.map +1 -0
  195. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  196. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  197. package/dist/src/modules/workspace/disk-agreement.d.ts +54 -6
  198. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  199. package/dist/src/modules/workspace/disk-agreement.js +93 -27
  200. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  201. package/dist/src/modules/workspace/effects.d.ts +64 -6
  202. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  203. package/dist/src/modules/workspace/effects.js +291 -44
  204. package/dist/src/modules/workspace/effects.js.map +1 -1
  205. package/dist/src/modules/workspace/index.d.ts +127 -27
  206. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  207. package/dist/src/modules/workspace/index.js +821 -248
  208. package/dist/src/modules/workspace/index.js.map +1 -1
  209. package/dist/src/modules/workspace/observe.d.ts +117 -15
  210. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  211. package/dist/src/modules/workspace/observe.js +436 -51
  212. package/dist/src/modules/workspace/observe.js.map +1 -1
  213. package/dist/src/modules/workspace/reconcile.d.ts +75 -8
  214. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  215. package/dist/src/modules/workspace/reconcile.js +576 -68
  216. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  217. package/dist/src/modules/workspace/types.d.ts +42 -3
  218. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  219. package/dist/src/modules/workspace/types.js.map +1 -1
  220. package/dist/src/modules/workspace/watcher.d.ts +7 -2
  221. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  222. package/dist/src/modules/workspace/watcher.js +28 -4
  223. package/dist/src/modules/workspace/watcher.js.map +1 -1
  224. package/dist/src/operator-log.d.ts.map +1 -1
  225. package/dist/src/operator-log.js.map +1 -1
  226. package/dist/src/prose-drafts.d.ts +240 -0
  227. package/dist/src/prose-drafts.d.ts.map +1 -0
  228. package/dist/src/prose-drafts.js +362 -0
  229. package/dist/src/prose-drafts.js.map +1 -0
  230. package/dist/src/prose-segments.d.ts +21 -2
  231. package/dist/src/prose-segments.d.ts.map +1 -1
  232. package/dist/src/prose-segments.js +46 -9
  233. package/dist/src/prose-segments.js.map +1 -1
  234. package/dist/src/provider-waits.d.ts.map +1 -1
  235. package/dist/src/provider-waits.js.map +1 -1
  236. package/dist/src/queue.d.ts.map +1 -1
  237. package/dist/src/record-journal.d.ts.map +1 -1
  238. package/dist/src/record-journal.js.map +1 -1
  239. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  240. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  241. package/dist/src/recovery/offline-branch.d.ts +1 -0
  242. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  243. package/dist/src/recovery/offline-branch.js +32 -25
  244. package/dist/src/recovery/offline-branch.js.map +1 -1
  245. package/dist/src/recovery/recover-cli.js.map +1 -1
  246. package/dist/src/runtime/liveness-watchdog.d.ts.map +1 -1
  247. package/dist/src/runtime/liveness-watchdog.js.map +1 -1
  248. package/dist/src/safe-slice.d.ts +5 -1
  249. package/dist/src/safe-slice.d.ts.map +1 -1
  250. package/dist/src/safe-slice.js +9 -1
  251. package/dist/src/safe-slice.js.map +1 -1
  252. package/dist/src/shutdown.d.ts.map +1 -1
  253. package/dist/src/shutdown.js.map +1 -1
  254. package/dist/src/stored-removal.d.ts +73 -0
  255. package/dist/src/stored-removal.d.ts.map +1 -0
  256. package/dist/src/stored-removal.js +100 -0
  257. package/dist/src/stored-removal.js.map +1 -0
  258. package/dist/src/thinking-token-stamp.js.map +1 -1
  259. package/dist/src/tool-image-ledger.d.ts +87 -19
  260. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  261. package/dist/src/tool-image-ledger.js +135 -32
  262. package/dist/src/tool-image-ledger.js.map +1 -1
  263. package/dist/src/tool-presentation.d.ts +9 -0
  264. package/dist/src/tool-presentation.d.ts.map +1 -1
  265. package/dist/src/tool-presentation.js +257 -60
  266. package/dist/src/tool-presentation.js.map +1 -1
  267. package/dist/src/tool-result-guard.d.ts.map +1 -1
  268. package/dist/src/tool-result-guard.js +7 -10
  269. package/dist/src/tool-result-guard.js.map +1 -1
  270. package/dist/src/tool-result-history.d.ts +32 -3
  271. package/dist/src/tool-result-history.d.ts.map +1 -1
  272. package/dist/src/tool-result-history.js +106 -19
  273. package/dist/src/tool-result-history.js.map +1 -1
  274. package/dist/src/tune-out/coordinator.d.ts +25 -1
  275. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  276. package/dist/src/tune-out/coordinator.js +260 -65
  277. package/dist/src/tune-out/coordinator.js.map +1 -1
  278. package/dist/src/tune-out/tools.d.ts +1 -1
  279. package/dist/src/tune-out/tools.d.ts.map +1 -1
  280. package/dist/src/types/agent.d.ts +59 -11
  281. package/dist/src/types/agent.d.ts.map +1 -1
  282. package/dist/src/types/events.d.ts +17 -0
  283. package/dist/src/types/events.d.ts.map +1 -1
  284. package/dist/src/types/framework.d.ts +31 -5
  285. package/dist/src/types/framework.d.ts.map +1 -1
  286. package/dist/src/types/inference-log.d.ts +1 -1
  287. package/dist/src/types/inference-log.d.ts.map +1 -1
  288. package/dist/src/types/module.d.ts +30 -7
  289. package/dist/src/types/module.d.ts.map +1 -1
  290. package/dist/src/types/trace.d.ts +151 -11
  291. package/dist/src/types/trace.d.ts.map +1 -1
  292. package/dist/src/usage/usage-tracker.d.ts +5 -0
  293. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  294. package/dist/src/usage/usage-tracker.js +35 -8
  295. package/dist/src/usage/usage-tracker.js.map +1 -1
  296. package/package.json +10 -9
  297. package/src/agent.ts +572 -105
  298. package/src/api/mcp-server-core.ts +681 -0
  299. package/src/api/mcp-server.ts +16 -685
  300. package/src/api/server.ts +55 -30
  301. package/src/api/types.ts +10 -2
  302. package/src/branch-names.ts +19 -0
  303. package/src/closest-names.ts +94 -0
  304. package/src/code-execution/py-runner.ts +200 -76
  305. package/src/code-execution/runtime-py.ts +49 -3
  306. package/src/code-execution/tool-definition.ts +28 -4
  307. package/src/config-checks.ts +48 -0
  308. package/src/deadline-timer.ts +44 -0
  309. package/src/error-message.ts +48 -0
  310. package/src/framework.ts +7158 -1936
  311. package/src/gate/event-gate.ts +28 -3
  312. package/src/index.ts +12 -3
  313. package/src/mcpl/channel-registry.ts +615 -289
  314. package/src/mcpl/checkpoint-manager.ts +104 -29
  315. package/src/mcpl/conversation-router.ts +28 -8
  316. package/src/mcpl/convert-block.ts +97 -0
  317. package/src/mcpl/errors.ts +28 -0
  318. package/src/mcpl/feature-set-manager.ts +4 -3
  319. package/src/mcpl/hook-orchestrator.ts +84 -77
  320. package/src/mcpl/inbound-source.ts +156 -0
  321. package/src/mcpl/index.ts +10 -1
  322. package/src/mcpl/inference-router.ts +174 -99
  323. package/src/mcpl/log-value.ts +116 -0
  324. package/src/mcpl/prose-stream-router.ts +6 -6
  325. package/src/mcpl/push-coalescer.ts +124 -24
  326. package/src/mcpl/push-handler.ts +86 -84
  327. package/src/mcpl/reference-fetcher.ts +71 -26
  328. package/src/mcpl/references.ts +81 -22
  329. package/src/mcpl/refusal-lines.ts +59 -0
  330. package/src/mcpl/server-connection.ts +496 -142
  331. package/src/mcpl/server-registry.ts +15 -4
  332. package/src/mcpl/skip-reply-wake.ts +73 -0
  333. package/src/mcpl/tool-classes.ts +3 -2
  334. package/src/mcpl/transport.ts +219 -26
  335. package/src/mcpl/types.ts +18 -3
  336. package/src/mcpl/visible-content.ts +27 -0
  337. package/src/module-registry.ts +58 -23
  338. package/src/modules/api/index.ts +1 -1
  339. package/src/modules/discord/discord-js-client.ts +26 -10
  340. package/src/modules/discord/index.ts +395 -160
  341. package/src/modules/discord/types.ts +15 -2
  342. package/src/modules/health/index.ts +2 -1
  343. package/src/modules/history/index.ts +410 -120
  344. package/src/modules/history/semantic.ts +189 -32
  345. package/src/modules/unknown-tool.ts +16 -0
  346. package/src/modules/workspace/disk-agreement.ts +125 -21
  347. package/src/modules/workspace/effects.ts +279 -35
  348. package/src/modules/workspace/index.ts +841 -261
  349. package/src/modules/workspace/observe.ts +456 -56
  350. package/src/modules/workspace/reconcile.ts +688 -76
  351. package/src/modules/workspace/types.ts +41 -2
  352. package/src/modules/workspace/watcher.ts +27 -4
  353. package/src/prose-drafts.ts +481 -0
  354. package/src/prose-segments.ts +51 -8
  355. package/src/recovery/offline-branch.ts +36 -29
  356. package/src/safe-slice.ts +9 -1
  357. package/src/stored-removal.ts +126 -0
  358. package/src/tool-image-ledger.ts +153 -34
  359. package/src/tool-presentation.ts +224 -40
  360. package/src/tool-result-guard.ts +7 -8
  361. package/src/tool-result-history.ts +124 -20
  362. package/src/tune-out/coordinator.ts +259 -65
  363. package/src/types/agent.ts +59 -13
  364. package/src/types/events.ts +17 -0
  365. package/src/types/framework.ts +31 -5
  366. package/src/types/inference-log.ts +1 -1
  367. package/src/types/module.ts +31 -7
  368. package/src/types/trace.ts +158 -12
  369. package/src/usage/usage-tracker.ts +32 -8
  370. package/dist/test/activation-request-sanitize.test.d.ts +0 -2
  371. package/dist/test/activation-request-sanitize.test.d.ts.map +0 -1
  372. package/dist/test/activation-request-sanitize.test.js +0 -89
  373. package/dist/test/activation-request-sanitize.test.js.map +0 -1
  374. package/dist/test/agent-cache-ttl.test.d.ts +0 -2
  375. package/dist/test/agent-cache-ttl.test.d.ts.map +0 -1
  376. package/dist/test/agent-cache-ttl.test.js +0 -41
  377. package/dist/test/agent-cache-ttl.test.js.map +0 -1
  378. package/dist/test/agent-runtime-settings.test.d.ts +0 -2
  379. package/dist/test/agent-runtime-settings.test.d.ts.map +0 -1
  380. package/dist/test/agent-runtime-settings.test.js +0 -462
  381. package/dist/test/agent-runtime-settings.test.js.map +0 -1
  382. package/dist/test/api-admin-gate.test.d.ts +0 -2
  383. package/dist/test/api-admin-gate.test.d.ts.map +0 -1
  384. package/dist/test/api-admin-gate.test.js +0 -116
  385. package/dist/test/api-admin-gate.test.js.map +0 -1
  386. package/dist/test/assistant-persist-refusal.test.d.ts +0 -2
  387. package/dist/test/assistant-persist-refusal.test.d.ts.map +0 -1
  388. package/dist/test/assistant-persist-refusal.test.js +0 -63
  389. package/dist/test/assistant-persist-refusal.test.js.map +0 -1
  390. package/dist/test/batched-wake-locus.test.d.ts +0 -2
  391. package/dist/test/batched-wake-locus.test.d.ts.map +0 -1
  392. package/dist/test/batched-wake-locus.test.js +0 -166
  393. package/dist/test/batched-wake-locus.test.js.map +0 -1
  394. package/dist/test/busy-agent-scheduler.test.d.ts +0 -2
  395. package/dist/test/busy-agent-scheduler.test.d.ts.map +0 -1
  396. package/dist/test/busy-agent-scheduler.test.js +0 -92
  397. package/dist/test/busy-agent-scheduler.test.js.map +0 -1
  398. package/dist/test/channel-incoming-targeting.test.d.ts +0 -2
  399. package/dist/test/channel-incoming-targeting.test.d.ts.map +0 -1
  400. package/dist/test/channel-incoming-targeting.test.js +0 -81
  401. package/dist/test/channel-incoming-targeting.test.js.map +0 -1
  402. package/dist/test/channel-label-history.test.d.ts +0 -2
  403. package/dist/test/channel-label-history.test.d.ts.map +0 -1
  404. package/dist/test/channel-label-history.test.js +0 -424
  405. package/dist/test/channel-label-history.test.js.map +0 -1
  406. package/dist/test/channel-lifecycle-provenance.test.d.ts +0 -2
  407. package/dist/test/channel-lifecycle-provenance.test.d.ts.map +0 -1
  408. package/dist/test/channel-lifecycle-provenance.test.js +0 -47
  409. package/dist/test/channel-lifecycle-provenance.test.js.map +0 -1
  410. package/dist/test/channel-registry-routing.test.d.ts +0 -2
  411. package/dist/test/channel-registry-routing.test.d.ts.map +0 -1
  412. package/dist/test/channel-registry-routing.test.js +0 -446
  413. package/dist/test/channel-registry-routing.test.js.map +0 -1
  414. package/dist/test/channel-registry-typing.test.d.ts +0 -2
  415. package/dist/test/channel-registry-typing.test.d.ts.map +0 -1
  416. package/dist/test/channel-registry-typing.test.js +0 -91
  417. package/dist/test/channel-registry-typing.test.js.map +0 -1
  418. package/dist/test/channels-changed-respond-first.test.d.ts +0 -2
  419. package/dist/test/channels-changed-respond-first.test.d.ts.map +0 -1
  420. package/dist/test/channels-changed-respond-first.test.js +0 -74
  421. package/dist/test/channels-changed-respond-first.test.js.map +0 -1
  422. package/dist/test/checkpoint-attribution.test.d.ts +0 -2
  423. package/dist/test/checkpoint-attribution.test.d.ts.map +0 -1
  424. package/dist/test/checkpoint-attribution.test.js +0 -200
  425. package/dist/test/checkpoint-attribution.test.js.map +0 -1
  426. package/dist/test/code-execution.test.d.ts +0 -11
  427. package/dist/test/code-execution.test.d.ts.map +0 -1
  428. package/dist/test/code-execution.test.js +0 -1272
  429. package/dist/test/code-execution.test.js.map +0 -1
  430. package/dist/test/component-defaults.test.d.ts +0 -2
  431. package/dist/test/component-defaults.test.d.ts.map +0 -1
  432. package/dist/test/component-defaults.test.js +0 -54
  433. package/dist/test/component-defaults.test.js.map +0 -1
  434. package/dist/test/conversation-fork-injection-scoping.test.d.ts +0 -2
  435. package/dist/test/conversation-fork-injection-scoping.test.d.ts.map +0 -1
  436. package/dist/test/conversation-fork-injection-scoping.test.js +0 -200
  437. package/dist/test/conversation-fork-injection-scoping.test.js.map +0 -1
  438. package/dist/test/conversation-router.test.d.ts +0 -2
  439. package/dist/test/conversation-router.test.d.ts.map +0 -1
  440. package/dist/test/conversation-router.test.js +0 -174
  441. package/dist/test/conversation-router.test.js.map +0 -1
  442. package/dist/test/conversation-routing.test.d.ts +0 -7
  443. package/dist/test/conversation-routing.test.d.ts.map +0 -1
  444. package/dist/test/conversation-routing.test.js +0 -387
  445. package/dist/test/conversation-routing.test.js.map +0 -1
  446. package/dist/test/deferred-wake-integrity.test.d.ts +0 -29
  447. package/dist/test/deferred-wake-integrity.test.d.ts.map +0 -1
  448. package/dist/test/deferred-wake-integrity.test.js +0 -320
  449. package/dist/test/deferred-wake-integrity.test.js.map +0 -1
  450. package/dist/test/discord-awareness-outbox.test.d.ts +0 -2
  451. package/dist/test/discord-awareness-outbox.test.d.ts.map +0 -1
  452. package/dist/test/discord-awareness-outbox.test.js +0 -267
  453. package/dist/test/discord-awareness-outbox.test.js.map +0 -1
  454. package/dist/test/discord-history-delete-window.test.d.ts +0 -2
  455. package/dist/test/discord-history-delete-window.test.d.ts.map +0 -1
  456. package/dist/test/discord-history-delete-window.test.js +0 -81
  457. package/dist/test/discord-history-delete-window.test.js.map +0 -1
  458. package/dist/test/discord-history-sync.test.d.ts +0 -2
  459. package/dist/test/discord-history-sync.test.d.ts.map +0 -1
  460. package/dist/test/discord-history-sync.test.js +0 -56
  461. package/dist/test/discord-history-sync.test.js.map +0 -1
  462. package/dist/test/ephemeral-settle.test.d.ts +0 -2
  463. package/dist/test/ephemeral-settle.test.d.ts.map +0 -1
  464. package/dist/test/ephemeral-settle.test.js +0 -354
  465. package/dist/test/ephemeral-settle.test.js.map +0 -1
  466. package/dist/test/event-gate-passthrough.test.d.ts +0 -15
  467. package/dist/test/event-gate-passthrough.test.d.ts.map +0 -1
  468. package/dist/test/event-gate-passthrough.test.js +0 -289
  469. package/dist/test/event-gate-passthrough.test.js.map +0 -1
  470. package/dist/test/event-gate-policy-mutation.test.d.ts +0 -2
  471. package/dist/test/event-gate-policy-mutation.test.d.ts.map +0 -1
  472. package/dist/test/event-gate-policy-mutation.test.js +0 -137
  473. package/dist/test/event-gate-policy-mutation.test.js.map +0 -1
  474. package/dist/test/event-gate-rate-limit.test.d.ts +0 -2
  475. package/dist/test/event-gate-rate-limit.test.d.ts.map +0 -1
  476. package/dist/test/event-gate-rate-limit.test.js +0 -627
  477. package/dist/test/event-gate-rate-limit.test.js.map +0 -1
  478. package/dist/test/event-gate-script.test.d.ts +0 -2
  479. package/dist/test/event-gate-script.test.d.ts.map +0 -1
  480. package/dist/test/event-gate-script.test.js +0 -95
  481. package/dist/test/event-gate-script.test.js.map +0 -1
  482. package/dist/test/event-gate-selfwake.test.d.ts +0 -15
  483. package/dist/test/event-gate-selfwake.test.d.ts.map +0 -1
  484. package/dist/test/event-gate-selfwake.test.js +0 -125
  485. package/dist/test/event-gate-selfwake.test.js.map +0 -1
  486. package/dist/test/event-gate-tags.test.d.ts +0 -2
  487. package/dist/test/event-gate-tags.test.d.ts.map +0 -1
  488. package/dist/test/event-gate-tags.test.js +0 -76
  489. package/dist/test/event-gate-tags.test.js.map +0 -1
  490. package/dist/test/event-gate.test.d.ts +0 -2
  491. package/dist/test/event-gate.test.d.ts.map +0 -1
  492. package/dist/test/event-gate.test.js +0 -919
  493. package/dist/test/event-gate.test.js.map +0 -1
  494. package/dist/test/explicit-prose-routing.test.d.ts +0 -11
  495. package/dist/test/explicit-prose-routing.test.d.ts.map +0 -1
  496. package/dist/test/explicit-prose-routing.test.js +0 -1394
  497. package/dist/test/explicit-prose-routing.test.js.map +0 -1
  498. package/dist/test/framework.test.d.ts +0 -5
  499. package/dist/test/framework.test.d.ts.map +0 -1
  500. package/dist/test/framework.test.js +0 -1048
  501. package/dist/test/framework.test.js.map +0 -1
  502. package/dist/test/gather-context-timeout.test.d.ts +0 -2
  503. package/dist/test/gather-context-timeout.test.d.ts.map +0 -1
  504. package/dist/test/gather-context-timeout.test.js +0 -120
  505. package/dist/test/gather-context-timeout.test.js.map +0 -1
  506. package/dist/test/health-snapshot.test.d.ts +0 -2
  507. package/dist/test/health-snapshot.test.d.ts.map +0 -1
  508. package/dist/test/health-snapshot.test.js +0 -74
  509. package/dist/test/health-snapshot.test.js.map +0 -1
  510. package/dist/test/helpers/coalescing-fixture.d.ts +0 -72
  511. package/dist/test/helpers/coalescing-fixture.d.ts.map +0 -1
  512. package/dist/test/helpers/coalescing-fixture.js +0 -146
  513. package/dist/test/helpers/coalescing-fixture.js.map +0 -1
  514. package/dist/test/helpers/coalescing-kill-child.d.ts +0 -2
  515. package/dist/test/helpers/coalescing-kill-child.d.ts.map +0 -1
  516. package/dist/test/helpers/coalescing-kill-child.js +0 -24
  517. package/dist/test/helpers/coalescing-kill-child.js.map +0 -1
  518. package/dist/test/helpers/mock-membrane.d.ts +0 -53
  519. package/dist/test/helpers/mock-membrane.d.ts.map +0 -1
  520. package/dist/test/helpers/mock-membrane.js +0 -168
  521. package/dist/test/helpers/mock-membrane.js.map +0 -1
  522. package/dist/test/helpers/pytc-stop-rows.d.ts +0 -11
  523. package/dist/test/helpers/pytc-stop-rows.d.ts.map +0 -1
  524. package/dist/test/helpers/pytc-stop-rows.js +0 -143
  525. package/dist/test/helpers/pytc-stop-rows.js.map +0 -1
  526. package/dist/test/helpers/quiesce-crash-child.d.ts +0 -2
  527. package/dist/test/helpers/quiesce-crash-child.d.ts.map +0 -1
  528. package/dist/test/helpers/quiesce-crash-child.js +0 -156
  529. package/dist/test/helpers/quiesce-crash-child.js.map +0 -1
  530. package/dist/test/history-module-overview.test.d.ts +0 -2
  531. package/dist/test/history-module-overview.test.d.ts.map +0 -1
  532. package/dist/test/history-module-overview.test.js +0 -711
  533. package/dist/test/history-module-overview.test.js.map +0 -1
  534. package/dist/test/history-module-realstore.test.d.ts +0 -2
  535. package/dist/test/history-module-realstore.test.d.ts.map +0 -1
  536. package/dist/test/history-module-realstore.test.js +0 -363
  537. package/dist/test/history-module-realstore.test.js.map +0 -1
  538. package/dist/test/history-module-semantic.test.d.ts +0 -2
  539. package/dist/test/history-module-semantic.test.d.ts.map +0 -1
  540. package/dist/test/history-module-semantic.test.js +0 -213
  541. package/dist/test/history-module-semantic.test.js.map +0 -1
  542. package/dist/test/history-module-ux.test.d.ts +0 -2
  543. package/dist/test/history-module-ux.test.d.ts.map +0 -1
  544. package/dist/test/history-module-ux.test.js +0 -304
  545. package/dist/test/history-module-ux.test.js.map +0 -1
  546. package/dist/test/history-module.test.d.ts +0 -2
  547. package/dist/test/history-module.test.d.ts.map +0 -1
  548. package/dist/test/history-module.test.js +0 -619
  549. package/dist/test/history-module.test.js.map +0 -1
  550. package/dist/test/history-semantic-review-findings.test.d.ts +0 -2
  551. package/dist/test/history-semantic-review-findings.test.d.ts.map +0 -1
  552. package/dist/test/history-semantic-review-findings.test.js +0 -338
  553. package/dist/test/history-semantic-review-findings.test.js.map +0 -1
  554. package/dist/test/history-semantic-sync-converges.test.d.ts +0 -2
  555. package/dist/test/history-semantic-sync-converges.test.d.ts.map +0 -1
  556. package/dist/test/history-semantic-sync-converges.test.js +0 -109
  557. package/dist/test/history-semantic-sync-converges.test.js.map +0 -1
  558. package/dist/test/host-quiesce.test.d.ts +0 -2
  559. package/dist/test/host-quiesce.test.d.ts.map +0 -1
  560. package/dist/test/host-quiesce.test.js +0 -863
  561. package/dist/test/host-quiesce.test.js.map +0 -1
  562. package/dist/test/inference-exhaustion-rewind.test.d.ts +0 -2
  563. package/dist/test/inference-exhaustion-rewind.test.d.ts.map +0 -1
  564. package/dist/test/inference-exhaustion-rewind.test.js +0 -309
  565. package/dist/test/inference-exhaustion-rewind.test.js.map +0 -1
  566. package/dist/test/inference-failure-bounds.test.d.ts +0 -2
  567. package/dist/test/inference-failure-bounds.test.d.ts.map +0 -1
  568. package/dist/test/inference-failure-bounds.test.js +0 -1201
  569. package/dist/test/inference-failure-bounds.test.js.map +0 -1
  570. package/dist/test/inference-failure-observability.test.d.ts +0 -2
  571. package/dist/test/inference-failure-observability.test.d.ts.map +0 -1
  572. package/dist/test/inference-failure-observability.test.js +0 -84
  573. package/dist/test/inference-failure-observability.test.js.map +0 -1
  574. package/dist/test/journal-tool.test.d.ts +0 -2
  575. package/dist/test/journal-tool.test.d.ts.map +0 -1
  576. package/dist/test/journal-tool.test.js +0 -33
  577. package/dist/test/journal-tool.test.js.map +0 -1
  578. package/dist/test/kv-unified-open-flight-retry.test.d.ts +0 -2
  579. package/dist/test/kv-unified-open-flight-retry.test.d.ts.map +0 -1
  580. package/dist/test/kv-unified-open-flight-retry.test.js +0 -189
  581. package/dist/test/kv-unified-open-flight-retry.test.js.map +0 -1
  582. package/dist/test/kv-unified-wiring.test.d.ts +0 -2
  583. package/dist/test/kv-unified-wiring.test.d.ts.map +0 -1
  584. package/dist/test/kv-unified-wiring.test.js +0 -95
  585. package/dist/test/kv-unified-wiring.test.js.map +0 -1
  586. package/dist/test/late-events-after-stop.test.d.ts +0 -2
  587. package/dist/test/late-events-after-stop.test.d.ts.map +0 -1
  588. package/dist/test/late-events-after-stop.test.js +0 -122
  589. package/dist/test/late-events-after-stop.test.js.map +0 -1
  590. package/dist/test/liveness-watchdog.test.d.ts +0 -2
  591. package/dist/test/liveness-watchdog.test.d.ts.map +0 -1
  592. package/dist/test/liveness-watchdog.test.js +0 -94
  593. package/dist/test/liveness-watchdog.test.js.map +0 -1
  594. package/dist/test/machine-close-provenance.test.d.ts +0 -2
  595. package/dist/test/machine-close-provenance.test.d.ts.map +0 -1
  596. package/dist/test/machine-close-provenance.test.js +0 -116
  597. package/dist/test/machine-close-provenance.test.js.map +0 -1
  598. package/dist/test/maintenance-timer.test.d.ts +0 -2
  599. package/dist/test/maintenance-timer.test.d.ts.map +0 -1
  600. package/dist/test/maintenance-timer.test.js +0 -265
  601. package/dist/test/maintenance-timer.test.js.map +0 -1
  602. package/dist/test/mcpl-access-provider.test.d.ts +0 -2
  603. package/dist/test/mcpl-access-provider.test.d.ts.map +0 -1
  604. package/dist/test/mcpl-access-provider.test.js +0 -20
  605. package/dist/test/mcpl-access-provider.test.js.map +0 -1
  606. package/dist/test/mcpl-awareness-barrier.test.d.ts +0 -2
  607. package/dist/test/mcpl-awareness-barrier.test.d.ts.map +0 -1
  608. package/dist/test/mcpl-awareness-barrier.test.js +0 -769
  609. package/dist/test/mcpl-awareness-barrier.test.js.map +0 -1
  610. package/dist/test/mcpl-capability-grant.test.d.ts +0 -10
  611. package/dist/test/mcpl-capability-grant.test.d.ts.map +0 -1
  612. package/dist/test/mcpl-capability-grant.test.js +0 -111
  613. package/dist/test/mcpl-capability-grant.test.js.map +0 -1
  614. package/dist/test/mcpl-capability-scoping.test.d.ts +0 -2
  615. package/dist/test/mcpl-capability-scoping.test.d.ts.map +0 -1
  616. package/dist/test/mcpl-capability-scoping.test.js +0 -266
  617. package/dist/test/mcpl-capability-scoping.test.js.map +0 -1
  618. package/dist/test/mcpl-child-env.test.d.ts +0 -2
  619. package/dist/test/mcpl-child-env.test.d.ts.map +0 -1
  620. package/dist/test/mcpl-child-env.test.js +0 -158
  621. package/dist/test/mcpl-child-env.test.js.map +0 -1
  622. package/dist/test/mcpl-coalescing.test.d.ts +0 -2
  623. package/dist/test/mcpl-coalescing.test.d.ts.map +0 -1
  624. package/dist/test/mcpl-coalescing.test.js +0 -1125
  625. package/dist/test/mcpl-coalescing.test.js.map +0 -1
  626. package/dist/test/mcpl-config-diagnostics.test.d.ts +0 -2
  627. package/dist/test/mcpl-config-diagnostics.test.d.ts.map +0 -1
  628. package/dist/test/mcpl-config-diagnostics.test.js +0 -452
  629. package/dist/test/mcpl-config-diagnostics.test.js.map +0 -1
  630. package/dist/test/mcpl-empty-content.test.d.ts +0 -2
  631. package/dist/test/mcpl-empty-content.test.d.ts.map +0 -1
  632. package/dist/test/mcpl-empty-content.test.js +0 -368
  633. package/dist/test/mcpl-empty-content.test.js.map +0 -1
  634. package/dist/test/mcpl-gate-roundtrip.test.d.ts +0 -2
  635. package/dist/test/mcpl-gate-roundtrip.test.d.ts.map +0 -1
  636. package/dist/test/mcpl-gate-roundtrip.test.js +0 -285
  637. package/dist/test/mcpl-gate-roundtrip.test.js.map +0 -1
  638. package/dist/test/mcpl-list-status.test.d.ts +0 -2
  639. package/dist/test/mcpl-list-status.test.d.ts.map +0 -1
  640. package/dist/test/mcpl-list-status.test.js +0 -82
  641. package/dist/test/mcpl-list-status.test.js.map +0 -1
  642. package/dist/test/mcpl-manifest-changed.test.d.ts +0 -2
  643. package/dist/test/mcpl-manifest-changed.test.d.ts.map +0 -1
  644. package/dist/test/mcpl-manifest-changed.test.js +0 -178
  645. package/dist/test/mcpl-manifest-changed.test.js.map +0 -1
  646. package/dist/test/mcpl-push-convert.test.d.ts +0 -2
  647. package/dist/test/mcpl-push-convert.test.d.ts.map +0 -1
  648. package/dist/test/mcpl-push-convert.test.js +0 -42
  649. package/dist/test/mcpl-push-convert.test.js.map +0 -1
  650. package/dist/test/mcpl-reconnect-events.test.d.ts +0 -2
  651. package/dist/test/mcpl-reconnect-events.test.d.ts.map +0 -1
  652. package/dist/test/mcpl-reconnect-events.test.js +0 -144
  653. package/dist/test/mcpl-reconnect-events.test.js.map +0 -1
  654. package/dist/test/mcpl-reconnect-reregistration.test.d.ts +0 -2
  655. package/dist/test/mcpl-reconnect-reregistration.test.d.ts.map +0 -1
  656. package/dist/test/mcpl-reconnect-reregistration.test.js +0 -236
  657. package/dist/test/mcpl-reconnect-reregistration.test.js.map +0 -1
  658. package/dist/test/mcpl-reference-fetcher.test.d.ts +0 -2
  659. package/dist/test/mcpl-reference-fetcher.test.d.ts.map +0 -1
  660. package/dist/test/mcpl-reference-fetcher.test.js +0 -427
  661. package/dist/test/mcpl-reference-fetcher.test.js.map +0 -1
  662. package/dist/test/mcpl-reference-fields.test.d.ts +0 -2
  663. package/dist/test/mcpl-reference-fields.test.d.ts.map +0 -1
  664. package/dist/test/mcpl-reference-fields.test.js +0 -149
  665. package/dist/test/mcpl-reference-fields.test.js.map +0 -1
  666. package/dist/test/mcpl-request-timeout.test.d.ts +0 -2
  667. package/dist/test/mcpl-request-timeout.test.d.ts.map +0 -1
  668. package/dist/test/mcpl-request-timeout.test.js +0 -138
  669. package/dist/test/mcpl-request-timeout.test.js.map +0 -1
  670. package/dist/test/mcpl-runtime-lifecycle.test.d.ts +0 -7
  671. package/dist/test/mcpl-runtime-lifecycle.test.d.ts.map +0 -1
  672. package/dist/test/mcpl-runtime-lifecycle.test.js +0 -142
  673. package/dist/test/mcpl-runtime-lifecycle.test.js.map +0 -1
  674. package/dist/test/mcpl-tool-class-listing.test.d.ts +0 -2
  675. package/dist/test/mcpl-tool-class-listing.test.d.ts.map +0 -1
  676. package/dist/test/mcpl-tool-class-listing.test.js +0 -147
  677. package/dist/test/mcpl-tool-class-listing.test.js.map +0 -1
  678. package/dist/test/mcpl-tool-classes.test.d.ts +0 -7
  679. package/dist/test/mcpl-tool-classes.test.d.ts.map +0 -1
  680. package/dist/test/mcpl-tool-classes.test.js +0 -80
  681. package/dist/test/mcpl-tool-classes.test.js.map +0 -1
  682. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts +0 -2
  683. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts.map +0 -1
  684. package/dist/test/mcpl-tool-lifecycle-e2e.test.js +0 -237
  685. package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +0 -1
  686. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts +0 -11
  687. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts.map +0 -1
  688. package/dist/test/mcpl-tool-lifecycle-emitter.test.js +0 -412
  689. package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +0 -1
  690. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts +0 -2
  691. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts.map +0 -1
  692. package/dist/test/mcpl-tool-lifecycle-script.test.js +0 -288
  693. package/dist/test/mcpl-tool-lifecycle-script.test.js.map +0 -1
  694. package/dist/test/mcpl-tool-lifecycle.test.d.ts +0 -11
  695. package/dist/test/mcpl-tool-lifecycle.test.d.ts.map +0 -1
  696. package/dist/test/mcpl-tool-lifecycle.test.js +0 -270
  697. package/dist/test/mcpl-tool-lifecycle.test.js.map +0 -1
  698. package/dist/test/mcpl-ws-transport.test.d.ts +0 -2
  699. package/dist/test/mcpl-ws-transport.test.d.ts.map +0 -1
  700. package/dist/test/mcpl-ws-transport.test.js +0 -258
  701. package/dist/test/mcpl-ws-transport.test.js.map +0 -1
  702. package/dist/test/module-context-integration.test.d.ts +0 -18
  703. package/dist/test/module-context-integration.test.d.ts.map +0 -1
  704. package/dist/test/module-context-integration.test.js +0 -181
  705. package/dist/test/module-context-integration.test.js.map +0 -1
  706. package/dist/test/offline-recovery-branch.test.d.ts +0 -2
  707. package/dist/test/offline-recovery-branch.test.d.ts.map +0 -1
  708. package/dist/test/offline-recovery-branch.test.js +0 -226
  709. package/dist/test/offline-recovery-branch.test.js.map +0 -1
  710. package/dist/test/operator-surgery.test.d.ts +0 -2
  711. package/dist/test/operator-surgery.test.d.ts.map +0 -1
  712. package/dist/test/operator-surgery.test.js +0 -398
  713. package/dist/test/operator-surgery.test.js.map +0 -1
  714. package/dist/test/ops-alert.test.d.ts +0 -2
  715. package/dist/test/ops-alert.test.d.ts.map +0 -1
  716. package/dist/test/ops-alert.test.js +0 -153
  717. package/dist/test/ops-alert.test.js.map +0 -1
  718. package/dist/test/overbudget-drain-breaker.test.d.ts +0 -2
  719. package/dist/test/overbudget-drain-breaker.test.d.ts.map +0 -1
  720. package/dist/test/overbudget-drain-breaker.test.js +0 -197
  721. package/dist/test/overbudget-drain-breaker.test.js.map +0 -1
  722. package/dist/test/per-agent-delivery.test.d.ts +0 -2
  723. package/dist/test/per-agent-delivery.test.d.ts.map +0 -1
  724. package/dist/test/per-agent-delivery.test.js +0 -108
  725. package/dist/test/per-agent-delivery.test.js.map +0 -1
  726. package/dist/test/physical-window-restart.test.d.ts +0 -14
  727. package/dist/test/physical-window-restart.test.d.ts.map +0 -1
  728. package/dist/test/physical-window-restart.test.js +0 -222
  729. package/dist/test/physical-window-restart.test.js.map +0 -1
  730. package/dist/test/placed-reaction-baseline.test.d.ts +0 -2
  731. package/dist/test/placed-reaction-baseline.test.d.ts.map +0 -1
  732. package/dist/test/placed-reaction-baseline.test.js +0 -312
  733. package/dist/test/placed-reaction-baseline.test.js.map +0 -1
  734. package/dist/test/present-while-acting.test.d.ts +0 -19
  735. package/dist/test/present-while-acting.test.d.ts.map +0 -1
  736. package/dist/test/present-while-acting.test.js +0 -706
  737. package/dist/test/present-while-acting.test.js.map +0 -1
  738. package/dist/test/prose-segments.test.d.ts +0 -2
  739. package/dist/test/prose-segments.test.d.ts.map +0 -1
  740. package/dist/test/prose-segments.test.js +0 -52
  741. package/dist/test/prose-segments.test.js.map +0 -1
  742. package/dist/test/prose-stream-router.test.d.ts +0 -2
  743. package/dist/test/prose-stream-router.test.d.ts.map +0 -1
  744. package/dist/test/prose-stream-router.test.js +0 -171
  745. package/dist/test/prose-stream-router.test.js.map +0 -1
  746. package/dist/test/provider-acceleration-cooldown.test.d.ts +0 -2
  747. package/dist/test/provider-acceleration-cooldown.test.d.ts.map +0 -1
  748. package/dist/test/provider-acceleration-cooldown.test.js +0 -435
  749. package/dist/test/provider-acceleration-cooldown.test.js.map +0 -1
  750. package/dist/test/provider-waits.test.d.ts +0 -2
  751. package/dist/test/provider-waits.test.d.ts.map +0 -1
  752. package/dist/test/provider-waits.test.js +0 -2196
  753. package/dist/test/provider-waits.test.js.map +0 -1
  754. package/dist/test/puppet-tool-call.test.d.ts +0 -2
  755. package/dist/test/puppet-tool-call.test.d.ts.map +0 -1
  756. package/dist/test/puppet-tool-call.test.js +0 -224
  757. package/dist/test/puppet-tool-call.test.js.map +0 -1
  758. package/dist/test/puppet-turn-reservation.test.d.ts +0 -2
  759. package/dist/test/puppet-turn-reservation.test.d.ts.map +0 -1
  760. package/dist/test/puppet-turn-reservation.test.js +0 -139
  761. package/dist/test/puppet-turn-reservation.test.js.map +0 -1
  762. package/dist/test/reaction-baseline-platform.test.d.ts +0 -2
  763. package/dist/test/reaction-baseline-platform.test.d.ts.map +0 -1
  764. package/dist/test/reaction-baseline-platform.test.js +0 -124
  765. package/dist/test/reaction-baseline-platform.test.js.map +0 -1
  766. package/dist/test/record-journal.test.d.ts +0 -6
  767. package/dist/test/record-journal.test.d.ts.map +0 -1
  768. package/dist/test/record-journal.test.js +0 -269
  769. package/dist/test/record-journal.test.js.map +0 -1
  770. package/dist/test/refusal-reaction-baseline.test.d.ts +0 -2
  771. package/dist/test/refusal-reaction-baseline.test.d.ts.map +0 -1
  772. package/dist/test/refusal-reaction-baseline.test.js +0 -81
  773. package/dist/test/refusal-reaction-baseline.test.js.map +0 -1
  774. package/dist/test/refusal-rewind.test.d.ts +0 -2
  775. package/dist/test/refusal-rewind.test.d.ts.map +0 -1
  776. package/dist/test/refusal-rewind.test.js +0 -108
  777. package/dist/test/refusal-rewind.test.js.map +0 -1
  778. package/dist/test/refusal-single-call.test.d.ts +0 -2
  779. package/dist/test/refusal-single-call.test.d.ts.map +0 -1
  780. package/dist/test/refusal-single-call.test.js +0 -177
  781. package/dist/test/refusal-single-call.test.js.map +0 -1
  782. package/dist/test/release-changelog.test.d.ts +0 -2
  783. package/dist/test/release-changelog.test.d.ts.map +0 -1
  784. package/dist/test/release-changelog.test.js +0 -159
  785. package/dist/test/release-changelog.test.js.map +0 -1
  786. package/dist/test/same-round-think-policy.test.d.ts +0 -2
  787. package/dist/test/same-round-think-policy.test.d.ts.map +0 -1
  788. package/dist/test/same-round-think-policy.test.js +0 -853
  789. package/dist/test/same-round-think-policy.test.js.map +0 -1
  790. package/dist/test/save-recent-image.test.d.ts +0 -26
  791. package/dist/test/save-recent-image.test.d.ts.map +0 -1
  792. package/dist/test/save-recent-image.test.js +0 -974
  793. package/dist/test/save-recent-image.test.js.map +0 -1
  794. package/dist/test/shutdown-errors.test.d.ts +0 -2
  795. package/dist/test/shutdown-errors.test.d.ts.map +0 -1
  796. package/dist/test/shutdown-errors.test.js +0 -662
  797. package/dist/test/shutdown-errors.test.js.map +0 -1
  798. package/dist/test/silent-heartbeat-rows.test.d.ts +0 -2
  799. package/dist/test/silent-heartbeat-rows.test.d.ts.map +0 -1
  800. package/dist/test/silent-heartbeat-rows.test.js +0 -451
  801. package/dist/test/silent-heartbeat-rows.test.js.map +0 -1
  802. package/dist/test/silent-heartbeat.test.d.ts +0 -2
  803. package/dist/test/silent-heartbeat.test.d.ts.map +0 -1
  804. package/dist/test/silent-heartbeat.test.js +0 -165
  805. package/dist/test/silent-heartbeat.test.js.map +0 -1
  806. package/dist/test/state-scaling-e2e.test.d.ts +0 -22
  807. package/dist/test/state-scaling-e2e.test.d.ts.map +0 -1
  808. package/dist/test/state-scaling-e2e.test.js +0 -206
  809. package/dist/test/state-scaling-e2e.test.js.map +0 -1
  810. package/dist/test/state-scaling.test.d.ts +0 -12
  811. package/dist/test/state-scaling.test.d.ts.map +0 -1
  812. package/dist/test/state-scaling.test.js +0 -251
  813. package/dist/test/state-scaling.test.js.map +0 -1
  814. package/dist/test/stop-with-work-in-flight.test.d.ts +0 -23
  815. package/dist/test/stop-with-work-in-flight.test.d.ts.map +0 -1
  816. package/dist/test/stop-with-work-in-flight.test.js +0 -672
  817. package/dist/test/stop-with-work-in-flight.test.js.map +0 -1
  818. package/dist/test/surgery-marks-receipt.test.d.ts +0 -2
  819. package/dist/test/surgery-marks-receipt.test.d.ts.map +0 -1
  820. package/dist/test/surgery-marks-receipt.test.js +0 -540
  821. package/dist/test/surgery-marks-receipt.test.js.map +0 -1
  822. package/dist/test/thinking-token-stamp.test.d.ts +0 -12
  823. package/dist/test/thinking-token-stamp.test.d.ts.map +0 -1
  824. package/dist/test/thinking-token-stamp.test.js +0 -129
  825. package/dist/test/thinking-token-stamp.test.js.map +0 -1
  826. package/dist/test/timezone.test.d.ts +0 -2
  827. package/dist/test/timezone.test.d.ts.map +0 -1
  828. package/dist/test/timezone.test.js +0 -18
  829. package/dist/test/timezone.test.js.map +0 -1
  830. package/dist/test/tool-batch-hook.test.d.ts +0 -8
  831. package/dist/test/tool-batch-hook.test.d.ts.map +0 -1
  832. package/dist/test/tool-batch-hook.test.js +0 -275
  833. package/dist/test/tool-batch-hook.test.js.map +0 -1
  834. package/dist/test/tool-policy.test.d.ts +0 -2
  835. package/dist/test/tool-policy.test.d.ts.map +0 -1
  836. package/dist/test/tool-policy.test.js +0 -51
  837. package/dist/test/tool-policy.test.js.map +0 -1
  838. package/dist/test/tool-presentation.test.d.ts +0 -2
  839. package/dist/test/tool-presentation.test.d.ts.map +0 -1
  840. package/dist/test/tool-presentation.test.js +0 -268
  841. package/dist/test/tool-presentation.test.js.map +0 -1
  842. package/dist/test/tool-result-content.test.d.ts +0 -2
  843. package/dist/test/tool-result-content.test.d.ts.map +0 -1
  844. package/dist/test/tool-result-content.test.js +0 -37
  845. package/dist/test/tool-result-content.test.js.map +0 -1
  846. package/dist/test/tool-result-guard.test.d.ts +0 -2
  847. package/dist/test/tool-result-guard.test.d.ts.map +0 -1
  848. package/dist/test/tool-result-guard.test.js +0 -3607
  849. package/dist/test/tool-result-guard.test.js.map +0 -1
  850. package/dist/test/tool-result-history.test.d.ts +0 -7
  851. package/dist/test/tool-result-history.test.d.ts.map +0 -1
  852. package/dist/test/tool-result-history.test.js +0 -156
  853. package/dist/test/tool-result-history.test.js.map +0 -1
  854. package/dist/test/tool-result-spill.test.d.ts +0 -13
  855. package/dist/test/tool-result-spill.test.d.ts.map +0 -1
  856. package/dist/test/tool-result-spill.test.js +0 -586
  857. package/dist/test/tool-result-spill.test.js.map +0 -1
  858. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts +0 -2
  859. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts.map +0 -1
  860. package/dist/test/tool-wrapper-prose-guard-integration.test.js +0 -485
  861. package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +0 -1
  862. package/dist/test/tool-wrapper-prose-guard.test.d.ts +0 -2
  863. package/dist/test/tool-wrapper-prose-guard.test.d.ts.map +0 -1
  864. package/dist/test/tool-wrapper-prose-guard.test.js +0 -34
  865. package/dist/test/tool-wrapper-prose-guard.test.js.map +0 -1
  866. package/dist/test/tools-observe-parser-conformance.test.d.ts +0 -2
  867. package/dist/test/tools-observe-parser-conformance.test.d.ts.map +0 -1
  868. package/dist/test/tools-observe-parser-conformance.test.js +0 -129
  869. package/dist/test/tools-observe-parser-conformance.test.js.map +0 -1
  870. package/dist/test/trunk-channel-routing.test.d.ts +0 -19
  871. package/dist/test/trunk-channel-routing.test.d.ts.map +0 -1
  872. package/dist/test/trunk-channel-routing.test.js +0 -329
  873. package/dist/test/trunk-channel-routing.test.js.map +0 -1
  874. package/dist/test/tune-out-e2e.test.d.ts +0 -2
  875. package/dist/test/tune-out-e2e.test.d.ts.map +0 -1
  876. package/dist/test/tune-out-e2e.test.js +0 -142
  877. package/dist/test/tune-out-e2e.test.js.map +0 -1
  878. package/dist/test/tune-out-gate-composition.test.d.ts +0 -2
  879. package/dist/test/tune-out-gate-composition.test.d.ts.map +0 -1
  880. package/dist/test/tune-out-gate-composition.test.js +0 -221
  881. package/dist/test/tune-out-gate-composition.test.js.map +0 -1
  882. package/dist/test/tune-out-lifecycle.test.d.ts +0 -2
  883. package/dist/test/tune-out-lifecycle.test.d.ts.map +0 -1
  884. package/dist/test/tune-out-lifecycle.test.js +0 -121
  885. package/dist/test/tune-out-lifecycle.test.js.map +0 -1
  886. package/dist/test/turn-trigger-provenance.test.d.ts +0 -2
  887. package/dist/test/turn-trigger-provenance.test.d.ts.map +0 -1
  888. package/dist/test/turn-trigger-provenance.test.js +0 -137
  889. package/dist/test/turn-trigger-provenance.test.js.map +0 -1
  890. package/dist/test/unconvertible-tool-result.test.d.ts +0 -2
  891. package/dist/test/unconvertible-tool-result.test.d.ts.map +0 -1
  892. package/dist/test/unconvertible-tool-result.test.js +0 -358
  893. package/dist/test/unconvertible-tool-result.test.js.map +0 -1
  894. package/dist/test/usage-accounting.test.d.ts +0 -2
  895. package/dist/test/usage-accounting.test.d.ts.map +0 -1
  896. package/dist/test/usage-accounting.test.js +0 -13
  897. package/dist/test/usage-accounting.test.js.map +0 -1
  898. package/dist/test/usage-tracker.test.d.ts +0 -2
  899. package/dist/test/usage-tracker.test.d.ts.map +0 -1
  900. package/dist/test/usage-tracker.test.js +0 -129
  901. package/dist/test/usage-tracker.test.js.map +0 -1
  902. package/dist/test/utils-surface.test.d.ts +0 -2
  903. package/dist/test/utils-surface.test.d.ts.map +0 -1
  904. package/dist/test/utils-surface.test.js +0 -145
  905. package/dist/test/utils-surface.test.js.map +0 -1
  906. package/dist/test/workspace-branch-continuation.test.d.ts +0 -15
  907. package/dist/test/workspace-branch-continuation.test.d.ts.map +0 -1
  908. package/dist/test/workspace-branch-continuation.test.js +0 -183
  909. package/dist/test/workspace-branch-continuation.test.js.map +0 -1
  910. package/dist/test/workspace-materialize-freshness.test.d.ts +0 -16
  911. package/dist/test/workspace-materialize-freshness.test.d.ts.map +0 -1
  912. package/dist/test/workspace-materialize-freshness.test.js +0 -252
  913. package/dist/test/workspace-materialize-freshness.test.js.map +0 -1
  914. package/dist/test/workspace-path-containment.test.d.ts +0 -19
  915. package/dist/test/workspace-path-containment.test.d.ts.map +0 -1
  916. package/dist/test/workspace-path-containment.test.js +0 -91
  917. package/dist/test/workspace-path-containment.test.js.map +0 -1
  918. package/dist/test/workspace-read-file-from-disk.test.d.ts +0 -17
  919. package/dist/test/workspace-read-file-from-disk.test.d.ts.map +0 -1
  920. package/dist/test/workspace-read-file-from-disk.test.js +0 -174
  921. package/dist/test/workspace-read-file-from-disk.test.js.map +0 -1
  922. package/dist/test/workspace-read-image.test.d.ts +0 -2
  923. package/dist/test/workspace-read-image.test.d.ts.map +0 -1
  924. package/dist/test/workspace-read-image.test.js +0 -597
  925. package/dist/test/workspace-read-image.test.js.map +0 -1
  926. package/dist/test/workspace-read-text.test.d.ts +0 -2
  927. package/dist/test/workspace-read-text.test.d.ts.map +0 -1
  928. package/dist/test/workspace-read-text.test.js +0 -101
  929. package/dist/test/workspace-read-text.test.js.map +0 -1
  930. package/dist/test/workspace-restore-order.test.d.ts +0 -16
  931. package/dist/test/workspace-restore-order.test.d.ts.map +0 -1
  932. package/dist/test/workspace-restore-order.test.js +0 -140
  933. package/dist/test/workspace-restore-order.test.js.map +0 -1
  934. package/dist/test/workspace-three-way.test.d.ts +0 -12
  935. package/dist/test/workspace-three-way.test.d.ts.map +0 -1
  936. package/dist/test/workspace-three-way.test.js +0 -3194
  937. package/dist/test/workspace-three-way.test.js.map +0 -1
  938. package/dist/test/workspace-watcher.test.d.ts +0 -2
  939. package/dist/test/workspace-watcher.test.d.ts.map +0 -1
  940. package/dist/test/workspace-watcher.test.js +0 -281
  941. package/dist/test/workspace-watcher.test.js.map +0 -1
  942. package/dist/test/xml-round-persist.test.d.ts +0 -19
  943. package/dist/test/xml-round-persist.test.d.ts.map +0 -1
  944. package/dist/test/xml-round-persist.test.js +0 -235
  945. package/dist/test/xml-round-persist.test.js.map +0 -1
  946. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -11,10 +11,11 @@
11
11
 
12
12
  import { EventEmitter } from 'node:events';
13
13
 
14
- import { openTransport, type McplTransport, type TransportCloseInfo } from './transport.js';
14
+ import { openTransport, STDERR_END_WAIT_MS, type McplTransport, type TransportCloseInfo } from './transport.js';
15
15
  import { maskNegotiatedCapabilities } from './capability-mask.js';
16
16
  import { CapabilityGrant, expandAdvertisementShorthand } from './capability-grant.js';
17
- import { CAPABILITY_DISABLED } from './errors.js';
17
+ import { CAPABILITY_DISABLED, boundedForLog, describeCause } from './errors.js';
18
+ import { logDetail, logValue } from './log-value.js';
18
19
 
19
20
  import type {
20
21
  McplServerConfig,
@@ -65,6 +66,9 @@ export interface McplConnectionCloseInfo {
65
66
  signal: NodeJS.Signals | null;
66
67
  /** WebSocket close reason, or a short description of the cause. */
67
68
  reason?: string;
69
+ /** True when `reason` is the peer's own text, a WebSocket server's close
70
+ * reason, rather than the transport's or the host's words. */
71
+ reasonFromPeer?: boolean;
68
72
  /** True when the host closed the link (`close()` / `reconnectAfterFailure()`),
69
73
  * false when the transport dropped unexpectedly. */
70
74
  byHost: boolean;
@@ -74,6 +78,37 @@ export interface McplConnectionCloseInfo {
74
78
  * Spring Boot + JDA servers can take 5-10s to boot, so 30s is safe. */
75
79
  const INITIALIZE_TIMEOUT_MS = 30_000;
76
80
 
81
+ /** A failed connect's `stderrTail`, the last of the server's stderr that its
82
+ * handshake's error keeps, when there is one. */
83
+ export function stderrTailOf(error: unknown): string | undefined {
84
+ const tail = (error as { stderrTail?: unknown } | null | undefined)?.stderrTail;
85
+ return typeof tail === 'string' && tail !== '' ? tail : undefined;
86
+ }
87
+
88
+ /** For the host's own log line about a failed connect: the server's stderr
89
+ * that the error keeps as `stderrTail`, one marked line per line of it,
90
+ * each through log-value, since it's the server's text. '' when there's
91
+ * none. */
92
+ export function withStderr(error: unknown): string {
93
+ const tail = stderrTailOf(error);
94
+ if (tail === undefined) return '';
95
+ return '. The last of its stderr:' + tail.split('\n').map((line) => `\n stderr: ${logDetail(line)}`).join('');
96
+ }
97
+
98
+ /** A transport close's reason, as an error message gives it: the transport's
99
+ * own words. A WebSocket peer's close reason is the server's text
100
+ * (`reasonFromPeer`), so an error gives the words the transport uses for a
101
+ * close without one, as `mcpl:server-closed` leaves that text out. A
102
+ * WebSocket close's code, a number, says what the server meant (4001: a
103
+ * refused credential), with or without a reason, so each error gives it too:
104
+ * a pending request's error has `code=`, and the handshake's adds it for any
105
+ * WebSocket close, since a close before the handshake completes reaches no
106
+ * 'close' event. A stdio child's exit reads as before. */
107
+ function closeReasonText(info: TransportCloseInfo): string {
108
+ if (info.reasonFromPeer) return 'websocket closed';
109
+ return info.reason ?? 'unknown';
110
+ }
111
+
77
112
  /** Default per-request timeout in milliseconds (see McplServerConfig.requestTimeoutMs).
78
113
  * A live-but-wedged server (accepts requests, never answers, never closes its
79
114
  * transport) would otherwise freeze the awaiting agent turn forever — no
@@ -84,6 +119,33 @@ const DEFAULT_REQUEST_TIMEOUT_MS = 60_000;
84
119
  /** MCP protocol version used in the initialize handshake. */
85
120
  const MCP_PROTOCOL_VERSION = '2024-11-05';
86
121
 
122
+ /**
123
+ * Why a request to an MCPL server produced no result, as far as the host can
124
+ * know it. Messages are unchanged from plain errors; the `outcome` makes the
125
+ * difference between "never left the host" and "left, and no answer came
126
+ * back" a fact a caller can act on instead of a string to match:
127
+ * - `not-sent`: the request was refused before anything was written (the
128
+ * connection was already closed);
129
+ * - `error-response`: the server answered with a JSON-RPC error (it may have
130
+ * acted before failing; the error alone does not say);
131
+ * - `no-response`: the request was handed to the transport and no answer
132
+ * came back (timeout, or the connection closed while awaiting). It does
133
+ * not prove the request reached the server — the transport can decline or
134
+ * drop a write — only that the host can no longer say it didn't.
135
+ */
136
+ export class McplRequestError extends Error {
137
+ constructor(
138
+ message: string,
139
+ readonly outcome: 'not-sent' | 'error-response' | 'no-response',
140
+ /** The JSON-RPC error's `data`, verbatim, when the server supplied one
141
+ * (e.g. which parts of a multi-part send were posted). */
142
+ readonly data?: unknown,
143
+ ) {
144
+ super(message);
145
+ this.name = 'McplRequestError';
146
+ }
147
+ }
148
+
87
149
  /**
88
150
  * Represents a pending JSON-RPC request awaiting a response.
89
151
  */
@@ -102,6 +164,13 @@ interface RequestOptions {
102
164
  surfaceOrphanedResponse?: boolean;
103
165
  }
104
166
 
167
+ /** A request's method for a log line, whatever the server sent there. */
168
+ function describeMethod(method: unknown): string {
169
+ return typeof method === 'string'
170
+ ? `method ${logValue(method)}`
171
+ : `a method of type ${method === null ? 'null' : typeof method}`;
172
+ }
173
+
105
174
  /**
106
175
  * McplServerConnection manages a single JSON-RPC 2.0 connection to an
107
176
  * MCPL server over stdio. Use the static `connect()` factory to create
@@ -116,8 +185,13 @@ interface RequestOptions {
116
185
  * - `'channels-incoming'` — Server sent `channels/incoming`
117
186
  * - `'error'` — Connection-level error
118
187
  * - `'close'` — Connection closed: `(code, signal, info: McplConnectionCloseInfo)`
119
- * - `'connect-failed'` — Initial connect failed; background retry scheduled
120
- * - `'reconnect-failed'` — A background reconnect attempt failed; next retry scheduled
188
+ * - `'connect-failed'` — Initial connect failed; background retry scheduled:
189
+ * `{ error, stderrTail?, attempt }`
190
+ * - `'reconnect-failed'` — A background reconnect attempt failed; next retry scheduled:
191
+ * `{ error, stderrTail?, attempt }`. `stderrTail` is the last of the
192
+ * server's stderr when its handshake failed by its transport closing, a
193
+ * transport error or its timeout and it had written any; `error` never
194
+ * carries it.
121
195
  * - `'reconnect'` — Background reconnect succeeded
122
196
  */
123
197
  export class McplServerConnection extends EventEmitter {
@@ -229,7 +303,10 @@ export class McplServerConnection extends EventEmitter {
229
303
  private pendingRequests = new Map<string | number, PendingRequest>();
230
304
  /** Metadata retained after selected request deadlines so a late response is
231
305
  * observable even though its original promise has already been rejected. */
232
- private orphanedRequests = new Map<string | number, { method: string; renderParams?: Record<string, unknown> }>();
306
+ private orphanedRequests = new Map<string | number, {
307
+ method: string;
308
+ renderParams?: { featureSet: string; key: string; eventId: string; channelId?: string };
309
+ }>();
233
310
  private closed = false;
234
311
  /** Set by `reconnectAfterFailure()` before it closes a live transport, so
235
312
  * the transport close handler reports that teardown as `byHost: true`. */
@@ -240,6 +317,9 @@ export class McplServerConnection extends EventEmitter {
240
317
 
241
318
  /** Per-request timeout in ms (0 disables). See McplServerConfig.requestTimeoutMs. */
242
319
  private requestTimeoutMs = DEFAULT_REQUEST_TIMEOUT_MS;
320
+ /** The deadline a channels/publish or channels/open request keeps when
321
+ * requestTimeoutMs is 0 (see sendChannelsPublish). */
322
+ private publishDeadlineMs = DEFAULT_REQUEST_TIMEOUT_MS;
243
323
 
244
324
  // Event buffering: control-plane traffic can be released independently from
245
325
  // inference-bearing data-plane traffic. This lets a server finish its own
@@ -248,15 +328,24 @@ export class McplServerConnection extends EventEmitter {
248
328
  private controlPlaneReady = false;
249
329
  private dataPlaneReady = false;
250
330
  private bufferedEvents: Array<{ event: string; args: unknown[] }> = [];
251
- /** Cap on buffered responder-less events during a plane pause (issue #122).
252
- * Held server→host requests are never dropped and may exceed this. */
253
- private static readonly MAX_BUFFERED_EVENTS = 1000;
331
+ /** How many of bufferedEvents are server→host requests, each holding a
332
+ * responder its server waits on. Every change to bufferedEvents keeps it. */
333
+ private heldRequests = 0;
334
+ /** Cap on held notifications (responder-less events) during a plane pause
335
+ * (issue #122), counted apart from requests: past it, the oldest held
336
+ * notification is dropped. */
337
+ private static readonly MAX_HELD_NOTIFICATIONS = 1000;
338
+ /** Budget of held requests during a plane pause (#387), counted apart from
339
+ * notifications: past it, a request is refused at once, never dropped. It
340
+ * bounds a server that pipelines requests without waiting for answers. A
341
+ * server that doesn't send a refused request again loses it (discord-mcpl
342
+ * doesn't), so the budget sits far above the notifications' cap, to leave
343
+ * a busy server's long pause room. */
344
+ private static readonly MAX_HELD_REQUESTS = 10_000;
254
345
  private droppedBufferedEvents = 0;
255
- /** True while ready()/readyControlPlane() re-emit a buffer snapshot. Items
256
- * re-buffering mid-flush were already admitted once — applying the cap to
257
- * them again would evict events that were legally held (the cap targets
258
- * NEW arrivals during a pause, not churn from control-plane flushes). */
259
- private flushDepth = 0;
346
+ /** Requests refused at the budget since the planes last opened (ready()),
347
+ * so each pause's first refusal is logged. */
348
+ private refusedHeldRequests = 0;
260
349
 
261
350
  // Reconnect state (adapted from Anarchid/agent-framework@mcpl-module-proto)
262
351
  private config: McplServerConfig | null = null;
@@ -275,6 +364,13 @@ export class McplServerConnection extends EventEmitter {
275
364
  return this.reconnectEnabled;
276
365
  }
277
366
 
367
+ /** Closed with no reconnect to come: after close(), whether or not its
368
+ * transport close succeeded, or a drop with reconnect off. A connection
369
+ * between retries keeps reconnectEnabled, so it isn't closed for good. */
370
+ private get closedForGood(): boolean {
371
+ return this.closed && !this.reconnectEnabled;
372
+ }
373
+
278
374
  /**
279
375
  * Private constructor. Use `McplServerConnection.connect()` instead.
280
376
  */
@@ -302,28 +398,38 @@ export class McplServerConnection extends EventEmitter {
302
398
  * Mark the connection as ready — flushes any events that arrived between
303
399
  * construction (when setupMessageRouting starts emitting) and now (when
304
400
  * the caller has attached listeners via wireMcplEvents).
401
+ *
402
+ * Does nothing once the connection is closed for good. Its policy was reset
403
+ * when it closed, so what it held that needs a grant would be refused, and a
404
+ * closed connection sends no response, so nothing it held could be answered.
405
+ * Only what needs no grant would pass, to listeners of a server that won't
406
+ * be served again. A connection between retries isn't closed for good: what
407
+ * it held, such as a reconnect stub's connect-failed, still reaches its
408
+ * listeners.
305
409
  */
306
410
  ready(): void {
411
+ if (this.closedForGood) return;
307
412
  this.controlPlaneReady = true;
308
413
  this.dataPlaneReady = true;
309
414
  const pending = this.bufferedEvents;
310
415
  this.bufferedEvents = [];
416
+ // The cap's drops are counted per pause: this flush ends one, so its line
417
+ // reports that pause's drops, and the next pause counts (and logs) its own.
418
+ const dropped = this.droppedBufferedEvents;
419
+ this.droppedBufferedEvents = 0;
420
+ this.heldRequests = 0;
421
+ this.refusedHeldRequests = 0;
311
422
  if (pending.length > 200) {
312
423
  console.error(
313
424
  `[mcpl] ${this.id}: flushing ${pending.length} buffered event(s) synchronously ` +
314
- `(long pause backlog${this.droppedBufferedEvents > 0 ? `; ${this.droppedBufferedEvents} dropped at cap` : ''})`,
425
+ `(long pause backlog${dropped > 0 ? `; ${dropped} dropped at cap` : ''})`,
315
426
  );
316
427
  }
317
- this.flushDepth++;
318
- try {
319
- for (const { event, args } of pending) {
320
- // Re-enter the gate for every buffered item. A control handler (notably
321
- // tools/list_changed) may install a newer data-plane barrier while this
322
- // snapshot is being flushed; later data items must observe that pause.
323
- this.emit(event, ...args);
324
- }
325
- } finally {
326
- this.flushDepth--;
428
+ for (const { event, args } of pending) {
429
+ // Re-enter the gate for every buffered item. A control handler (notably
430
+ // tools/list_changed) may install a newer data-plane barrier while this
431
+ // snapshot is being flushed; later data items must observe that pause.
432
+ this.dispatchInboundEvent(event, ...args);
327
433
  }
328
434
  }
329
435
 
@@ -331,24 +437,22 @@ export class McplServerConnection extends EventEmitter {
331
437
  * Release only server-establishment and lifecycle/control traffic. Responses
332
438
  * to host requests are never event-buffered, so tools/list and tools/call
333
439
  * responses remain live as well. Inference-bearing requests stay queued in
334
- * their original relative order until {@link ready} is called.
440
+ * their original relative order until {@link ready} is called. Like
441
+ * {@link ready}, it does nothing once the connection is closed for good.
335
442
  */
336
443
  readyControlPlane(): void {
444
+ if (this.closedForGood) return;
337
445
  this.controlPlaneReady = true;
338
446
  const pending = this.bufferedEvents;
339
447
  this.bufferedEvents = [];
340
- this.flushDepth++;
341
- try {
342
- for (const item of pending) {
343
- // Re-enter the ADMISSION gate (this.emit), never super.emit: control
344
- // events include channels-register/changed, which are grant-gated —
345
- // the old direct flush bypassed positive-grant enforcement entirely
346
- // (PR #79 review blocker 3). Data-plane items re-buffer in order via
347
- // the same call, since dataPlaneReady is still false.
348
- this.emit(item.event, ...item.args);
349
- }
350
- } finally {
351
- this.flushDepth--;
448
+ this.heldRequests = 0;
449
+ for (const item of pending) {
450
+ // Re-enter the ADMISSION gate (this.emit), never super.emit: control
451
+ // events include channels-register/changed, which are grant-gated —
452
+ // the old direct flush bypassed positive-grant enforcement entirely
453
+ // (PR #79 review blocker 3). Data-plane items re-buffer in order via
454
+ // the same call, since dataPlaneReady is still false.
455
+ this.dispatchInboundEvent(item.event, ...item.args);
352
456
  }
353
457
  }
354
458
 
@@ -403,44 +507,84 @@ export class McplServerConnection extends EventEmitter {
403
507
  if (responder?.respondError) {
404
508
  responder.respondError(CAPABILITY_DISABLED, `${name} rejected: capability "${requiredCap}" ${phase}`, { capability: requiredCap });
405
509
  } else {
406
- console.error(`[mcpl] ${this.id}: discarded ${name} — "${requiredCap}" ${phase}`);
510
+ console.error(`[mcpl] ${this.id}: discarded ${logValue(name)} — "${requiredCap}" ${phase}`);
407
511
  }
408
512
  return true;
409
513
  }
514
+ // §6.6: a request that will never be answered MUST get an error. A
515
+ // request whose event nothing on this host listens for would never be.
516
+ const request = args[1] as {
517
+ respond?: (result: unknown) => void;
518
+ respondError?: (code: number, message: string, data?: unknown) => void;
519
+ } | undefined;
520
+ if (typeof request?.respondError === 'function' && this.listenerCount(event) === 0) {
521
+ request.respondError(-32601, 'Method not found');
522
+ console.error(`[mcpl] ${this.id}: answered -32601 to ${logValue(name)}, which nothing on this host handles`);
523
+ return true;
524
+ }
525
+ // mcpl/manifestChanged (§17.3) and tools/list_changed are notifications.
526
+ // Sent as a request, either is answered with an empty result as it's
527
+ // admitted, and passed on as the notification is, with no responder:
528
+ // the host acts on it the same way, so the answer doesn't depend on what
529
+ // the refresh does, and it's written before any request the refresh
530
+ // sends. This is where live routing and buffer flushes meet, so a request
531
+ // held while its plane is closed is answered only when it's let through,
532
+ // never by a startup that fails first.
533
+ if ((name === 'manifest-changed' || name === 'tools-list-changed') && typeof request?.respond === 'function') {
534
+ request.respond({});
535
+ return super.emit(event, args[0]);
536
+ }
410
537
  return super.emit(event, ...args);
411
538
  }
412
- // Buffer cap (issue #122): a long data-plane pause (quiesce window) on a
413
- // busy server would otherwise grow this array without bound. Only
414
- // responder-LESS events are ever dropped — a buffered server→host REQUEST
415
- // holds a live responder the server is blocking on, and dropping it would
416
- // strand that call forever (the server timing out and reconnecting is the
417
- // accepted bound there, and reconnect re-runs the barrier funnel).
418
- if (this.flushDepth === 0 && this.bufferedEvents.length >= McplServerConnection.MAX_BUFFERED_EVENTS) {
419
- const hasResponder = (item: { args: unknown[] }): boolean => {
420
- const responder = item.args[1] as { respond?: unknown } | undefined;
421
- return typeof responder?.respond === 'function';
422
- };
423
- if (!hasResponder({ args })) {
424
- this.droppedBufferedEvents++;
425
- if (this.droppedBufferedEvents % 100 === 1) {
426
- console.error(
427
- `[mcpl] ${this.id}: buffered-event cap (${McplServerConnection.MAX_BUFFERED_EVENTS}) — ` +
428
- `dropped ${this.droppedBufferedEvents} responder-less event(s) while the plane is paused`,
429
- );
430
- }
431
- const dropIndex = this.bufferedEvents.findIndex((item) => !hasResponder(item));
432
- if (dropIndex >= 0) {
433
- this.bufferedEvents.splice(dropIndex, 1); // drop-oldest non-request
434
- this.bufferedEvents.push({ event: name, args });
435
- }
436
- // else: buffer is all held requests — drop the incoming event instead.
437
- return true;
539
+ // Held until the plane opens. A long pause (a quiesce, say) on a busy or a
540
+ // runaway server would otherwise grow this array without bound, so
541
+ // requests and notifications each have a bound, counted apart. A request
542
+ // holds a responder its server waits on, and dropping it would strand that
543
+ // call, so past MAX_HELD_REQUESTS (#387) it's refused at once with -32000,
544
+ // the code of the host's other transient refusals, and its server can send
545
+ // it again. A notification has no one to tell, so past
546
+ // MAX_HELD_NOTIFICATIONS (issue #122) the oldest held notification is
547
+ // dropped to make room. A flush takes the whole buffer and zeroes its
548
+ // count, so what it holds again was admitted within these bounds and
549
+ // stays within them.
550
+ const responder = args[1] as { respond?: unknown; respondError?: (code: number, message: string) => void } | undefined;
551
+ const isRequest = McplServerConnection.hasResponder({ args });
552
+ if (isRequest && this.heldRequests >= McplServerConnection.MAX_HELD_REQUESTS) {
553
+ this.refusedHeldRequests++;
554
+ if (this.refusedHeldRequests % 100 === 1) {
555
+ console.error(
556
+ `[mcpl] ${this.id}: held-request budget (${McplServerConnection.MAX_HELD_REQUESTS}) — ` +
557
+ `refused ${this.refusedHeldRequests} request(s) with -32000 while the plane is paused`,
558
+ );
438
559
  }
560
+ responder?.respondError?.(
561
+ -32000,
562
+ `the host is busy: ${McplServerConnection.MAX_HELD_REQUESTS} of this server's requests are already waiting; send this one again later`,
563
+ );
564
+ return true;
565
+ }
566
+ if (!isRequest && this.bufferedEvents.length - this.heldRequests >= McplServerConnection.MAX_HELD_NOTIFICATIONS) {
567
+ this.droppedBufferedEvents++;
568
+ if (this.droppedBufferedEvents % 100 === 1) {
569
+ console.error(
570
+ `[mcpl] ${this.id}: buffered-event cap (${McplServerConnection.MAX_HELD_NOTIFICATIONS}) — ` +
571
+ `dropped ${this.droppedBufferedEvents} responder-less event(s) while the plane is paused`,
572
+ );
573
+ }
574
+ const oldest = this.bufferedEvents.findIndex((item) => !McplServerConnection.hasResponder(item));
575
+ if (oldest >= 0) this.bufferedEvents.splice(oldest, 1);
439
576
  }
440
577
  this.bufferedEvents.push({ event: name, args });
578
+ if (isRequest) this.heldRequests++;
441
579
  return true;
442
580
  }
443
581
 
582
+ /** A buffered server→host request: it carries a responder its server waits on. */
583
+ private static hasResponder(item: { args: unknown[] }): boolean {
584
+ const responder = item.args[1] as { respond?: unknown } | undefined;
585
+ return typeof responder?.respond === 'function';
586
+ }
587
+
444
588
  /** Event-name form of METHOD_TO_REQUIRED_CAPABILITY, for admission-time
445
589
  * enforcement in emit(). */
446
590
  private static readonly EVENT_TO_REQUIRED_CAPABILITY: Record<string, string> = {
@@ -507,8 +651,9 @@ export class McplServerConnection extends EventEmitter {
507
651
  connection.allowHostCommands = config.allowHostCommands === true;
508
652
  connection.requestTimeoutMs = config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
509
653
 
510
- // Store config for reconnection
511
- if (config.reconnect) {
654
+ // Store config for reconnection. Only `true` turns reconnect on, as at
655
+ // every other reader of it.
656
+ if (config.reconnect === true) {
512
657
  connection.config = config;
513
658
  connection.hostCapabilities = hostCapabilities;
514
659
  connection.reconnectEnabled = true;
@@ -531,6 +676,15 @@ export class McplServerConnection extends EventEmitter {
531
676
  hostCapabilities: McplHostCapabilities,
532
677
  ): Promise<{ transport: McplTransport; capabilities: McplCapabilities | null; droppedCapabilities: ReadonlySet<string>; mcpToolsAdvertised: boolean }> {
533
678
  const transport = await openTransport(config);
679
+ // Once the handshake stops listening for 'error', this logs what the
680
+ // transport reports, until the handshake hands the transport on, or for
681
+ // good if the handshake fails. EventEmitter throws an 'error' that has no
682
+ // listener, and from an I/O callback nothing catches it. A malformed
683
+ // WebSocket frame that arrives with the initialize response, or while a
684
+ // failed handshake's close() runs, is such an error.
685
+ const logAfterSettled = (err: Error) => {
686
+ console.error(`[mcpl] ${config.id}: transport error after the handshake settled: ${err.message}`);
687
+ };
534
688
 
535
689
  try {
536
690
  const initId = 0; // use id=0 for the handshake
@@ -548,10 +702,20 @@ export class McplServerConnection extends EventEmitter {
548
702
  // Await the initialize response, racing an early transport close/error and
549
703
  // a timeout. All three paths clean up their listeners.
550
704
  const { mcpl: rawCapabilities, mcpToolsAdvertised } = await new Promise<{ mcpl: McplCapabilities | null; mcpToolsAdvertised: boolean }>((resolve, reject) => {
705
+ // When the transport fails, the end of the server's stderr often says
706
+ // why, such as a missing token or a crash at startup. It goes on the
707
+ // error as `stderrTail`, never into the message: an error's message
708
+ // travels to traces and tool results, and a server's stderr is its
709
+ // own text, which can hold a credential.
710
+ const failed = (failure: string): Error & { stderrTail?: string } => {
711
+ const tail = transport.stderrTail.trimEnd();
712
+ return Object.assign(new Error(failure), tail ? { stderrTail: tail } : {});
713
+ };
551
714
  const cleanup = () => {
552
715
  transport.off('line', onLine);
553
716
  transport.off('close', onClose);
554
717
  transport.off('error', onError);
718
+ transport.on('error', logAfterSettled);
555
719
  clearTimeout(timer);
556
720
  };
557
721
  const onLine = (line: string) => {
@@ -561,10 +725,30 @@ export class McplServerConnection extends EventEmitter {
561
725
  } catch {
562
726
  return; // Ignore non-JSON lines (e.g. logback output from Java servers)
563
727
  }
728
+ if (msg === null || typeof msg !== 'object' || Array.isArray(msg)) return;
729
+ // A request or a notification from the server is never the
730
+ // initialize response, whatever its id: a server's own ids can start
731
+ // at 0, this handshake's. MCP lets a server ping before
732
+ // initialization completes, and the ping gets its empty result, as
733
+ // on a connected transport. Anything else it sends now is ignored.
734
+ if ('method' in msg) {
735
+ const request = msg as unknown as JsonRpcRequest;
736
+ if (request.method === 'ping' && request.id != null) {
737
+ transport.writeLine(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: {} }));
738
+ }
739
+ return;
740
+ }
564
741
  if (msg.id !== initId) return;
565
742
  cleanup();
566
743
  if (msg.error) {
567
- reject(new Error(`MCPL server "${config.id}" initialize error: ${msg.error.message}`));
744
+ // describeCause rather than the template's own conversion: the
745
+ // server's `message` can be any JSON value, and one that has no
746
+ // primitive form, such as {"toString":1}, would throw out of this
747
+ // listener after cleanup() has cleared the timeout: an uncaught
748
+ // exception, which ends a host that doesn't catch them, and a
749
+ // handshake left to wait forever. It's the server's text in an
750
+ // error's message, so it's bounded as errors.ts says.
751
+ reject(new Error(`MCPL server "${config.id}" initialize error: ${boundedForLog(describeCause(msg.error.message))}`));
568
752
  return;
569
753
  }
570
754
  const result = msg.result as Record<string, unknown> | undefined;
@@ -580,15 +764,22 @@ export class McplServerConnection extends EventEmitter {
580
764
  };
581
765
  const onClose = (info: TransportCloseInfo) => {
582
766
  cleanup();
583
- reject(new Error(`MCPL server "${config.id}" transport closed before handshake completed (${info.reason ?? 'unknown'})`));
767
+ const code = transport.kind === 'websocket' && typeof info.code === 'number' ? `, code ${info.code}` : '';
768
+ const failure = `MCPL server "${config.id}" transport closed before handshake completed (${closeReasonText(info)}${code})`;
769
+ // The close comes at a stdio child's exit, which Node can emit before
770
+ // it has read the last of the child's stderr, or when the host closes
771
+ // the transport, which then ends the child. The tail is taken once
772
+ // stderr has ended, waiting at most STDERR_END_WAIT_MS. A WebSocket
773
+ // transport has no stderr to wait for.
774
+ void transport.stderrEnded(STDERR_END_WAIT_MS).then(() => reject(failed(failure)));
584
775
  };
585
776
  const onError = (err: Error) => {
586
777
  cleanup();
587
- reject(new Error(`MCPL server "${config.id}" transport error during handshake: ${err.message}`));
778
+ reject(failed(`MCPL server "${config.id}" transport error during handshake: ${err.message}`));
588
779
  };
589
780
  const timer = setTimeout(() => {
590
781
  cleanup();
591
- reject(new Error(`MCPL server "${config.id}" initialize handshake timed out`));
782
+ reject(failed(`MCPL server "${config.id}" initialize handshake timed out`));
592
783
  }, INITIALIZE_TIMEOUT_MS);
593
784
 
594
785
  transport.on('line', onLine);
@@ -610,9 +801,13 @@ export class McplServerConnection extends EventEmitter {
610
801
  // had never been advertised (hooks, streaming, queries all read this).
611
802
  const { capabilities: scoped, dropped } = maskNegotiatedCapabilities(capabilities, config);
612
803
  if (dropped.length > 0) {
613
- console.error(`MCPL server "${config.id}" capabilities masked by host config: ${dropped.join(', ')}`);
804
+ console.error(`MCPL server "${config.id}" capabilities masked by host config: ${dropped.map(logValue).join(', ')}`);
614
805
  }
615
806
 
807
+ // The caller wires the transport, or keeps it for close() with a
808
+ // listener of its own, in the continuation of this return, before any
809
+ // I/O callback can emit.
810
+ transport.off('error', logAfterSettled);
616
811
  return { transport, capabilities: scoped, droppedCapabilities: new Set(dropped), mcpToolsAdvertised };
617
812
  } catch (err) {
618
813
  // Never leak the child / socket if the handshake fails.
@@ -634,17 +829,18 @@ export class McplServerConnection extends EventEmitter {
634
829
  try {
635
830
  return await McplServerConnection.connect(config, hostCapabilities);
636
831
  } catch (error) {
637
- if (!config.reconnect) {
832
+ if (config.reconnect !== true) {
638
833
  throw error;
639
834
  }
640
835
 
641
836
  // Non-blocking start: create a disconnected stub that will reconnect in background
642
- console.error(`MCPL server "${config.id}" initial connect failed, will retry:`, (error as Error).message);
837
+ console.error(`MCPL server "${config.id}" initial connect failed, will retry: ${(error as Error).message}${withStderr(error)}`);
643
838
  const stub = McplServerConnection.createDisconnectedStub(config, hostCapabilities);
644
839
  // Surface the initial failure. The event is buffered by the emit()
645
840
  // override until the host wires listeners and calls ready(), so it is
646
841
  // not lost in the window before wireMcplEvents runs.
647
- stub.emit('connect-failed', { error: (error as Error).message, attempt: 0 });
842
+ const stderrTail = stderrTailOf(error);
843
+ stub.emit('connect-failed', { error: (error as Error).message, ...(stderrTail ? { stderrTail } : {}), attempt: 0 });
648
844
  return stub;
649
845
  }
650
846
  }
@@ -748,9 +944,13 @@ export class McplServerConnection extends EventEmitter {
748
944
  return this.sendRequest(McplMethod.StateRollback, params as unknown as Record<string, unknown>) as Promise<StateRollbackResult>;
749
945
  }
750
946
 
751
- /** Send `channels/open` request and await result. */
947
+ /** Send `channels/open` request and await result. It keeps a deadline as
948
+ * channels/publish does: a delivery opens a closed channel before it
949
+ * publishes, so an open that is never answered would hold the delivery,
950
+ * and the turn that waits for it, for good. */
752
951
  sendChannelsOpen(params: ChannelsOpenParams): Promise<ChannelsOpenResult> {
753
- return this.sendRequest(McplMethod.ChannelsOpen, params as unknown as Record<string, unknown>) as Promise<ChannelsOpenResult>;
952
+ const timeoutMs = this.requestTimeoutMs > 0 ? this.requestTimeoutMs : this.publishDeadlineMs;
953
+ return this.sendRequest(McplMethod.ChannelsOpen, params as unknown as Record<string, unknown>, { timeoutMs }) as Promise<ChannelsOpenResult>;
754
954
  }
755
955
 
756
956
  /** Send `channels/close` request and await result. */
@@ -775,13 +975,20 @@ export class McplServerConnection extends EventEmitter {
775
975
  * Send `channels/publish`.
776
976
  * May be sent as a request (if an ACK is desired) or notification.
777
977
  * When `params.stream` is true, sends as a notification (no ACK).
978
+ *
979
+ * A request always has a deadline: the server's requestTimeoutMs, or
980
+ * publishDeadlineMs when that is 0 (disabled). A publish is a side effect
981
+ * whose outcome the resident is told and a held draft's attempt records,
982
+ * so one that is never answered would hold both open for good. Its expiry
983
+ * is a no-response, which the caller reads as unknown.
778
984
  */
779
985
  sendChannelsPublish(params: ChannelsPublishParams): Promise<ChannelsPublishResult | void> {
780
986
  if (params.stream) {
781
987
  this.sendNotification(McplMethod.ChannelsPublish, params as unknown as Record<string, unknown>);
782
988
  return Promise.resolve();
783
989
  }
784
- return this.sendRequest(McplMethod.ChannelsPublish, params as unknown as Record<string, unknown>) as Promise<ChannelsPublishResult>;
990
+ const timeoutMs = this.requestTimeoutMs > 0 ? this.requestTimeoutMs : this.publishDeadlineMs;
991
+ return this.sendRequest(McplMethod.ChannelsPublish, params as unknown as Record<string, unknown>, { timeoutMs }) as Promise<ChannelsPublishResult>;
785
992
  }
786
993
 
787
994
  /** Send `channels/outgoing/chunk` notification. */
@@ -874,7 +1081,7 @@ export class McplServerConnection extends EventEmitter {
874
1081
  // Reject all pending requests
875
1082
  for (const [id, pending] of this.pendingRequests) {
876
1083
  if (pending.timer) clearTimeout(pending.timer);
877
- pending.reject(new Error(`Connection to MCPL server "${this.id}" closed while awaiting response for ${pending.method} (id=${id})`));
1084
+ pending.reject(new McplRequestError(`Connection to MCPL server "${this.id}" closed while awaiting response for ${pending.method} (id=${id})`, 'no-response'));
878
1085
  }
879
1086
  this.pendingRequests.clear();
880
1087
  this.orphanedRequests.clear();
@@ -885,7 +1092,8 @@ export class McplServerConnection extends EventEmitter {
885
1092
  const attempt = Promise.resolve().then(async () => {
886
1093
  // An already opened handshake owns a transport too. It hands that
887
1094
  // transport back without admission once reconnect has been disabled.
888
- // The registry bounds this wait; retry reuses this real close attempt.
1095
+ // Only the registry's closeAll bounds its caller's wait for this; retry
1096
+ // reuses this real close attempt.
889
1097
  if (this.reconnectPromise) await this.reconnectPromise;
890
1098
  if (this.transport) await this.transport.close();
891
1099
  this.closeIncomplete = false;
@@ -989,6 +1197,13 @@ export class McplServerConnection extends EventEmitter {
989
1197
  // The prior transport was disconnected before this retry began. Keep
990
1198
  // the fresh, unadmitted transport owned by close(), including on a
991
1199
  // failed transport cleanup, instead of reviving a stopped connection.
1200
+ // It isn't wired, and the handshake has removed its own listeners, so
1201
+ // an error it reports from here on, such as a malformed frame from a
1202
+ // WebSocket server while close() closes it, is logged here rather than
1203
+ // thrown where nothing catches it.
1204
+ transport.on('error', (err: Error) => {
1205
+ console.error(`[mcpl] ${this.id}: a transport kept for close() reported an error: ${err.message}`);
1206
+ });
992
1207
  this.transport = transport;
993
1208
  return;
994
1209
  }
@@ -1013,9 +1228,10 @@ export class McplServerConnection extends EventEmitter {
1013
1228
  this.reconnectAttempts = 0;
1014
1229
  this.emit('reconnect', { attempts: attempt });
1015
1230
  } catch (error) {
1016
- console.error(`MCPL server "${this.id}" reconnect failed:`, (error as Error).message);
1231
+ console.error(`MCPL server "${this.id}" reconnect failed: ${(error as Error).message}${withStderr(error)}`);
1017
1232
  this.reconnectAttempts = attempt + 1;
1018
- this.emit('reconnect-failed', { error: (error as Error).message, attempt });
1233
+ const stderrTail = stderrTailOf(error);
1234
+ this.emit('reconnect-failed', { error: (error as Error).message, ...(stderrTail ? { stderrTail } : {}), attempt });
1019
1235
  this.scheduleReconnect();
1020
1236
  }
1021
1237
  }
@@ -1041,7 +1257,7 @@ export class McplServerConnection extends EventEmitter {
1041
1257
  options: RequestOptions = {},
1042
1258
  ): Promise<unknown> {
1043
1259
  if (this.closed) {
1044
- return Promise.reject(new Error(`Cannot send request: connection to "${this.id}" is closed`));
1260
+ return Promise.reject(new McplRequestError(`Cannot send request: connection to "${this.id}" is closed`, 'not-sent'));
1045
1261
  }
1046
1262
 
1047
1263
  const id = this.nextRequestId++;
@@ -1059,23 +1275,47 @@ export class McplServerConnection extends EventEmitter {
1059
1275
  pending.timer = setTimeout(() => {
1060
1276
  this.pendingRequests.delete(id);
1061
1277
  if (options.surfaceOrphanedResponse) {
1062
- this.orphanedRequests.set(id, { method, ...(method === 'push/render' ? { renderParams: { featureSet: params.featureSet, key: params.key, eventId: params.eventId } } : {}) });
1278
+ this.orphanedRequests.set(id, {
1279
+ method,
1280
+ ...(method === 'push/render'
1281
+ ? {
1282
+ renderParams: {
1283
+ featureSet: params.featureSet as string,
1284
+ key: params.key as string,
1285
+ eventId: params.eventId as string,
1286
+ ...(typeof params.channelId === 'string' ? { channelId: params.channelId } : {}),
1287
+ },
1288
+ }
1289
+ : {}),
1290
+ });
1063
1291
  if (this.orphanedRequests.size > 4096) this.orphanedRequests.delete(this.orphanedRequests.keys().next().value!);
1064
1292
  }
1065
- reject(new Error(
1293
+ reject(new McplRequestError(
1066
1294
  `MCPL server "${this.id}" did not respond to ${method} (id=${id}) ` +
1067
1295
  `within ${timeoutMs}ms — the server may be hung. The response ` +
1068
1296
  `outcome is unknown: the request was abandoned locally but was not ` +
1069
1297
  `cancelled, so the tool may still have completed server-side; verify ` +
1070
1298
  `state before retrying; a blind retry of a stateful/side-effecting ` +
1071
1299
  `tool may duplicate it.`,
1300
+ 'no-response',
1072
1301
  ));
1073
1302
  }, timeoutMs);
1074
1303
  // Don't hold the event loop open for the watchdog alone.
1075
1304
  pending.timer.unref?.();
1076
1305
  }
1077
1306
  this.pendingRequests.set(id, pending);
1078
- this.transport!.writeLine(JSON.stringify(request));
1307
+ try {
1308
+ this.transport!.writeLine(JSON.stringify(request));
1309
+ } catch (err) {
1310
+ // A synchronous write rejection sent no request. Remove its pending
1311
+ // state and watchdog before reporting that it is safe to retry.
1312
+ this.pendingRequests.delete(id);
1313
+ if (pending.timer) clearTimeout(pending.timer);
1314
+ reject(new McplRequestError(
1315
+ `Cannot send ${method} to MCPL server "${this.id}": ${err instanceof Error ? err.message : String(err)}`,
1316
+ 'not-sent',
1317
+ ));
1318
+ }
1079
1319
  });
1080
1320
  }
1081
1321
 
@@ -1165,7 +1405,9 @@ export class McplServerConnection extends EventEmitter {
1165
1405
  this.setupLifecycle(transport);
1166
1406
  // Surface transport diagnostics (stdio child stderr) as 'stderr' events,
1167
1407
  // preserving the `{ line }` payload existing consumers expect.
1168
- transport.on('stderr', (line: string) => this.emit('stderr', { line }));
1408
+ // Through the same containment boundary as every inbound event, so a
1409
+ // stderr listener that throws is reported, not thrown into the transport.
1410
+ transport.on('stderr', (line: string) => this.dispatchInboundEvent('stderr', { line }));
1169
1411
  }
1170
1412
 
1171
1413
  /**
@@ -1181,61 +1423,148 @@ export class McplServerConnection extends EventEmitter {
1181
1423
  return;
1182
1424
  }
1183
1425
 
1184
- // Is this a response to one of our outbound requests?
1185
- if ('id' in msg && msg.id != null && !('method' in msg)) {
1186
- this.handleResponse(msg as JsonRpcResponse);
1187
- return;
1426
+ // JSON-RPC messages must be objects. Ignore unrelated stdout/log values
1427
+ // before property access, just as malformed JSON lines are ignored.
1428
+ if (msg === null || typeof msg !== 'object' || Array.isArray(msg)) return;
1429
+ try {
1430
+ this.dispatchMessage(msg);
1431
+ } catch (error) {
1432
+ const request = msg as { method?: unknown; id?: unknown };
1433
+ this.reportInboundFailure(error, {
1434
+ ...(typeof request.method === 'string' ? { event: request.method } : {}),
1435
+ ...(typeof request.id === 'string' || typeof request.id === 'number' ? { requestId: request.id } : {}),
1436
+ });
1188
1437
  }
1438
+ });
1439
+ }
1189
1440
 
1190
- // It is an inbound request or notification from the server
1191
- const request = msg as JsonRpcRequest;
1192
- const eventName = McplServerConnection.METHOD_TO_EVENT[request.method];
1193
-
1194
- // §7 is removed in 0.5.0: scope/elevate is no longer a method. Answer
1195
- // rather than hang (§6.6 — a method that will never be answered MUST
1196
- // return an error).
1197
- // featureSets/changed is REMOVED in 0.5.0 (§6.7 — it carried a
1198
- // server-authored change payload, the self-attestation defect; the
1199
- // need is met by §17's host-diffed manifest fetch). It was still
1200
- // routed, control-plane classified, and mutating declarations — a
1201
- // live ungated self-attestation path (PR #79 review blocker 4).
1202
- if (request.method === McplMethod.FeatureSetsChanged) {
1203
- if (request.id != null) {
1204
- this.sendErrorResponse(request.id, -32601, 'featureSets/changed removed in MCPL 0.5.0 (superseded by mcpl/manifestChanged, SPEC §17)');
1205
- } else {
1206
- console.error(`[mcpl] ${this.id}: discarded featureSets/changed — removed in 0.5.0 (§6.7/§17)`);
1207
- }
1208
- return;
1441
+ /** Contain synchronous dispatch failures; async RPC handlers own their promises. */
1442
+ private dispatchMessage(msg: JsonRpcRequest | JsonRpcResponse): void {
1443
+ // Is this a response to one of our outbound requests?
1444
+ if ('id' in msg && msg.id != null && !('method' in msg)) {
1445
+ this.handleResponse(msg as JsonRpcResponse);
1446
+ return;
1447
+ }
1448
+
1449
+ // It is an inbound request or notification from the server
1450
+ const request = msg as JsonRpcRequest;
1451
+
1452
+ // MCP's ping, which either side may send: its receiver answers promptly
1453
+ // with an empty result. It's answered as it arrives, before admission and
1454
+ // buffering, since it asks only whether the connection is alive, and a
1455
+ // paused plane mustn't hold that answer. A ping sent as a notification
1456
+ // has nothing to answer. The handshake answers one too.
1457
+ if (request.method === 'ping') {
1458
+ if (request.id != null) this.sendResponse(request.id, {});
1459
+ return;
1460
+ }
1461
+
1462
+ const eventName = typeof request.method === 'string' && Object.hasOwn(McplServerConnection.METHOD_TO_EVENT, request.method)
1463
+ ? McplServerConnection.METHOD_TO_EVENT[request.method] : undefined;
1464
+
1465
+ // §7 is removed in 0.5.0: scope/elevate is no longer a method. Answer
1466
+ // rather than hang (§6.6 — a method that will never be answered MUST
1467
+ // return an error).
1468
+ // featureSets/changed is REMOVED in 0.5.0 (§6.7 — it carried a
1469
+ // server-authored change payload, the self-attestation defect; the
1470
+ // need is met by §17's host-diffed manifest fetch). It was still
1471
+ // routed, control-plane classified, and mutating declarations — a
1472
+ // live ungated self-attestation path (PR #79 review blocker 4).
1473
+ if (request.method === McplMethod.FeatureSetsChanged) {
1474
+ if (request.id != null) {
1475
+ this.sendErrorResponse(request.id, -32601, 'featureSets/changed removed in MCPL 0.5.0 (superseded by mcpl/manifestChanged, SPEC §17)');
1476
+ } else {
1477
+ console.error(`[mcpl] ${this.id}: discarded featureSets/changed — removed in 0.5.0 (§6.7/§17)`);
1209
1478
  }
1479
+ return;
1480
+ }
1210
1481
 
1211
- if (request.method === McplMethod.ScopeElevate) {
1212
- if (request.id != null) {
1213
- this.sendErrorResponse(request.id, -32601, 'scope/elevate removed in MCPL 0.5.0 (SPEC §7)');
1214
- }
1215
- return;
1482
+ if (request.method === McplMethod.ScopeElevate) {
1483
+ if (request.id != null) {
1484
+ this.sendErrorResponse(request.id, -32601, 'scope/elevate removed in MCPL 0.5.0 (SPEC §7)');
1216
1485
  }
1486
+ return;
1487
+ }
1217
1488
 
1218
- // Positive-grant enforcement (§5.4, §14.1) happens at ADMISSION, in
1219
- // the emit() override below — the one choke-point that live routing
1220
- // and staged-buffer flushes share. See the comment there for why
1221
- // rejecting here, at line receipt, was wrong for staged connections.
1222
-
1223
- if (eventName) {
1224
- // Emit the typed event with params and (for requests) a respond callback
1225
- if (request.id != null) {
1226
- // Server expects a response — provide a respond helper
1227
- this.emit(eventName, request.params, {
1228
- id: request.id,
1229
- respond: (result: unknown) => this.sendResponse(request.id!, result),
1230
- respondError: (code: number, message: string, data?: unknown) =>
1231
- this.sendErrorResponse(request.id!, code, message, data),
1232
- });
1233
- } else {
1234
- // Notification — no response expected
1235
- this.emit(eventName, request.params);
1236
- }
1489
+ // Positive-grant enforcement (§5.4, §14.1) happens at ADMISSION, in
1490
+ // the emit() override below — the one choke-point that live routing
1491
+ // and staged-buffer flushes share. See the comment there for why
1492
+ // rejecting here, at line receipt, was wrong for staged connections.
1493
+
1494
+ if (!eventName) {
1495
+ // §6.6: a request that will never be answered MUST get an error, so a
1496
+ // request (it has an id) whose method isn't a string, or isn't one this
1497
+ // host handles, is answered -32601. A notification nobody handles is
1498
+ // ignored, as JSON-RPC asks.
1499
+ if (request.id != null) {
1500
+ this.sendErrorResponse(request.id, -32601, 'Method not found');
1501
+ console.error(`[mcpl] ${this.id}: answered -32601 to a request for ${describeMethod(request.method)}, which this host doesn't handle`);
1237
1502
  }
1238
- });
1503
+ return;
1504
+ }
1505
+
1506
+ // Emit the typed event with params and (for requests) a respond callback
1507
+ if (request.id != null) {
1508
+ // Server expects a response — provide a respond helper
1509
+ this.dispatchInboundEvent(eventName, request.params, {
1510
+ id: request.id,
1511
+ respond: (result: unknown) => this.sendResponse(request.id!, result),
1512
+ respondError: (code: number, message: string, data?: unknown) =>
1513
+ this.sendErrorResponse(request.id!, code, message, data),
1514
+ });
1515
+ } else {
1516
+ // Notification — no response expected
1517
+ this.dispatchInboundEvent(eventName, request.params);
1518
+ }
1519
+ }
1520
+
1521
+ /** Live delivery and delayed plane flushes share the same containment boundary. */
1522
+ private dispatchInboundEvent(event: string, ...args: unknown[]): void {
1523
+ try {
1524
+ this.emit(event, ...args);
1525
+ } catch (error) {
1526
+ const requestId = (args[1] as { id?: unknown } | undefined)?.id;
1527
+ this.reportInboundFailure(error, {
1528
+ event,
1529
+ ...(typeof requestId === 'string' || typeof requestId === 'number' ? { requestId } : {}),
1530
+ });
1531
+ }
1532
+ }
1533
+
1534
+ /** Report a failure the containment boundary caught, naming the event (or
1535
+ * method) and request it was dispatching, and what failed. The message is
1536
+ * what the framework's 'error' listener traces. */
1537
+ private reportInboundFailure(cause: unknown, context: { event?: string; requestId?: string | number } = {}): void {
1538
+ const where = (show: (text: string) => string): string => (context.event === undefined ? '' : ` for ${show(context.event)}`) +
1539
+ (context.requestId === undefined ? '' : ` (request ${show(String(context.requestId))})`);
1540
+ // The error's message is what the 'error' listener traces, as text a
1541
+ // reader parses, so it is bounded rather than escaped (boundedForLog);
1542
+ // the log line prints the same through log-value.
1543
+ const error = new Error(`MCPL server "${this.id}" inbound dispatch failed${where(boundedForLog)}: ${boundedForLog(describeCause(cause))}`, { cause });
1544
+ console.error(`[mcpl] ${this.id}: inbound dispatch failed${where(logValue)}: ${logDetail(describeCause(cause))}`);
1545
+ this.emitToErrorListeners(error);
1546
+ }
1547
+
1548
+ /**
1549
+ * Give an error to the connection's 'error' listeners, and say whether it
1550
+ * has any. EventEmitter throws an 'error' that nothing listens for, and
1551
+ * from a transport's callback, where these errors arise, nothing catches
1552
+ * that throw, so it ends the process. A bare connection has no listener:
1553
+ * the class is exported, and a probe, a playtest or a harness often attaches
1554
+ * none. So with no listener, the error is the caller's to log, unless it
1555
+ * already has. A listener that throws is caught and logged, with the error
1556
+ * it was handling.
1557
+ */
1558
+ private emitToErrorListeners(error: Error): boolean {
1559
+ if (this.listenerCount('error') === 0) return false;
1560
+ try { this.emit('error', error); }
1561
+ catch (listenerError) {
1562
+ console.error(
1563
+ `[mcpl] ${this.id}: an 'error' listener failed: ${logDetail(describeCause(listenerError))}` +
1564
+ `, handling ${logDetail(error.message)}`,
1565
+ );
1566
+ }
1567
+ return true;
1239
1568
  }
1240
1569
 
1241
1570
  /**
@@ -1252,10 +1581,17 @@ export class McplServerConnection extends EventEmitter {
1252
1581
  // re-inject either result because the original dispatch context is gone.
1253
1582
  const orphaned = this.orphanedRequests.get(response.id);
1254
1583
  this.orphanedRequests.delete(response.id);
1255
- if (orphaned?.renderParams) {
1256
- this.emit('orphaned-render-response', { params: orphaned.renderParams, result: response.result, error: response.error });
1257
- return; // audit only: a timeout fallback can never be replaced
1258
- }
1584
+ // A push/render answered after its timeout (RFC-006 §5.3) is reported
1585
+ // with the render's featureSet, key, eventId and, for a channel-scoped
1586
+ // subject, channelId, kept from its request when the timeout fired, so
1587
+ // its discarded answer can be recorded beside its batch's other
1588
+ // coalescing records (§11). It is only reported: the fallback the
1589
+ // timeout materialized stands (§5.4 rule 3). A late JSON-RPC error is
1590
+ // passed on as `error`, so its record can be told from a late result's,
1591
+ // and so is one beside a result, which JSON-RPC forbids: the live path
1592
+ // rejects such an answer as an error.
1593
+ const render = orphaned?.renderParams ?? {};
1594
+ const failure = response.error ? { error: { code: response.error.code, message: response.error.message } } : {};
1259
1595
  const result = response.result;
1260
1596
  if (result && typeof result === 'object') {
1261
1597
  const r = result as { state?: unknown; checkpoint?: unknown };
@@ -1265,6 +1601,8 @@ export class McplServerConnection extends EventEmitter {
1265
1601
  method: orphaned?.method,
1266
1602
  hadState: r.state !== undefined,
1267
1603
  hadCheckpoint: r.checkpoint !== undefined,
1604
+ ...render,
1605
+ ...failure,
1268
1606
  });
1269
1607
  }
1270
1608
  } else if (orphaned) {
@@ -1273,6 +1611,8 @@ export class McplServerConnection extends EventEmitter {
1273
1611
  method: orphaned.method,
1274
1612
  hadState: false,
1275
1613
  hadCheckpoint: false,
1614
+ ...render,
1615
+ ...failure,
1276
1616
  });
1277
1617
  }
1278
1618
  return; // Orphaned response — ignore
@@ -1282,8 +1622,19 @@ export class McplServerConnection extends EventEmitter {
1282
1622
  if (pending.timer) clearTimeout(pending.timer);
1283
1623
 
1284
1624
  if (response.error) {
1625
+ // describeCause rather than the template's own conversion, as for an
1626
+ // initialize error: the server's code and message can be any JSON
1627
+ // value, and one with no primitive form, such as {"toString":1}, would
1628
+ // throw here, after the request has left pendingRequests and its timer
1629
+ // is cleared, so it would never settle. Both are the server's text, a
1630
+ // code as much as a message, since a server can send a string, so both
1631
+ // are bounded as errors.ts says.
1285
1632
  pending.reject(
1286
- new Error(`MCPL server "${this.id}" returned error for ${pending.method}: [${response.error.code}] ${response.error.message}`),
1633
+ new McplRequestError(
1634
+ `MCPL server "${this.id}" returned error for ${pending.method}: [${boundedForLog(describeCause(response.error.code))}] ${boundedForLog(describeCause(response.error.message))}`,
1635
+ 'error-response',
1636
+ (response.error as { data?: unknown }).data,
1637
+ ),
1287
1638
  );
1288
1639
  } else {
1289
1640
  pending.resolve(response.result);
@@ -1324,7 +1675,8 @@ export class McplServerConnection extends EventEmitter {
1324
1675
  private setupLifecycle(transport: McplTransport): void {
1325
1676
  this.hostCloseRequested = false;
1326
1677
  transport.on('error', (err: Error) => {
1327
- this.emit('error', new Error(`MCPL server "${this.id}" transport error: ${err.message}`));
1678
+ const error = new Error(`MCPL server "${this.id}" transport error: ${err.message}`);
1679
+ if (!this.emitToErrorListeners(error)) console.error(`[mcpl] ${this.id}: transport error: ${logDetail(err.message)}`);
1328
1680
  });
1329
1681
 
1330
1682
  transport.on('close', (info: TransportCloseInfo) => {
@@ -1336,8 +1688,9 @@ export class McplServerConnection extends EventEmitter {
1336
1688
  for (const [id, pending] of this.pendingRequests) {
1337
1689
  if (pending.timer) clearTimeout(pending.timer);
1338
1690
  pending.reject(
1339
- new Error(
1340
- `MCPL server "${this.id}" disconnected unexpectedly (code=${info.code ?? 'n/a'}, signal=${info.signal ?? 'n/a'}, reason=${info.reason ?? 'unknown'}) while awaiting ${pending.method} (id=${id})`,
1691
+ new McplRequestError(
1692
+ `MCPL server "${this.id}" disconnected unexpectedly (code=${info.code ?? 'n/a'}, signal=${info.signal ?? 'n/a'}, reason=${closeReasonText(info)}) while awaiting ${pending.method} (id=${id})`,
1693
+ 'no-response',
1341
1694
  ),
1342
1695
  );
1343
1696
  }
@@ -1355,6 +1708,7 @@ export class McplServerConnection extends EventEmitter {
1355
1708
  code: info.code ?? null,
1356
1709
  signal: info.signal ?? null,
1357
1710
  reason: info.reason ?? (byHost ? 'closed by host' : undefined),
1711
+ ...(info.reasonFromPeer ? { reasonFromPeer: true } : {}),
1358
1712
  byHost,
1359
1713
  };
1360
1714
  this.emit('close', closeInfo.code, closeInfo.signal, closeInfo);