@animalabs/agent-framework 0.22.2 → 0.22.4

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