@cc-monitoring/proxy-core 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (388) hide show
  1. package/dist/cli/__tests__/commands.test.js +1 -1
  2. package/dist/cli/commands/exec.js +31 -42
  3. package/dist/docs/404.html +2 -2
  4. package/dist/docs/assets/{app.B9A39uFv.js → app.DtYNT5zS.js} +1 -1
  5. package/dist/docs/assets/chunks/@localSearchIndexroot.C4sjikMO.js +1 -0
  6. package/dist/docs/assets/chunks/{VPLocalSearchBox.DdhC696L.js → VPLocalSearchBox.DpXF9ZAI.js} +1 -1
  7. package/dist/docs/assets/chunks/{theme.CfB2tOFi.js → theme.TS_gUyc7.js} +2 -2
  8. package/dist/docs/assets/{proxy-cli_data-hooks.md.w9Oe1OD3.js → proxy-cli_data-hooks.md.Bz8CVbxO.js} +1 -1
  9. package/dist/docs/assets/{proxy-core_ui-routes.md.Dyqkeoiv.js → proxy-core_ui-routes.md.B21t1p7R.js} +1 -1
  10. package/dist/docs/hashmap.json +1 -1
  11. package/dist/docs/index.html +3 -3
  12. package/dist/docs/overview.html +3 -3
  13. package/dist/docs/packages-utils.html +3 -3
  14. package/dist/docs/proxy-admin/env-and-build.html +3 -3
  15. package/dist/docs/proxy-admin/index.html +3 -3
  16. package/dist/docs/proxy-admin/layout-and-menu.html +3 -3
  17. package/dist/docs/proxy-admin/pages.html +3 -3
  18. package/dist/docs/proxy-admin/routing-and-auth.html +3 -3
  19. package/dist/docs/proxy-admin/services-and-mock.html +3 -3
  20. package/dist/docs/proxy-cli/api-layer.html +3 -3
  21. package/dist/docs/proxy-cli/app-shell.html +3 -3
  22. package/dist/docs/proxy-cli/components-common.html +3 -3
  23. package/dist/docs/proxy-cli/components-config.html +3 -3
  24. package/dist/docs/proxy-cli/components-requests.html +3 -3
  25. package/dist/docs/proxy-cli/components-stats.html +3 -3
  26. package/dist/docs/proxy-cli/components-status.html +3 -3
  27. package/dist/docs/proxy-cli/data-hooks.html +5 -5
  28. package/dist/docs/proxy-cli/index.html +3 -3
  29. package/dist/docs/proxy-cli/utils-and-i18n.html +3 -3
  30. package/dist/docs/proxy-core/chat-api.html +3 -3
  31. package/dist/docs/proxy-core/cli.html +3 -3
  32. package/dist/docs/proxy-core/config.html +3 -3
  33. package/dist/docs/proxy-core/data-layer.html +3 -3
  34. package/dist/docs/proxy-core/entry.html +3 -3
  35. package/dist/docs/proxy-core/index.html +3 -3
  36. package/dist/docs/proxy-core/pm2.html +3 -3
  37. package/dist/docs/proxy-core/providers.html +3 -3
  38. package/dist/docs/proxy-core/proxy.html +3 -3
  39. package/dist/docs/proxy-core/stats.html +3 -3
  40. package/dist/docs/proxy-core/tool.html +3 -3
  41. package/dist/docs/proxy-core/ui-routes.html +5 -5
  42. package/dist/docs/proxy-core/utilities.html +3 -3
  43. package/dist/docs/quickstart.html +3 -3
  44. package/dist/docs/request-flow.html +3 -3
  45. package/dist/logger/index.d.ts +0 -3
  46. package/dist/logger/index.js +0 -1
  47. package/dist/mcp-server/tools.js +8 -9
  48. package/dist/server/__tests__/providers-route.test.js +1 -0
  49. package/dist/server/auth.d.ts +0 -1
  50. package/dist/server/auth.js +1 -1
  51. package/dist/server/chat-route.js +48 -162
  52. package/dist/server/data-push.d.ts +0 -1
  53. package/dist/server/data-push.js +0 -7
  54. package/dist/server/proxy.js +128 -224
  55. package/dist/server/ui-route.js +76 -59
  56. package/dist/tools/index.d.ts +1 -1
  57. package/dist/tools/index.js +1 -1
  58. package/dist/tools/registry.d.ts +0 -4
  59. package/dist/tools/registry.js +0 -8
  60. package/dist/types/config.d.ts +0 -13
  61. package/dist/types/pm2.d.ts +1 -2
  62. package/dist/ui/assets/{1c-DAu68mP4.js → 1c-CCx-FOtz.js} +1 -1
  63. package/dist/ui/assets/{abnf-Cu8RHCHK.js → abnf-Bwbi42Z8.js} +1 -1
  64. package/dist/ui/assets/{abnfDiagram-VRR7QNED-BUBToPXF.js → abnfDiagram-VRR7QNED-Dm1-8q0E.js} +1 -1
  65. package/dist/ui/assets/{accesslog-BG-34XOy.js → accesslog-DCytz_-m.js} +1 -1
  66. package/dist/ui/assets/{actionscript-iw0HHMGM.js → actionscript-3udf15oh.js} +1 -1
  67. package/dist/ui/assets/{ada-qRqj6VGQ.js → ada-M5Xa74xG.js} +1 -1
  68. package/dist/ui/assets/{angelscript-BeaXyx_P.js → angelscript-qlrFxfW-.js} +1 -1
  69. package/dist/ui/assets/{apache-CU8d-z9X.js → apache-B-sF-DQH.js} +1 -1
  70. package/dist/ui/assets/{applescript-d1Wxkqz1.js → applescript-4FdcBnbI.js} +1 -1
  71. package/dist/ui/assets/{arc-BMsPIm3j.js → arc-BB3K1enp.js} +1 -1
  72. package/dist/ui/assets/{arcade-CtbgrWTM.js → arcade-B_yqWaaG.js} +1 -1
  73. package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-CVjC5TrS.js → architectureDiagram-ZJ3FMSHR-B39vkY8V.js} +1 -1
  74. package/dist/ui/assets/{arduino-Bc9L39Hr.js → arduino-yAcBoTWU.js} +1 -1
  75. package/dist/ui/assets/{armasm-DuWmpjWR.js → armasm-wIcY84bI.js} +1 -1
  76. package/dist/ui/assets/{asciidoc-CDIhFTnx.js → asciidoc-Bxnu28-Z.js} +1 -1
  77. package/dist/ui/assets/{aspectj-SYj-57Es.js → aspectj-B2cKJA_O.js} +1 -1
  78. package/dist/ui/assets/{autohotkey-hBi5dq37.js → autohotkey-B_rMWTtE.js} +1 -1
  79. package/dist/ui/assets/{autoit-BSawXzhg.js → autoit-DwcuvMwv.js} +1 -1
  80. package/dist/ui/assets/{avrasm-CwYom8Np.js → avrasm-heGX1PXK.js} +1 -1
  81. package/dist/ui/assets/{awk-BvBRfGo2.js → awk-BiqCQAEf.js} +1 -1
  82. package/dist/ui/assets/{axapta-CqUavA8k.js → axapta-Cv8M-Ih6.js} +1 -1
  83. package/dist/ui/assets/{bash-BS_ZnmEu.js → bash-Divgn3JV.js} +1 -1
  84. package/dist/ui/assets/{basic-xbP4IXrN.js → basic-B9dnAP55.js} +1 -1
  85. package/dist/ui/assets/{blockDiagram-677ZJIJ3-CmpI3f5p.js → blockDiagram-677ZJIJ3-DQ1mf7A_.js} +1 -1
  86. package/dist/ui/assets/{bnf-BECwu6uW.js → bnf-kIL5mSsP.js} +1 -1
  87. package/dist/ui/assets/{brainfuck-QQgu4j4N.js → brainfuck-DqB7xDjH.js} +1 -1
  88. package/dist/ui/assets/{coq-IDMIFfem.js → c-HmsCM6sx.js} +1 -1
  89. package/dist/ui/assets/{c-like-DYrFOtXy.js → c-like-De5MhE7G.js} +1 -1
  90. package/dist/ui/assets/{c4Diagram-LMCZKHZV-B6Hgngz9.js → c4Diagram-LMCZKHZV-DQxtYsAx.js} +1 -1
  91. package/dist/ui/assets/{cal-CNMrJ6v5.js → cal-mYdfz9en.js} +1 -1
  92. package/dist/ui/assets/{capnproto-DYCKl6oY.js → capnproto-D04CRlOt.js} +1 -1
  93. package/dist/ui/assets/{ceylon-mb8tRPl0.js → ceylon-pi9lFCja.js} +1 -1
  94. package/dist/ui/assets/channel-ChTtxQDg.js +1 -0
  95. package/dist/ui/assets/{chunk-2Q5K7J3B-LxvQ-G67.js → chunk-2Q5K7J3B-BDD1nPt8.js} +1 -1
  96. package/dist/ui/assets/{chunk-32BRIVSS-DxzKK6Aw.js → chunk-32BRIVSS-DgeQFBb5.js} +1 -1
  97. package/dist/ui/assets/{chunk-5VM5RSS4-CZEoYJ2W.js → chunk-5VM5RSS4-C7Xf2SnI.js} +1 -1
  98. package/dist/ui/assets/{chunk-EX3LRPZG-DS2PytrN.js → chunk-EX3LRPZG-B_3p1HEv.js} +1 -1
  99. package/dist/ui/assets/{chunk-JWPE2WC7-UX0Sr1Ie.js → chunk-JWPE2WC7-Dvs7u8eY.js} +1 -1
  100. package/dist/ui/assets/{chunk-MOJQB5TN-YbJgT9t4.js → chunk-MOJQB5TN-By21wDCN.js} +1 -1
  101. package/dist/ui/assets/{chunk-RYQCIY6F-DS2VH_U9.js → chunk-RYQCIY6F-6NC700r1.js} +1 -1
  102. package/dist/ui/assets/{chunk-V7JOEXUC-CZr0pkI1.js → chunk-V7JOEXUC-vEUqZ3rh.js} +1 -1
  103. package/dist/ui/assets/{chunk-VR4S4FIN-50opPAD3.js → chunk-VR4S4FIN-6tX2dNN9.js} +1 -1
  104. package/dist/ui/assets/{chunk-XXDRQBXY-DAAX9l7U.js → chunk-XXDRQBXY-qDb2jxAR.js} +1 -1
  105. package/dist/ui/assets/classDiagram-OUVF2IWQ-Ccbvamlu.js +1 -0
  106. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-Ccbvamlu.js +1 -0
  107. package/dist/ui/assets/{clean-C4X7dSkh.js → clean-CLCsDUl1.js} +1 -1
  108. package/dist/ui/assets/{clojure-DSg9gUa7.js → clojure-dVi5Xifj.js} +1 -1
  109. package/dist/ui/assets/{clojure-repl-CagRYx7h.js → clojure-repl-BO_FpFmF.js} +1 -1
  110. package/dist/ui/assets/{cmake-CFdBn53c.js → cmake-CP5aJbyK.js} +1 -1
  111. package/dist/ui/assets/{coffeescript-CJZtMOPx.js → coffeescript-ZEfu_9pF.js} +1 -1
  112. package/dist/ui/assets/{c-BRJEPYra.js → coq-6aKUn3zn.js} +1 -1
  113. package/dist/ui/assets/{cos-Bx2VJuzG.js → cos-BohCnRN2.js} +1 -1
  114. package/dist/ui/assets/{cose-bilkent-JH36ORCC-zWRLsZpZ.js → cose-bilkent-JH36ORCC-DyXCbbro.js} +1 -1
  115. package/dist/ui/assets/{cpp-CsG6DlC4.js → cpp-FOgPWPEt.js} +1 -1
  116. package/dist/ui/assets/{crmsh-DTy9MnmJ.js → crmsh-B0OYb-Oe.js} +1 -1
  117. package/dist/ui/assets/{crystal-BwgrLrZ1.js → crystal-CuWb_dXm.js} +1 -1
  118. package/dist/ui/assets/{csharp-B2VeTPAF.js → csharp-BbcqM09j.js} +1 -1
  119. package/dist/ui/assets/{csp-CTpydNhH.js → csp-rgHnTaDq.js} +1 -1
  120. package/dist/ui/assets/{css-B0mMUbpY.js → css-C-ibh7ZG.js} +1 -1
  121. package/dist/ui/assets/{cynefin-VYW2F7L2-BmjQEj6q.js → cynefin-VYW2F7L2-CkuBhgC4.js} +1 -1
  122. package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-Dr0Zrke0.js → cynefinDiagram-TSTJHNR4-eycFyDao.js} +1 -1
  123. package/dist/ui/assets/{d-DjuDZnbI.js → d-C0gXxJ0O.js} +1 -1
  124. package/dist/ui/assets/{dagre-VKFMJZFB-xoTPT2Uu.js → dagre-VKFMJZFB-DzqX9e49.js} +1 -1
  125. package/dist/ui/assets/{dart-xR3GU9TJ.js → dart-C-fTpuUV.js} +1 -1
  126. package/dist/ui/assets/{delphi-bJas5QnG.js → delphi-Chm0B9xv.js} +1 -1
  127. package/dist/ui/assets/{diagram-FQU43EPY-rL_IU7gU.js → diagram-FQU43EPY-BEgCqfg1.js} +1 -1
  128. package/dist/ui/assets/{diagram-G47NLZAW-EcDiCVGj.js → diagram-G47NLZAW-Cw11Vs2v.js} +1 -1
  129. package/dist/ui/assets/{diagram-NH7WQ7WH-CGGXOjev.js → diagram-NH7WQ7WH-DSG_UWpP.js} +1 -1
  130. package/dist/ui/assets/{diagram-OA4YK3LP-DnE7hDjD.js → diagram-OA4YK3LP-CJz-WOaJ.js} +1 -1
  131. package/dist/ui/assets/{diagram-WEI45ONY-CTJH5eD8.js → diagram-WEI45ONY-CBXjBCvc.js} +1 -1
  132. package/dist/ui/assets/{diff-doJFF3fv.js → diff-C-vyuMSL.js} +1 -1
  133. package/dist/ui/assets/{django-D3b-owa_.js → django-CJK7lReT.js} +1 -1
  134. package/dist/ui/assets/{dns-C42KYV-Z.js → dns-D02SHjSy.js} +1 -1
  135. package/dist/ui/assets/{dockerfile-9KUINc2j.js → dockerfile-trKL1Bqu.js} +1 -1
  136. package/dist/ui/assets/{dos-CxnlJ6qp.js → dos-C52dy-sK.js} +1 -1
  137. package/dist/ui/assets/{dsconfig-6CMMCwmY.js → dsconfig-MzHgzVrt.js} +1 -1
  138. package/dist/ui/assets/{dts-D78rdUIB.js → dts-B137dHyX.js} +1 -1
  139. package/dist/ui/assets/{dust-Dv1uTfJU.js → dust-BcbM0r5C.js} +1 -1
  140. package/dist/ui/assets/{ebnf-BGbG1cFK.js → ebnf-DkbpI7bK.js} +1 -1
  141. package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-z2VgRSUV.js → ebnfDiagram-CCIWWBDH-aI5uQ7w1.js} +1 -1
  142. package/dist/ui/assets/{elixir-ZgAQVY1J.js → elixir-BOtDuqQy.js} +1 -1
  143. package/dist/ui/assets/{elm-CudiFuNu.js → elm-DS8Tyyu-.js} +1 -1
  144. package/dist/ui/assets/{erDiagram-Q63AITRT-X1TODuRv.js → erDiagram-Q63AITRT-2vCbd4Mm.js} +1 -1
  145. package/dist/ui/assets/{erb-Bz_NZh6W.js → erb-CSXECRbn.js} +1 -1
  146. package/dist/ui/assets/{erlang-DNuj1nb2.js → erlang-BMxlgKPJ.js} +1 -1
  147. package/dist/ui/assets/{erlang-repl-SP1Gan9W.js → erlang-repl-DPzlolPg.js} +1 -1
  148. package/dist/ui/assets/{excel-0K77uECF.js → excel-CW2Uxed3.js} +1 -1
  149. package/dist/ui/assets/{fix-CalJq7JD.js → fix-UW84SlCs.js} +1 -1
  150. package/dist/ui/assets/{flix-BlIs11_w.js → flix-4UGiPULd.js} +1 -1
  151. package/dist/ui/assets/{flowDiagram-23GEKE2U-DA2dnmc0.js → flowDiagram-23GEKE2U-R5PbCbZI.js} +1 -1
  152. package/dist/ui/assets/{fortran-ZCobXY2R.js → fortran-nhHsngdu.js} +1 -1
  153. package/dist/ui/assets/{fsharp-Be8rwUtc.js → fsharp-CDyZ1ST5.js} +1 -1
  154. package/dist/ui/assets/{gams-DUat8frQ.js → gams-DHzkkUie.js} +1 -1
  155. package/dist/ui/assets/{ganttDiagram-NO4QXBWP-DdFwaIGZ.js → ganttDiagram-NO4QXBWP-CGcq4Ie_.js} +1 -1
  156. package/dist/ui/assets/{gauss-BB4U88dy.js → gauss-DdhFGyBv.js} +1 -1
  157. package/dist/ui/assets/{gcode-DzeUZuZg.js → gcode-ImHh8OLA.js} +1 -1
  158. package/dist/ui/assets/{gherkin-B_8vW_BO.js → gherkin-CTWAW-XR.js} +1 -1
  159. package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-B-Dn8x6I.js → gitGraphDiagram-IHSO6WYX-8nM2Z9lD.js} +1 -1
  160. package/dist/ui/assets/{glsl-DGHGjPC1.js → glsl-0_W_27G2.js} +1 -1
  161. package/dist/ui/assets/{gml-BYEku8Yh.js → gml-BoDggu2z.js} +1 -1
  162. package/dist/ui/assets/{go-D8aSgQMc.js → go-DYfFygwl.js} +1 -1
  163. package/dist/ui/assets/{golo-CDjCU_jh.js → golo-Mlq-TCg9.js} +1 -1
  164. package/dist/ui/assets/{gradle-BeUw7tl_.js → gradle-BALAinEB.js} +1 -1
  165. package/dist/ui/assets/{groovy-5iCQOtR3.js → groovy-Dht--dWU.js} +1 -1
  166. package/dist/ui/assets/{haml-BEdL8FJi.js → haml-DpMrxg0d.js} +1 -1
  167. package/dist/ui/assets/{handlebars-BuYQNzoK.js → handlebars-DqHzujNj.js} +1 -1
  168. package/dist/ui/assets/{haskell-I4FCBcW0.js → haskell-DZSchhkY.js} +1 -1
  169. package/dist/ui/assets/{haxe-yigyKfFr.js → haxe-C0zBRjdy.js} +1 -1
  170. package/dist/ui/assets/{hsp-ZUk4j7d1.js → hsp-D_PwbSv2.js} +1 -1
  171. package/dist/ui/assets/{htmlbars-QYP3lT3u.js → htmlbars-DxAFMG8u.js} +1 -1
  172. package/dist/ui/assets/{http-BJpD1O71.js → http-DvTRF0Do.js} +1 -1
  173. package/dist/ui/assets/{hy-CIJ1bP6S.js → hy-lVO-kNyp.js} +1 -1
  174. package/dist/ui/assets/{index-BDXWttnT.js → index-BbMRVVGt.js} +3 -3
  175. package/dist/ui/assets/{index-COAgrx1J.js → index-Ci23SMK2.js} +242 -242
  176. package/dist/ui/assets/index-DlsVXaHT.css +10 -0
  177. package/dist/ui/assets/{infoDiagram-FWYZ7A6U-fTg9eLNt.js → infoDiagram-FWYZ7A6U-C7WYDlvc.js} +1 -1
  178. package/dist/ui/assets/{inform7-DAsu-lC2.js → inform7-B8Tf2n8v.js} +1 -1
  179. package/dist/ui/assets/{ini-Bhz-zHCg.js → ini-DSoYMaLF.js} +1 -1
  180. package/dist/ui/assets/{irpf90-BunhbwBl.js → irpf90-RCPdkB14.js} +1 -1
  181. package/dist/ui/assets/{isbl-q9L6hOhP.js → isbl-C2p75PPj.js} +1 -1
  182. package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-B8G0sdgd.js → ishikawaDiagram-FXEZZL3T-Cm6jsPlc.js} +1 -1
  183. package/dist/ui/assets/{java-Iks5Pkau.js → java-DeY4Yuia.js} +1 -1
  184. package/dist/ui/assets/{javascript-C4vltXPw.js → javascript-3uX1CO-H.js} +1 -1
  185. package/dist/ui/assets/{jboss-cli-BQBvd2X2.js → jboss-cli-DgnD8mEc.js} +1 -1
  186. package/dist/ui/assets/{journeyDiagram-5HDEW3XC-Crbzgrum.js → journeyDiagram-5HDEW3XC-DEGV1uA5.js} +1 -1
  187. package/dist/ui/assets/{json-DXK0_jUK.js → json-BV2PmJJp.js} +1 -1
  188. package/dist/ui/assets/{julia-CCYoBiYK.js → julia-B-m8kQm7.js} +1 -1
  189. package/dist/ui/assets/{julia-repl-y8v2Oorl.js → julia-repl-C51atU2X.js} +1 -1
  190. package/dist/ui/assets/{kanban-definition-HUTT4EX6-C8sCOsBX.js → kanban-definition-HUTT4EX6-BJ4k5iTX.js} +1 -1
  191. package/dist/ui/assets/{kotlin-Bnjk7_fw.js → kotlin-CYBziIgl.js} +1 -1
  192. package/dist/ui/assets/{lasso-B-al6x63.js → lasso-Dw2SBMDW.js} +1 -1
  193. package/dist/ui/assets/{latex-BUmqlb9r.js → latex-Dpd35yke.js} +1 -1
  194. package/dist/ui/assets/{ldif-D42RWj6Q.js → ldif-Ce9EZU__.js} +1 -1
  195. package/dist/ui/assets/{leaf-CrH4BZ0m.js → leaf-CpkZzQtC.js} +1 -1
  196. package/dist/ui/assets/{less-upmRlQQW.js → less-Uzo7M0FD.js} +1 -1
  197. package/dist/ui/assets/{lisp-DHYS22SA.js → lisp-DWXDlJYm.js} +1 -1
  198. package/dist/ui/assets/{livecodeserver-CeQNmFP3.js → livecodeserver-uEyPEgVJ.js} +1 -1
  199. package/dist/ui/assets/{livescript-PJWpY1JI.js → livescript-BQ5f07oK.js} +1 -1
  200. package/dist/ui/assets/{llvm-BKtKWwCt.js → llvm-BAvP-skE.js} +1 -1
  201. package/dist/ui/assets/{lsl-RWRLRjk7.js → lsl-DhbiIKu6.js} +1 -1
  202. package/dist/ui/assets/{lua-BFUDiPGm.js → lua-COxeUeLx.js} +1 -1
  203. package/dist/ui/assets/{makefile-CUDyOz5D.js → makefile-DhDx-IgL.js} +1 -1
  204. package/dist/ui/assets/{markdown-zZCLypc6.js → markdown-DX5_kSxq.js} +1 -1
  205. package/dist/ui/assets/{mathematica-BHbxKxnq.js → mathematica-D351ZddB.js} +1 -1
  206. package/dist/ui/assets/{matlab-DlGtg--p.js → matlab-CELqIiwF.js} +1 -1
  207. package/dist/ui/assets/{maxima-BBBeS3Ra.js → maxima-B_YljrMm.js} +1 -1
  208. package/dist/ui/assets/{mel-nh8j7W_6.js → mel-DltsbNS8.js} +1 -1
  209. package/dist/ui/assets/{mercury-DyyD-pqr.js → mercury-axX-5Vjj.js} +1 -1
  210. package/dist/ui/assets/{mindmap-definition-LN4V7U3C-CJlhDHqM.js → mindmap-definition-LN4V7U3C-Bl1EJo6p.js} +1 -1
  211. package/dist/ui/assets/{mipsasm-hiEhRRiq.js → mipsasm-BxmerVwX.js} +1 -1
  212. package/dist/ui/assets/{mizar-BZa3iAAL.js → mizar-XNHfbpL2.js} +1 -1
  213. package/dist/ui/assets/{mojolicious-BCIm2V_y.js → mojolicious-BR0U_7zk.js} +1 -1
  214. package/dist/ui/assets/{monkey-zmK-7N8b.js → monkey-lLuu9_f-.js} +1 -1
  215. package/dist/ui/assets/{moonscript-BsS_Mn3D.js → moonscript-DoaZ3DRQ.js} +1 -1
  216. package/dist/ui/assets/{n1ql-D7xVgDP0.js → n1ql-C6TId6Iu.js} +1 -1
  217. package/dist/ui/assets/{nginx-ct2q4dtd.js → nginx-BezSG-JT.js} +1 -1
  218. package/dist/ui/assets/{nim-RO0UOmW3.js → nim-Bb0rfXie.js} +1 -1
  219. package/dist/ui/assets/{nix-BcRJxPKH.js → nix-o3sJ5-54.js} +1 -1
  220. package/dist/ui/assets/{node-repl-DgIefwxW.js → node-repl-Sv5hhcTf.js} +1 -1
  221. package/dist/ui/assets/{nsis-DqHs9QhB.js → nsis-B45BJFhF.js} +1 -1
  222. package/dist/ui/assets/{objectivec-BBcWqc7Y.js → objectivec-CzS6zVgh.js} +1 -1
  223. package/dist/ui/assets/{ocaml-BExfw7D6.js → ocaml-Bqux7PyP.js} +1 -1
  224. package/dist/ui/assets/{openscad-CHPRELQb.js → openscad-4Wf6mF84.js} +1 -1
  225. package/dist/ui/assets/{oxygene-DpS9uMJW.js → oxygene-Fvwqgkkt.js} +1 -1
  226. package/dist/ui/assets/{parser3-CjJ_QdBp.js → parser3-zEfzT5wv.js} +1 -1
  227. package/dist/ui/assets/{pegDiagram-2B236MQR-GM70woGy.js → pegDiagram-2B236MQR-Dd4rIztM.js} +1 -1
  228. package/dist/ui/assets/{perl-BSNM2Kt8.js → perl-CsS1Gs6o.js} +1 -1
  229. package/dist/ui/assets/{pf-Z-hKf_88.js → pf-BNH1jO0R.js} +1 -1
  230. package/dist/ui/assets/{pgsql-DDgznxBg.js → pgsql-DqPigHrq.js} +1 -1
  231. package/dist/ui/assets/{php-BzAhxF-l.js → php-CdOl9bRs.js} +1 -1
  232. package/dist/ui/assets/{php-template-DkgcKHRc.js → php-template-DPfirJg2.js} +1 -1
  233. package/dist/ui/assets/{pieDiagram-ENE6RG2P-Bst7mPyz.js → pieDiagram-ENE6RG2P-DGaJNf4S.js} +1 -1
  234. package/dist/ui/assets/{plaintext-BYEppD0R.js → plaintext-EHbgBKzw.js} +1 -1
  235. package/dist/ui/assets/{pony-BT_kQd1K.js → pony-DmJajtp2.js} +1 -1
  236. package/dist/ui/assets/{powershell-BfRsuSsf.js → powershell-DfGzdWR6.js} +1 -1
  237. package/dist/ui/assets/{processing-DpzWe5Iu.js → processing-BT0ETgPG.js} +1 -1
  238. package/dist/ui/assets/{profile-BCOhS5cM.js → profile-B3I-x5Lt.js} +1 -1
  239. package/dist/ui/assets/{prolog-OxaCCaW8.js → prolog-B_4QJIvI.js} +1 -1
  240. package/dist/ui/assets/{properties-DMFlA2Ca.js → properties-BFVI8weS.js} +1 -1
  241. package/dist/ui/assets/{protobuf-CRDFkXvZ.js → protobuf-PaF39oZZ.js} +1 -1
  242. package/dist/ui/assets/{puppet-DnrVyLzx.js → puppet-BDC6Q8VF.js} +1 -1
  243. package/dist/ui/assets/{purebasic-Dht4Hniv.js → purebasic-B2ejrOZK.js} +1 -1
  244. package/dist/ui/assets/{python-B0aMirWu.js → python-BOxtIk9H.js} +1 -1
  245. package/dist/ui/assets/{python-repl-BlYDBGa7.js → python-repl-BslBh_Mx.js} +1 -1
  246. package/dist/ui/assets/{q-DzrtW9kT.js → q-BPe8WLGW.js} +1 -1
  247. package/dist/ui/assets/{qml-DnfQsR3i.js → qml-BazRR6fz.js} +1 -1
  248. package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-DNRYurBT.js → quadrantDiagram-ABIIQ3AL-BQ7aPkHk.js} +1 -1
  249. package/dist/ui/assets/{r-DGI_ZuTD.js → r-C09pGNJC.js} +1 -1
  250. package/dist/ui/assets/{railroadDiagram-RFXS5EU6-CmbC3Vz4.js → railroadDiagram-RFXS5EU6-sCO9VGvE.js} +1 -1
  251. package/dist/ui/assets/{reasonml-3SohMgh2.js → reasonml-S7dzwVL9.js} +1 -1
  252. package/dist/ui/assets/{requirementDiagram-TGXJPOKE-8CxrXHco.js → requirementDiagram-TGXJPOKE-CfT5aVZg.js} +1 -1
  253. package/dist/ui/assets/{rib-DfRSd4Qa.js → rib-fM2EwQd4.js} +1 -1
  254. package/dist/ui/assets/{roboconf-CQczGdGW.js → roboconf-D7AaeyrW.js} +1 -1
  255. package/dist/ui/assets/{routeros-DCka-T2i.js → routeros-c6Q7mKuq.js} +1 -1
  256. package/dist/ui/assets/{rsl-Dr8MOwMo.js → rsl-sCpEQBxh.js} +1 -1
  257. package/dist/ui/assets/{ruby-C2zFSkh_.js → ruby-lcKhz2w9.js} +1 -1
  258. package/dist/ui/assets/{ruleslanguage-C97YsgQq.js → ruleslanguage-BW4ATOuX.js} +1 -1
  259. package/dist/ui/assets/{rust-H3h8kd9A.js → rust-BbpU-0VY.js} +1 -1
  260. package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-DBXLWjEq.js → sankeyDiagram-HTMAVEWB-CaweCpvN.js} +1 -1
  261. package/dist/ui/assets/{sas-04z0Xu8P.js → sas-BPt5R0dx.js} +1 -1
  262. package/dist/ui/assets/{scala-DyB9Aoiv.js → scala-DxW_vqXs.js} +1 -1
  263. package/dist/ui/assets/{scheme-DBj6nxUi.js → scheme-T2Q_jWzT.js} +1 -1
  264. package/dist/ui/assets/{scilab-Btj7AD9s.js → scilab-DMORg9lV.js} +1 -1
  265. package/dist/ui/assets/{scss-BXZJyXt7.js → scss-t0VsosqT.js} +1 -1
  266. package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DXIkBFKC.js → sequenceDiagram-DBY2YBRQ-o-H_R4zb.js} +1 -1
  267. package/dist/ui/assets/{shell-BsreQR1Z.js → shell-CnCDa1s9.js} +1 -1
  268. package/dist/ui/assets/{sizeCapture-X5ZJPWSS-ocS9jxAQ.js → sizeCapture-X5ZJPWSS-BNLkHGDS.js} +1 -1
  269. package/dist/ui/assets/{smali-D9wQw9zm.js → smali-_n-BxJyG.js} +1 -1
  270. package/dist/ui/assets/{smalltalk-Dku6G_H3.js → smalltalk-B90PXJwK.js} +1 -1
  271. package/dist/ui/assets/{sml-BknyU6ya.js → sml-fuY7bj-n.js} +1 -1
  272. package/dist/ui/assets/{sqf-DRYMaOg8.js → sqf-COpwkyuo.js} +1 -1
  273. package/dist/ui/assets/{sql-Cw3Ax4KA.js → sql-CXIT0j-x.js} +1 -1
  274. package/dist/ui/assets/{sql_more-vWdslLE0.js → sql_more-C1Oxq4rx.js} +1 -1
  275. package/dist/ui/assets/{stan-8XH5bDS6.js → stan-BZEpaHeC.js} +1 -1
  276. package/dist/ui/assets/{stata-4e77wgfe.js → stata-CkBwaiZM.js} +1 -1
  277. package/dist/ui/assets/{stateDiagram-2N3HPSRC-RMmL9jMG.js → stateDiagram-2N3HPSRC-BkdnNF7I.js} +1 -1
  278. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-0JnZ1VSQ.js +1 -0
  279. package/dist/ui/assets/{step21-ByIeDMY3.js → step21-fs9N_U3O.js} +1 -1
  280. package/dist/ui/assets/{stylus-ZAhJyWsw.js → stylus-Bs_9cvKZ.js} +1 -1
  281. package/dist/ui/assets/{subunit-pPW2UGkj.js → subunit-DvgcOCqJ.js} +1 -1
  282. package/dist/ui/assets/{swift-CX3BB5az.js → swift-BE4ONsur.js} +1 -1
  283. package/dist/ui/assets/{swimlanes-5IMT3BWC-C2zAuJ56.js → swimlanes-5IMT3BWC-uqTAc7o7.js} +2 -2
  284. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DQRIIEmi.js +8 -0
  285. package/dist/ui/assets/{taggerscript-BHcjbWIC.js → taggerscript-BhmPJ64C.js} +1 -1
  286. package/dist/ui/assets/{tap-BOl1lBlS.js → tap-DkueIVKV.js} +1 -1
  287. package/dist/ui/assets/{tcl-DZjeOBDh.js → tcl-DyXOOkFi.js} +1 -1
  288. package/dist/ui/assets/{thrift-BxboWg4x.js → thrift-Dhgbk56T.js} +1 -1
  289. package/dist/ui/assets/{timeline-definition-FHXFAJF6-BOxsxyq_.js → timeline-definition-FHXFAJF6-DBAk9Ouc.js} +1 -1
  290. package/dist/ui/assets/{tp-BNM6ql3J.js → tp-BsXyrRGH.js} +1 -1
  291. package/dist/ui/assets/{twig-Dj9ZiXD4.js → twig-J0HqIuHw.js} +1 -1
  292. package/dist/ui/assets/{typescript-7MEJlu_6.js → typescript-Dkwvul39.js} +1 -1
  293. package/dist/ui/assets/{vala-DNqOAgHJ.js → vala-CRGnf8aY.js} +1 -1
  294. package/dist/ui/assets/{vbnet-T0mNKVc_.js → vbnet-BtJAUe3z.js} +1 -1
  295. package/dist/ui/assets/{vbscript-CeuwVMAI.js → vbscript-RgFFNuM3.js} +1 -1
  296. package/dist/ui/assets/{vbscript-html-BbJSt2w6.js → vbscript-html-DO32Io9Y.js} +1 -1
  297. package/dist/ui/assets/{vennDiagram-L72KCM5P-BX9mWeiT.js → vennDiagram-L72KCM5P-BJi6y0hh.js} +1 -1
  298. package/dist/ui/assets/{verilog-DYuhYfkX.js → verilog-C4h6MLcI.js} +1 -1
  299. package/dist/ui/assets/{vhdl-Cf9aT-t7.js → vhdl-DOafePyU.js} +1 -1
  300. package/dist/ui/assets/{vim-DciP44K1.js → vim-BAdTA9TY.js} +1 -1
  301. package/dist/ui/assets/{wardleyDiagram-EHGQE667-CDj2rOzu.js → wardleyDiagram-EHGQE667-C7c_4IJ6.js} +1 -1
  302. package/dist/ui/assets/{x86asm-E-AN_LXO.js → x86asm-BCL6__QH.js} +1 -1
  303. package/dist/ui/assets/{xl-CxYLJelN.js → xl-qIzE4HOe.js} +1 -1
  304. package/dist/ui/assets/{xml-yz1SRLuU.js → xml-DE2sJXYU.js} +1 -1
  305. package/dist/ui/assets/{xquery-BLzBF3tV.js → xquery-CQ35t92y.js} +1 -1
  306. package/dist/ui/assets/{xychartDiagram-FW5EYKEG-Czapk9-Z.js → xychartDiagram-FW5EYKEG-D2ILn0jL.js} +1 -1
  307. package/dist/ui/assets/{yaml-Cv4Y7iN_.js → yaml-5KaAvG5C.js} +1 -1
  308. package/dist/ui/assets/{zephir-KRcdQfEX.js → zephir-CbR3Ryfq.js} +1 -1
  309. package/dist/ui/index.html +2 -2
  310. package/dist/utils/__tests__/abort-signals.test.js +67 -0
  311. package/dist/utils/__tests__/inject-loop.test.js +1 -53
  312. package/dist/utils/__tests__/learn-tasks-db.test.js +82 -0
  313. package/dist/utils/__tests__/openai-converter.test.js +25 -0
  314. package/dist/utils/__tests__/pi-crawl-tools.test.js +15 -4
  315. package/dist/utils/__tests__/pi-dedup-reconcile.test.js +11 -9
  316. package/dist/utils/__tests__/pi-events.test.js +172 -0
  317. package/dist/utils/__tests__/pi-learn-orchestrator.test.js +216 -6
  318. package/dist/utils/__tests__/pi-runtime-json.test.js +38 -3
  319. package/dist/utils/__tests__/providers-db.test.js +40 -2
  320. package/dist/utils/__tests__/request-writer.test.js +271 -39
  321. package/dist/utils/__tests__/sse-protocol.test.d.ts +1 -0
  322. package/dist/utils/__tests__/sse-protocol.test.js +115 -0
  323. package/dist/utils/__tests__/vault.test.d.ts +1 -0
  324. package/dist/utils/__tests__/{knowledge-store.test.js → vault.test.js} +16 -16
  325. package/dist/utils/abort-signals.d.ts +13 -0
  326. package/dist/utils/abort-signals.js +33 -0
  327. package/dist/utils/db.d.ts +1 -0
  328. package/dist/utils/db.js +24 -0
  329. package/dist/utils/esm-dirname.d.ts +0 -15
  330. package/dist/utils/esm-dirname.js +0 -4
  331. package/dist/utils/inject-loop.d.ts +0 -27
  332. package/dist/utils/inject-loop.js +2 -56
  333. package/dist/utils/learn-tasks-db.d.ts +15 -0
  334. package/dist/utils/learn-tasks-db.js +35 -0
  335. package/dist/utils/openai-converter.js +88 -78
  336. package/dist/utils/pi-browser-tools.d.ts +0 -2
  337. package/dist/utils/pi-browser-tools.js +0 -174
  338. package/dist/utils/pi-crawl-tools.d.ts +2 -1
  339. package/dist/utils/pi-crawl-tools.js +16 -11
  340. package/dist/utils/pi-dedup.d.ts +8 -30
  341. package/dist/utils/pi-dedup.js +32 -67
  342. package/dist/utils/pi-events.d.ts +65 -0
  343. package/dist/utils/pi-events.js +98 -0
  344. package/dist/utils/pi-learn-orchestrator.d.ts +6 -5
  345. package/dist/utils/pi-learn-orchestrator.js +71 -106
  346. package/dist/utils/pi-runtime.d.ts +5 -6
  347. package/dist/utils/pi-runtime.js +38 -42
  348. package/dist/utils/pi-sandbox-ops.d.ts +0 -36
  349. package/dist/utils/pi-sandbox-ops.js +5 -190
  350. package/dist/utils/providers-db.d.ts +3 -0
  351. package/dist/utils/providers-db.js +21 -7
  352. package/dist/utils/request-writer.d.ts +59 -30
  353. package/dist/utils/request-writer.js +178 -58
  354. package/dist/utils/sse-protocol.d.ts +34 -0
  355. package/dist/utils/sse-protocol.js +121 -0
  356. package/dist/utils/sse-stream-processor.d.ts +4 -9
  357. package/dist/utils/sse-stream-processor.js +13 -104
  358. package/dist/utils/sse-writer.d.ts +1 -1
  359. package/dist/utils/sse-writer.js +3 -2
  360. package/dist/utils/stats-aggregator.js +3 -0
  361. package/dist/utils/tool-injector.js +7 -0
  362. package/dist/utils/vault.d.ts +111 -0
  363. package/dist/utils/vault.js +434 -0
  364. package/package.json +1 -1
  365. package/dist/docs/assets/chunks/@localSearchIndexroot.B6Qfxe6W.js +0 -1
  366. package/dist/types/api.d.ts +0 -20
  367. package/dist/types/index.d.ts +0 -4
  368. package/dist/types/index.js +0 -4
  369. package/dist/types/log.d.ts +0 -13
  370. package/dist/ui/assets/channel-Bc4Td8eZ.js +0 -1
  371. package/dist/ui/assets/classDiagram-OUVF2IWQ-BicxhZFq.js +0 -1
  372. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-BicxhZFq.js +0 -1
  373. package/dist/ui/assets/index-C0fxlU9d.css +0 -10
  374. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-QvaEO5U6.js +0 -1
  375. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DPgCOY0D.js +0 -8
  376. package/dist/utils/__tests__/sse-accumulator.test.js +0 -83
  377. package/dist/utils/knowledge-store.d.ts +0 -51
  378. package/dist/utils/knowledge-store.js +0 -241
  379. package/dist/utils/migrate-files-to-db.d.ts +0 -1
  380. package/dist/utils/migrate-files-to-db.js +0 -138
  381. package/dist/utils/sse-accumulator.d.ts +0 -9
  382. package/dist/utils/sse-accumulator.js +0 -59
  383. /package/dist/docs/assets/{proxy-cli_data-hooks.md.w9Oe1OD3.lean.js → proxy-cli_data-hooks.md.Bz8CVbxO.lean.js} +0 -0
  384. /package/dist/docs/assets/{proxy-core_ui-routes.md.Dyqkeoiv.lean.js → proxy-core_ui-routes.md.B21t1p7R.lean.js} +0 -0
  385. /package/dist/{types/api.js → utils/__tests__/abort-signals.test.d.ts} +0 -0
  386. /package/dist/{types/log.js → utils/__tests__/learn-tasks-db.test.d.ts} +0 -0
  387. /package/dist/utils/__tests__/{knowledge-store.test.d.ts → openai-converter.test.d.ts} +0 -0
  388. /package/dist/utils/__tests__/{sse-accumulator.test.d.ts → pi-events.test.d.ts} +0 -0
@@ -1,30 +1,22 @@
1
1
  import { initDatabase, getDatabase } from './db.js';
2
2
  import { parseUpstreamEvents } from './inject-loop.js';
3
- export function extractTokenUsage(events) {
4
- if (!events)
5
- return undefined;
6
- const messageDelta = events.find((e) => e?.type === 'message_delta');
7
- return messageDelta?.usage;
8
- }
9
- // --- SSE Event Batch Writer (incremental DB writes during streaming) ---
10
- export const EVENT_BATCH_SIZE = 10;
11
- // Cached prepared statements for batch writes
3
+ import { pushNewRequest } from '../server/data-push.js';
4
+ // --- Private implementation ---
5
+ const EVENT_BATCH_SIZE = 10;
6
+ // Cached prepared statement for batch writes
12
7
  let insertEventStmt = null;
13
- let deleteRequestStmt = null;
14
8
  let cachedDbInstance = null;
15
- // Invalidate cached stmts when DB instance changes (tests create fresh DB per suite)
9
+ // Invalidate cached stmt when DB instance changes (tests create fresh DB per suite)
16
10
  function ensureStmtCacheValid(db) {
17
11
  if (db !== cachedDbInstance) {
18
12
  insertEventStmt = null;
19
- deleteRequestStmt = null;
20
13
  cachedDbInstance = db;
21
14
  }
22
15
  }
23
16
  /**
24
17
  * Flush a batch of SSE events to the response_events table.
25
- * Called during streaming every ~10 events to avoid in-memory accumulation.
26
18
  */
27
- export function flushEventBatch(sessionId, requestId, batch, startIndex) {
19
+ function flushEventBatch(sessionId, requestId, batch, startIndex) {
28
20
  const db = getDatabase();
29
21
  ensureStmtCacheValid(db);
30
22
  if (!insertEventStmt) {
@@ -35,28 +27,15 @@ export function flushEventBatch(sessionId, requestId, batch, startIndex) {
35
27
  insertEventStmt.run(requestId, sessionId, startIndex + i, event.type ?? null, JSON.stringify(event.data));
36
28
  }
37
29
  }
38
- /**
39
- * Delete response_events rows for a request (used when cloudRequestId differs from local requestId).
40
- */
41
- export function deleteResponseEvents(requestId, sessionId) {
42
- const db = getDatabase();
43
- db.prepare('DELETE FROM response_events WHERE request_id = ? AND session_id = ?').run(requestId, sessionId);
30
+ function extractUsage(events) {
31
+ if (!events)
32
+ return undefined;
33
+ const messageDelta = events.find((e) => e?.type === 'message_delta');
34
+ return messageDelta?.usage;
44
35
  }
45
- // --- Request DB Operations ---
46
- // Save request to SQLite database
47
- export async function saveRequestDB(sessionId, requestId, data) {
48
- const db = initDatabase();
49
- const events = data.response?.events;
50
- const usage = events ? extractTokenUsage(events) : undefined;
51
- // For JSON responses (non-streaming), events are still in the array — flush them first
52
- if (events && events.length > 0) {
53
- const batch = events.map((e, i) => ({
54
- index: i,
55
- type: e?.type ?? undefined,
56
- data: e
57
- }));
58
- flushEventBatch(sessionId, requestId, batch, 0);
59
- }
36
+ function writeCompletedRow(args) {
37
+ const db = getDatabase();
38
+ const { meta } = args;
60
39
  const stmt = db.prepare(`
61
40
  INSERT OR REPLACE INTO requests (
62
41
  request_id, session_id, timestamp, method, path, status_code, response_time,
@@ -68,24 +47,155 @@ export async function saveRequestDB(sessionId, requestId, data) {
68
47
  ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
69
48
  )
70
49
  `);
71
- stmt.run(requestId, sessionId, data.timestamp, data.request.method, data.request.path, data.response?.statusCode ?? 0, data.response?.completedAt && data.timestamp
72
- ? Math.round(new Date(data.response.completedAt).getTime() - new Date(data.timestamp).getTime())
73
- : 0, data.apiKey || null, data.proxyApiKey || null, data.baseUrl || null, data.model || null, data.machineId || null, data.request.headers['user-agent'] || null, usage?.input_tokens || null, usage?.output_tokens || null, usage?.cache_read_input_tokens || null, usage?.cache_creation_input_tokens || null, JSON.stringify(data.request.headers), data.request.body ? JSON.stringify(data.request.body) : null, data.response?.headers ? JSON.stringify(data.response.headers) : null, null, // response_events now stored in separate table
74
- data.response?.completedAt || null, data.response?.closedAt || null, data.response?.error || null);
50
+ stmt.run(args.requestId, meta.sessionId, meta.timestamp, meta.request.method, meta.request.path, args.statusCode, args.responseTime, meta.apiKey || null, meta.proxyApiKey || null, meta.baseUrl || null, meta.model || null, meta.machineId || null, meta.request.headers['user-agent'] || null, args.usage?.input_tokens || null, args.usage?.output_tokens || null, args.usage?.cache_read_input_tokens || null, args.usage?.cache_creation_input_tokens || null, JSON.stringify(meta.request.headers), meta.request.body ? JSON.stringify(meta.request.body) : null, args.headers ? JSON.stringify(args.headers) : null, null, // response_events now stored in separate table
51
+ args.completedAt || null, args.closedAt || null, args.error || null);
75
52
  }
76
- // Update token columns for a request (streaming: usage extracted from tailBuffer after save)
77
- export function updateRequestTokens(requestId, sessionId, usage) {
78
- const db = getDatabase();
79
- db.prepare('UPDATE requests SET input_tokens = ?, output_tokens = ?, cache_read_tokens = ?, cache_creation_tokens = ? WHERE request_id = ? AND session_id = ?').run(usage?.input_tokens || null, usage?.output_tokens || null, usage?.cache_read_input_tokens || null, usage?.cache_creation_input_tokens || null, requestId, sessionId);
53
+ function buildSummary(meta, requestId, statusCode, responseTime, usage, withPendingId, closedAt) {
54
+ return {
55
+ requestId,
56
+ sessionId: meta.sessionId,
57
+ compositeId: `${meta.sessionId}:${requestId}`,
58
+ timestamp: meta.timestamp,
59
+ method: meta.request.method,
60
+ path: meta.request.path,
61
+ statusCode,
62
+ responseTime,
63
+ baseUrl: meta.baseUrl,
64
+ model: meta.model,
65
+ machineId: meta.machineId,
66
+ userAgent: meta.request.headers['user-agent'],
67
+ usage,
68
+ pendingId: withPendingId ? `${meta.sessionId}:${meta.localRequestId}` : undefined,
69
+ closedAt
70
+ };
80
71
  }
81
- // Delete a request row by requestId + sessionId (for pending → completed replacement)
82
- export function deleteRequestRow(requestId, sessionId) {
83
- const db = getDatabase();
84
- ensureStmtCacheValid(db);
85
- if (!deleteRequestStmt) {
86
- deleteRequestStmt = db.prepare('DELETE FROM requests WHERE request_id = ? AND session_id = ?');
72
+ // --- Public API ---
73
+ export function createRequestRecorder(meta) {
74
+ const eventBatch = [];
75
+ const tailBuffer = [];
76
+ let eventIndex = 0;
77
+ const startTime = Date.now();
78
+ let pendingCalled = false;
79
+ function flushRemaining() {
80
+ if (eventBatch.length > 0) {
81
+ flushEventBatch(meta.sessionId, meta.localRequestId, eventBatch, eventIndex - eventBatch.length);
82
+ eventBatch.length = 0;
83
+ }
87
84
  }
88
- deleteRequestStmt.run(requestId, sessionId);
85
+ function appendEvent(event) {
86
+ const entry = { index: eventIndex, type: event?.type, data: event };
87
+ eventBatch.push(entry);
88
+ // Maintain tail buffer (last 5 events for usage extraction)
89
+ tailBuffer.push(event);
90
+ if (tailBuffer.length > 5) {
91
+ tailBuffer.shift();
92
+ }
93
+ // Flush batch to DB when threshold reached
94
+ if (eventBatch.length >= EVENT_BATCH_SIZE) {
95
+ flushEventBatch(meta.sessionId, meta.localRequestId, eventBatch, eventIndex - eventBatch.length + 1);
96
+ eventBatch.length = 0; // Reset batch (memory freed)
97
+ }
98
+ eventIndex++;
99
+ }
100
+ return {
101
+ async pending() {
102
+ if (pendingCalled)
103
+ return;
104
+ pendingCalled = true;
105
+ writeCompletedRow({
106
+ meta,
107
+ requestId: meta.localRequestId,
108
+ statusCode: 0,
109
+ responseTime: 0
110
+ });
111
+ pushNewRequest(buildSummary(meta, meta.localRequestId, 0, 0, undefined, false), 'pending');
112
+ },
113
+ appendEvent,
114
+ // 上游响应头到达:回写真实 status_code,状态仍 pending(UI 保留 spinner)
115
+ headers({ statusCode, headers }) {
116
+ getDatabase().prepare('UPDATE requests SET status_code = ?, response_headers = ? WHERE request_id = ? AND session_id = ?').run(statusCode, headers ? JSON.stringify(headers) : null, meta.localRequestId, meta.sessionId);
117
+ pushNewRequest(buildSummary(meta, meta.localRequestId, statusCode, 0, undefined, false, undefined), 'pending');
118
+ },
119
+ async complete({ cloudRequestId, statusCode, headers }) {
120
+ // Flush remaining events in batch
121
+ flushRemaining();
122
+ // Usage synthesis: prefer message_delta, otherwise convert OpenAI-style usage
123
+ let usage = extractUsage(tailBuffer);
124
+ if (!usage) {
125
+ const openaiEvent = tailBuffer.find((e) => e?.usage);
126
+ if (openaiEvent) {
127
+ appendEvent({
128
+ type: 'message_delta',
129
+ usage: {
130
+ output_tokens: openaiEvent.usage.completion_tokens || 0
131
+ }
132
+ });
133
+ usage = extractUsage(tailBuffer);
134
+ }
135
+ }
136
+ // Ensure the synthetic event (if any) is written before row replacement
137
+ flushRemaining();
138
+ const completedAt = new Date().toISOString();
139
+ const finalId = cloudRequestId ?? meta.localRequestId;
140
+ const responseTime = Date.now() - startTime;
141
+ const db = getDatabase();
142
+ if (finalId !== meta.localRequestId) {
143
+ const replace = db.transaction(() => {
144
+ db.prepare('UPDATE response_events SET request_id = ? WHERE request_id = ? AND session_id = ?').run(finalId, meta.localRequestId, meta.sessionId);
145
+ writeCompletedRow({
146
+ meta, requestId: finalId, statusCode, responseTime, headers, usage, completedAt
147
+ });
148
+ db.prepare('DELETE FROM requests WHERE request_id = ? AND session_id = ?').run(meta.localRequestId, meta.sessionId);
149
+ });
150
+ replace();
151
+ }
152
+ else {
153
+ writeCompletedRow({
154
+ meta, requestId: finalId, statusCode, responseTime, headers, usage, completedAt
155
+ });
156
+ }
157
+ pushNewRequest(buildSummary(meta, finalId, statusCode, responseTime, usage, finalId !== meta.localRequestId), 'completed');
158
+ },
159
+ // 流被截断/挂死:保留真实 status_code,通过 closed_at + error 标记中断
160
+ interrupt({ statusCode, error }) {
161
+ flushRemaining();
162
+ const responseTime = Date.now() - startTime;
163
+ const closedAt = new Date().toISOString();
164
+ getDatabase().prepare('UPDATE requests SET status_code = ?, response_time = ?, closed_at = ?, error = ? WHERE request_id = ? AND session_id = ?').run(statusCode, responseTime, closedAt, error, meta.localRequestId, meta.sessionId);
165
+ pushNewRequest(buildSummary(meta, meta.localRequestId, statusCode, responseTime, undefined, false, closedAt), 'completed');
166
+ },
167
+ fail({ statusCode, error }) {
168
+ const responseTime = Date.now() - startTime;
169
+ const closedAt = new Date().toISOString();
170
+ getDatabase().prepare('UPDATE requests SET status_code = ?, response_time = ?, closed_at = ?, error = ? WHERE request_id = ? AND session_id = ?').run(statusCode, responseTime, closedAt, error, meta.localRequestId, meta.sessionId);
171
+ pushNewRequest(buildSummary(meta, meta.localRequestId, statusCode, responseTime, undefined, false, closedAt), 'completed');
172
+ }
173
+ };
174
+ }
175
+ // Record an inject loop iteration: completed row + events + push, no pending, responseTime 0
176
+ export async function recordIteration(meta) {
177
+ initDatabase();
178
+ const events = meta.response.events ?? [];
179
+ if (events.length > 0) {
180
+ const batch = events.map((e, i) => ({
181
+ index: i,
182
+ type: e?.type,
183
+ data: e
184
+ }));
185
+ flushEventBatch(meta.sessionId, meta.localRequestId, batch, 0);
186
+ }
187
+ const usage = extractUsage(events);
188
+ const completedAt = new Date().toISOString();
189
+ writeCompletedRow({
190
+ meta,
191
+ requestId: meta.localRequestId,
192
+ statusCode: meta.response.statusCode,
193
+ responseTime: 0,
194
+ headers: meta.response.headers,
195
+ usage,
196
+ completedAt
197
+ });
198
+ pushNewRequest(buildSummary(meta, meta.localRequestId, meta.response.statusCode, 0, usage, false), 'completed');
89
199
  }
90
200
  // Load single request by compositeId (sessionId:requestId)
91
201
  export async function loadRequestDB(compositeId) {
@@ -165,7 +275,7 @@ export async function listRequestDB(limit = 1000, before) {
165
275
  SELECT
166
276
  request_id, session_id, timestamp, method, path, status_code, response_time,
167
277
  api_key, proxy_api_key, base_url, model, machine_id, user_agent,
168
- input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens
278
+ input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens, closed_at
169
279
  FROM requests
170
280
  ${whereClause}
171
281
  ORDER BY timestamp DESC
@@ -194,7 +304,8 @@ export async function listRequestDB(limit = 1000, before) {
194
304
  output_tokens: row.output_tokens,
195
305
  cache_read_input_tokens: row.cache_read_tokens,
196
306
  cache_creation_input_tokens: row.cache_creation_tokens
197
- } : undefined
307
+ } : undefined,
308
+ closedAt: row.closed_at || undefined
198
309
  })),
199
310
  hasMore
200
311
  };
@@ -212,13 +323,22 @@ export async function cleanOldRequestsDB(daysToKeep = 7) {
212
323
  db.prepare(`DELETE FROM response_events WHERE request_id IN (SELECT request_id FROM requests WHERE timestamp < ?)`).run(cutoff);
213
324
  db.prepare(`DELETE FROM requests WHERE timestamp < ?`).run(cutoff);
214
325
  }
215
- // Check if a sessionId exists in the database
216
- export function sessionIdExists(sessionId) {
326
+ // 启动时回收上次进程遗留的僵尸 SSE 行:未完成、未关闭且超龄,逐行标记为中断
327
+ // (status_code 保持原值不动),返回处理行数
328
+ export function interruptStaleRequestsOnStartup(maxAgeMs = 5 * 60000) {
217
329
  const db = initDatabase();
218
- const row = db.prepare(`
219
- SELECT 1 FROM requests WHERE session_id = ? LIMIT 1
220
- `).get(sessionId);
221
- return !!row;
330
+ const cutoff = new Date(Date.now() - maxAgeMs).toISOString();
331
+ const rows = db.prepare(`
332
+ SELECT request_id, session_id
333
+ FROM requests
334
+ WHERE completed_at IS NULL AND closed_at IS NULL AND timestamp < ?
335
+ `).all(cutoff);
336
+ const closedAt = new Date().toISOString();
337
+ const stmt = db.prepare('UPDATE requests SET closed_at = ?, error = ? WHERE request_id = ? AND session_id = ?');
338
+ for (const row of rows) {
339
+ stmt.run(closedAt, 'interrupted: proxy restarted', row.request_id, row.session_id);
340
+ }
341
+ return rows.length;
222
342
  }
223
343
  // Load session history for multi-turn chat resume
224
344
  // Returns the last request's messages + assistant response, to prepend to new messages
@@ -0,0 +1,34 @@
1
+ /**
2
+ * SSE 帧协议:字节流 ↔ SSE 帧 的唯一知识收敛点。
3
+ *
4
+ * - SSE 帧(frame):字节流按 SSE 规范切分出的单位,由若干字段行
5
+ * (event: / data: / id: / 注释 / 空行分发)组成。
6
+ * - SSE 事件(event):SSE 帧的 data 字段解析出的 JSON 消息。
7
+ *
8
+ * 解析遵循 HTML spec 的 event stream 语义:残帧缓冲、LF/CRLF/CR 行尾、
9
+ * 空行分发、字段行去掉恰好一个可选空格。
10
+ */
11
+ export interface SSEFrame {
12
+ event?: string;
13
+ data: string[];
14
+ id?: string;
15
+ }
16
+ export interface SSEDecoder {
17
+ write(chunk: Buffer | string): void;
18
+ end(): void;
19
+ }
20
+ /** 创建 SSE 帧解码器:每分发一个完整 SSE 帧回调一次 */
21
+ export declare function createSSEDecoder(onFrame: (frame: SSEFrame) => void): SSEDecoder;
22
+ /**
23
+ * 编码单个 SSE 帧。data 为已序列化好的字符串(调用方负责 JSON.stringify)。
24
+ * 有 event:`event: <event>\ndata: <data>\n\n`;无 event:`data: <data>\n\n`。
25
+ */
26
+ export declare function encodeSSEFrame(args: {
27
+ event?: string;
28
+ data: string;
29
+ }): string;
30
+ /**
31
+ * 创建 SSE 事件解码器:帧 data 用 \n join 后,[DONE] 触发 onDone,
32
+ * 其余尝试 JSON.parse 成功后触发 onEvent,解析失败静默跳过。
33
+ */
34
+ export declare function createEventDecoder(onEvent: (event: any) => void, onDone?: () => void): SSEDecoder;
@@ -0,0 +1,121 @@
1
+ /**
2
+ * SSE 帧协议:字节流 ↔ SSE 帧 的唯一知识收敛点。
3
+ *
4
+ * - SSE 帧(frame):字节流按 SSE 规范切分出的单位,由若干字段行
5
+ * (event: / data: / id: / 注释 / 空行分发)组成。
6
+ * - SSE 事件(event):SSE 帧的 data 字段解析出的 JSON 消息。
7
+ *
8
+ * 解析遵循 HTML spec 的 event stream 语义:残帧缓冲、LF/CRLF/CR 行尾、
9
+ * 空行分发、字段行去掉恰好一个可选空格。
10
+ */
11
+ /** 创建 SSE 帧解码器:每分发一个完整 SSE 帧回调一次 */
12
+ export function createSSEDecoder(onFrame) {
13
+ // 残帧缓冲:跨 chunk 的不完整行
14
+ let leftover = '';
15
+ let event;
16
+ let data = [];
17
+ let id;
18
+ /** 分发当前帧:至少含一个 data 行才回调;分发后重置字段状态 */
19
+ function dispatch() {
20
+ if (data.length > 0) {
21
+ onFrame({ event, data, id });
22
+ }
23
+ event = undefined;
24
+ id = undefined;
25
+ data = [];
26
+ }
27
+ /** 处理一个完整行 */
28
+ function handleLine(line) {
29
+ // 空行 = 一帧分发
30
+ if (line === '') {
31
+ dispatch();
32
+ return;
33
+ }
34
+ // 以冒号开头的行是注释,忽略
35
+ if (line.startsWith(':'))
36
+ return;
37
+ let field;
38
+ let value;
39
+ const colon = line.indexOf(':');
40
+ if (colon === -1) {
41
+ field = line;
42
+ value = '';
43
+ }
44
+ else {
45
+ field = line.slice(0, colon);
46
+ value = line.slice(colon + 1);
47
+ // 去掉字段值行首恰好一个可选空格
48
+ if (value.startsWith(' '))
49
+ value = value.slice(1);
50
+ }
51
+ if (field === 'event') {
52
+ event = value;
53
+ }
54
+ else if (field === 'data') {
55
+ // 多行 data 逐行保留,消费时用 \n join
56
+ data.push(value);
57
+ }
58
+ else if (field === 'id') {
59
+ id = value;
60
+ }
61
+ }
62
+ /** 消费文本中所有完整行,末段保留为残帧 */
63
+ function feed(text) {
64
+ // CRLF 与单独 CR 统一为 LF
65
+ const normalized = text.replace(/\r\n?/g, '\n');
66
+ const lines = normalized.split('\n');
67
+ leftover = lines.pop() || '';
68
+ for (const line of lines)
69
+ handleLine(line);
70
+ }
71
+ return {
72
+ write(chunk) {
73
+ const chunkText = typeof chunk === 'string' ? chunk : chunk.toString('utf-8');
74
+ feed(leftover + chunkText);
75
+ },
76
+ end() {
77
+ // 先按残帧缓冲补一次切行
78
+ if (leftover !== '') {
79
+ const normalized = leftover.replace(/\r\n?/g, '\n');
80
+ leftover = '';
81
+ for (const line of normalized.split('\n'))
82
+ handleLine(line);
83
+ }
84
+ // 再对缓冲中尚未分发的非空帧做一次分发(末尾无空行也能输出最后一帧)
85
+ if (data.length > 0)
86
+ dispatch();
87
+ // 清空状态
88
+ leftover = '';
89
+ event = undefined;
90
+ id = undefined;
91
+ data = [];
92
+ }
93
+ };
94
+ }
95
+ /**
96
+ * 编码单个 SSE 帧。data 为已序列化好的字符串(调用方负责 JSON.stringify)。
97
+ * 有 event:`event: <event>\ndata: <data>\n\n`;无 event:`data: <data>\n\n`。
98
+ */
99
+ export function encodeSSEFrame(args) {
100
+ const prefix = args.event !== undefined ? `event: ${args.event}\n` : '';
101
+ return `${prefix}data: ${args.data}\n\n`;
102
+ }
103
+ /**
104
+ * 创建 SSE 事件解码器:帧 data 用 \n join 后,[DONE] 触发 onDone,
105
+ * 其余尝试 JSON.parse 成功后触发 onEvent,解析失败静默跳过。
106
+ */
107
+ export function createEventDecoder(onEvent, onDone) {
108
+ return createSSEDecoder((frame) => {
109
+ const text = frame.data.join('\n');
110
+ if (text.trim() === '[DONE]') {
111
+ onDone?.();
112
+ return;
113
+ }
114
+ try {
115
+ onEvent(JSON.parse(text));
116
+ }
117
+ catch {
118
+ // 非 JSON data 静默跳过
119
+ }
120
+ });
121
+ }
@@ -4,23 +4,18 @@ import { type ParsedUpstream } from './inject-loop.js';
4
4
  * SSE 增量流式处理器:边转发原始 chunk 到客户端,边增量解析事件累积状态。
5
5
  * stream end 后提供 getParsedUpstream() 和 hasInjectedToolUse() 供注入检测。
6
6
  *
7
- * 跨 chunk 行边界通过 leftover 缓冲处理(参考 SSEAccumulator)。
7
+ * 跨 chunk 残帧由内部 sse-protocol decoder 缓冲处理。
8
8
  */
9
9
  export declare class SSEStreamProcessor {
10
10
  events: any[];
11
- private contentBlocks;
12
- private stopReason;
13
- private usage;
14
- private leftover;
11
+ private decoder;
15
12
  private raw;
16
13
  constructor(raw: ServerResponse);
17
14
  /** 处理一个 chunk:转发到 reply.raw + 增量解析事件 */
18
15
  processChunk(chunk: Buffer): void;
19
- /** 处理 leftover 中残留的最后一行(stream end 后调用) */
16
+ /** 收尾残帧(stream end 后调用) */
20
17
  flushLeftover(): void;
21
- /** 增量解析单个事件,更新 contentBlocks / stopReason / usage */
22
- private processEvent;
23
- /** 从累积状态构建 ParsedUpstream */
18
+ /** 从累积事件构建 ParsedUpstream */
24
19
  getParsedUpstream(): ParsedUpstream;
25
20
  /** 检测是否有注入的 MCP tool_use */
26
21
  hasInjectedToolUse(): boolean;
@@ -1,9 +1,10 @@
1
- import { findInjectedCall } from './inject-loop.js';
1
+ import { findInjectedCall, parseUpstreamEvents } from './inject-loop.js';
2
+ import { createEventDecoder } from './sse-protocol.js';
2
3
  /**
3
4
  * SSE 增量流式处理器:边转发原始 chunk 到客户端,边增量解析事件累积状态。
4
5
  * stream end 后提供 getParsedUpstream() 和 hasInjectedToolUse() 供注入检测。
5
6
  *
6
- * 跨 chunk 行边界通过 leftover 缓冲处理(参考 SSEAccumulator)。
7
+ * 跨 chunk 残帧由内部 sse-protocol decoder 缓冲处理。
7
8
  */
8
9
  export class SSEStreamProcessor {
9
10
  constructor(raw) {
@@ -13,29 +14,11 @@ export class SSEStreamProcessor {
13
14
  writable: true,
14
15
  value: []
15
16
  });
16
- Object.defineProperty(this, "contentBlocks", {
17
+ Object.defineProperty(this, "decoder", {
17
18
  enumerable: true,
18
19
  configurable: true,
19
20
  writable: true,
20
- value: new Map()
21
- });
22
- Object.defineProperty(this, "stopReason", {
23
- enumerable: true,
24
- configurable: true,
25
- writable: true,
26
- value: ''
27
- });
28
- Object.defineProperty(this, "usage", {
29
- enumerable: true,
30
- configurable: true,
31
- writable: true,
32
- value: undefined
33
- });
34
- Object.defineProperty(this, "leftover", {
35
- enumerable: true,
36
- configurable: true,
37
- writable: true,
38
- value: ''
21
+ value: void 0
39
22
  });
40
23
  Object.defineProperty(this, "raw", {
41
24
  enumerable: true,
@@ -44,101 +27,27 @@ export class SSEStreamProcessor {
44
27
  value: void 0
45
28
  });
46
29
  this.raw = raw;
30
+ this.decoder = createEventDecoder((event) => this.events.push(event));
47
31
  }
48
32
  /** 处理一个 chunk:转发到 reply.raw + 增量解析事件 */
49
33
  processChunk(chunk) {
50
34
  // 转发原始 chunk 到客户端
51
35
  this.raw.write(chunk);
52
- const text = this.leftover + chunk.toString('utf-8');
53
- const lines = text.split('\n');
54
- // 最后一行可能不完整,保留到下次
55
- this.leftover = lines.pop() || '';
56
- for (const line of lines) {
57
- if (line.startsWith('data:')) {
58
- const d = line.slice(5).trim();
59
- if (!d || d === '[DONE]')
60
- continue;
61
- try {
62
- const event = JSON.parse(d);
63
- this.events.push(event);
64
- this.processEvent(event);
65
- }
66
- catch {
67
- // 非 JSON 行跳过
68
- }
69
- }
70
- }
36
+ this.decoder.write(chunk);
71
37
  }
72
- /** 处理 leftover 中残留的最后一行(stream end 后调用) */
38
+ /** 收尾残帧(stream end 后调用) */
73
39
  flushLeftover() {
74
- if (this.leftover.startsWith('data:')) {
75
- const d = this.leftover.slice(5).trim();
76
- if (d && d !== '[DONE]') {
77
- try {
78
- const event = JSON.parse(d);
79
- this.events.push(event);
80
- this.processEvent(event);
81
- }
82
- catch {
83
- // skip
84
- }
85
- }
86
- }
87
- this.leftover = '';
40
+ this.decoder.end();
88
41
  }
89
- /** 增量解析单个事件,更新 contentBlocks / stopReason / usage */
90
- processEvent(e) {
91
- if (e?.type === 'content_block_start') {
92
- const cb = e.content_block || {};
93
- this.contentBlocks.set(e.index, {
94
- type: cb.type,
95
- text: cb.type === 'text' ? '' : undefined,
96
- id: cb.id,
97
- name: cb.name,
98
- input: cb.type === 'tool_use' ? '' : undefined
99
- });
100
- }
101
- else if (e?.type === 'content_block_delta') {
102
- const b = this.contentBlocks.get(e.index);
103
- if (!b)
104
- return;
105
- const d = e.delta || {};
106
- if (d.type === 'text_delta')
107
- b.text = (b.text || '') + d.text;
108
- if (d.type === 'thinking_delta')
109
- b.text = (b.text || '') + d.thinking;
110
- if (d.type === 'input_json_delta')
111
- b.input = (b.input || '') + (d.partial_json || '');
112
- }
113
- else if (e?.type === 'message_delta') {
114
- this.stopReason = e.delta?.stop_reason || this.stopReason;
115
- this.usage = e.usage;
116
- }
117
- }
118
- /** 从累积状态构建 ParsedUpstream */
42
+ /** 从累积事件构建 ParsedUpstream */
119
43
  getParsedUpstream() {
120
- const ordered = Array.from(this.contentBlocks.entries())
121
- .sort((a, b) => a[0] - b[0])
122
- .map(([, b]) => {
123
- if (b.type === 'tool_use') {
124
- let input = {};
125
- try {
126
- input = b.input ? JSON.parse(b.input) : {};
127
- }
128
- catch {
129
- input = {};
130
- }
131
- return { ...b, input };
132
- }
133
- return b;
134
- });
135
- return { blocks: ordered, stopReason: this.stopReason, usage: this.usage };
44
+ return parseUpstreamEvents(this.events);
136
45
  }
137
46
  /** 检测是否有注入的 MCP tool_use */
138
47
  hasInjectedToolUse() {
139
- if (this.stopReason !== 'tool_use')
140
- return false;
141
48
  const parsed = this.getParsedUpstream();
49
+ if (parsed.stopReason !== 'tool_use')
50
+ return false;
142
51
  return !!findInjectedCall(parsed);
143
52
  }
144
53
  }
@@ -1,6 +1,6 @@
1
1
  import type { ServerResponse } from 'http';
2
2
  /**
3
- * SSE 构造器(后端)—— 与 sse-accumulator(解析器)互为逆向。
3
+ * SSE 构造器(后端)—— 与 sse-protocol(帧解析器)互为逆向。
4
4
  *
5
5
  * 用于 proxy 主动构造并回写合成 SSE 流,让 Claude Code 客户端
6
6
  * 将其识别为一次正常的模型文本回答。事件骨架遵循 Anthropic
@@ -1,5 +1,6 @@
1
+ import { encodeSSEFrame } from './sse-protocol.js';
1
2
  /**
2
- * SSE 构造器(后端)—— 与 sse-accumulator(解析器)互为逆向。
3
+ * SSE 构造器(后端)—— 与 sse-protocol(帧解析器)互为逆向。
3
4
  *
4
5
  * 用于 proxy 主动构造并回写合成 SSE 流,让 Claude Code 客户端
5
6
  * 将其识别为一次正常的模型文本回答。事件骨架遵循 Anthropic
@@ -7,7 +8,7 @@
7
8
  */
8
9
  /** 写单个 SSE 事件:`event: <type>\ndata: {json}\n\n`(Anthropic 双行格式) */
9
10
  export function writeSSEEvent(raw, event) {
10
- raw.write(`event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`);
11
+ raw.write(encodeSSEFrame({ event: event.type, data: JSON.stringify(event) }));
11
12
  }
12
13
  /**
13
14
  * 把一段文本伪装成模型的正常 text 输出,构造完整合成流写回。