@smthrs/gateway 0.35.0 → 1.0.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (605) hide show
  1. package/CHANGELOG.md +198 -0
  2. package/LICENSE +1 -1
  3. package/README.md +92 -0
  4. package/dist/cjs/Diagnosis.d.ts +275 -0
  5. package/dist/cjs/Diagnosis.d.ts.map +1 -0
  6. package/dist/cjs/Diagnosis.js +476 -0
  7. package/dist/cjs/Diagnosis.js.map +7 -0
  8. package/dist/cjs/EngineTrace.d.ts +76 -0
  9. package/dist/cjs/EngineTrace.d.ts.map +1 -0
  10. package/dist/cjs/EngineTrace.js +501 -0
  11. package/dist/cjs/EngineTrace.js.map +7 -0
  12. package/dist/cjs/GatewayError.d.ts +54 -0
  13. package/dist/cjs/GatewayError.d.ts.map +1 -0
  14. package/dist/cjs/GatewayError.js +51 -0
  15. package/dist/cjs/GatewayError.js.map +7 -0
  16. package/dist/cjs/GatewayProjection.d.ts +480 -0
  17. package/dist/cjs/GatewayProjection.d.ts.map +1 -0
  18. package/dist/cjs/GatewayProjection.js +462 -0
  19. package/dist/cjs/GatewayProjection.js.map +7 -0
  20. package/dist/cjs/GatewayRpcs.d.ts +1886 -0
  21. package/dist/cjs/GatewayRpcs.d.ts.map +1 -0
  22. package/dist/cjs/GatewayRpcs.js +121 -0
  23. package/dist/cjs/GatewayRpcs.js.map +7 -0
  24. package/dist/cjs/GatewaySchema.d.ts +3274 -0
  25. package/dist/cjs/GatewaySchema.d.ts.map +1 -0
  26. package/dist/cjs/GatewaySchema.js +141 -0
  27. package/dist/cjs/GatewaySchema.js.map +7 -0
  28. package/dist/cjs/GatewayServer.d.ts +427 -0
  29. package/dist/cjs/GatewayServer.d.ts.map +1 -0
  30. package/dist/cjs/GatewayServer.js +428 -0
  31. package/dist/cjs/GatewayServer.js.map +7 -0
  32. package/dist/cjs/HostBranchPresence.d.ts +12 -0
  33. package/dist/cjs/HostBranchPresence.d.ts.map +1 -0
  34. package/dist/cjs/HostBranchPresence.js +82 -0
  35. package/dist/cjs/HostBranchPresence.js.map +7 -0
  36. package/dist/cjs/Projections.d.ts +209 -0
  37. package/dist/cjs/Projections.d.ts.map +1 -0
  38. package/dist/cjs/Projections.js +906 -0
  39. package/dist/cjs/Projections.js.map +7 -0
  40. package/dist/cjs/RunDevTools.d.ts +181 -0
  41. package/dist/cjs/RunDevTools.d.ts.map +1 -0
  42. package/dist/cjs/RunDevTools.js +195 -0
  43. package/dist/cjs/RunDevTools.js.map +7 -0
  44. package/dist/cjs/RunHistory.d.ts +185 -0
  45. package/dist/cjs/RunHistory.d.ts.map +1 -0
  46. package/dist/cjs/RunHistory.js +68 -0
  47. package/dist/cjs/RunHistory.js.map +7 -0
  48. package/dist/cjs/RunTrace.d.ts +753 -0
  49. package/dist/cjs/RunTrace.d.ts.map +1 -0
  50. package/dist/cjs/RunTrace.js +1593 -0
  51. package/dist/cjs/RunTrace.js.map +7 -0
  52. package/dist/cjs/RuntimeBridge.d.ts +1386 -0
  53. package/dist/cjs/RuntimeBridge.d.ts.map +1 -0
  54. package/dist/cjs/RuntimeBridge.js +598 -0
  55. package/dist/cjs/RuntimeBridge.js.map +7 -0
  56. package/dist/cjs/bun/BunGateway.d.ts +20 -0
  57. package/dist/cjs/bun/BunGateway.d.ts.map +1 -0
  58. package/dist/cjs/bun/BunGateway.js +62 -0
  59. package/dist/cjs/bun/BunGateway.js.map +7 -0
  60. package/dist/cjs/index.d.ts +65 -0
  61. package/dist/cjs/index.d.ts.map +1 -0
  62. package/dist/cjs/index.js +59 -0
  63. package/dist/cjs/index.js.map +7 -0
  64. package/dist/cjs/internal/NativeGateway.d.ts +176 -0
  65. package/dist/cjs/internal/NativeGateway.d.ts.map +1 -0
  66. package/dist/cjs/internal/NativeGateway.js +187 -0
  67. package/dist/cjs/internal/NativeGateway.js.map +7 -0
  68. package/dist/cjs/internal/actionRenderings.d.ts +2 -0
  69. package/dist/cjs/internal/actionRenderings.d.ts.map +1 -0
  70. package/dist/cjs/internal/actionRenderings.js +224 -0
  71. package/dist/cjs/internal/actionRenderings.js.map +7 -0
  72. package/dist/cjs/internal/callEvents.d.ts +97 -0
  73. package/dist/cjs/internal/callEvents.d.ts.map +1 -0
  74. package/dist/cjs/internal/callEvents.js +169 -0
  75. package/dist/cjs/internal/callEvents.js.map +7 -0
  76. package/dist/cjs/internal/digestIndex.d.ts +31 -0
  77. package/dist/cjs/internal/digestIndex.d.ts.map +1 -0
  78. package/dist/cjs/internal/digestIndex.js +105 -0
  79. package/dist/cjs/internal/digestIndex.js.map +7 -0
  80. package/dist/cjs/internal/digestMemory.d.ts +19 -0
  81. package/dist/cjs/internal/digestMemory.d.ts.map +1 -0
  82. package/dist/cjs/internal/digestMemory.js +33 -0
  83. package/dist/cjs/internal/digestMemory.js.map +7 -0
  84. package/dist/cjs/internal/inspectLabels.d.ts +8 -0
  85. package/dist/cjs/internal/inspectLabels.d.ts.map +1 -0
  86. package/dist/cjs/internal/inspectLabels.js +29 -0
  87. package/dist/cjs/internal/inspectLabels.js.map +7 -0
  88. package/dist/cjs/internal/nativeResolution.d.ts +41 -0
  89. package/dist/cjs/internal/nativeResolution.d.ts.map +1 -0
  90. package/dist/cjs/internal/nativeResolution.js +62 -0
  91. package/dist/cjs/internal/nativeResolution.js.map +7 -0
  92. package/dist/cjs/internal/nodeEvents.d.ts +47 -0
  93. package/dist/cjs/internal/nodeEvents.d.ts.map +1 -0
  94. package/dist/cjs/internal/nodeEvents.js +60 -0
  95. package/dist/cjs/internal/nodeEvents.js.map +7 -0
  96. package/dist/cjs/node/NodeGateway.d.ts +16 -0
  97. package/dist/cjs/node/NodeGateway.d.ts.map +1 -0
  98. package/dist/cjs/node/NodeGateway.js +48 -0
  99. package/dist/cjs/node/NodeGateway.js.map +7 -0
  100. package/dist/cjs/package.json +1 -0
  101. package/dist/esm/Diagnosis.d.ts +275 -0
  102. package/dist/esm/Diagnosis.d.ts.map +1 -0
  103. package/dist/esm/Diagnosis.js +697 -0
  104. package/dist/esm/Diagnosis.js.map +1 -0
  105. package/dist/esm/EngineTrace.d.ts +76 -0
  106. package/dist/esm/EngineTrace.d.ts.map +1 -0
  107. package/dist/esm/EngineTrace.js +548 -0
  108. package/dist/esm/EngineTrace.js.map +1 -0
  109. package/dist/esm/GatewayError.d.ts +54 -0
  110. package/dist/esm/GatewayError.d.ts.map +1 -0
  111. package/dist/esm/GatewayError.js +60 -0
  112. package/dist/esm/GatewayError.js.map +1 -0
  113. package/dist/esm/GatewayProjection.d.ts +480 -0
  114. package/dist/esm/GatewayProjection.d.ts.map +1 -0
  115. package/dist/esm/GatewayProjection.js +792 -0
  116. package/dist/esm/GatewayProjection.js.map +1 -0
  117. package/dist/esm/GatewayRpcs.d.ts +1886 -0
  118. package/dist/esm/GatewayRpcs.d.ts.map +1 -0
  119. package/dist/esm/GatewayRpcs.js +145 -0
  120. package/dist/esm/GatewayRpcs.js.map +1 -0
  121. package/dist/esm/GatewaySchema.d.ts +3274 -0
  122. package/dist/esm/GatewaySchema.d.ts.map +1 -0
  123. package/dist/esm/GatewaySchema.js +244 -0
  124. package/dist/esm/GatewaySchema.js.map +1 -0
  125. package/dist/esm/GatewayServer.d.ts +427 -0
  126. package/dist/esm/GatewayServer.d.ts.map +1 -0
  127. package/dist/esm/GatewayServer.js +725 -0
  128. package/dist/esm/GatewayServer.js.map +1 -0
  129. package/dist/esm/HostBranchPresence.d.ts +12 -0
  130. package/dist/esm/HostBranchPresence.d.ts.map +1 -0
  131. package/dist/esm/HostBranchPresence.js +54 -0
  132. package/dist/esm/HostBranchPresence.js.map +1 -0
  133. package/dist/esm/Projections.d.ts +209 -0
  134. package/dist/esm/Projections.d.ts.map +1 -0
  135. package/dist/esm/Projections.js +1254 -0
  136. package/dist/esm/Projections.js.map +1 -0
  137. package/dist/esm/RunDevTools.d.ts +181 -0
  138. package/dist/esm/RunDevTools.d.ts.map +1 -0
  139. package/dist/esm/RunDevTools.js +281 -0
  140. package/dist/esm/RunDevTools.js.map +1 -0
  141. package/dist/esm/RunHistory.d.ts +185 -0
  142. package/dist/esm/RunHistory.d.ts.map +1 -0
  143. package/dist/esm/RunHistory.js +109 -0
  144. package/dist/esm/RunHistory.js.map +1 -0
  145. package/dist/esm/RunTrace.d.ts +753 -0
  146. package/dist/esm/RunTrace.d.ts.map +1 -0
  147. package/dist/esm/RunTrace.js +2105 -0
  148. package/dist/esm/RunTrace.js.map +1 -0
  149. package/dist/esm/RuntimeBridge.d.ts +1386 -0
  150. package/dist/esm/RuntimeBridge.d.ts.map +1 -0
  151. package/dist/esm/RuntimeBridge.js +659 -0
  152. package/dist/esm/RuntimeBridge.js.map +1 -0
  153. package/dist/esm/bun/BunGateway.d.ts +20 -0
  154. package/dist/esm/bun/BunGateway.d.ts.map +1 -0
  155. package/dist/esm/bun/BunGateway.js +32 -0
  156. package/dist/esm/bun/BunGateway.js.map +1 -0
  157. package/dist/esm/index.d.ts +65 -0
  158. package/dist/esm/index.d.ts.map +1 -0
  159. package/dist/esm/index.js +65 -0
  160. package/dist/esm/index.js.map +1 -0
  161. package/dist/esm/internal/NativeGateway.d.ts +176 -0
  162. package/dist/esm/internal/NativeGateway.d.ts.map +1 -0
  163. package/dist/esm/internal/NativeGateway.js +268 -0
  164. package/dist/esm/internal/NativeGateway.js.map +1 -0
  165. package/dist/esm/internal/actionRenderings.d.ts +2 -0
  166. package/dist/esm/internal/actionRenderings.d.ts.map +1 -0
  167. package/dist/esm/internal/actionRenderings.js +202 -0
  168. package/dist/esm/internal/actionRenderings.js.map +1 -0
  169. package/dist/esm/internal/callEvents.d.ts +97 -0
  170. package/dist/esm/internal/callEvents.d.ts.map +1 -0
  171. package/dist/esm/internal/callEvents.js +206 -0
  172. package/dist/esm/internal/callEvents.js.map +1 -0
  173. package/dist/esm/internal/digestIndex.d.ts +31 -0
  174. package/dist/esm/internal/digestIndex.d.ts.map +1 -0
  175. package/dist/esm/internal/digestIndex.js +87 -0
  176. package/dist/esm/internal/digestIndex.js.map +1 -0
  177. package/dist/esm/internal/digestMemory.d.ts +19 -0
  178. package/dist/esm/internal/digestMemory.d.ts.map +1 -0
  179. package/dist/esm/internal/digestMemory.js +23 -0
  180. package/dist/esm/internal/digestMemory.js.map +1 -0
  181. package/dist/esm/internal/inspectLabels.d.ts +8 -0
  182. package/dist/esm/internal/inspectLabels.d.ts.map +1 -0
  183. package/dist/esm/internal/inspectLabels.js +12 -0
  184. package/dist/esm/internal/inspectLabels.js.map +1 -0
  185. package/dist/esm/internal/nativeResolution.d.ts +41 -0
  186. package/dist/esm/internal/nativeResolution.d.ts.map +1 -0
  187. package/dist/esm/internal/nativeResolution.js +78 -0
  188. package/dist/esm/internal/nativeResolution.js.map +1 -0
  189. package/dist/esm/internal/nodeEvents.d.ts +47 -0
  190. package/dist/esm/internal/nodeEvents.d.ts.map +1 -0
  191. package/dist/esm/internal/nodeEvents.js +60 -0
  192. package/dist/esm/internal/nodeEvents.js.map +1 -0
  193. package/dist/esm/node/NodeGateway.d.ts +16 -0
  194. package/dist/esm/node/NodeGateway.d.ts.map +1 -0
  195. package/dist/esm/node/NodeGateway.js +13 -0
  196. package/dist/esm/node/NodeGateway.js.map +1 -0
  197. package/dist/vendor/adapters.json +2707 -0
  198. package/dist/vendor/bun/BunChildProcessSpawner.d.ts +7 -0
  199. package/dist/vendor/bun/BunChildProcessSpawner.js +14 -0
  200. package/dist/vendor/bun/BunClusterHttp.d.ts +83 -0
  201. package/dist/vendor/bun/BunClusterHttp.js +39 -0
  202. package/dist/vendor/bun/BunClusterSocket.d.ts +65 -0
  203. package/dist/vendor/bun/BunClusterSocket.js +22 -0
  204. package/dist/vendor/bun/BunCrypto.d.ts +10 -0
  205. package/dist/vendor/bun/BunCrypto.js +8 -0
  206. package/dist/vendor/bun/BunFileSystem.d.ts +10 -0
  207. package/dist/vendor/bun/BunFileSystem.js +9 -0
  208. package/dist/vendor/bun/BunHttpClient.d.ts +9 -0
  209. package/dist/vendor/bun/BunHttpClient.js +1 -0
  210. package/dist/vendor/bun/BunHttpPlatform.d.ts +10 -0
  211. package/dist/vendor/bun/BunHttpPlatform.js +11 -0
  212. package/dist/vendor/bun/BunHttpServer.d.ts +142 -0
  213. package/dist/vendor/bun/BunHttpServer.js +38 -0
  214. package/dist/vendor/bun/BunHttpServerRequest.d.ts +18 -0
  215. package/dist/vendor/bun/BunHttpServerRequest.js +7 -0
  216. package/dist/vendor/bun/BunMultipart.d.ts +31 -0
  217. package/dist/vendor/bun/BunMultipart.js +12 -0
  218. package/dist/vendor/bun/BunPath.d.ts +24 -0
  219. package/dist/vendor/bun/BunPath.js +12 -0
  220. package/dist/vendor/bun/BunRedis.d.ts +49 -0
  221. package/dist/vendor/bun/BunRedis.js +11 -0
  222. package/dist/vendor/bun/BunRuntime.d.ts +85 -0
  223. package/dist/vendor/bun/BunRuntime.js +8 -0
  224. package/dist/vendor/bun/BunServices.d.ts +34 -0
  225. package/dist/vendor/bun/BunServices.js +23 -0
  226. package/dist/vendor/bun/BunSink.d.ts +8 -0
  227. package/dist/vendor/bun/BunSink.js +12 -0
  228. package/dist/vendor/bun/BunSocket.d.ts +40 -0
  229. package/dist/vendor/bun/BunSocket.js +29 -0
  230. package/dist/vendor/bun/BunSocketServer.d.ts +8 -0
  231. package/dist/vendor/bun/BunSocketServer.js +21 -0
  232. package/dist/vendor/bun/BunStdio.d.ts +11 -0
  233. package/dist/vendor/bun/BunStdio.js +10 -0
  234. package/dist/vendor/bun/BunStream.d.ts +19 -0
  235. package/dist/vendor/bun/BunStream.js +30 -0
  236. package/dist/vendor/bun/BunTerminal.d.ts +21 -0
  237. package/dist/vendor/bun/BunTerminal.js +10 -0
  238. package/dist/vendor/bun/BunWorker.d.ts +20 -0
  239. package/dist/vendor/bun/BunWorker.js +9 -0
  240. package/dist/vendor/bun/BunWorkerRunner.d.ts +12 -0
  241. package/dist/vendor/bun/BunWorkerRunner.js +7 -0
  242. package/dist/vendor/bun/LICENSE +21 -0
  243. package/dist/vendor/bun/index.d.ts +92 -0
  244. package/dist/vendor/bun/index.js +107 -0
  245. package/dist/vendor/chunk-2GCOZTTW.js +48 -0
  246. package/dist/vendor/chunk-37CUR3PO.js +81 -0
  247. package/dist/vendor/chunk-3ARKKENZ.js +45 -0
  248. package/dist/vendor/chunk-3NV2UDBI.js +7 -0
  249. package/dist/vendor/chunk-3OSW7CT7.js +143 -0
  250. package/dist/vendor/chunk-62R63L74.js +62 -0
  251. package/dist/vendor/chunk-6AQLBC2I.js +118 -0
  252. package/dist/vendor/chunk-6C5H7S6B.js +18 -0
  253. package/dist/vendor/chunk-6DY5RBZD.js +85 -0
  254. package/dist/vendor/chunk-6UPBD47P.js +53 -0
  255. package/dist/vendor/chunk-AVVVN75Z.js +96 -0
  256. package/dist/vendor/chunk-B4DHEMBB.js +14 -0
  257. package/dist/vendor/chunk-BCK3NJOX.js +15 -0
  258. package/dist/vendor/chunk-BFBIHJ6X.js +0 -0
  259. package/dist/vendor/chunk-CES4OUM4.js +63 -0
  260. package/dist/vendor/chunk-D64L6YND.js +59 -0
  261. package/dist/vendor/chunk-DS2R6WOM.js +18 -0
  262. package/dist/vendor/chunk-DX4Z23DM.js +65 -0
  263. package/dist/vendor/chunk-DZ2VOUDP.js +564 -0
  264. package/dist/vendor/chunk-FOXN6JPJ.js +61 -0
  265. package/dist/vendor/chunk-FPQF7CR5.js +55 -0
  266. package/dist/vendor/chunk-FUTCTCEG.js +20 -0
  267. package/dist/vendor/chunk-GUPAV2YZ.js +18 -0
  268. package/dist/vendor/chunk-H2Z2Y4QH.js +70 -0
  269. package/dist/vendor/chunk-HAEDVSSM.js +129 -0
  270. package/dist/vendor/chunk-HY7BBL3K.js +93 -0
  271. package/dist/vendor/chunk-IFTTT6D5.js +31 -0
  272. package/dist/vendor/chunk-KQDSNB7M.js +26 -0
  273. package/dist/vendor/chunk-LIHLXXGQ.js +26 -0
  274. package/dist/vendor/chunk-LKCGQEE5.js +28 -0
  275. package/dist/vendor/chunk-MH2J3BYB.js +0 -0
  276. package/dist/vendor/chunk-ML2NAFH2.js +131 -0
  277. package/dist/vendor/chunk-MLFIZ5O2.js +0 -0
  278. package/dist/vendor/chunk-MLKGABMK.js +9 -0
  279. package/dist/vendor/chunk-MSCLEMYX.js +71 -0
  280. package/dist/vendor/chunk-OBWXQKVP.js +57 -0
  281. package/dist/vendor/chunk-QR557K66.js +20 -0
  282. package/dist/vendor/chunk-R4QUY7DH.js +18 -0
  283. package/dist/vendor/chunk-RGECXXJS.js +18 -0
  284. package/dist/vendor/chunk-TFY7W6D4.js +36 -0
  285. package/dist/vendor/chunk-TGPIVY4A.js +104 -0
  286. package/dist/vendor/chunk-TGXCX6W3.js +398 -0
  287. package/dist/vendor/chunk-TOHSFXMV.js +437 -0
  288. package/dist/vendor/chunk-UHIDPUFF.js +34 -0
  289. package/dist/vendor/chunk-ULT6CWUI.js +109 -0
  290. package/dist/vendor/chunk-UXBGYQR3.js +18 -0
  291. package/dist/vendor/chunk-V6LUGQ7O.js +21 -0
  292. package/dist/vendor/chunk-W4OASVX6.js +92 -0
  293. package/dist/vendor/chunk-WAII54GA.js +18 -0
  294. package/dist/vendor/chunk-WECQDT36.js +426 -0
  295. package/dist/vendor/chunk-WHKMOC7Z.js +28 -0
  296. package/dist/vendor/chunk-WVFOZ2UL.js +40 -0
  297. package/dist/vendor/chunk-X73E2UPI.js +18 -0
  298. package/dist/vendor/chunk-XCYARUII.js +63 -0
  299. package/dist/vendor/chunk-XFEVTDVD.js +34 -0
  300. package/dist/vendor/chunk-XFZZYSJ4.js +22 -0
  301. package/dist/vendor/chunk-XJWJXLXJ.js +18 -0
  302. package/dist/vendor/chunk-XY3Q62EO.js +18 -0
  303. package/dist/vendor/chunk-YDASSC75.js +394 -0
  304. package/dist/vendor/chunk-Z6C7SO5Z.js +507 -0
  305. package/dist/vendor/chunk-Z7QNPJEB.js +229 -0
  306. package/dist/vendor/chunk-Z7QPP4YH.js +249 -0
  307. package/dist/vendor/chunk-ZCHYLHJH.js +86 -0
  308. package/dist/vendor/chunk-ZIQVYVMA.js +22 -0
  309. package/dist/vendor/chunk-ZPIG2CUA.js +34 -0
  310. package/dist/vendor/cjs/bun/BunChildProcessSpawner.d.ts +7 -0
  311. package/dist/vendor/cjs/bun/BunChildProcessSpawner.js +1 -0
  312. package/dist/vendor/cjs/bun/BunClusterHttp.d.ts +83 -0
  313. package/dist/vendor/cjs/bun/BunClusterHttp.js +1 -0
  314. package/dist/vendor/cjs/bun/BunClusterSocket.d.ts +65 -0
  315. package/dist/vendor/cjs/bun/BunClusterSocket.js +1 -0
  316. package/dist/vendor/cjs/bun/BunCrypto.d.ts +10 -0
  317. package/dist/vendor/cjs/bun/BunCrypto.js +1 -0
  318. package/dist/vendor/cjs/bun/BunFileSystem.d.ts +10 -0
  319. package/dist/vendor/cjs/bun/BunFileSystem.js +1 -0
  320. package/dist/vendor/cjs/bun/BunHttpClient.d.ts +9 -0
  321. package/dist/vendor/cjs/bun/BunHttpClient.js +1 -0
  322. package/dist/vendor/cjs/bun/BunHttpPlatform.d.ts +10 -0
  323. package/dist/vendor/cjs/bun/BunHttpPlatform.js +1 -0
  324. package/dist/vendor/cjs/bun/BunHttpServer.d.ts +142 -0
  325. package/dist/vendor/cjs/bun/BunHttpServer.js +1 -0
  326. package/dist/vendor/cjs/bun/BunHttpServerRequest.d.ts +18 -0
  327. package/dist/vendor/cjs/bun/BunHttpServerRequest.js +1 -0
  328. package/dist/vendor/cjs/bun/BunMultipart.d.ts +31 -0
  329. package/dist/vendor/cjs/bun/BunMultipart.js +1 -0
  330. package/dist/vendor/cjs/bun/BunPath.d.ts +24 -0
  331. package/dist/vendor/cjs/bun/BunPath.js +1 -0
  332. package/dist/vendor/cjs/bun/BunRedis.d.ts +49 -0
  333. package/dist/vendor/cjs/bun/BunRedis.js +1 -0
  334. package/dist/vendor/cjs/bun/BunRuntime.d.ts +85 -0
  335. package/dist/vendor/cjs/bun/BunRuntime.js +1 -0
  336. package/dist/vendor/cjs/bun/BunServices.d.ts +34 -0
  337. package/dist/vendor/cjs/bun/BunServices.js +1 -0
  338. package/dist/vendor/cjs/bun/BunSink.d.ts +8 -0
  339. package/dist/vendor/cjs/bun/BunSink.js +1 -0
  340. package/dist/vendor/cjs/bun/BunSocket.d.ts +40 -0
  341. package/dist/vendor/cjs/bun/BunSocket.js +1 -0
  342. package/dist/vendor/cjs/bun/BunSocketServer.d.ts +8 -0
  343. package/dist/vendor/cjs/bun/BunSocketServer.js +1 -0
  344. package/dist/vendor/cjs/bun/BunStdio.d.ts +11 -0
  345. package/dist/vendor/cjs/bun/BunStdio.js +1 -0
  346. package/dist/vendor/cjs/bun/BunStream.d.ts +19 -0
  347. package/dist/vendor/cjs/bun/BunStream.js +1 -0
  348. package/dist/vendor/cjs/bun/BunTerminal.d.ts +21 -0
  349. package/dist/vendor/cjs/bun/BunTerminal.js +1 -0
  350. package/dist/vendor/cjs/bun/BunWorker.d.ts +20 -0
  351. package/dist/vendor/cjs/bun/BunWorker.js +1 -0
  352. package/dist/vendor/cjs/bun/BunWorkerRunner.d.ts +12 -0
  353. package/dist/vendor/cjs/bun/BunWorkerRunner.js +1 -0
  354. package/dist/vendor/cjs/bun/index.d.ts +92 -0
  355. package/dist/vendor/cjs/bun/index.js +1 -0
  356. package/dist/vendor/cjs/node/NodeChildProcessSpawner.d.ts +7 -0
  357. package/dist/vendor/cjs/node/NodeChildProcessSpawner.js +1 -0
  358. package/dist/vendor/cjs/node/NodeClusterHttp.d.ts +63 -0
  359. package/dist/vendor/cjs/node/NodeClusterHttp.js +1 -0
  360. package/dist/vendor/cjs/node/NodeClusterSocket.d.ts +79 -0
  361. package/dist/vendor/cjs/node/NodeClusterSocket.js +1 -0
  362. package/dist/vendor/cjs/node/NodeCrypto.d.ts +10 -0
  363. package/dist/vendor/cjs/node/NodeCrypto.js +1 -0
  364. package/dist/vendor/cjs/node/NodeFileSystem.d.ts +10 -0
  365. package/dist/vendor/cjs/node/NodeFileSystem.js +1 -0
  366. package/dist/vendor/cjs/node/NodeHttpClient.d.ts +179 -0
  367. package/dist/vendor/cjs/node/NodeHttpClient.js +1 -0
  368. package/dist/vendor/cjs/node/NodeHttpIncomingMessage.d.ts +62 -0
  369. package/dist/vendor/cjs/node/NodeHttpIncomingMessage.js +1 -0
  370. package/dist/vendor/cjs/node/NodeHttpPlatform.d.ts +36 -0
  371. package/dist/vendor/cjs/node/NodeHttpPlatform.js +1 -0
  372. package/dist/vendor/cjs/node/NodeHttpServer.d.ts +120 -0
  373. package/dist/vendor/cjs/node/NodeHttpServer.js +1 -0
  374. package/dist/vendor/cjs/node/NodeHttpServerRequest.d.ts +29 -0
  375. package/dist/vendor/cjs/node/NodeHttpServerRequest.js +1 -0
  376. package/dist/vendor/cjs/node/NodeMultipart.d.ts +46 -0
  377. package/dist/vendor/cjs/node/NodeMultipart.js +1 -0
  378. package/dist/vendor/cjs/node/NodeMultipartParser.d.ts +97 -0
  379. package/dist/vendor/cjs/node/NodeMultipartParser.js +1 -0
  380. package/dist/vendor/cjs/node/NodePath.d.ts +27 -0
  381. package/dist/vendor/cjs/node/NodePath.js +1 -0
  382. package/dist/vendor/cjs/node/NodeRedis.d.ts +74 -0
  383. package/dist/vendor/cjs/node/NodeRedis.js +1 -0
  384. package/dist/vendor/cjs/node/NodeRuntime.d.ts +85 -0
  385. package/dist/vendor/cjs/node/NodeRuntime.js +1 -0
  386. package/dist/vendor/cjs/node/NodeServices.d.ts +34 -0
  387. package/dist/vendor/cjs/node/NodeServices.js +1 -0
  388. package/dist/vendor/cjs/node/NodeSink.d.ts +8 -0
  389. package/dist/vendor/cjs/node/NodeSink.js +1 -0
  390. package/dist/vendor/cjs/node/NodeSocket.d.ts +38 -0
  391. package/dist/vendor/cjs/node/NodeSocket.js +1 -0
  392. package/dist/vendor/cjs/node/NodeSocketServer.d.ts +8 -0
  393. package/dist/vendor/cjs/node/NodeSocketServer.js +1 -0
  394. package/dist/vendor/cjs/node/NodeStdio.d.ts +11 -0
  395. package/dist/vendor/cjs/node/NodeStdio.js +1 -0
  396. package/dist/vendor/cjs/node/NodeStream.d.ts +8 -0
  397. package/dist/vendor/cjs/node/NodeStream.js +1 -0
  398. package/dist/vendor/cjs/node/NodeTerminal.d.ts +21 -0
  399. package/dist/vendor/cjs/node/NodeTerminal.js +1 -0
  400. package/dist/vendor/cjs/node/NodeWorker.d.ts +22 -0
  401. package/dist/vendor/cjs/node/NodeWorker.js +1 -0
  402. package/dist/vendor/cjs/node/NodeWorkerRunner.d.ts +12 -0
  403. package/dist/vendor/cjs/node/NodeWorkerRunner.js +1 -0
  404. package/dist/vendor/cjs/node/Undici.d.ts +28 -0
  405. package/dist/vendor/cjs/node/Undici.js +1 -0
  406. package/dist/vendor/cjs/node/index.d.ts +100 -0
  407. package/dist/vendor/cjs/node/index.js +1 -0
  408. package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.d.ts +57 -0
  409. package/dist/vendor/cjs/node-shared/NodeChildProcessSpawner.js +1 -0
  410. package/dist/vendor/cjs/node-shared/NodeClusterSocket.d.ts +22 -0
  411. package/dist/vendor/cjs/node-shared/NodeClusterSocket.js +1 -0
  412. package/dist/vendor/cjs/node-shared/NodeCrypto.d.ts +27 -0
  413. package/dist/vendor/cjs/node-shared/NodeCrypto.js +1 -0
  414. package/dist/vendor/cjs/node-shared/NodeFileSystem.d.ts +11 -0
  415. package/dist/vendor/cjs/node-shared/NodeFileSystem.js +1 -0
  416. package/dist/vendor/cjs/node-shared/NodeHttpCompression.d.ts +36 -0
  417. package/dist/vendor/cjs/node-shared/NodeHttpCompression.js +1 -0
  418. package/dist/vendor/cjs/node-shared/NodePath.d.ts +27 -0
  419. package/dist/vendor/cjs/node-shared/NodePath.js +1 -0
  420. package/dist/vendor/cjs/node-shared/NodeRuntime.d.ts +47 -0
  421. package/dist/vendor/cjs/node-shared/NodeRuntime.js +1 -0
  422. package/dist/vendor/cjs/node-shared/NodeSink.d.ts +69 -0
  423. package/dist/vendor/cjs/node-shared/NodeSink.js +1 -0
  424. package/dist/vendor/cjs/node-shared/NodeSocket.d.ts +134 -0
  425. package/dist/vendor/cjs/node-shared/NodeSocket.js +1 -0
  426. package/dist/vendor/cjs/node-shared/NodeSocketServer.d.ts +80 -0
  427. package/dist/vendor/cjs/node-shared/NodeSocketServer.js +1 -0
  428. package/dist/vendor/cjs/node-shared/NodeStdio.d.ts +12 -0
  429. package/dist/vendor/cjs/node-shared/NodeStdio.js +1 -0
  430. package/dist/vendor/cjs/node-shared/NodeStream.d.ts +179 -0
  431. package/dist/vendor/cjs/node-shared/NodeStream.js +1 -0
  432. package/dist/vendor/cjs/node-shared/NodeTerminal.d.ts +22 -0
  433. package/dist/vendor/cjs/node-shared/NodeTerminal.js +1 -0
  434. package/dist/vendor/cjs/node-shared/index.d.ts +56 -0
  435. package/dist/vendor/cjs/node-shared/index.js +1 -0
  436. package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
  437. package/dist/vendor/cjs/node-shared/internal/nodeChildProcessSpawner.js +1 -0
  438. package/dist/vendor/cjs/node-shared/internal/utils.d.ts +2 -0
  439. package/dist/vendor/cjs/node-shared/internal/utils.js +1 -0
  440. package/dist/vendor/cjs/package.json +1 -0
  441. package/dist/vendor/cjs/platform-bun.d.ts +92 -0
  442. package/dist/vendor/cjs/platform-bun.js +1 -0
  443. package/dist/vendor/cjs/platform-node-shared.d.ts +56 -0
  444. package/dist/vendor/cjs/platform-node-shared.js +1 -0
  445. package/dist/vendor/cjs/platform-node.d.ts +100 -0
  446. package/dist/vendor/cjs/platform-node.js +1 -0
  447. package/dist/vendor/node/LICENSE +21 -0
  448. package/dist/vendor/node/NodeChildProcessSpawner.d.ts +7 -0
  449. package/dist/vendor/node/NodeChildProcessSpawner.js +14 -0
  450. package/dist/vendor/node/NodeClusterHttp.d.ts +63 -0
  451. package/dist/vendor/node/NodeClusterHttp.js +43 -0
  452. package/dist/vendor/node/NodeClusterSocket.d.ts +79 -0
  453. package/dist/vendor/node/NodeClusterSocket.js +30 -0
  454. package/dist/vendor/node/NodeCrypto.d.ts +10 -0
  455. package/dist/vendor/node/NodeCrypto.js +8 -0
  456. package/dist/vendor/node/NodeFileSystem.d.ts +10 -0
  457. package/dist/vendor/node/NodeFileSystem.js +9 -0
  458. package/dist/vendor/node/NodeHttpClient.d.ts +179 -0
  459. package/dist/vendor/node/NodeHttpClient.js +46 -0
  460. package/dist/vendor/node/NodeHttpIncomingMessage.d.ts +62 -0
  461. package/dist/vendor/node/NodeHttpIncomingMessage.js +10 -0
  462. package/dist/vendor/node/NodeHttpPlatform.d.ts +36 -0
  463. package/dist/vendor/node/NodeHttpPlatform.js +16 -0
  464. package/dist/vendor/node/NodeHttpServer.d.ts +120 -0
  465. package/dist/vendor/node/NodeHttpServer.js +46 -0
  466. package/dist/vendor/node/NodeHttpServerRequest.d.ts +29 -0
  467. package/dist/vendor/node/NodeHttpServerRequest.js +9 -0
  468. package/dist/vendor/node/NodeMultipart.d.ts +46 -0
  469. package/dist/vendor/node/NodeMultipart.js +15 -0
  470. package/dist/vendor/node/NodeMultipartParser.d.ts +97 -0
  471. package/dist/vendor/node/NodeMultipartParser.js +11 -0
  472. package/dist/vendor/node/NodePath.d.ts +27 -0
  473. package/dist/vendor/node/NodePath.js +12 -0
  474. package/dist/vendor/node/NodeRedis.d.ts +74 -0
  475. package/dist/vendor/node/NodeRedis.js +11 -0
  476. package/dist/vendor/node/NodeRuntime.d.ts +85 -0
  477. package/dist/vendor/node/NodeRuntime.js +8 -0
  478. package/dist/vendor/node/NodeServices.d.ts +34 -0
  479. package/dist/vendor/node/NodeServices.js +23 -0
  480. package/dist/vendor/node/NodeSink.d.ts +8 -0
  481. package/dist/vendor/node/NodeSink.js +12 -0
  482. package/dist/vendor/node/NodeSocket.d.ts +38 -0
  483. package/dist/vendor/node/NodeSocket.js +31 -0
  484. package/dist/vendor/node/NodeSocketServer.d.ts +8 -0
  485. package/dist/vendor/node/NodeSocketServer.js +21 -0
  486. package/dist/vendor/node/NodeStdio.d.ts +11 -0
  487. package/dist/vendor/node/NodeStdio.js +10 -0
  488. package/dist/vendor/node/NodeStream.d.ts +8 -0
  489. package/dist/vendor/node/NodeStream.js +27 -0
  490. package/dist/vendor/node/NodeTerminal.d.ts +21 -0
  491. package/dist/vendor/node/NodeTerminal.js +10 -0
  492. package/dist/vendor/node/NodeWorker.d.ts +22 -0
  493. package/dist/vendor/node/NodeWorker.js +9 -0
  494. package/dist/vendor/node/NodeWorkerRunner.d.ts +12 -0
  495. package/dist/vendor/node/NodeWorkerRunner.js +7 -0
  496. package/dist/vendor/node/Undici.d.ts +28 -0
  497. package/dist/vendor/node/Undici.js +9 -0
  498. package/dist/vendor/node/index.d.ts +100 -0
  499. package/dist/vendor/node/index.js +115 -0
  500. package/dist/vendor/node-shared/LICENSE +21 -0
  501. package/dist/vendor/node-shared/NodeChildProcessSpawner.d.ts +57 -0
  502. package/dist/vendor/node-shared/NodeChildProcessSpawner.js +13 -0
  503. package/dist/vendor/node-shared/NodeClusterSocket.d.ts +22 -0
  504. package/dist/vendor/node-shared/NodeClusterSocket.js +11 -0
  505. package/dist/vendor/node-shared/NodeCrypto.d.ts +27 -0
  506. package/dist/vendor/node-shared/NodeCrypto.js +9 -0
  507. package/dist/vendor/node-shared/NodeFileSystem.d.ts +11 -0
  508. package/dist/vendor/node-shared/NodeFileSystem.js +8 -0
  509. package/dist/vendor/node-shared/NodeHttpCompression.d.ts +36 -0
  510. package/dist/vendor/node-shared/NodeHttpCompression.js +13 -0
  511. package/dist/vendor/node-shared/NodePath.d.ts +27 -0
  512. package/dist/vendor/node-shared/NodePath.js +11 -0
  513. package/dist/vendor/node-shared/NodeRuntime.d.ts +47 -0
  514. package/dist/vendor/node-shared/NodeRuntime.js +7 -0
  515. package/dist/vendor/node-shared/NodeSink.d.ts +69 -0
  516. package/dist/vendor/node-shared/NodeSink.js +11 -0
  517. package/dist/vendor/node-shared/NodeSocket.d.ts +134 -0
  518. package/dist/vendor/node-shared/NodeSocket.js +23 -0
  519. package/dist/vendor/node-shared/NodeSocketServer.d.ts +80 -0
  520. package/dist/vendor/node-shared/NodeSocketServer.js +20 -0
  521. package/dist/vendor/node-shared/NodeStdio.d.ts +12 -0
  522. package/dist/vendor/node-shared/NodeStdio.js +9 -0
  523. package/dist/vendor/node-shared/NodeStream.d.ts +179 -0
  524. package/dist/vendor/node-shared/NodeStream.js +26 -0
  525. package/dist/vendor/node-shared/NodeTerminal.d.ts +22 -0
  526. package/dist/vendor/node-shared/NodeTerminal.js +9 -0
  527. package/dist/vendor/node-shared/index.d.ts +56 -0
  528. package/dist/vendor/node-shared/index.js +58 -0
  529. package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.d.ts +4 -0
  530. package/dist/vendor/node-shared/internal/nodeChildProcessSpawner.js +7 -0
  531. package/dist/vendor/node-shared/internal/utils.d.ts +2 -0
  532. package/dist/vendor/node-shared/internal/utils.js +7 -0
  533. package/dist/vendor/platform-bun.d.ts +92 -0
  534. package/dist/vendor/platform-bun.js +107 -0
  535. package/dist/vendor/platform-node-shared.d.ts +56 -0
  536. package/dist/vendor/platform-node-shared.js +58 -0
  537. package/dist/vendor/platform-node.d.ts +100 -0
  538. package/dist/vendor/platform-node.js +115 -0
  539. package/docs/README.md +158 -0
  540. package/docs/api.md +601 -0
  541. package/docs/concepts/projections.md +250 -0
  542. package/docs/concepts/subscriptions.md +204 -0
  543. package/docs/concepts/trust-boundary.md +256 -0
  544. package/docs/guides/diagnose-a-run.md +115 -0
  545. package/docs/guides/follow-a-run.md +150 -0
  546. package/docs/guides/host-the-gateway.md +153 -0
  547. package/docs/guides/read-a-projection.md +138 -0
  548. package/docs/guides/serve-beyond-loopback.md +166 -0
  549. package/docs/guides/submit-an-approval.md +187 -0
  550. package/docs/guides/testing.md +148 -0
  551. package/docs/installation.md +89 -0
  552. package/docs/quickstart.md +200 -0
  553. package/docs/troubleshooting.md +355 -0
  554. package/package.json +264 -32
  555. package/src/Diagnosis.ts +892 -0
  556. package/src/EngineTrace.ts +605 -0
  557. package/src/GatewayError.ts +71 -0
  558. package/src/GatewayProjection.ts +948 -0
  559. package/src/GatewayRpcs.ts +179 -0
  560. package/src/GatewaySchema.ts +516 -0
  561. package/src/GatewayServer.ts +932 -0
  562. package/src/HostBranchPresence.ts +72 -0
  563. package/src/Projections.ts +1735 -0
  564. package/src/RunDevTools.ts +394 -0
  565. package/src/RunHistory.ts +174 -0
  566. package/src/RunTrace.ts +2793 -0
  567. package/src/RuntimeBridge.ts +835 -0
  568. package/src/bun/BunGateway.ts +52 -0
  569. package/src/index.ts +77 -0
  570. package/src/internal/NativeGateway.ts +360 -0
  571. package/src/internal/actionRenderings.ts +201 -0
  572. package/src/internal/callEvents.ts +257 -0
  573. package/src/internal/digestIndex.ts +134 -0
  574. package/src/internal/digestMemory.ts +27 -0
  575. package/src/internal/inspectLabels.ts +13 -0
  576. package/src/internal/nativeResolution.ts +103 -0
  577. package/src/internal/nodeEvents.ts +100 -0
  578. package/src/node/NodeGateway.ts +30 -0
  579. package/openapi.yaml +0 -29945
  580. package/src/README.md +0 -39
  581. package/src/api/README.md +0 -23
  582. package/src/api/apiCollectionNames.js +0 -10
  583. package/src/api/index.d.ts +0 -126
  584. package/src/api/index.js +0 -14
  585. package/src/api/normalizeApiRow.js +0 -36
  586. package/src/api/serializeAccountRow.js +0 -10
  587. package/src/api/serializeApprovalRow.js +0 -53
  588. package/src/api/serializeComparisonScoreRow.js +0 -18
  589. package/src/api/serializeCronRow.js +0 -30
  590. package/src/api/serializeDocRow.js +0 -20
  591. package/src/api/serializeMemoryFactRow.js +0 -21
  592. package/src/api/serializePromptRow.js +0 -10
  593. package/src/api/serializeRunEventRow.js +0 -28
  594. package/src/api/serializeRunRow.js +0 -93
  595. package/src/api/serializeScoreDetailRow.js +0 -25
  596. package/src/api/serializeScoreRow.js +0 -26
  597. package/src/api/serializeTicketRow.js +0 -20
  598. package/src/api/serializeWorkflowRow.js +0 -10
  599. package/src/auth/scopes.d.ts +0 -19
  600. package/src/auth/scopes.js +0 -164
  601. package/src/index.d.ts +0 -316
  602. package/src/index.js +0 -108
  603. package/src/rpc/gatewayRpcTypes.ts +0 -186
  604. package/src/rpc/index.d.ts +0 -223
  605. package/src/rpc/index.js +0 -2527
@@ -0,0 +1,892 @@
1
+ /**
2
+ * The run diagnosis: what happened to a run, computed from its own control
3
+ * events.
4
+ *
5
+ * The old gateway answered this question with a `whatHappened` RPC that read
6
+ * run rows, node-iteration rows, and attempt rows out of the engine database
7
+ * and optionally asked an agent to narrate them. The rc.0 gateway serves the
8
+ * same answer as a field of the `run-summary` projection, computed from the
9
+ * ordered `ControlEvent` deltas `Control.watch` already publishes. Nothing
10
+ * here opens a database, so a diagnosis read through a relay is the same
11
+ * diagnosis a local reader computes.
12
+ *
13
+ * This is the one fold both surfaces read. `@smthrs/cli` `Forensics` calls
14
+ * `digest` and adds what a terminal card needs on top of it: duplicate calls,
15
+ * per-flow counts, the parked approval payload, and the declined-launch state
16
+ * the wire vocabulary does not carry. The counts, the refusal aggregation, and
17
+ * the clipping are therefore one implementation, not two that drift.
18
+ *
19
+ * @since 1.0.0
20
+ */
21
+
22
+ import { ControlSchema } from "@smthrs/control"
23
+ import * as Fault from "@smthrs/flow/Fault"
24
+ import { HashMap, Schema } from "effect"
25
+ import { callEventKey, callScope, nativeCallEvent, nativeStepEvent, uniqueCallEvents } from "./internal/callEvents.ts"
26
+ import * as DigestIndex from "./internal/digestIndex.ts"
27
+ import { encodedBytes, recordDigestBytes } from "./internal/digestMemory.ts"
28
+ import * as NativeResolution from "./internal/nativeResolution.ts"
29
+
30
+ /**
31
+ * Keeps one start and settlement per durable call identity, preferring a
32
+ * committed native fact over telemetry at the first observation's position.
33
+ * Unidentified legacy events remain distinct because their identity cannot
34
+ * be recovered from flow names and inputs. Shared with CLI call counts.
35
+ *
36
+ * @since 1.0.0
37
+ * @category projections
38
+ */
39
+ export { uniqueCallEvents }
40
+
41
+ /**
42
+ * Native fact normalization and stable call/checkpoint identities.
43
+ * Incremental readers retain these keys to match the full history fold.
44
+ *
45
+ * @since 1.0.0
46
+ * @category projections
47
+ */
48
+ export { callEventKey, callScope, nativeCallEvent, nativeStepEvent } from "./internal/callEvents.ts"
49
+
50
+ /**
51
+ * Finds an open call by ID, with name/FIFO fallback only for legacy starts.
52
+ * Shared by gateway node output and the CLI's compatible flow/ordinal IDs.
53
+ *
54
+ * @since 1.0.0
55
+ * @category projections
56
+ */
57
+ export { openCallIndex } from "./internal/callEvents.ts"
58
+
59
+ /**
60
+ * The run statuses a digest may report.
61
+ *
62
+ * `@smthrs/control` `ControlSchema.RunStatus` is the vocabulary; this is the
63
+ * runtime set the fold checks a journaled kind against.
64
+ *
65
+ * @since 1.0.0
66
+ * @category models
67
+ */
68
+ export type RunStatus = ControlSchema.RunStatus
69
+
70
+ /**
71
+ * Every `control.run.*` suffix that names a status rather than an operation.
72
+ *
73
+ * `@smthrs/control` journals `control.run.lineage`, `control.run.resume`,
74
+ * `control.run.resumed`, `control.run.cancel-requested`, and
75
+ * `control.run.pending` under the same prefix as the status transitions, and
76
+ * `Lineage.derive` adds one more to every followed stream. Reading a status
77
+ * off the prefix alone made a live run's verdict read `lineage` or `resume`,
78
+ * so the fold accepts only the schema statuses a client may render.
79
+ */
80
+ const runStatuses: ReadonlySet<string> = new Set(ControlSchema.RunStatus.literals)
81
+
82
+ /**
83
+ * One refused flow call, aggregated by its refusal message.
84
+ *
85
+ * @since 1.0.0
86
+ * @category models
87
+ */
88
+ export interface Refusal {
89
+ readonly message: string
90
+ readonly count: number
91
+ }
92
+
93
+ /**
94
+ * Everything the diagnosis computes from one run's events.
95
+ *
96
+ * @since 1.0.0
97
+ * @category models
98
+ */
99
+ export interface Digest {
100
+ /** The last run status seen, or undefined before launch. */
101
+ readonly status: RunStatus | undefined
102
+ /** The journaled failure cause, when the run failed and recorded one. */
103
+ readonly cause: string | undefined
104
+ /** The typed fault stamped beside {@link cause}; it is written and cleared with it. */
105
+ readonly fault?: Fault.Fault | undefined
106
+ /** The model seat the last opened turn ran on. */
107
+ readonly seat: string | undefined
108
+ readonly turns: number
109
+ readonly calls: number
110
+ readonly callsFailed: number
111
+ readonly editsAttempted: number
112
+ readonly editsSucceeded: number
113
+ /** Refusal messages, descending by count. */
114
+ readonly refusals: ReadonlyArray<Refusal>
115
+ readonly inputTokens: number
116
+ readonly outputTokens: number
117
+ /** USD the run's priced model calls cost; zero when none was priced. */
118
+ readonly costUsd: number
119
+ /** The final assistant output, when the run resolved. */
120
+ readonly finalOutput: string | undefined
121
+ /** Root binding and committed native result, retained across bounded windows. */
122
+ readonly nativeResolution?: NativeResolution.NativeResolution | undefined
123
+ /** The pending ask's question, when the run parked for approval. */
124
+ readonly parkedQuestion: string | undefined
125
+ /** The earliest time a kind this fold handles occurred at. */
126
+ readonly startedAt: number | undefined
127
+ /** The latest time a kind this fold handles occurred at. */
128
+ readonly endedAt: number | undefined
129
+ }
130
+
131
+ /** Flows whose calls count as edit attempts. */
132
+ const editFlows: ReadonlySet<string> = new Set(["write", "edit", "apply_patch"])
133
+
134
+ /**
135
+ * Reads a payload as a record. Wire payloads are `Json`, so every field read
136
+ * tolerates absence and the digest of a malformed journal is a sparse digest,
137
+ * never a throw.
138
+ *
139
+ * @param value the payload to read
140
+ * @since 1.0.0
141
+ * @category conversions
142
+ */
143
+ export const asRecord = (value: unknown): Record<string, unknown> =>
144
+ typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : {}
145
+
146
+ /**
147
+ * Reads a payload field as a string, or nothing when it is not one.
148
+ *
149
+ * @param value the field to read
150
+ * @since 1.0.0
151
+ * @category conversions
152
+ */
153
+ export const asString = (value: unknown): string | undefined => typeof value === "string" ? value : undefined
154
+
155
+ const isFault = Schema.is(Fault.Fault)
156
+
157
+ /**
158
+ * Reads a payload field as a number, or nothing when it is not one.
159
+ *
160
+ * @param value the field to read
161
+ * @since 1.0.0
162
+ * @category conversions
163
+ */
164
+ export const asNumber = (value: unknown): number | undefined => typeof value === "number" ? value : undefined
165
+
166
+ /**
167
+ * Occurrence time: the payload's own stamp, else journal admission time.
168
+ *
169
+ * @param event the event to time
170
+ * @since 1.0.0
171
+ * @category conversions
172
+ */
173
+ export const timeOf = (event: ControlSchema.ControlEvent): number =>
174
+ asNumber(asRecord(event.payload).at) ?? event.occurredAt
175
+
176
+ /**
177
+ * The first line, whichever line ending produced it. Splitting on `\n` alone
178
+ * left the `\r` of a CRLF cause on the wire, and every reader of a one-line
179
+ * field, here and in `@smthrs/cli` `Forensics`, wants the same answer.
180
+ *
181
+ * @param text the text to read one line of
182
+ * @since 1.0.0
183
+ * @category conversions
184
+ */
185
+ export const firstLine = (text: string): string => {
186
+ const index = text.search(/[\r\n]/)
187
+ return index < 0 ? text : text.slice(0, index)
188
+ }
189
+
190
+ /**
191
+ * Truncates to a display width, marking the cut.
192
+ *
193
+ * The cut is made on code points, never on UTF-16 code units. Slicing code
194
+ * units splits an astral character in half and puts a lone surrogate on the
195
+ * wire, where a Go decoder silently replaces it with U+FFFD and a strict
196
+ * decoder rejects the whole frame; the result of this function is always well
197
+ * formed. A clipped result is exactly `width` code points, so `width` 1 is the
198
+ * ellipsis alone and `width` 0, or any negative width, is the empty string.
199
+ *
200
+ * @param text the text to clip
201
+ * @param width the greatest number of code points to keep
202
+ * @since 1.0.0
203
+ * @category rendering
204
+ */
205
+ export const clip = (text: string, width: number): string => {
206
+ if (width <= 0) return ""
207
+ const points = [...text]
208
+ return points.length <= width ? text : `${points.slice(0, width - 1).join("")}…`
209
+ }
210
+
211
+ /** The mutable accumulator the fold below writes into. */
212
+ interface Accumulator {
213
+ status: RunStatus | undefined
214
+ cause: string | undefined
215
+ fault: Fault.Fault | undefined
216
+ seat: string | undefined
217
+ turns: number
218
+ calls: number
219
+ callsFailed: number
220
+ editsAttempted: number
221
+ editsSucceeded: number
222
+ inputTokens: number
223
+ outputTokens: number
224
+ costUsd: number
225
+ finalOutput: string | undefined
226
+ parkedQuestion: string | undefined
227
+ }
228
+
229
+ /**
230
+ * Which events may write a run-level field.
231
+ *
232
+ * `uniqueCallEvents` normalizes a native step fact into the `control.agent.*`
233
+ * event the step recorded, so this fold reads two streams at once: the run's
234
+ * own, and one per step a module run dispatched. A step's record carries the
235
+ * `step` object its checkpoint was written under, which is what `callScope`
236
+ * reads; the run's own records carry none. Every run-level field therefore
237
+ * belongs to one of three classes, and a new handler has to name its class
238
+ * before it compiles:
239
+ *
240
+ * - `aggregate`: the field sums or counts what the whole run did, steps
241
+ * included, so a step's record contributes to it like any other.
242
+ * - `root`: the field is the run's own answer or state, so only an unscoped
243
+ * record may set it. A step's record is skipped.
244
+ * - scope dependent: the field means something only beside the scope that
245
+ * recorded it, so it is kept per scope rather than run wide. No field of
246
+ * this digest is one; `GatewayProjection.callHistory` holds the one that is,
247
+ * the seat a call ran on.
248
+ *
249
+ * The table, field by field:
250
+ *
251
+ * | Field | Class | Why |
252
+ * | ------------------------------- | --------- | ---------------------------------------------------------- |
253
+ * | `turns` | aggregate | a turn a step opened is a turn this run opened |
254
+ * | `seat` | aggregate | the seat of the run's last opened turn, wherever it opened |
255
+ * | `inputTokens`, `outputTokens` | aggregate | a step spends the run's budget, so the run pays for it |
256
+ * | `costUsd` | aggregate | the dollars of those same calls |
257
+ * | `calls`, `editsAttempted` | aggregate | a call a step made is a call this run made |
258
+ * | `callsFailed`, `editsSucceeded` | aggregate | the settlement of one of those calls |
259
+ * | `refusals` | aggregate | the messages those settlements refused with |
260
+ * | `startedAt`, `endedAt` | aggregate | a step runs inside the run's span, so its records widen it |
261
+ * | `finalOutput` | root | THE run's answer; a step's answer is the step's |
262
+ * | `parkedQuestion` | root | THE question the run is parked on |
263
+ * | `status`, `cause` | root | THE run's terminal state, from `control.run.*` alone |
264
+ *
265
+ * `status`, `cause` and `parkedQuestion` are root only by construction as well
266
+ * as by this class: `StepFact.Fact` accepts an `eventType` matching
267
+ * `^control\.agent\.[a-z-]+$`, so no step fact can normalize to a
268
+ * `control.run.*` kind or to `control.approval.requested`.
269
+ */
270
+ type Reach = "aggregate" | "root"
271
+
272
+ /** One kind's contribution, and the class of the fields it writes. */
273
+ interface Handler {
274
+ readonly reach: Reach
275
+ readonly apply: (accumulator: Accumulator, payload: Record<string, unknown>) => void
276
+ }
277
+
278
+ const handlers: Readonly<Record<string, Handler>> = {
279
+ "control.agent.turn-opened": {
280
+ reach: "aggregate",
281
+ apply: (accumulator, payload) => {
282
+ accumulator.turns += 1
283
+ accumulator.seat = asString(payload.seat) ?? accumulator.seat
284
+ }
285
+ },
286
+ "control.agent.model-settled": {
287
+ reach: "aggregate",
288
+ apply: (accumulator, payload) => {
289
+ const usage = asRecord(payload.usage)
290
+ accumulator.inputTokens += asNumber(usage.inputTokens) ?? 0
291
+ accumulator.outputTokens += asNumber(usage.outputTokens) ?? 0
292
+ const cost = asNumber(payload.costUsd)
293
+ if (cost !== undefined && Number.isFinite(cost) && cost > 0) accumulator.costUsd += cost
294
+ }
295
+ },
296
+ "control.agent.cell-call-started": {
297
+ reach: "aggregate",
298
+ apply: (accumulator, payload) => {
299
+ accumulator.calls += 1
300
+ if (editFlows.has(asString(payload.flowName) ?? "")) accumulator.editsAttempted += 1
301
+ }
302
+ },
303
+ "control.agent.resolved": {
304
+ reach: "root",
305
+ apply: (accumulator, payload) => {
306
+ accumulator.finalOutput = asString(payload.text)
307
+ }
308
+ },
309
+ "control.approval.requested": {
310
+ reach: "root",
311
+ apply: (accumulator, payload) => {
312
+ accumulator.parkedQuestion = asString(payload.question)
313
+ }
314
+ }
315
+ }
316
+
317
+ /**
318
+ * The kinds this fold handles, with the class each one's fields belong to.
319
+ *
320
+ * Exported so a test can hold the table above against the map rather than
321
+ * trusting a comment, and so a new handler that names no class fails both the
322
+ * compiler and that test.
323
+ *
324
+ * @since 1.0.0
325
+ * @category models
326
+ */
327
+ export const handlerReach: Readonly<Record<string, "aggregate" | "root">> = Object.fromEntries(
328
+ Object.entries(handlers).map(([kind, handler]) => [kind, handler.reach])
329
+ )
330
+
331
+ /**
332
+ * Computes the diagnosis facts for one run from its ordered control events.
333
+ *
334
+ * Total on purpose: an event this vocabulary does not know contributes
335
+ * nothing rather than failing the fold.
336
+ *
337
+ * @param events the run's ordered control events
338
+ * @since 1.0.0
339
+ * @category constructors
340
+ */
341
+ const rawDigest = (events: ReadonlyArray<ControlSchema.ControlEvent>): Digest => {
342
+ const accumulator: Accumulator = {
343
+ status: undefined,
344
+ cause: undefined,
345
+ fault: undefined,
346
+ seat: undefined,
347
+ turns: 0,
348
+ calls: 0,
349
+ callsFailed: 0,
350
+ editsAttempted: 0,
351
+ editsSucceeded: 0,
352
+ inputTokens: 0,
353
+ outputTokens: 0,
354
+ costUsd: 0,
355
+ finalOutput: undefined,
356
+ parkedQuestion: undefined
357
+ }
358
+ const refusalCounts = new Map<string, number>()
359
+ let startedAt: number | undefined
360
+ let endedAt: number | undefined
361
+ let nativeResolution: NativeResolution.NativeResolution | undefined
362
+
363
+ /**
364
+ * Widens the span this digest reports.
365
+ *
366
+ * Only a kind this fold handles widens it. The gateway merges a keepalive
367
+ * event whose kind no emitter uses into every followed `Watch` stream
368
+ * (`GatewayServer.watchHeartbeatKind`), and a fold that let an unhandled kind
369
+ * contribute its timestamp reported a run that ran for as long as it was
370
+ * watched.
371
+ */
372
+ const observe = (at: number): void => {
373
+ startedAt = startedAt === undefined ? at : Math.min(startedAt, at)
374
+ endedAt = endedAt === undefined ? at : Math.max(endedAt, at)
375
+ }
376
+
377
+ for (const event of uniqueCallEvents(events)) {
378
+ nativeResolution = NativeResolution.combine(nativeResolution, NativeResolution.fromEvent(event))
379
+ const payload = asRecord(event.payload)
380
+ const at = timeOf(event)
381
+ const handler = Object.hasOwn(handlers, event.kind) ? handlers[event.kind] : undefined
382
+ if (handler !== undefined) {
383
+ // A step's record still widens the span it was recorded in, because the
384
+ // step ran inside this run. Whether it may write the field is the
385
+ // handler's class: a root-only field keeps the root's reading.
386
+ observe(at)
387
+ if (handler.reach === "aggregate" || callScope(event) === undefined) handler.apply(accumulator, payload)
388
+ continue
389
+ }
390
+ if (event.kind === "control.agent.cell-call-settled") {
391
+ observe(at)
392
+ if (asString(payload.outcome) === "failure") {
393
+ accumulator.callsFailed += 1
394
+ const message = firstLine(asString(payload.message) ?? "unknown refusal")
395
+ refusalCounts.set(message, (refusalCounts.get(message) ?? 0) + 1)
396
+ } else if (editFlows.has(asString(payload.flowName) ?? "")) {
397
+ accumulator.editsSucceeded += 1
398
+ }
399
+ continue
400
+ }
401
+ if (event.kind.startsWith("control.run.")) {
402
+ const status = event.kind.slice("control.run.".length)
403
+ if (!runStatuses.has(status)) continue
404
+ observe(at)
405
+ accumulator.status = status as RunStatus
406
+ if (status === "failed") accumulator.cause = asString(payload.cause)
407
+ // A resumed run is no longer failed, so the fault of its last failure goes.
408
+ accumulator.fault = status === "failed" && isFault(payload.fault) ? payload.fault : undefined
409
+ }
410
+ }
411
+
412
+ return {
413
+ ...accumulator,
414
+ ...(nativeResolution === undefined ? {} : { nativeResolution }),
415
+ refusals: [...refusalCounts.entries()]
416
+ .map(([message, count]) => ({ message, count }))
417
+ .sort((left, right) => right.count - left.count),
418
+ startedAt,
419
+ endedAt
420
+ }
421
+ }
422
+
423
+ const counters = [
424
+ "turns",
425
+ "calls",
426
+ "callsFailed",
427
+ "editsAttempted",
428
+ "editsSucceeded",
429
+ "inputTokens",
430
+ "outputTokens",
431
+ "costUsd"
432
+ ] as const
433
+ type ContributionValue = Partial<Pick<Digest, typeof counters[number] | "seat" | "startedAt" | "endedAt" | "refusals">>
434
+
435
+ const contributionValue = (value: Digest): ContributionValue => ({
436
+ ...Object.fromEntries(counters.filter((counter) => value[counter] !== 0).map((counter) => [counter, value[counter]])),
437
+ ...(value.seat === undefined ? {} : { seat: value.seat }),
438
+ ...(value.startedAt === undefined ? {} : { startedAt: value.startedAt }),
439
+ ...(value.endedAt === undefined ? {} : { endedAt: value.endedAt }),
440
+ ...(value.refusals.length === 0 ? {} : { refusals: value.refusals })
441
+ })
442
+
443
+ interface Contribution {
444
+ readonly ordinal: number
445
+ readonly authoritative: boolean
446
+ readonly value: ContributionValue
447
+ }
448
+
449
+ interface DigestState {
450
+ readonly base: Digest
451
+ readonly writes: { readonly cause: boolean; readonly finalOutput: boolean; readonly parkedQuestion: boolean }
452
+ readonly baseSeatOrdinal: number | undefined
453
+ readonly baseRefusals: ReadonlyMap<string, number>
454
+ readonly indexes: Indexes
455
+ readonly contributions: HashMap.HashMap<string, Contribution>
456
+ readonly contributionBytes: number
457
+ readonly length: number
458
+ }
459
+
460
+ interface Indexes {
461
+ readonly timings: DigestIndex.Index | undefined
462
+ readonly refusals: HashMap.HashMap<string, DigestIndex.Index>
463
+ readonly refusalBytes: number
464
+ }
465
+
466
+ const emptyIndexes = (): Indexes => ({ timings: undefined, refusals: HashMap.empty(), refusalBytes: 0 })
467
+ const refusalIndexBytes = (message: string, tree: DigestIndex.Index | undefined): number =>
468
+ tree === undefined ? 0 : encodedBytes(message) + tree.bytes
469
+
470
+ const indexContribution = (indexes: Indexes, previous: Contribution | undefined, next: Contribution): Indexes => {
471
+ let refusals = indexes.refusals
472
+ let refusalBytes = indexes.refusalBytes
473
+ for (const refusal of previous?.value.refusals ?? []) {
474
+ if (next.value.refusals?.some((member) => member.message === refusal.message)) continue
475
+ // Every previous refusal was indexed when its contribution was retained.
476
+ const oldTree = HashMap.getUnsafe(refusals, refusal.message)
477
+ const tree = DigestIndex.remove(oldTree, next.ordinal)
478
+ refusalBytes += refusalIndexBytes(refusal.message, tree) - refusalIndexBytes(refusal.message, oldTree)
479
+ refusals = tree === undefined
480
+ ? HashMap.remove(refusals, refusal.message)
481
+ : HashMap.set(refusals, refusal.message, tree)
482
+ }
483
+ for (const refusal of next.value.refusals ?? []) {
484
+ if (previous?.value.refusals?.some((member) => member.message === refusal.message)) continue
485
+ const old = HashMap.get(refusals, refusal.message)
486
+ const oldTree = old._tag === "Some" ? old.value : undefined
487
+ const tree = DigestIndex.set(oldTree, next.ordinal)
488
+ refusalBytes += refusalIndexBytes(refusal.message, tree) - refusalIndexBytes(refusal.message, oldTree)
489
+ refusals = HashMap.set(refusals, refusal.message, tree)
490
+ }
491
+ return {
492
+ timings: DigestIndex.set(indexes.timings, next.ordinal, next.value.startedAt, next.value.endedAt),
493
+ refusals,
494
+ refusalBytes
495
+ }
496
+ }
497
+
498
+ // Scalar contributions only: no model input, call output, or event body is
499
+ // retained. Weak associations keep the public Digest and its wire shape intact.
500
+ const digestStates = new WeakMap<Digest, DigestState>()
501
+ const remember = (value: Digest, state: DigestState): Digest => {
502
+ digestStates.set(value, state)
503
+ recordDigestBytes(
504
+ value,
505
+ encodedBytes(value) + (value === state.base ? 0 : encodedBytes(state.base)) +
506
+ state.contributionBytes + (state.indexes.timings?.bytes ?? 0) + state.indexes.refusalBytes + encodedBytes({
507
+ writes: state.writes,
508
+ baseSeatOrdinal: state.baseSeatOrdinal,
509
+ baseRefusals: [...state.baseRefusals],
510
+ length: state.length
511
+ })
512
+ )
513
+ return value
514
+ }
515
+
516
+ /**
517
+ * A `control.run.*` verdict stamped with a run id other than `runId`, such as
518
+ * a child's riding in the parent's events. It must not set the digested run's
519
+ * status or failure cause. An unstamped verdict is the run's own.
520
+ *
521
+ * @param event the event to classify
522
+ * @param runId the run being digested; omitted, no verdict is foreign
523
+ * @category predicates
524
+ * @since 1.0.0
525
+ */
526
+ export const foreignVerdict = (event: ControlSchema.ControlEvent, runId: string | undefined): boolean =>
527
+ runId !== undefined && event.runId !== undefined && event.runId !== runId && event.kind.startsWith("control.run.")
528
+
529
+ /**
530
+ * Folds one event range, retaining compact identities for later combination.
531
+ * Native facts supersede telemetry at its first position across ranges too.
532
+ *
533
+ * @param events the range to fold
534
+ * @param runId the run being digested; a `control.run.*` verdict stamped with
535
+ * another run's id is skipped. Omitted, every verdict folds.
536
+ * @category constructors
537
+ * @since 1.0.0
538
+ */
539
+ export const digest = (events: ReadonlyArray<ControlSchema.ControlEvent>, runId?: string): Digest => {
540
+ if (runId !== undefined && events.some((event) => foreignVerdict(event, runId))) {
541
+ events = events.filter((event) => !foreignVerdict(event, runId))
542
+ }
543
+ let contributions = HashMap.empty<string, Contribution>()
544
+ let indexes = emptyIndexes()
545
+ let contributionBytes = 0
546
+ const baseEvents: Array<ControlSchema.ControlEvent> = []
547
+ const baseRefusals = new Map<string, number>()
548
+ const writes = { cause: false, finalOutput: false, parkedQuestion: false }
549
+ let baseSeatOrdinal: number | undefined
550
+ for (const [ordinal, event] of events.entries()) {
551
+ const key = callEventKey(event)
552
+ if (key === undefined) {
553
+ baseEvents.push(event)
554
+ if (event.kind === "control.run.failed") writes.cause = true
555
+ if (callScope(event) === undefined) {
556
+ if (event.kind === "control.agent.resolved") writes.finalOutput = true
557
+ if (event.kind === "control.approval.requested") writes.parkedQuestion = true
558
+ }
559
+ const payload = asRecord(event.payload)
560
+ if (event.kind === "control.agent.turn-opened" && asString(payload.seat) !== undefined) baseSeatOrdinal = ordinal
561
+ if (event.kind === "control.agent.cell-call-settled" && payload.outcome === "failure") {
562
+ const message = firstLine(asString(payload.message) ?? "unknown refusal")
563
+ if (!baseRefusals.has(message)) baseRefusals.set(message, ordinal)
564
+ }
565
+ continue
566
+ }
567
+ const native = nativeStepEvent(event) ?? nativeCallEvent(event)
568
+ const previous = HashMap.get(contributions, key)
569
+ if (previous._tag === "Some" && (previous.value.authoritative || native === undefined)) continue
570
+ const contribution = {
571
+ ordinal: previous._tag === "Some" ? previous.value.ordinal : ordinal,
572
+ authoritative: native !== undefined,
573
+ value: contributionValue(rawDigest([native ?? event]))
574
+ }
575
+ contributionBytes += encodedBytes([key, contribution]) -
576
+ (previous._tag === "Some" ? encodedBytes([key, previous.value]) : 0)
577
+ contributions = HashMap.set(contributions, key, contribution)
578
+ indexes = indexContribution(indexes, previous._tag === "Some" ? previous.value : undefined, contribution)
579
+ }
580
+ const value = rawDigest(events)
581
+ return remember(value, {
582
+ base: baseEvents.length === events.length ? value : rawDigest(baseEvents),
583
+ writes,
584
+ baseSeatOrdinal,
585
+ baseRefusals,
586
+ indexes,
587
+ contributions,
588
+ contributionBytes,
589
+ length: events.length
590
+ })
591
+ }
592
+
593
+ /**
594
+ * The wall-clock span the events cover, rendered for a reader.
595
+ *
596
+ * Only the span is read, so a caller carrying a wider digest of its own, as
597
+ * `@smthrs/cli` `Forensics` does, measures it with this rather than a copy.
598
+ *
599
+ * @param value the span to measure
600
+ * @since 1.0.0
601
+ * @category rendering
602
+ */
603
+ export const duration = (value: Pick<Digest, "startedAt" | "endedAt">): string => {
604
+ if (value.startedAt === undefined || value.endedAt === undefined) return "0s"
605
+ const seconds = Math.max(0, Math.round((value.endedAt - value.startedAt) / 1000))
606
+ return seconds < 60 ? `${seconds}s` : `${Math.floor(seconds / 60)}m ${String(seconds % 60).padStart(2, "0")}s`
607
+ }
608
+
609
+ /**
610
+ * A USD amount for a reader: cents from one dollar, four places below it, so
611
+ * a cheap run never reads as `$0.00`.
612
+ *
613
+ * @param value dollars, finite and non-negative
614
+ * @since 1.0.0
615
+ * @category rendering
616
+ */
617
+ export const usd = (value: number): string => `$${value.toFixed(value >= 1 ? 2 : 4)}`
618
+
619
+ /**
620
+ * Assistant text, or a typed module's committed result under its bound root.
621
+ * @category projections
622
+ * @since 1.0.0
623
+ */
624
+ export const resolvedOutput = (value: Pick<Digest, "finalOutput" | "nativeResolution">): string | undefined =>
625
+ value.finalOutput ?? NativeResolution.output(value.nativeResolution)
626
+
627
+ /**
628
+ * The one-line verdict: the status plus the reason that most explains it.
629
+ *
630
+ * Priority order mirrors what a reader needs first: a recorded failure cause,
631
+ * then a park's question, then the "worked but never edited" pathology a green
632
+ * status would otherwise hide, then the resolved output.
633
+ *
634
+ * @param value the digest to judge
635
+ * @since 1.0.0
636
+ * @category rendering
637
+ */
638
+ export const verdict = (value: Digest): string => {
639
+ const status = value.status ?? "unlaunched"
640
+ const output = resolvedOutput(value)
641
+ if (status === "failed") {
642
+ return value.cause === undefined
643
+ ? "failed — no cause recorded in the journal"
644
+ : `failed — ${clip(firstLine(value.cause), 100)}`
645
+ }
646
+ if (status === "waiting-approval") {
647
+ return value.parkedQuestion === undefined
648
+ ? "waiting-approval — a permission gate is pending"
649
+ : `waiting-approval — asks: ${clip(value.parkedQuestion, 90)}`
650
+ }
651
+ if (status === "completed" && value.calls > 0 && value.editsAttempted === 0) {
652
+ return `completed — but 0 of ${value.calls} calls attempted an edit; the run only read`
653
+ }
654
+ if (status === "completed" && output !== undefined && output.length > 0) {
655
+ return `completed — ${clip(firstLine(output), 100)}`
656
+ }
657
+ return status
658
+ }
659
+
660
+ const label = (name: string): string => name.padEnd(10)
661
+
662
+ /**
663
+ * Identity a diagnosis is rendered for.
664
+ *
665
+ * @since 1.0.0
666
+ * @category models
667
+ */
668
+ export interface Subject {
669
+ readonly runId: string
670
+ readonly flowId?: string | undefined
671
+ }
672
+
673
+ /**
674
+ * Renders the diagnosis card for one run: verdict, activity evidence, tokens,
675
+ * cost when any call was priced, refusals, cause, and output.
676
+ *
677
+ * @param subject the run being diagnosed
678
+ * @param value the digest computed from its events
679
+ * @since 1.0.0
680
+ * @category rendering
681
+ */
682
+ export const render = (subject: Subject, value: Digest): string => {
683
+ const output = resolvedOutput(value)
684
+ const lines: Array<string> = [
685
+ `${label("Verdict")}${verdict(value)}`,
686
+ `${label("Run")}${subject.runId}${subject.flowId === undefined ? "" : ` · ${subject.flowId}`}${
687
+ value.seat === undefined ? "" : ` · ${value.seat}`
688
+ } · ${duration(value)}`,
689
+ `${
690
+ label("Activity")
691
+ }${value.turns} turns · ${value.calls} calls (${value.callsFailed} refused) · edits ${value.editsSucceeded}/${value.editsAttempted}`,
692
+ `${label("Tokens")}${value.inputTokens} in / ${value.outputTokens} out`,
693
+ ...(value.costUsd > 0 ? [`${label("Cost")}${usd(value.costUsd)}`] : [])
694
+ ]
695
+ for (const [index, refusal] of value.refusals.slice(0, 3).entries()) {
696
+ lines.push(`${label(index === 0 ? "Refusals" : "")}${refusal.count}× ${clip(refusal.message, 110)}`)
697
+ }
698
+ if (value.cause !== undefined) lines.push(`${label("Cause")}${clip(firstLine(value.cause), 120)}`)
699
+ if (output !== undefined && output.length > 0) {
700
+ lines.push(`${label("Output")}${clip(firstLine(output), 120)}`)
701
+ }
702
+ return lines.join("\n")
703
+ }
704
+
705
+ /**
706
+ * A digest of no events at all: the identity {@link combine} folds onto.
707
+ *
708
+ * @since 1.0.0
709
+ * @category constructors
710
+ */
711
+ export const emptyDigest = (): Digest => digest([])
712
+
713
+ const earliest = (left: number | undefined, right: number | undefined): number | undefined =>
714
+ left === undefined ? right : right === undefined ? left : Math.min(left, right)
715
+ const latest = (left: number | undefined, right: number | undefined): number | undefined =>
716
+ left === undefined ? right : right === undefined ? left : Math.max(left, right)
717
+
718
+ /**
719
+ * Folds two digests of adjacent event ranges into the digest of both.
720
+ *
721
+ * `digest` is a left fold over an ordered range, so the digest of a whole
722
+ * journal is the digest of its prefix combined with the digest of its
723
+ * remainder. That identity is what lets a bounded reader keep exact counters
724
+ * for a run whose journal it cannot hold: it folds the events it drops into a
725
+ * carry digest and combines that carry with the digest of the window it kept.
726
+ *
727
+ * Used for contributions that do not overlap. Written fields may deliberately
728
+ * clear an older value. Refusal counts merge and re-sort. The span widens.
729
+ *
730
+ * @param earlier the digest of the earlier range
731
+ * @param later the digest of the range that follows it
732
+ * @since 1.0.0
733
+ * @category constructors
734
+ */
735
+ const combinePlain = (earlier: Digest, later: Digest, writes: DigestState["writes"]): Digest => {
736
+ const counts = new Map<string, number>()
737
+ for (const refusal of [...earlier.refusals, ...later.refusals]) {
738
+ counts.set(refusal.message, (counts.get(refusal.message) ?? 0) + refusal.count)
739
+ }
740
+ return {
741
+ status: later.status ?? earlier.status,
742
+ cause: writes.cause ? later.cause : earlier.cause,
743
+ fault: writes.cause || (later.status !== undefined && later.status !== "failed") ? later.fault : earlier.fault,
744
+ seat: later.seat ?? earlier.seat,
745
+ turns: earlier.turns + later.turns,
746
+ calls: earlier.calls + later.calls,
747
+ callsFailed: earlier.callsFailed + later.callsFailed,
748
+ editsAttempted: earlier.editsAttempted + later.editsAttempted,
749
+ editsSucceeded: earlier.editsSucceeded + later.editsSucceeded,
750
+ refusals: [...counts.entries()]
751
+ .map(([message, count]) => ({ message, count }))
752
+ .sort((left, right) => right.count - left.count),
753
+ inputTokens: earlier.inputTokens + later.inputTokens,
754
+ outputTokens: earlier.outputTokens + later.outputTokens,
755
+ costUsd: earlier.costUsd + later.costUsd,
756
+ finalOutput: writes.finalOutput ? later.finalOutput : earlier.finalOutput,
757
+ nativeResolution: NativeResolution.combine(earlier.nativeResolution, later.nativeResolution),
758
+ parkedQuestion: writes.parkedQuestion ? later.parkedQuestion : earlier.parkedQuestion,
759
+ startedAt: earliest(earlier.startedAt, later.startedAt),
760
+ endedAt: latest(earlier.endedAt, later.endedAt)
761
+ }
762
+ }
763
+
764
+ const stateOf = (value: Digest): DigestState =>
765
+ digestStates.get(value) ?? {
766
+ base: value,
767
+ writes: {
768
+ cause: value.cause !== undefined,
769
+ finalOutput: value.finalOutput !== undefined,
770
+ parkedQuestion: value.parkedQuestion !== undefined
771
+ },
772
+ baseSeatOrdinal: value.seat === undefined ? undefined : 0,
773
+ baseRefusals: new Map(value.refusals.map((refusal) => [refusal.message, 0])),
774
+ indexes: emptyIndexes(),
775
+ contributions: HashMap.empty(),
776
+ contributionBytes: 0,
777
+ length: 1
778
+ }
779
+
780
+ /** Rebuild only scalar facts; keyed observations never own root result/state fields. */
781
+ const combinedFacts = (state: DigestState): Digest => {
782
+ const result = { ...state.base }
783
+ let seatOrdinal = state.baseSeatOrdinal ?? -1
784
+ const refusals = new Map(state.base.refusals.map((refusal) => [refusal.message, {
785
+ count: refusal.count,
786
+ ordinal: state.baseRefusals.get(refusal.message)!
787
+ }]))
788
+ for (const [, contribution] of state.contributions) {
789
+ const value = contribution.value
790
+ for (const key of counters) result[key] += value[key] ?? 0
791
+ if (value.seat !== undefined && contribution.ordinal > seatOrdinal) {
792
+ result.seat = value.seat
793
+ seatOrdinal = contribution.ordinal
794
+ }
795
+ result.startedAt = earliest(result.startedAt, value.startedAt)
796
+ result.endedAt = latest(result.endedAt, value.endedAt)
797
+ for (const refusal of value.refusals ?? []) {
798
+ const previous = refusals.get(refusal.message)
799
+ refusals.set(refusal.message, {
800
+ count: (previous?.count ?? 0) + refusal.count,
801
+ ordinal: Math.min(previous?.ordinal ?? contribution.ordinal, contribution.ordinal)
802
+ })
803
+ }
804
+ }
805
+ result.refusals = [...refusals].sort(([, left], [, right]) =>
806
+ right.count - left.count || left.ordinal - right.ordinal
807
+ )
808
+ .map(([message, { count }]) => ({ message, count }))
809
+ return result
810
+ }
811
+
812
+ /**
813
+ * Combines adjacent digests without counting an identified call or checkpoint
814
+ * twice. A later native fact replaces the earlier telemetry contribution.
815
+ * Identity state is private and must stay with the in-memory digest; a plain
816
+ * reconstructed Digest is treated as an already aggregated, unkeyed value.
817
+ * @category constructors
818
+ * @since 1.0.0
819
+ */
820
+ export const combine = (earlier: Digest, later: Digest): Digest => {
821
+ const left = stateOf(earlier)
822
+ const right = stateOf(later)
823
+ let contributions = left.contributions
824
+ let indexes = left.indexes
825
+ let contributionBytes = left.contributionBytes
826
+ let accepted = HashMap.empty<string, Contribution>()
827
+ const corrected = { ...earlier }
828
+ for (const [key, value] of right.contributions) {
829
+ const previous = HashMap.get(contributions, key)
830
+ if (previous._tag === "Some" && (previous.value.authoritative || !value.authoritative)) continue
831
+ if (previous._tag === "Some") {
832
+ const old = previous.value.value
833
+ const next = value.value
834
+ for (const counter of counters) corrected[counter] += (next[counter] ?? 0) - (old[counter] ?? 0)
835
+ } else accepted = HashMap.set(accepted, key, value)
836
+ const contribution = {
837
+ ...value,
838
+ ordinal: previous._tag === "Some" ? previous.value.ordinal : left.length + value.ordinal
839
+ }
840
+ contributionBytes += encodedBytes([key, contribution]) -
841
+ (previous._tag === "Some" ? encodedBytes([key, previous.value]) : 0)
842
+ contributions = HashMap.set(contributions, key, contribution)
843
+ indexes = indexContribution(indexes, previous._tag === "Some" ? previous.value : undefined, contribution)
844
+ }
845
+ const baseRefusals = new Map(left.baseRefusals)
846
+ for (const [message, ordinal] of right.baseRefusals) {
847
+ if (!baseRefusals.has(message)) baseRefusals.set(message, left.length + ordinal)
848
+ }
849
+ const incomingComplete = HashMap.size(accepted) === HashMap.size(right.contributions)
850
+ const incoming = incomingComplete ? later : combinedFacts({ ...right, contributions: accepted })
851
+ const state: DigestState = {
852
+ base: combinePlain(left.base, right.base, right.writes),
853
+ writes: {
854
+ cause: left.writes.cause || right.writes.cause,
855
+ finalOutput: left.writes.finalOutput || right.writes.finalOutput,
856
+ parkedQuestion: left.writes.parkedQuestion || right.writes.parkedQuestion
857
+ },
858
+ baseSeatOrdinal: right.baseSeatOrdinal === undefined ? left.baseSeatOrdinal : left.length + right.baseSeatOrdinal,
859
+ baseRefusals,
860
+ indexes,
861
+ contributions,
862
+ contributionBytes,
863
+ length: left.length + right.length
864
+ }
865
+ // Appending new identities (or replaying an existing one) should cost the
866
+ // incoming range, not re-fold the entire retained ledger on every eviction.
867
+ // Indexed timestamps and refusal positions handle native corrections without
868
+ // re-scanning all identities. Refusal rendering costs distinct messages.
869
+ const value = { ...combinePlain(corrected, incoming, right.writes) }
870
+ value.startedAt = state.base.startedAt
871
+ value.endedAt = state.base.endedAt
872
+ if (indexes.timings?.min !== undefined) {
873
+ value.startedAt = Math.min(value.startedAt ?? indexes.timings.min, indexes.timings.min)
874
+ }
875
+ if (indexes.timings?.max !== undefined) {
876
+ value.endedAt = Math.max(value.endedAt ?? indexes.timings.max, indexes.timings.max)
877
+ }
878
+ const refusals = new Map(state.base.refusals.map((refusal) => [refusal.message, {
879
+ count: refusal.count,
880
+ ordinal: baseRefusals.get(refusal.message)!
881
+ }]))
882
+ for (const [message, tree] of indexes.refusals) {
883
+ const previous = refusals.get(message)
884
+ refusals.set(message, {
885
+ count: (previous?.count ?? 0) + tree.size,
886
+ ordinal: Math.min(previous?.ordinal ?? tree.first, tree.first)
887
+ })
888
+ }
889
+ value.refusals = [...refusals].sort(([, a], [, b]) => b.count - a.count || a.ordinal - b.ordinal)
890
+ .map(([message, { count }]) => ({ message, count }))
891
+ return remember(value, state)
892
+ }