@cc-monitoring/proxy-core 0.3.1 → 0.4.1

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 (409) hide show
  1. package/dist/cli/__tests__/commands.test.js +20 -1
  2. package/dist/cli/commands/exec.js +31 -42
  3. package/dist/cli/commands/repair.d.ts +1 -0
  4. package/dist/cli/commands/repair.js +15 -0
  5. package/dist/cli/index.js +30 -0
  6. package/dist/docs/404.html +2 -2
  7. package/dist/docs/assets/{app.B9A39uFv.js → app.g7N9jkzn.js} +1 -1
  8. package/dist/docs/assets/chunks/@localSearchIndexroot.IHxQqfJH.js +1 -0
  9. package/dist/docs/assets/chunks/{VPLocalSearchBox.DdhC696L.js → VPLocalSearchBox.BHwI475_.js} +1 -1
  10. package/dist/docs/assets/chunks/{theme.CfB2tOFi.js → theme.FhAJSNDh.js} +2 -2
  11. package/dist/docs/assets/{proxy-cli_data-hooks.md.w9Oe1OD3.js → proxy-cli_data-hooks.md.Bz8CVbxO.js} +1 -1
  12. package/dist/docs/assets/{proxy-core_ui-routes.md.Dyqkeoiv.js → proxy-core_ui-routes.md.B21t1p7R.js} +1 -1
  13. package/dist/docs/hashmap.json +1 -1
  14. package/dist/docs/index.html +3 -3
  15. package/dist/docs/overview.html +3 -3
  16. package/dist/docs/packages-utils.html +3 -3
  17. package/dist/docs/proxy-admin/env-and-build.html +3 -3
  18. package/dist/docs/proxy-admin/index.html +3 -3
  19. package/dist/docs/proxy-admin/layout-and-menu.html +3 -3
  20. package/dist/docs/proxy-admin/pages.html +3 -3
  21. package/dist/docs/proxy-admin/routing-and-auth.html +3 -3
  22. package/dist/docs/proxy-admin/services-and-mock.html +3 -3
  23. package/dist/docs/proxy-cli/api-layer.html +3 -3
  24. package/dist/docs/proxy-cli/app-shell.html +3 -3
  25. package/dist/docs/proxy-cli/components-common.html +3 -3
  26. package/dist/docs/proxy-cli/components-config.html +3 -3
  27. package/dist/docs/proxy-cli/components-requests.html +3 -3
  28. package/dist/docs/proxy-cli/components-stats.html +3 -3
  29. package/dist/docs/proxy-cli/components-status.html +3 -3
  30. package/dist/docs/proxy-cli/data-hooks.html +5 -5
  31. package/dist/docs/proxy-cli/index.html +3 -3
  32. package/dist/docs/proxy-cli/utils-and-i18n.html +3 -3
  33. package/dist/docs/proxy-core/chat-api.html +3 -3
  34. package/dist/docs/proxy-core/cli.html +3 -3
  35. package/dist/docs/proxy-core/config.html +3 -3
  36. package/dist/docs/proxy-core/data-layer.html +3 -3
  37. package/dist/docs/proxy-core/entry.html +3 -3
  38. package/dist/docs/proxy-core/index.html +3 -3
  39. package/dist/docs/proxy-core/pm2.html +3 -3
  40. package/dist/docs/proxy-core/providers.html +3 -3
  41. package/dist/docs/proxy-core/proxy.html +3 -3
  42. package/dist/docs/proxy-core/stats.html +3 -3
  43. package/dist/docs/proxy-core/tool.html +3 -3
  44. package/dist/docs/proxy-core/ui-routes.html +5 -5
  45. package/dist/docs/proxy-core/utilities.html +3 -3
  46. package/dist/docs/quickstart.html +3 -3
  47. package/dist/docs/request-flow.html +3 -3
  48. package/dist/logger/index.d.ts +0 -3
  49. package/dist/logger/index.js +0 -1
  50. package/dist/mcp-server/tools.js +8 -9
  51. package/dist/server/__tests__/data-push.test.js +44 -0
  52. package/dist/server/__tests__/providers-route.test.js +1 -0
  53. package/dist/server/__tests__/proxy.test.js +281 -2
  54. package/dist/server/__tests__/server.test.js +15 -10
  55. package/dist/server/__tests__/ui-route.test.js +43 -0
  56. package/dist/server/auth.d.ts +0 -1
  57. package/dist/server/auth.js +1 -1
  58. package/dist/server/chat-route.js +48 -162
  59. package/dist/server/data-push.d.ts +2 -1
  60. package/dist/server/data-push.js +22 -7
  61. package/dist/server/index.js +4 -3
  62. package/dist/server/proxy.js +193 -229
  63. package/dist/server/ui-route.js +84 -60
  64. package/dist/tools/index.d.ts +1 -1
  65. package/dist/tools/index.js +1 -1
  66. package/dist/tools/registry.d.ts +0 -4
  67. package/dist/tools/registry.js +0 -8
  68. package/dist/types/config.d.ts +0 -13
  69. package/dist/types/pm2.d.ts +1 -2
  70. package/dist/ui/assets/{1c-DAu68mP4.js → 1c-CaPSZBmB.js} +1 -1
  71. package/dist/ui/assets/{abnf-Cu8RHCHK.js → abnf-DBDOsmne.js} +1 -1
  72. package/dist/ui/assets/{abnfDiagram-VRR7QNED-BUBToPXF.js → abnfDiagram-VRR7QNED-D8zK__Mj.js} +1 -1
  73. package/dist/ui/assets/{accesslog-BG-34XOy.js → accesslog-BOLs2Kig.js} +1 -1
  74. package/dist/ui/assets/{actionscript-iw0HHMGM.js → actionscript-BZYKhS1B.js} +1 -1
  75. package/dist/ui/assets/{ada-qRqj6VGQ.js → ada-DyacnMpg.js} +1 -1
  76. package/dist/ui/assets/{angelscript-BeaXyx_P.js → angelscript-CAN6j0H3.js} +1 -1
  77. package/dist/ui/assets/{apache-CU8d-z9X.js → apache-BE4vouiQ.js} +1 -1
  78. package/dist/ui/assets/{applescript-d1Wxkqz1.js → applescript-CS88I1yz.js} +1 -1
  79. package/dist/ui/assets/{arc-BMsPIm3j.js → arc-CTMmdrSV.js} +1 -1
  80. package/dist/ui/assets/{arcade-CtbgrWTM.js → arcade-B0f0f5SD.js} +1 -1
  81. package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-CVjC5TrS.js → architectureDiagram-ZJ3FMSHR-Dtvpnopp.js} +1 -1
  82. package/dist/ui/assets/{arduino-Bc9L39Hr.js → arduino-Bhm-OSb2.js} +1 -1
  83. package/dist/ui/assets/{armasm-DuWmpjWR.js → armasm-CEy-mDHc.js} +1 -1
  84. package/dist/ui/assets/{asciidoc-CDIhFTnx.js → asciidoc-CrZqQBTj.js} +1 -1
  85. package/dist/ui/assets/{aspectj-SYj-57Es.js → aspectj-B4IlFyyJ.js} +1 -1
  86. package/dist/ui/assets/{autohotkey-hBi5dq37.js → autohotkey-Cihy-FjA.js} +1 -1
  87. package/dist/ui/assets/{autoit-BSawXzhg.js → autoit-Dis_JVJq.js} +1 -1
  88. package/dist/ui/assets/{avrasm-CwYom8Np.js → avrasm-CVhMycHj.js} +1 -1
  89. package/dist/ui/assets/{awk-BvBRfGo2.js → awk-BCViwLf5.js} +1 -1
  90. package/dist/ui/assets/{axapta-CqUavA8k.js → axapta-pWB4JVB_.js} +1 -1
  91. package/dist/ui/assets/{bash-BS_ZnmEu.js → bash-B6Giryub.js} +1 -1
  92. package/dist/ui/assets/{basic-xbP4IXrN.js → basic-DcrjcHB0.js} +1 -1
  93. package/dist/ui/assets/{blockDiagram-677ZJIJ3-CmpI3f5p.js → blockDiagram-677ZJIJ3-DfhtgI1r.js} +1 -1
  94. package/dist/ui/assets/{bnf-BECwu6uW.js → bnf-cpKU0967.js} +1 -1
  95. package/dist/ui/assets/{brainfuck-QQgu4j4N.js → brainfuck-CFFdk4cM.js} +1 -1
  96. package/dist/ui/assets/{coq-IDMIFfem.js → c-CW6KPMeI.js} +1 -1
  97. package/dist/ui/assets/{c-like-DYrFOtXy.js → c-like-CWn59vrg.js} +1 -1
  98. package/dist/ui/assets/{c4Diagram-LMCZKHZV-B6Hgngz9.js → c4Diagram-LMCZKHZV-D1Oh6k37.js} +1 -1
  99. package/dist/ui/assets/{cal-CNMrJ6v5.js → cal-8i26_L39.js} +1 -1
  100. package/dist/ui/assets/{capnproto-DYCKl6oY.js → capnproto-CviwnFBf.js} +1 -1
  101. package/dist/ui/assets/{ceylon-mb8tRPl0.js → ceylon-CQyc4rWs.js} +1 -1
  102. package/dist/ui/assets/channel-Da2MvpNG.js +1 -0
  103. package/dist/ui/assets/{chunk-2Q5K7J3B-LxvQ-G67.js → chunk-2Q5K7J3B-oswPBwIn.js} +1 -1
  104. package/dist/ui/assets/{chunk-32BRIVSS-DxzKK6Aw.js → chunk-32BRIVSS-B5pU_9b9.js} +1 -1
  105. package/dist/ui/assets/{chunk-5VM5RSS4-CZEoYJ2W.js → chunk-5VM5RSS4-gvtfMc4w.js} +1 -1
  106. package/dist/ui/assets/{chunk-EX3LRPZG-DS2PytrN.js → chunk-EX3LRPZG-BkBaDMy4.js} +1 -1
  107. package/dist/ui/assets/{chunk-JWPE2WC7-UX0Sr1Ie.js → chunk-JWPE2WC7-Ch-C75ar.js} +1 -1
  108. package/dist/ui/assets/{chunk-MOJQB5TN-YbJgT9t4.js → chunk-MOJQB5TN-BfYhj1jN.js} +1 -1
  109. package/dist/ui/assets/{chunk-RYQCIY6F-DS2VH_U9.js → chunk-RYQCIY6F-D8izfruP.js} +1 -1
  110. package/dist/ui/assets/{chunk-V7JOEXUC-CZr0pkI1.js → chunk-V7JOEXUC-CbzHnW90.js} +1 -1
  111. package/dist/ui/assets/{chunk-VR4S4FIN-50opPAD3.js → chunk-VR4S4FIN-Dr4M5qZA.js} +1 -1
  112. package/dist/ui/assets/{chunk-XXDRQBXY-DAAX9l7U.js → chunk-XXDRQBXY-QE-R8dRe.js} +1 -1
  113. package/dist/ui/assets/classDiagram-OUVF2IWQ-mHUiWjcC.js +1 -0
  114. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-mHUiWjcC.js +1 -0
  115. package/dist/ui/assets/{clean-C4X7dSkh.js → clean-DZeAtQ7H.js} +1 -1
  116. package/dist/ui/assets/{clojure-DSg9gUa7.js → clojure-U4ebZ7NQ.js} +1 -1
  117. package/dist/ui/assets/{clojure-repl-CagRYx7h.js → clojure-repl-B4QSIzUI.js} +1 -1
  118. package/dist/ui/assets/{cmake-CFdBn53c.js → cmake-UHexZySb.js} +1 -1
  119. package/dist/ui/assets/{coffeescript-CJZtMOPx.js → coffeescript-Dg56H9Mr.js} +1 -1
  120. package/dist/ui/assets/{c-BRJEPYra.js → coq-C1g3mm0X.js} +1 -1
  121. package/dist/ui/assets/{cos-Bx2VJuzG.js → cos-BL4DdyGh.js} +1 -1
  122. package/dist/ui/assets/{cose-bilkent-JH36ORCC-zWRLsZpZ.js → cose-bilkent-JH36ORCC-BHQslHP3.js} +1 -1
  123. package/dist/ui/assets/{cpp-CsG6DlC4.js → cpp-keZI-XAd.js} +1 -1
  124. package/dist/ui/assets/{crmsh-DTy9MnmJ.js → crmsh-DdXYVeeA.js} +1 -1
  125. package/dist/ui/assets/{crystal-BwgrLrZ1.js → crystal-C4AN0m0I.js} +1 -1
  126. package/dist/ui/assets/{csharp-B2VeTPAF.js → csharp-COUyKsNR.js} +1 -1
  127. package/dist/ui/assets/{csp-CTpydNhH.js → csp-DBc-rgSJ.js} +1 -1
  128. package/dist/ui/assets/{css-B0mMUbpY.js → css-B8m6O_Pw.js} +1 -1
  129. package/dist/ui/assets/{cynefin-VYW2F7L2-BmjQEj6q.js → cynefin-VYW2F7L2-B3L-WcKn.js} +1 -1
  130. package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-Dr0Zrke0.js → cynefinDiagram-TSTJHNR4-fzaM4qcZ.js} +1 -1
  131. package/dist/ui/assets/{d-DjuDZnbI.js → d-dgQN4Rko.js} +1 -1
  132. package/dist/ui/assets/{dagre-VKFMJZFB-xoTPT2Uu.js → dagre-VKFMJZFB-DJHj16mR.js} +1 -1
  133. package/dist/ui/assets/{dart-xR3GU9TJ.js → dart-D2Y7LOq-.js} +1 -1
  134. package/dist/ui/assets/{delphi-bJas5QnG.js → delphi-DaGcSk5A.js} +1 -1
  135. package/dist/ui/assets/{diagram-FQU43EPY-rL_IU7gU.js → diagram-FQU43EPY-iZEZ1f-R.js} +1 -1
  136. package/dist/ui/assets/{diagram-G47NLZAW-EcDiCVGj.js → diagram-G47NLZAW-rkQb3r-C.js} +1 -1
  137. package/dist/ui/assets/{diagram-NH7WQ7WH-CGGXOjev.js → diagram-NH7WQ7WH-B4Fy72tP.js} +1 -1
  138. package/dist/ui/assets/{diagram-OA4YK3LP-DnE7hDjD.js → diagram-OA4YK3LP-BndmuIBq.js} +1 -1
  139. package/dist/ui/assets/{diagram-WEI45ONY-CTJH5eD8.js → diagram-WEI45ONY-CwlAiqOe.js} +1 -1
  140. package/dist/ui/assets/{diff-doJFF3fv.js → diff-prcRV1Y3.js} +1 -1
  141. package/dist/ui/assets/{django-D3b-owa_.js → django-B1zIoGSx.js} +1 -1
  142. package/dist/ui/assets/{dns-C42KYV-Z.js → dns-ZxI_aTwc.js} +1 -1
  143. package/dist/ui/assets/{dockerfile-9KUINc2j.js → dockerfile-Dp_fT6E-.js} +1 -1
  144. package/dist/ui/assets/{dos-CxnlJ6qp.js → dos-Cuu5c8vv.js} +1 -1
  145. package/dist/ui/assets/{dsconfig-6CMMCwmY.js → dsconfig-DcGTOhbS.js} +1 -1
  146. package/dist/ui/assets/{dts-D78rdUIB.js → dts-DCF8VaRk.js} +1 -1
  147. package/dist/ui/assets/{dust-Dv1uTfJU.js → dust-DeCmZWMK.js} +1 -1
  148. package/dist/ui/assets/{ebnf-BGbG1cFK.js → ebnf-BHQQcuF_.js} +1 -1
  149. package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-z2VgRSUV.js → ebnfDiagram-CCIWWBDH-DJ_RuhTm.js} +1 -1
  150. package/dist/ui/assets/{elixir-ZgAQVY1J.js → elixir-BHmweJ4d.js} +1 -1
  151. package/dist/ui/assets/{elm-CudiFuNu.js → elm-v76Hd2B3.js} +1 -1
  152. package/dist/ui/assets/{erDiagram-Q63AITRT-X1TODuRv.js → erDiagram-Q63AITRT-DVZkY5RZ.js} +1 -1
  153. package/dist/ui/assets/{erb-Bz_NZh6W.js → erb-xvWF5bfx.js} +1 -1
  154. package/dist/ui/assets/{erlang-DNuj1nb2.js → erlang-CKBMURym.js} +1 -1
  155. package/dist/ui/assets/{erlang-repl-SP1Gan9W.js → erlang-repl-BjcfXt3Z.js} +1 -1
  156. package/dist/ui/assets/{excel-0K77uECF.js → excel-Cdrtxhml.js} +1 -1
  157. package/dist/ui/assets/{fix-CalJq7JD.js → fix-CB-So5So.js} +1 -1
  158. package/dist/ui/assets/{flix-BlIs11_w.js → flix-VM9AOrq6.js} +1 -1
  159. package/dist/ui/assets/{flowDiagram-23GEKE2U-DA2dnmc0.js → flowDiagram-23GEKE2U-vyGW67Xm.js} +1 -1
  160. package/dist/ui/assets/{fortran-ZCobXY2R.js → fortran-CcwJVO8H.js} +1 -1
  161. package/dist/ui/assets/{fsharp-Be8rwUtc.js → fsharp-DiATpw1u.js} +1 -1
  162. package/dist/ui/assets/{gams-DUat8frQ.js → gams-Csg9YNPz.js} +1 -1
  163. package/dist/ui/assets/{ganttDiagram-NO4QXBWP-DdFwaIGZ.js → ganttDiagram-NO4QXBWP-C2TRbwLw.js} +1 -1
  164. package/dist/ui/assets/{gauss-BB4U88dy.js → gauss-Bc4TC8Wh.js} +1 -1
  165. package/dist/ui/assets/{gcode-DzeUZuZg.js → gcode-Rig_2OoA.js} +1 -1
  166. package/dist/ui/assets/{gherkin-B_8vW_BO.js → gherkin-ByBU06QB.js} +1 -1
  167. package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-B-Dn8x6I.js → gitGraphDiagram-IHSO6WYX-CEiqfFIF.js} +1 -1
  168. package/dist/ui/assets/{glsl-DGHGjPC1.js → glsl-C8D6y2Tn.js} +1 -1
  169. package/dist/ui/assets/{gml-BYEku8Yh.js → gml-PHpGPHbT.js} +1 -1
  170. package/dist/ui/assets/{go-D8aSgQMc.js → go-BL_o_3ez.js} +1 -1
  171. package/dist/ui/assets/{golo-CDjCU_jh.js → golo-CWQ6dTUz.js} +1 -1
  172. package/dist/ui/assets/{gradle-BeUw7tl_.js → gradle-Y_I2KN2z.js} +1 -1
  173. package/dist/ui/assets/{groovy-5iCQOtR3.js → groovy-JnIv8p2l.js} +1 -1
  174. package/dist/ui/assets/{haml-BEdL8FJi.js → haml-B8W_h6mZ.js} +1 -1
  175. package/dist/ui/assets/{handlebars-BuYQNzoK.js → handlebars-DVm8mJuD.js} +1 -1
  176. package/dist/ui/assets/{haskell-I4FCBcW0.js → haskell-DlDi2Ty7.js} +1 -1
  177. package/dist/ui/assets/{haxe-yigyKfFr.js → haxe-CftFNVE-.js} +1 -1
  178. package/dist/ui/assets/{hsp-ZUk4j7d1.js → hsp-C67xnq9C.js} +1 -1
  179. package/dist/ui/assets/{htmlbars-QYP3lT3u.js → htmlbars-CmJCm67U.js} +1 -1
  180. package/dist/ui/assets/{http-BJpD1O71.js → http-b-FPEcHP.js} +1 -1
  181. package/dist/ui/assets/{hy-CIJ1bP6S.js → hy-BWD3ncpN.js} +1 -1
  182. package/dist/ui/assets/{index-COAgrx1J.js → index-C7s1zgJb.js} +242 -242
  183. package/dist/ui/assets/{index-BDXWttnT.js → index-D2UBwfSG.js} +3 -3
  184. package/dist/ui/assets/index-DlsVXaHT.css +10 -0
  185. package/dist/ui/assets/{infoDiagram-FWYZ7A6U-fTg9eLNt.js → infoDiagram-FWYZ7A6U-C0Px17IN.js} +1 -1
  186. package/dist/ui/assets/{inform7-DAsu-lC2.js → inform7-C-OYaMO5.js} +1 -1
  187. package/dist/ui/assets/{ini-Bhz-zHCg.js → ini-CVyYmykw.js} +1 -1
  188. package/dist/ui/assets/{irpf90-BunhbwBl.js → irpf90-BcpjWXIz.js} +1 -1
  189. package/dist/ui/assets/{isbl-q9L6hOhP.js → isbl-ZraBBeEr.js} +1 -1
  190. package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-B8G0sdgd.js → ishikawaDiagram-FXEZZL3T-BjmTMgpO.js} +1 -1
  191. package/dist/ui/assets/{java-Iks5Pkau.js → java-D_mE2DT6.js} +1 -1
  192. package/dist/ui/assets/{javascript-C4vltXPw.js → javascript-akXESsox.js} +1 -1
  193. package/dist/ui/assets/{jboss-cli-BQBvd2X2.js → jboss-cli-CFe3gTDt.js} +1 -1
  194. package/dist/ui/assets/{journeyDiagram-5HDEW3XC-Crbzgrum.js → journeyDiagram-5HDEW3XC-BpgJUvs6.js} +1 -1
  195. package/dist/ui/assets/{json-DXK0_jUK.js → json-sjN7AzRC.js} +1 -1
  196. package/dist/ui/assets/{julia-CCYoBiYK.js → julia-BJJYbUMV.js} +1 -1
  197. package/dist/ui/assets/{julia-repl-y8v2Oorl.js → julia-repl-BwruD8Ix.js} +1 -1
  198. package/dist/ui/assets/{kanban-definition-HUTT4EX6-C8sCOsBX.js → kanban-definition-HUTT4EX6-DFlE9edA.js} +1 -1
  199. package/dist/ui/assets/{kotlin-Bnjk7_fw.js → kotlin-CAIQsLCF.js} +1 -1
  200. package/dist/ui/assets/{lasso-B-al6x63.js → lasso-sU67h-5u.js} +1 -1
  201. package/dist/ui/assets/{latex-BUmqlb9r.js → latex-CVX-jP88.js} +1 -1
  202. package/dist/ui/assets/{ldif-D42RWj6Q.js → ldif-DGM9xbFZ.js} +1 -1
  203. package/dist/ui/assets/{leaf-CrH4BZ0m.js → leaf-AlB_zmwz.js} +1 -1
  204. package/dist/ui/assets/{less-upmRlQQW.js → less-CKwfEdZQ.js} +1 -1
  205. package/dist/ui/assets/{lisp-DHYS22SA.js → lisp-CXYLaAPw.js} +1 -1
  206. package/dist/ui/assets/{livecodeserver-CeQNmFP3.js → livecodeserver-C02fGGTS.js} +1 -1
  207. package/dist/ui/assets/{livescript-PJWpY1JI.js → livescript-CBMa8QF_.js} +1 -1
  208. package/dist/ui/assets/{llvm-BKtKWwCt.js → llvm-WXTIohTC.js} +1 -1
  209. package/dist/ui/assets/{lsl-RWRLRjk7.js → lsl-4obd2U_I.js} +1 -1
  210. package/dist/ui/assets/{lua-BFUDiPGm.js → lua-DTSy-TjF.js} +1 -1
  211. package/dist/ui/assets/{makefile-CUDyOz5D.js → makefile-Bf2UEO0i.js} +1 -1
  212. package/dist/ui/assets/{markdown-zZCLypc6.js → markdown-BgoGmFfJ.js} +1 -1
  213. package/dist/ui/assets/{mathematica-BHbxKxnq.js → mathematica-CSiA8KQh.js} +1 -1
  214. package/dist/ui/assets/{matlab-DlGtg--p.js → matlab-DoMvLsGB.js} +1 -1
  215. package/dist/ui/assets/{maxima-BBBeS3Ra.js → maxima-BFO4dfZO.js} +1 -1
  216. package/dist/ui/assets/{mel-nh8j7W_6.js → mel-DyBpmDxt.js} +1 -1
  217. package/dist/ui/assets/{mercury-DyyD-pqr.js → mercury-OL5G5uU6.js} +1 -1
  218. package/dist/ui/assets/{mindmap-definition-LN4V7U3C-CJlhDHqM.js → mindmap-definition-LN4V7U3C-s-nUZuCs.js} +1 -1
  219. package/dist/ui/assets/{mipsasm-hiEhRRiq.js → mipsasm-KQwdm39j.js} +1 -1
  220. package/dist/ui/assets/{mizar-BZa3iAAL.js → mizar-BqndJ30I.js} +1 -1
  221. package/dist/ui/assets/{mojolicious-BCIm2V_y.js → mojolicious-Bvc1uJd-.js} +1 -1
  222. package/dist/ui/assets/{monkey-zmK-7N8b.js → monkey-Dl_gLm7-.js} +1 -1
  223. package/dist/ui/assets/{moonscript-BsS_Mn3D.js → moonscript-BL6R6eAz.js} +1 -1
  224. package/dist/ui/assets/{n1ql-D7xVgDP0.js → n1ql-C09iOJfQ.js} +1 -1
  225. package/dist/ui/assets/{nginx-ct2q4dtd.js → nginx-C7W01nBr.js} +1 -1
  226. package/dist/ui/assets/{nim-RO0UOmW3.js → nim-Dj78szvD.js} +1 -1
  227. package/dist/ui/assets/{nix-BcRJxPKH.js → nix-BOtGyPmd.js} +1 -1
  228. package/dist/ui/assets/{node-repl-DgIefwxW.js → node-repl-19nZvZ4A.js} +1 -1
  229. package/dist/ui/assets/{nsis-DqHs9QhB.js → nsis-ByCl1zIm.js} +1 -1
  230. package/dist/ui/assets/{objectivec-BBcWqc7Y.js → objectivec-BhdaT_Jr.js} +1 -1
  231. package/dist/ui/assets/{ocaml-BExfw7D6.js → ocaml-D_NXvSO7.js} +1 -1
  232. package/dist/ui/assets/{openscad-CHPRELQb.js → openscad-DOhagvnA.js} +1 -1
  233. package/dist/ui/assets/{oxygene-DpS9uMJW.js → oxygene-5BnkqMRH.js} +1 -1
  234. package/dist/ui/assets/{parser3-CjJ_QdBp.js → parser3-jSWlxi8m.js} +1 -1
  235. package/dist/ui/assets/{pegDiagram-2B236MQR-GM70woGy.js → pegDiagram-2B236MQR-CideH-XT.js} +1 -1
  236. package/dist/ui/assets/{perl-BSNM2Kt8.js → perl-CfsqjZ4b.js} +1 -1
  237. package/dist/ui/assets/{pf-Z-hKf_88.js → pf-kOewxO29.js} +1 -1
  238. package/dist/ui/assets/{pgsql-DDgznxBg.js → pgsql-CXm2Xd-Z.js} +1 -1
  239. package/dist/ui/assets/{php-BzAhxF-l.js → php-CRiA_dH8.js} +1 -1
  240. package/dist/ui/assets/{php-template-DkgcKHRc.js → php-template-ByMrxqSd.js} +1 -1
  241. package/dist/ui/assets/{pieDiagram-ENE6RG2P-Bst7mPyz.js → pieDiagram-ENE6RG2P-CJkCdB38.js} +1 -1
  242. package/dist/ui/assets/{plaintext-BYEppD0R.js → plaintext-BJx0R6A5.js} +1 -1
  243. package/dist/ui/assets/{pony-BT_kQd1K.js → pony-CozCHtz4.js} +1 -1
  244. package/dist/ui/assets/{powershell-BfRsuSsf.js → powershell-BT7gMMgn.js} +1 -1
  245. package/dist/ui/assets/{processing-DpzWe5Iu.js → processing-FOIxn_W_.js} +1 -1
  246. package/dist/ui/assets/{profile-BCOhS5cM.js → profile-BsoUuD9w.js} +1 -1
  247. package/dist/ui/assets/{prolog-OxaCCaW8.js → prolog-Bd3gvQ2N.js} +1 -1
  248. package/dist/ui/assets/{properties-DMFlA2Ca.js → properties-BWGFdny9.js} +1 -1
  249. package/dist/ui/assets/{protobuf-CRDFkXvZ.js → protobuf-pQSKoOOY.js} +1 -1
  250. package/dist/ui/assets/{puppet-DnrVyLzx.js → puppet-DnEN_mgS.js} +1 -1
  251. package/dist/ui/assets/{purebasic-Dht4Hniv.js → purebasic-BqoOGoRw.js} +1 -1
  252. package/dist/ui/assets/{python-B0aMirWu.js → python-TeVYomkE.js} +1 -1
  253. package/dist/ui/assets/{python-repl-BlYDBGa7.js → python-repl-zqu5igFS.js} +1 -1
  254. package/dist/ui/assets/{q-DzrtW9kT.js → q-CZC9Dltd.js} +1 -1
  255. package/dist/ui/assets/{qml-DnfQsR3i.js → qml-ZNInP45Q.js} +1 -1
  256. package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-DNRYurBT.js → quadrantDiagram-ABIIQ3AL-Dd7PwxsF.js} +1 -1
  257. package/dist/ui/assets/{r-DGI_ZuTD.js → r-B39DAmkC.js} +1 -1
  258. package/dist/ui/assets/{railroadDiagram-RFXS5EU6-CmbC3Vz4.js → railroadDiagram-RFXS5EU6-DtO5PVFZ.js} +1 -1
  259. package/dist/ui/assets/{reasonml-3SohMgh2.js → reasonml-B-ZWFJt_.js} +1 -1
  260. package/dist/ui/assets/{requirementDiagram-TGXJPOKE-8CxrXHco.js → requirementDiagram-TGXJPOKE-DihF4OTj.js} +1 -1
  261. package/dist/ui/assets/{rib-DfRSd4Qa.js → rib-CnGG0qMF.js} +1 -1
  262. package/dist/ui/assets/{roboconf-CQczGdGW.js → roboconf-Ewtfps4u.js} +1 -1
  263. package/dist/ui/assets/{routeros-DCka-T2i.js → routeros-CPcmP1c7.js} +1 -1
  264. package/dist/ui/assets/{rsl-Dr8MOwMo.js → rsl-NbjWFbPH.js} +1 -1
  265. package/dist/ui/assets/{ruby-C2zFSkh_.js → ruby-DWDdy5yE.js} +1 -1
  266. package/dist/ui/assets/{ruleslanguage-C97YsgQq.js → ruleslanguage-Cv_DZe2r.js} +1 -1
  267. package/dist/ui/assets/{rust-H3h8kd9A.js → rust-NZnsfER5.js} +1 -1
  268. package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-DBXLWjEq.js → sankeyDiagram-HTMAVEWB-D6i-Mzte.js} +1 -1
  269. package/dist/ui/assets/{sas-04z0Xu8P.js → sas-C4wv0P6G.js} +1 -1
  270. package/dist/ui/assets/{scala-DyB9Aoiv.js → scala-DUdTOIgx.js} +1 -1
  271. package/dist/ui/assets/{scheme-DBj6nxUi.js → scheme-DEdFa14t.js} +1 -1
  272. package/dist/ui/assets/{scilab-Btj7AD9s.js → scilab-xY51J2bR.js} +1 -1
  273. package/dist/ui/assets/{scss-BXZJyXt7.js → scss-BEYp1sXc.js} +1 -1
  274. package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DXIkBFKC.js → sequenceDiagram-DBY2YBRQ-njQlqy_J.js} +1 -1
  275. package/dist/ui/assets/{shell-BsreQR1Z.js → shell-fq6bkhOw.js} +1 -1
  276. package/dist/ui/assets/{sizeCapture-X5ZJPWSS-ocS9jxAQ.js → sizeCapture-X5ZJPWSS-tLn70-Fb.js} +1 -1
  277. package/dist/ui/assets/{smali-D9wQw9zm.js → smali-CsSAuSYg.js} +1 -1
  278. package/dist/ui/assets/{smalltalk-Dku6G_H3.js → smalltalk-DJ7zrd87.js} +1 -1
  279. package/dist/ui/assets/{sml-BknyU6ya.js → sml-CnDwl0nH.js} +1 -1
  280. package/dist/ui/assets/{sqf-DRYMaOg8.js → sqf-Cc2SX4Zy.js} +1 -1
  281. package/dist/ui/assets/{sql-Cw3Ax4KA.js → sql-DUQA_V_4.js} +1 -1
  282. package/dist/ui/assets/{sql_more-vWdslLE0.js → sql_more-BHoH-8oO.js} +1 -1
  283. package/dist/ui/assets/{stan-8XH5bDS6.js → stan-D-7F5jH6.js} +1 -1
  284. package/dist/ui/assets/{stata-4e77wgfe.js → stata-xKD_DnDE.js} +1 -1
  285. package/dist/ui/assets/{stateDiagram-2N3HPSRC-RMmL9jMG.js → stateDiagram-2N3HPSRC-B4O8weor.js} +1 -1
  286. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-CO881_ht.js +1 -0
  287. package/dist/ui/assets/{step21-ByIeDMY3.js → step21-obc_kzQY.js} +1 -1
  288. package/dist/ui/assets/{stylus-ZAhJyWsw.js → stylus-CkAUSRd-.js} +1 -1
  289. package/dist/ui/assets/{subunit-pPW2UGkj.js → subunit-BDv8PGo1.js} +1 -1
  290. package/dist/ui/assets/{swift-CX3BB5az.js → swift-CHsYyW-p.js} +1 -1
  291. package/dist/ui/assets/{swimlanes-5IMT3BWC-C2zAuJ56.js → swimlanes-5IMT3BWC-DSr9Ty4A.js} +2 -2
  292. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DFMCDs8b.js +8 -0
  293. package/dist/ui/assets/{taggerscript-BHcjbWIC.js → taggerscript-C_2JQgO9.js} +1 -1
  294. package/dist/ui/assets/{tap-BOl1lBlS.js → tap-Bi497Z2c.js} +1 -1
  295. package/dist/ui/assets/{tcl-DZjeOBDh.js → tcl-B1XMvLaD.js} +1 -1
  296. package/dist/ui/assets/{thrift-BxboWg4x.js → thrift-D9X0Hmmc.js} +1 -1
  297. package/dist/ui/assets/{timeline-definition-FHXFAJF6-BOxsxyq_.js → timeline-definition-FHXFAJF6-C4_gj50B.js} +1 -1
  298. package/dist/ui/assets/{tp-BNM6ql3J.js → tp-CJG4Odbx.js} +1 -1
  299. package/dist/ui/assets/{twig-Dj9ZiXD4.js → twig-flj72_wc.js} +1 -1
  300. package/dist/ui/assets/{typescript-7MEJlu_6.js → typescript-CWPwVoLd.js} +1 -1
  301. package/dist/ui/assets/{vala-DNqOAgHJ.js → vala-LuCNWNuU.js} +1 -1
  302. package/dist/ui/assets/{vbnet-T0mNKVc_.js → vbnet-CGUT6ss0.js} +1 -1
  303. package/dist/ui/assets/{vbscript-CeuwVMAI.js → vbscript-CNiUBJhn.js} +1 -1
  304. package/dist/ui/assets/{vbscript-html-BbJSt2w6.js → vbscript-html-CJGgjjbc.js} +1 -1
  305. package/dist/ui/assets/{vennDiagram-L72KCM5P-BX9mWeiT.js → vennDiagram-L72KCM5P-BxcAUnYo.js} +1 -1
  306. package/dist/ui/assets/{verilog-DYuhYfkX.js → verilog-C4f9ZBTK.js} +1 -1
  307. package/dist/ui/assets/{vhdl-Cf9aT-t7.js → vhdl-CyDQIZve.js} +1 -1
  308. package/dist/ui/assets/{vim-DciP44K1.js → vim-XAUBqa0M.js} +1 -1
  309. package/dist/ui/assets/{wardleyDiagram-EHGQE667-CDj2rOzu.js → wardleyDiagram-EHGQE667-DlwSH77q.js} +1 -1
  310. package/dist/ui/assets/{x86asm-E-AN_LXO.js → x86asm-Cp6vHuUx.js} +1 -1
  311. package/dist/ui/assets/{xl-CxYLJelN.js → xl-BHgDofIM.js} +1 -1
  312. package/dist/ui/assets/{xml-yz1SRLuU.js → xml-QloVn4s_.js} +1 -1
  313. package/dist/ui/assets/{xquery-BLzBF3tV.js → xquery-spJZLmyM.js} +1 -1
  314. package/dist/ui/assets/{xychartDiagram-FW5EYKEG-Czapk9-Z.js → xychartDiagram-FW5EYKEG-BxGVZcnb.js} +1 -1
  315. package/dist/ui/assets/{yaml-Cv4Y7iN_.js → yaml-CUju4iq0.js} +1 -1
  316. package/dist/ui/assets/{zephir-KRcdQfEX.js → zephir-ChVpmD0Y.js} +1 -1
  317. package/dist/ui/index.html +2 -2
  318. package/dist/utils/__tests__/abort-signals.test.js +67 -0
  319. package/dist/utils/__tests__/db-maintenance.test.js +55 -0
  320. package/dist/utils/__tests__/db-migration.test.js +79 -1
  321. package/dist/utils/__tests__/inject-loop.test.js +1 -53
  322. package/dist/utils/__tests__/learn-tasks-db.test.js +82 -0
  323. package/dist/utils/__tests__/openai-converter.test.js +25 -0
  324. package/dist/utils/__tests__/pi-crawl-tools.test.js +15 -4
  325. package/dist/utils/__tests__/pi-dedup-reconcile.test.js +11 -9
  326. package/dist/utils/__tests__/pi-events.test.d.ts +1 -0
  327. package/dist/utils/__tests__/pi-events.test.js +172 -0
  328. package/dist/utils/__tests__/pi-learn-orchestrator.test.js +216 -6
  329. package/dist/utils/__tests__/pi-runtime-json.test.js +38 -3
  330. package/dist/utils/__tests__/providers-db.test.js +40 -2
  331. package/dist/utils/__tests__/request-writer.test.js +532 -39
  332. package/dist/utils/__tests__/sse-protocol.test.d.ts +1 -0
  333. package/dist/utils/__tests__/sse-protocol.test.js +115 -0
  334. package/dist/utils/__tests__/stats-aggregator.test.d.ts +1 -0
  335. package/dist/utils/__tests__/stats-aggregator.test.js +114 -0
  336. package/dist/utils/__tests__/vault.test.d.ts +1 -0
  337. package/dist/utils/__tests__/{knowledge-store.test.js → vault.test.js} +16 -16
  338. package/dist/utils/abort-signals.d.ts +13 -0
  339. package/dist/utils/abort-signals.js +33 -0
  340. package/dist/utils/db-maintenance.d.ts +8 -0
  341. package/dist/utils/db-maintenance.js +18 -0
  342. package/dist/utils/db.d.ts +2 -0
  343. package/dist/utils/db.js +86 -0
  344. package/dist/utils/esm-dirname.d.ts +0 -15
  345. package/dist/utils/esm-dirname.js +0 -4
  346. package/dist/utils/inject-loop.d.ts +0 -27
  347. package/dist/utils/inject-loop.js +2 -56
  348. package/dist/utils/learn-tasks-db.d.ts +15 -0
  349. package/dist/utils/learn-tasks-db.js +35 -0
  350. package/dist/utils/openai-converter.js +88 -78
  351. package/dist/utils/pi-browser-tools.d.ts +0 -2
  352. package/dist/utils/pi-browser-tools.js +0 -174
  353. package/dist/utils/pi-crawl-tools.d.ts +2 -1
  354. package/dist/utils/pi-crawl-tools.js +16 -11
  355. package/dist/utils/pi-dedup.d.ts +8 -30
  356. package/dist/utils/pi-dedup.js +32 -67
  357. package/dist/utils/pi-events.d.ts +65 -0
  358. package/dist/utils/pi-events.js +98 -0
  359. package/dist/utils/pi-learn-orchestrator.d.ts +6 -5
  360. package/dist/utils/pi-learn-orchestrator.js +71 -106
  361. package/dist/utils/pi-runtime.d.ts +5 -6
  362. package/dist/utils/pi-runtime.js +38 -42
  363. package/dist/utils/pi-sandbox-ops.d.ts +0 -36
  364. package/dist/utils/pi-sandbox-ops.js +5 -190
  365. package/dist/utils/providers-db.d.ts +3 -0
  366. package/dist/utils/providers-db.js +21 -7
  367. package/dist/utils/request-writer.d.ts +77 -26
  368. package/dist/utils/request-writer.js +362 -56
  369. package/dist/utils/sse-protocol.d.ts +34 -0
  370. package/dist/utils/sse-protocol.js +121 -0
  371. package/dist/utils/sse-stream-processor.d.ts +4 -9
  372. package/dist/utils/sse-stream-processor.js +13 -104
  373. package/dist/utils/sse-writer.d.ts +1 -1
  374. package/dist/utils/sse-writer.js +3 -2
  375. package/dist/utils/stats-aggregator.d.ts +1 -1
  376. package/dist/utils/stats-aggregator.js +44 -24
  377. package/dist/utils/tool-injector.js +7 -0
  378. package/dist/utils/vault.d.ts +111 -0
  379. package/dist/utils/vault.js +434 -0
  380. package/ecosystem.config.cjs +2 -1
  381. package/package.json +1 -1
  382. package/dist/docs/assets/chunks/@localSearchIndexroot.B6Qfxe6W.js +0 -1
  383. package/dist/server/middleware/__tests__/request-id.test.js +0 -28
  384. package/dist/server/middleware/request-id.d.ts +0 -2
  385. package/dist/server/middleware/request-id.js +0 -12
  386. package/dist/types/api.d.ts +0 -20
  387. package/dist/types/index.d.ts +0 -4
  388. package/dist/types/index.js +0 -4
  389. package/dist/types/log.d.ts +0 -13
  390. package/dist/ui/assets/channel-Bc4Td8eZ.js +0 -1
  391. package/dist/ui/assets/classDiagram-OUVF2IWQ-BicxhZFq.js +0 -1
  392. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-BicxhZFq.js +0 -1
  393. package/dist/ui/assets/index-C0fxlU9d.css +0 -10
  394. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-QvaEO5U6.js +0 -1
  395. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DPgCOY0D.js +0 -8
  396. package/dist/utils/__tests__/sse-accumulator.test.js +0 -83
  397. package/dist/utils/knowledge-store.d.ts +0 -51
  398. package/dist/utils/knowledge-store.js +0 -241
  399. package/dist/utils/migrate-files-to-db.d.ts +0 -1
  400. package/dist/utils/migrate-files-to-db.js +0 -138
  401. package/dist/utils/sse-accumulator.d.ts +0 -9
  402. package/dist/utils/sse-accumulator.js +0 -59
  403. /package/dist/docs/assets/{proxy-cli_data-hooks.md.w9Oe1OD3.lean.js → proxy-cli_data-hooks.md.Bz8CVbxO.lean.js} +0 -0
  404. /package/dist/docs/assets/{proxy-core_ui-routes.md.Dyqkeoiv.lean.js → proxy-core_ui-routes.md.B21t1p7R.lean.js} +0 -0
  405. /package/dist/server/{middleware/__tests__/request-id.test.d.ts → __tests__/data-push.test.d.ts} +0 -0
  406. /package/dist/{types/api.js → utils/__tests__/abort-signals.test.d.ts} +0 -0
  407. /package/dist/{types/log.js → utils/__tests__/db-maintenance.test.d.ts} +0 -0
  408. /package/dist/utils/__tests__/{knowledge-store.test.d.ts → learn-tasks-db.test.d.ts} +0 -0
  409. /package/dist/utils/__tests__/{sse-accumulator.test.d.ts → openai-converter.test.d.ts} +0 -0
@@ -1,11 +1,8 @@
1
1
  import pino from 'pino';
2
2
  import type { LogConfig } from '../types/config.js';
3
- declare const LEVEL_MAP: Record<string, number>;
4
- declare const NUM_TO_LEVEL: Record<number, string>;
5
3
  export declare function createLogger(config: LogConfig): pino.Logger;
6
4
  export declare function readLogs(filePath: string, options: {
7
5
  limit?: number;
8
6
  level?: string;
9
7
  grep?: string;
10
8
  }): Promise<string[]>;
11
- export { LEVEL_MAP, NUM_TO_LEVEL };
@@ -116,4 +116,3 @@ export async function readLogs(filePath, options) {
116
116
  }
117
117
  return filtered;
118
118
  }
119
- export { LEVEL_MAP, NUM_TO_LEVEL };
@@ -2,8 +2,8 @@ import fs from 'fs';
2
2
  import { CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
3
3
  import { getDatabase } from '../utils/db.js';
4
4
  import { listRequestDB } from '../utils/request-writer.js';
5
- import { listProviders } from '../utils/providers-db.js';
6
- import { knowledgeStore } from '../utils/knowledge-store.js';
5
+ import { getActiveProvider } from '../utils/providers-db.js';
6
+ import { vault } from '../utils/vault.js';
7
7
  function ok(text) {
8
8
  return { content: [{ type: 'text', text }] };
9
9
  }
@@ -18,8 +18,7 @@ async function handleGetStatus(_args, ctx) {
18
18
  const countRow = db.prepare('SELECT COUNT(*) AS n FROM requests').get();
19
19
  let defaultProvider = null;
20
20
  try {
21
- const providers = listProviders(db);
22
- const def = providers.find(p => p.default);
21
+ const def = getActiveProvider(db);
23
22
  if (def) {
24
23
  defaultProvider = { name: def.name, model: def.model, base_url: def.base_url };
25
24
  }
@@ -192,10 +191,10 @@ const HANDLERS = {
192
191
  list_requests: handleListRequests,
193
192
  get_token_stats: handleGetTokenStats,
194
193
  get_logs: handleGetLogs,
195
- list_topics: async () => ok(JSON.stringify(await knowledgeStore.listTopics(), null, 2)),
194
+ list_topics: async () => ok(JSON.stringify(await vault.listTopics(), null, 2)),
196
195
  get_topic: async (args) => {
197
196
  try {
198
- return ok(JSON.stringify(await knowledgeStore.getTopic(args.topic), null, 2));
197
+ return ok(JSON.stringify(await vault.getTopic(args.topic), null, 2));
199
198
  }
200
199
  catch (e) {
201
200
  const msg = e instanceof Error ? e.message : String(e);
@@ -206,7 +205,7 @@ const HANDLERS = {
206
205
  }
207
206
  },
208
207
  query_knowledge: async (args) => {
209
- const hits = await knowledgeStore.queryKnowledge(args.query ?? '', args.limit);
208
+ const hits = await vault.queryKnowledge(args.query ?? '', args.limit);
210
209
  if (hits.length === 0) {
211
210
  return ok('No knowledge chunks matched. Call list_topics to browse available topics, or refine your query.');
212
211
  }
@@ -214,10 +213,10 @@ const HANDLERS = {
214
213
  hits: hits.map(h => ({ topic: h.topic, chunkId: h.chunkId, title: h.title, body: h.body })),
215
214
  }, null, 2));
216
215
  },
217
- search_chunks: async (args) => ok(JSON.stringify(await knowledgeStore.searchChunks(args.query ?? ''), null, 2)),
216
+ search_chunks: async (args) => ok(JSON.stringify(await vault.searchChunks(args.query ?? ''), null, 2)),
218
217
  read_chunk: async (args) => {
219
218
  try {
220
- const body = await knowledgeStore.readChunk(args.topic, args.chunk_id);
219
+ const body = await vault.readChunk(args.topic, args.chunk_id);
221
220
  return ok(body);
222
221
  }
223
222
  catch (e) {
@@ -0,0 +1,44 @@
1
+ import { WebSocket } from 'ws';
2
+ import { addDataClient, removeDataClient, pushNewRequest } from '../data-push';
3
+ // 统计 fake client 收到的各类广播
4
+ function messagesOf(send) {
5
+ return send.mock.calls.map((call) => JSON.parse(call[0]));
6
+ }
7
+ describe('data-push stats notify debounce', () => {
8
+ let send;
9
+ const fakeWs = {
10
+ readyState: WebSocket.OPEN,
11
+ send: jest.fn()
12
+ };
13
+ beforeEach(() => {
14
+ jest.useFakeTimers();
15
+ send = fakeWs.send;
16
+ send.mockClear();
17
+ addDataClient(fakeWs);
18
+ });
19
+ afterEach(() => {
20
+ removeDataClient(fakeWs);
21
+ jest.clearAllTimers();
22
+ jest.useRealTimers();
23
+ });
24
+ it('trailing:重复 completed push 会重置延迟窗口,只在最后一次后 1.5s 广播一次', () => {
25
+ // t=0 第一次 completed push
26
+ pushNewRequest({ id: 1 }, 'completed');
27
+ jest.advanceTimersByTime(1000);
28
+ // t=1000 第二次 completed push,trailing 重置:窗口从第二次重新起算
29
+ pushNewRequest({ id: 2 }, 'completed');
30
+ // 距第二次 1499ms(总 2499ms)仍无 stats 广播;若没有重置,第一次的 timer 在 t=1500 就会触发
31
+ jest.advanceTimersByTime(1499);
32
+ expect(messagesOf(send).filter((m) => m.type === 'stats')).toHaveLength(0);
33
+ // 总 2500ms(距第二次 1500ms)恰好广播一次
34
+ jest.advanceTimersByTime(1);
35
+ const statsMessages = messagesOf(send).filter((m) => m.type === 'stats');
36
+ expect(statsMessages).toHaveLength(1);
37
+ expect(statsMessages[0]).toEqual({ type: 'stats', action: 'notify' });
38
+ });
39
+ it('pending push 不产生 stats 广播', () => {
40
+ pushNewRequest({ id: 1 }, 'pending');
41
+ jest.advanceTimersByTime(5000);
42
+ expect(messagesOf(send).filter((m) => m.type === 'stats')).toHaveLength(0);
43
+ });
44
+ });
@@ -49,6 +49,7 @@ jest.mock('@utils/db', () => {
49
49
  provider TEXT NOT NULL,
50
50
  is_default INTEGER NOT NULL DEFAULT 0,
51
51
  is_openai_compatible INTEGER NOT NULL DEFAULT 0,
52
+ auth_style TEXT NOT NULL DEFAULT 'bearer',
52
53
  created_at TEXT DEFAULT CURRENT_TIMESTAMP,
53
54
  updated_at TEXT DEFAULT CURRENT_TIMESTAMP
54
55
  )
@@ -1,4 +1,6 @@
1
- import { getErrorStatusCode, getErrorMessage, resolveProxyTarget, filterForwardHeaders } from '../proxy';
1
+ import { getErrorStatusCode, getErrorMessage, resolveProxyTarget, filterForwardHeaders, setupProxy } from '../proxy';
2
+ import Fastify from 'fastify';
3
+ import http from 'node:http';
2
4
  import Database from 'better-sqlite3';
3
5
  jest.mock('@utils/db', () => ({
4
6
  __esModule: true,
@@ -6,7 +8,24 @@ jest.mock('@utils/db', () => ({
6
8
  initDatabase: jest.fn(),
7
9
  closeDatabase: jest.fn()
8
10
  }));
9
- const { getDatabase } = jest.requireMock('@utils/db');
11
+ jest.mock('@config/index', () => ({
12
+ loadConfig: jest.fn().mockResolvedValue({ storage: { maxDays: 7 } })
13
+ }));
14
+ jest.mock('../../utils/mcp-manager', () => ({
15
+ mcpManager: {
16
+ init: jest.fn().mockResolvedValue(undefined),
17
+ close: jest.fn().mockResolvedValue(undefined)
18
+ }
19
+ }));
20
+ jest.mock('../../utils/machine-id', () => ({
21
+ getMachineId: jest.fn().mockResolvedValue('test-machine-id'),
22
+ getMachineIdSync: jest.fn().mockReturnValue('test-machine-id'),
23
+ preloadMachineId: jest.fn().mockResolvedValue(undefined)
24
+ }));
25
+ jest.mock('../../utils/stats-aggregator', () => ({
26
+ aggregateStats: jest.fn()
27
+ }));
28
+ const { getDatabase, initDatabase } = jest.requireMock('@utils/db');
10
29
  function makeError(code, message) {
11
30
  const error = new Error(message);
12
31
  error.code = code;
@@ -135,3 +154,263 @@ describe('filterForwardHeaders with authStyle', () => {
135
154
  expect(out['x-api-key']).toBe('inbound-key');
136
155
  });
137
156
  });
157
+ // --- G2: 逻辑终止识别 + 收割接入(setupProxy 集成测试)---
158
+ // 构造集成测试用内存库:仅建 proxy.ts 运行路径触及的表
159
+ function createIntegrationDb() {
160
+ const db = new Database(':memory:');
161
+ db.exec(`
162
+ CREATE TABLE requests (
163
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
164
+ request_id TEXT UNIQUE NOT NULL,
165
+ session_id TEXT NOT NULL,
166
+ timestamp TEXT NOT NULL,
167
+ method TEXT NOT NULL,
168
+ path TEXT NOT NULL,
169
+ status_code INTEGER NOT NULL,
170
+ response_time INTEGER NOT NULL,
171
+ api_key TEXT,
172
+ proxy_api_key TEXT,
173
+ base_url TEXT,
174
+ model TEXT,
175
+ machine_id TEXT,
176
+ user_agent TEXT,
177
+ input_tokens INTEGER,
178
+ output_tokens INTEGER,
179
+ cache_read_tokens INTEGER,
180
+ cache_creation_tokens INTEGER,
181
+ request_headers TEXT,
182
+ request_body TEXT,
183
+ response_headers TEXT,
184
+ response_events TEXT,
185
+ completed_at TEXT,
186
+ closed_at TEXT,
187
+ error TEXT,
188
+ created_at TEXT DEFAULT CURRENT_TIMESTAMP
189
+ );
190
+ CREATE TABLE response_events (
191
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
192
+ request_id TEXT NOT NULL,
193
+ session_id TEXT NOT NULL,
194
+ event_index INTEGER NOT NULL,
195
+ event_type TEXT,
196
+ event_data TEXT NOT NULL
197
+ );
198
+ CREATE TABLE learn_tasks (
199
+ task_id TEXT PRIMARY KEY,
200
+ slug TEXT NOT NULL,
201
+ source_type TEXT NOT NULL,
202
+ label TEXT NOT NULL,
203
+ status TEXT NOT NULL,
204
+ error TEXT,
205
+ created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
206
+ ended_at TEXT
207
+ );
208
+ CREATE TABLE providers (
209
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
210
+ name TEXT UNIQUE NOT NULL,
211
+ base_url TEXT,
212
+ api_key TEXT,
213
+ model TEXT,
214
+ haiku_model TEXT,
215
+ sonnet_model TEXT,
216
+ opus_model TEXT,
217
+ subagent_model TEXT,
218
+ provider TEXT NOT NULL,
219
+ is_default INTEGER NOT NULL DEFAULT 0,
220
+ is_openai_compatible INTEGER NOT NULL DEFAULT 0,
221
+ auth_style TEXT NOT NULL DEFAULT 'bearer',
222
+ created_at TEXT DEFAULT CURRENT_TIMESTAMP,
223
+ updated_at TEXT DEFAULT CURRENT_TIMESTAMP
224
+ );
225
+ `);
226
+ return db;
227
+ }
228
+ function sseFrame(event, data) {
229
+ const body = typeof data === 'string' ? data : JSON.stringify(data);
230
+ return event !== null ? `event: ${event}\ndata: ${body}\n\n` : `data: ${body}\n\n`;
231
+ }
232
+ const completeClaudeFrames = [
233
+ sseFrame('message_start', { type: 'message_start', usage: { input_tokens: 10, cache_read_input_tokens: 2 } }),
234
+ sseFrame('ping', { type: 'ping' }),
235
+ sseFrame('message_delta', { type: 'message_delta', usage: { output_tokens: 4 } }),
236
+ sseFrame('message_stop', { type: 'message_stop' })
237
+ ];
238
+ const incompleteClaudeFrames = [
239
+ sseFrame('message_start', { type: 'message_start', usage: { input_tokens: 3 } }),
240
+ sseFrame('content_block_start', { type: 'content_block_start', index: 0, content_block: { type: 'text', text: '' } }),
241
+ sseFrame('content_block_delta', { type: 'content_block_delta', index: 0, delta: { type: 'text_delta', text: 'hel' } })
242
+ ];
243
+ // 上游 Web 流:逐帧异步入队;endAfter=false 时入队后保持悬挂(不 close)。
244
+ // singleChunk=true 时所有帧合并为一次 enqueue(模拟真实 TCP 合包,如
245
+ // finish_reason chunk 与紧随的 [DONE] 通常在同一缓冲到达)。
246
+ function createUpstreamWebStream(frames, endAfter = false, singleChunk = false) {
247
+ let controller;
248
+ const webStream = new ReadableStream({
249
+ start(c) { controller = c; }
250
+ });
251
+ void (async () => {
252
+ try {
253
+ if (singleChunk) {
254
+ controller.enqueue(Buffer.from(frames.join(''), 'utf-8'));
255
+ }
256
+ else {
257
+ for (const frame of frames) {
258
+ controller.enqueue(Buffer.from(frame, 'utf-8'));
259
+ await new Promise(r => setTimeout(r, 3));
260
+ }
261
+ }
262
+ if (endAfter)
263
+ controller.close();
264
+ }
265
+ catch {
266
+ // nodeStream.destroy 取消 web 流后 controller 已关闭,忽略后续入队
267
+ }
268
+ })();
269
+ return webStream;
270
+ }
271
+ async function waitFor(predicate, { timeout = 3000, interval = 20 } = {}) {
272
+ const start = Date.now();
273
+ while (Date.now() - start < timeout) {
274
+ const value = predicate();
275
+ if (value !== undefined)
276
+ return value;
277
+ await new Promise(r => setTimeout(r, interval));
278
+ }
279
+ throw new Error('waitFor timed out');
280
+ }
281
+ function mockUpstreamFetch(webStream, requestId) {
282
+ return jest.spyOn(globalThis, 'fetch').mockImplementation(async () => new Response(webStream, {
283
+ status: 200,
284
+ headers: { 'content-type': 'text/event-stream', 'x-request-id': requestId }
285
+ }));
286
+ }
287
+ const proxyConfig = {
288
+ target: 'https://upstream.example.com/apps/anthropic',
289
+ changeOrigin: true
290
+ };
291
+ const requestPayload = JSON.stringify({
292
+ model: 'claude-sonnet-4-20250514',
293
+ max_tokens: 16,
294
+ messages: [{ role: 'user', content: 'hi' }]
295
+ });
296
+ describe('setupProxy SSE lifecycle (G2)', () => {
297
+ let db;
298
+ let fastify;
299
+ beforeEach(() => {
300
+ jest.clearAllMocks();
301
+ db = createIntegrationDb();
302
+ getDatabase.mockReturnValue(db);
303
+ initDatabase.mockReturnValue(db);
304
+ fastify = Fastify();
305
+ });
306
+ afterEach(async () => {
307
+ delete process.env.CCM_STREAM_IDLE_TIMEOUT_MS;
308
+ await fastify.close();
309
+ db.close();
310
+ });
311
+ test('message_stop 已发出后上游悬挂:行落 completed_at,不标中断,客户端不悬挂', async () => {
312
+ await setupProxy(fastify, proxyConfig);
313
+ mockUpstreamFetch(createUpstreamWebStream(completeClaudeFrames), 'cloud-req-1');
314
+ const response = await fastify.inject({
315
+ method: 'POST',
316
+ url: '/v1/messages',
317
+ headers: { 'content-type': 'application/json' },
318
+ payload: requestPayload
319
+ });
320
+ expect(response.statusCode).toBe(200);
321
+ expect(response.payload).toContain('message_stop');
322
+ const row = db.prepare('SELECT * FROM requests WHERE request_id = ?').get('cloud-req-1');
323
+ expect(row).toBeDefined();
324
+ expect(row.completed_at).not.toBeNull();
325
+ expect(row.closed_at).toBeNull();
326
+ expect(row.error).toBeNull();
327
+ });
328
+ test('无 message_stop 的 idle 超时仍标中断(closed_at + error)', async () => {
329
+ // 测试专用时长覆盖:真实定时器,只缩短看门狗超时
330
+ process.env.CCM_STREAM_IDLE_TIMEOUT_MS = '80';
331
+ await setupProxy(fastify, proxyConfig);
332
+ mockUpstreamFetch(createUpstreamWebStream(incompleteClaudeFrames), 'cloud-req-2');
333
+ // 走真实 TCP:中断分支 pipe 不结束客户端(保持既有语义),客户端自行判超时
334
+ await fastify.listen({ port: 0, host: '127.0.0.1' });
335
+ const port = fastify.server.address().port;
336
+ const clientReq = http.request({
337
+ port,
338
+ host: '127.0.0.1',
339
+ method: 'POST',
340
+ path: '/v1/messages',
341
+ headers: { 'content-type': 'application/json', 'content-length': Buffer.byteLength(requestPayload) }
342
+ });
343
+ clientReq.on('error', () => { });
344
+ clientReq.end(requestPayload);
345
+ // 客户端收到数据后看门狗触发,不再有数据;保底 1s 后自毁连接
346
+ const clientTimer = setTimeout(() => clientReq.destroy(), 1000);
347
+ clientReq.on('close', () => clearTimeout(clientTimer));
348
+ const row = await waitFor(() => {
349
+ const r = db.prepare('SELECT * FROM requests LIMIT 1').get();
350
+ return r && r.closed_at ? r : undefined;
351
+ });
352
+ expect(row.completed_at).toBeNull();
353
+ expect(row.closed_at).not.toBeNull();
354
+ expect(row.error).toContain('idle timeout');
355
+ expect(row.status_code).toBe(200);
356
+ });
357
+ test('OpenAI 流 finish_reason + [DONE] 后上游悬挂:行落 completed_at', async () => {
358
+ db.prepare(`
359
+ INSERT INTO providers (name, base_url, api_key, model, provider, is_default, is_openai_compatible, auth_style)
360
+ VALUES ('openai-test', 'https://openai.example.com/v1', 'k', 'gpt-4o', 'openai', 1, 1, 'bearer')
361
+ `).run();
362
+ await setupProxy(fastify, proxyConfig);
363
+ const openaiFrames = [
364
+ sseFrame(null, { id: 'chat-1', choices: [{ delta: { role: 'assistant' }, finish_reason: null }] }),
365
+ sseFrame(null, { id: 'chat-1', choices: [{ delta: { content: 'hi' }, finish_reason: null }] }),
366
+ sseFrame(null, { id: 'chat-1', choices: [{ delta: {}, finish_reason: 'stop' }], usage: { prompt_tokens: 5, completion_tokens: 7 } }),
367
+ sseFrame(null, '[DONE]')
368
+ ];
369
+ const fetchSpy = mockUpstreamFetch(createUpstreamWebStream(openaiFrames, false, true), 'cloud-openai-1');
370
+ const response = await fastify.inject({
371
+ method: 'POST',
372
+ url: '/v1/messages',
373
+ headers: { 'content-type': 'application/json' },
374
+ payload: requestPayload
375
+ });
376
+ expect(response.statusCode).toBe(200);
377
+ expect(response.payload).toContain('message_stop');
378
+ expect(fetchSpy.mock.calls[0][0]).toBe('https://openai.example.com/v1/chat/completions');
379
+ const row = db.prepare('SELECT * FROM requests WHERE request_id = ?').get('cloud-openai-1');
380
+ expect(row).toBeDefined();
381
+ expect(row.completed_at).not.toBeNull();
382
+ expect(row.closed_at).toBeNull();
383
+ expect(row.error).toBeNull();
384
+ });
385
+ test('message_stop 到达后客户端断开:内容已完整交付,仍走 complete', async () => {
386
+ await setupProxy(fastify, proxyConfig);
387
+ mockUpstreamFetch(createUpstreamWebStream(completeClaudeFrames), 'cloud-req-3');
388
+ await fastify.listen({ port: 0, host: '127.0.0.1' });
389
+ const port = fastify.server.address().port;
390
+ await new Promise((resolve, reject) => {
391
+ const clientReq = http.request({
392
+ port,
393
+ host: '127.0.0.1',
394
+ method: 'POST',
395
+ path: '/v1/messages',
396
+ headers: { 'content-type': 'application/json', 'content-length': Buffer.byteLength(requestPayload) }
397
+ });
398
+ clientReq.on('error', () => { });
399
+ clientReq.on('response', (res) => {
400
+ res.on('data', (chunk) => {
401
+ if (chunk.toString().includes('message_stop'))
402
+ clientReq.destroy();
403
+ });
404
+ });
405
+ clientReq.on('close', () => resolve());
406
+ setTimeout(() => reject(new Error('client did not close')), 3000).unref();
407
+ clientReq.end(requestPayload);
408
+ });
409
+ const row = await waitFor(() => {
410
+ const r = db.prepare('SELECT * FROM requests WHERE request_id = ?').get('cloud-req-3');
411
+ return r && r.completed_at ? r : undefined;
412
+ });
413
+ expect(row.closed_at).toBeNull();
414
+ expect(row.error).toBeNull();
415
+ });
416
+ });
@@ -105,22 +105,27 @@ describe('createServer', () => {
105
105
  expect(response).toBeDefined();
106
106
  expect(typeof response.statusCode).toBe('number');
107
107
  });
108
- it('propagates request ID from x-request-id header', async () => {
108
+ it('uses x-request-id header value as request id when header present', async () => {
109
109
  server = await createServer();
110
+ server.get('/request-id-echo', async (request) => ({ id: request.id }));
110
111
  const response = await server.inject({
111
112
  method: 'GET',
112
- url: '/test',
113
- headers: { 'x-request-id': 'custom-id-123' }
113
+ url: '/request-id-echo',
114
+ headers: { 'x-request-id': 'my-trace-123' }
114
115
  });
115
- expect(response).toBeDefined();
116
+ expect(JSON.parse(response.body).id).toBe('my-trace-123');
116
117
  });
117
- it('handles request without x-request-id header', async () => {
118
+ it('generates non-default nanoid request id without header, unique per request', async () => {
118
119
  server = await createServer();
119
- const response = await server.inject({
120
- method: 'GET',
121
- url: '/test'
122
- });
123
- expect(response).toBeDefined();
120
+ server.get('/request-id-echo', async (request) => ({ id: request.id }));
121
+ const response1 = await server.inject({ method: 'GET', url: '/request-id-echo' });
122
+ const response2 = await server.inject({ method: 'GET', url: '/request-id-echo' });
123
+ const id1 = JSON.parse(response1.body).id;
124
+ const id2 = JSON.parse(response2.body).id;
125
+ expect(id1).not.toMatch(/^req-\d+$/);
126
+ expect(id2).not.toMatch(/^req-\d+$/);
127
+ expect(id1).toHaveLength(16);
128
+ expect(id1).not.toBe(id2);
124
129
  });
125
130
  it('server closes cleanly', async () => {
126
131
  server = await createServer();
@@ -1,4 +1,5 @@
1
1
  import Fastify from 'fastify';
2
+ import * as statsAggregator from '@utils/stats-aggregator';
2
3
  import { setupUiRoutes } from '../ui-route';
3
4
  // Mock PM2 utils
4
5
  jest.mock('@utils/pm2', () => ({
@@ -372,4 +373,46 @@ describe('setupUiRoutes', () => {
372
373
  expect(body.error).toContain('Disk write failed');
373
374
  });
374
375
  });
376
+ describe('GET /ui/api/stats', () => {
377
+ let aggregateSpy;
378
+ let getStatsSpy;
379
+ beforeEach(() => {
380
+ aggregateSpy = jest.spyOn(statsAggregator, 'aggregateStats').mockImplementation(() => { });
381
+ getStatsSpy = jest.spyOn(statsAggregator, 'getStatsData').mockReturnValue({ hourly: {}, lastUpdated: null });
382
+ });
383
+ afterEach(() => {
384
+ aggregateSpy.mockRestore();
385
+ getStatsSpy.mockRestore();
386
+ });
387
+ it('读前触发 aggregateStats 并返回 200', async () => {
388
+ const response = await server.inject({ method: 'GET', url: '/ui/api/stats' });
389
+ expect(aggregateSpy).toHaveBeenCalledTimes(1);
390
+ expect(aggregateSpy).toHaveBeenCalledWith(7);
391
+ expect(getStatsSpy).toHaveBeenCalledTimes(1);
392
+ // 必须先聚合再读取
393
+ expect(aggregateSpy.mock.invocationCallOrder[0]).toBeLessThan(getStatsSpy.mock.invocationCallOrder[0]);
394
+ expect(response.statusCode).toBe(200);
395
+ expect(JSON.parse(response.body)).toEqual({ hourly: {}, lastUpdated: null });
396
+ });
397
+ it('聚合失败只记录不阻断读取,仍返回 200', async () => {
398
+ aggregateSpy.mockImplementation(() => { throw new Error('agg boom'); });
399
+ // inject 请求的 request.log 来自 server.log.child(),替换为可观测的 mock
400
+ const logError = jest.fn();
401
+ jest.spyOn(server.log, 'child').mockReturnValue({
402
+ level: 'info',
403
+ fatal: jest.fn(),
404
+ error: logError,
405
+ warn: jest.fn(),
406
+ info: jest.fn(),
407
+ debug: jest.fn(),
408
+ trace: jest.fn(),
409
+ child: jest.fn()
410
+ });
411
+ const response = await server.inject({ method: 'GET', url: '/ui/api/stats' });
412
+ expect(response.statusCode).toBe(200);
413
+ expect(getStatsSpy).toHaveBeenCalledTimes(1);
414
+ // 聚合异常必须记录日志
415
+ expect(logError).toHaveBeenCalledTimes(1);
416
+ });
417
+ });
375
418
  });
@@ -1,2 +1 @@
1
- export declare const AUTH_TOKEN_ENV = "UI_AUTH_TOKEN";
2
1
  export declare function checkAuth(request: any, config: any): boolean;
@@ -1,4 +1,4 @@
1
- export const AUTH_TOKEN_ENV = 'UI_AUTH_TOKEN';
1
+ const AUTH_TOKEN_ENV = 'UI_AUTH_TOKEN';
2
2
  export function checkAuth(request, config) {
3
3
  // If no auth token configured, allow all (dev mode)
4
4
  const token = config?.auth?.token || process.env[AUTH_TOKEN_ENV];