@cc-monitoring/proxy-core 0.1.5 → 0.1.7

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 (445) hide show
  1. package/dist/docs/404.html +22 -0
  2. package/dist/docs/assets/app.BxFOH0P1.js +1 -0
  3. package/dist/docs/assets/chunks/@localSearchIndexroot.Cuu7C9vz.js +1 -0
  4. package/dist/docs/assets/chunks/VPLocalSearchBox.CYDhNgXW.js +9 -0
  5. package/dist/docs/assets/chunks/abnfDiagram-VRR7QNED.RG1C5NpS.js +1 -0
  6. package/dist/docs/assets/chunks/arc.C9NMazfV.js +1 -0
  7. package/dist/docs/assets/chunks/architectureDiagram-ZJ3FMSHR.u2IZtOa6.js +36 -0
  8. package/dist/docs/assets/chunks/blockDiagram-677ZJIJ3.DdHVir7t.js +132 -0
  9. package/dist/docs/assets/chunks/c4Diagram-LMCZKHZV.gSbgoaJo.js +10 -0
  10. package/dist/docs/assets/chunks/channel.Cc6zpfFP.js +1 -0
  11. package/dist/docs/assets/chunks/chunk-2Q5K7J3B.HRSdtksv.js +1 -0
  12. package/dist/docs/assets/chunks/chunk-32BRIVSS.BYzKapof.js +1 -0
  13. package/dist/docs/assets/chunks/chunk-5VM5RSS4.c3oeF0uS.js +15 -0
  14. package/dist/docs/assets/chunks/chunk-EX3LRPZG.Cz5AKl7t.js +231 -0
  15. package/dist/docs/assets/chunks/chunk-JWPE2WC7.DtJxsA7-.js +1 -0
  16. package/dist/docs/assets/chunks/chunk-MOJQB5TN.h5kO0Dtu.js +88 -0
  17. package/dist/docs/assets/chunks/chunk-RYQCIY6F.Ch_NfMTR.js +1 -0
  18. package/dist/docs/assets/chunks/chunk-V7JOEXUC.CHrHyPoW.js +206 -0
  19. package/dist/docs/assets/chunks/chunk-VR4S4FIN.DG8DIrH3.js +1 -0
  20. package/dist/docs/assets/chunks/chunk-XXDRQBXY.CSXBN12Y.js +1 -0
  21. package/dist/docs/assets/chunks/classDiagram-OUVF2IWQ.DV5B4KLJ.js +1 -0
  22. package/dist/docs/assets/chunks/classDiagram-v2-EOCWNBFH.DV5B4KLJ.js +1 -0
  23. package/dist/docs/assets/chunks/cose-bilkent-JH36ORCC.BeFuOTgi.js +1 -0
  24. package/dist/docs/assets/chunks/cynefin-VYW2F7L2.DaXIfh7Y.js +178 -0
  25. package/dist/docs/assets/chunks/cynefinDiagram-TSTJHNR4.BrJcHEEe.js +62 -0
  26. package/dist/docs/assets/chunks/cytoscape.esm.CUqq0XTU.js +331 -0
  27. package/dist/docs/assets/chunks/dagre-VKFMJZFB.D4vaA23X.js +4 -0
  28. package/dist/docs/assets/chunks/defaultLocale.DX6XiGOO.js +1 -0
  29. package/dist/docs/assets/chunks/diagram-FQU43EPY.uwRFLKRx.js +3 -0
  30. package/dist/docs/assets/chunks/diagram-G47NLZAW.Byfc9d0H.js +24 -0
  31. package/dist/docs/assets/chunks/diagram-NH7WQ7WH.CxjBEGZX.js +24 -0
  32. package/dist/docs/assets/chunks/diagram-OA4YK3LP.CU1jGXMi.js +30 -0
  33. package/dist/docs/assets/chunks/diagram-WEI45ONY.yXgVkURA.js +41 -0
  34. package/dist/docs/assets/chunks/ebnfDiagram-CCIWWBDH.UucqGQ_d.js +1 -0
  35. package/dist/docs/assets/chunks/erDiagram-Q63AITRT.C6qmOrvh.js +85 -0
  36. package/dist/docs/assets/chunks/flowDiagram-23GEKE2U.BZLu-WUl.js +156 -0
  37. package/dist/docs/assets/chunks/framework.D_Xv2a7c.js +19 -0
  38. package/dist/docs/assets/chunks/ganttDiagram-NO4QXBWP.DUzsw4Yr.js +292 -0
  39. package/dist/docs/assets/chunks/gitGraphDiagram-IHSO6WYX.BqLfYTI7.js +106 -0
  40. package/dist/docs/assets/chunks/graph.C2PyVmSI.js +1 -0
  41. package/dist/docs/assets/chunks/infoDiagram-FWYZ7A6U.CiKWveW9.js +2 -0
  42. package/dist/docs/assets/chunks/init.Gi6I4Gst.js +1 -0
  43. package/dist/docs/assets/chunks/ishikawaDiagram-FXEZZL3T.jerUXEXA.js +70 -0
  44. package/dist/docs/assets/chunks/journeyDiagram-5HDEW3XC.Cqzvo6I_.js +139 -0
  45. package/dist/docs/assets/chunks/kanban-definition-HUTT4EX6.BzJ4OPe5.js +89 -0
  46. package/dist/docs/assets/chunks/katex.C5jXJg4s.js +257 -0
  47. package/dist/docs/assets/chunks/layout.BG3qr61M.js +1 -0
  48. package/dist/docs/assets/chunks/linear.hFjgYGMN.js +1 -0
  49. package/dist/docs/assets/chunks/map.DwDi8XlU.js +1 -0
  50. package/dist/docs/assets/chunks/mermaid-client.D3gEaJ5e.js +2 -0
  51. package/dist/docs/assets/chunks/mermaid.core.CEHdFh45.js +314 -0
  52. package/dist/docs/assets/chunks/mindmap-definition-LN4V7U3C.ChC5FJW6.js +96 -0
  53. package/dist/docs/assets/chunks/ordinal.BYWQX77i.js +1 -0
  54. package/dist/docs/assets/chunks/pegDiagram-2B236MQR.ClnjsRYs.js +1 -0
  55. package/dist/docs/assets/chunks/pieDiagram-ENE6RG2P.Bb0MqerK.js +39 -0
  56. package/dist/docs/assets/chunks/quadrantDiagram-ABIIQ3AL.Do6HK_yb.js +7 -0
  57. package/dist/docs/assets/chunks/railroadDiagram-RFXS5EU6.D35m6hQn.js +1 -0
  58. package/dist/docs/assets/chunks/requirementDiagram-TGXJPOKE.DMtjRYUg.js +84 -0
  59. package/dist/docs/assets/chunks/sankeyDiagram-HTMAVEWB.dfXDu62B.js +40 -0
  60. package/dist/docs/assets/chunks/sequenceDiagram-DBY2YBRQ.CLZ0rZTY.js +162 -0
  61. package/dist/docs/assets/chunks/sizeCapture-X5ZJPWSS.DWvGYLUT.js +1 -0
  62. package/dist/docs/assets/chunks/stateDiagram-2N3HPSRC.DY8sDkI0.js +1 -0
  63. package/dist/docs/assets/chunks/stateDiagram-v2-6OUMAXLB.B9v-Vq5L.js +1 -0
  64. package/dist/docs/assets/chunks/swimlanes-5IMT3BWC.Dy9SffeT.js +2 -0
  65. package/dist/docs/assets/chunks/swimlanesDiagram-G3AALYLV.Kb9LnCTH.js +8 -0
  66. package/dist/docs/assets/chunks/theme.BLEczZWC.js +2 -0
  67. package/dist/docs/assets/chunks/timeline-definition-FHXFAJF6.CH6uzgIu.js +120 -0
  68. package/dist/docs/assets/chunks/vennDiagram-L72KCM5P.7EBCJmyP.js +34 -0
  69. package/dist/docs/assets/chunks/wardleyDiagram-EHGQE667.DPHAQssL.js +78 -0
  70. package/dist/docs/assets/chunks/xychartDiagram-FW5EYKEG.aKgxZVbK.js +7 -0
  71. package/dist/docs/assets/index.md.p9floL_p.js +1 -0
  72. package/dist/docs/assets/index.md.p9floL_p.lean.js +1 -0
  73. package/dist/docs/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
  74. package/dist/docs/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
  75. package/dist/docs/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
  76. package/dist/docs/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
  77. package/dist/docs/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
  78. package/dist/docs/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
  79. package/dist/docs/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
  80. package/dist/docs/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
  81. package/dist/docs/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
  82. package/dist/docs/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
  83. package/dist/docs/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
  84. package/dist/docs/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
  85. package/dist/docs/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
  86. package/dist/docs/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
  87. package/dist/docs/assets/overview.md.BKVdLT3o.js +70 -0
  88. package/dist/docs/assets/overview.md.BKVdLT3o.lean.js +1 -0
  89. package/dist/docs/assets/packages-utils.md.CvgYp5Ll.js +31 -0
  90. package/dist/docs/assets/packages-utils.md.CvgYp5Ll.lean.js +1 -0
  91. package/dist/docs/assets/proxy-admin_env-and-build.md.xkeQNYS3.js +40 -0
  92. package/dist/docs/assets/proxy-admin_env-and-build.md.xkeQNYS3.lean.js +1 -0
  93. package/dist/docs/assets/proxy-admin_index.md.DBLI0n0G.js +38 -0
  94. package/dist/docs/assets/proxy-admin_index.md.DBLI0n0G.lean.js +1 -0
  95. package/dist/docs/assets/proxy-admin_layout-and-menu.md.BKGcu49p.js +48 -0
  96. package/dist/docs/assets/proxy-admin_layout-and-menu.md.BKGcu49p.lean.js +1 -0
  97. package/dist/docs/assets/proxy-admin_pages.md.m_fGvvOH.js +51 -0
  98. package/dist/docs/assets/proxy-admin_pages.md.m_fGvvOH.lean.js +1 -0
  99. package/dist/docs/assets/proxy-admin_routing-and-auth.md.DZsdFese.js +106 -0
  100. package/dist/docs/assets/proxy-admin_routing-and-auth.md.DZsdFese.lean.js +1 -0
  101. package/dist/docs/assets/proxy-admin_services-and-mock.md.sdNPcf25.js +66 -0
  102. package/dist/docs/assets/proxy-admin_services-and-mock.md.sdNPcf25.lean.js +1 -0
  103. package/dist/docs/assets/proxy-cli_api-layer.md.GfdbtEUx.js +1 -0
  104. package/dist/docs/assets/proxy-cli_api-layer.md.GfdbtEUx.lean.js +1 -0
  105. package/dist/docs/assets/proxy-cli_app-shell.md.Do18CYhW.js +83 -0
  106. package/dist/docs/assets/proxy-cli_app-shell.md.Do18CYhW.lean.js +1 -0
  107. package/dist/docs/assets/proxy-cli_components-common.md.Dd6Yazvz.js +23 -0
  108. package/dist/docs/assets/proxy-cli_components-common.md.Dd6Yazvz.lean.js +1 -0
  109. package/dist/docs/assets/proxy-cli_components-config.md.B81Y3ta2.js +46 -0
  110. package/dist/docs/assets/proxy-cli_components-config.md.B81Y3ta2.lean.js +1 -0
  111. package/dist/docs/assets/proxy-cli_components-requests.md.vN8IrwL_.js +84 -0
  112. package/dist/docs/assets/proxy-cli_components-requests.md.vN8IrwL_.lean.js +1 -0
  113. package/dist/docs/assets/proxy-cli_components-stats.md.B90esaNa.js +14 -0
  114. package/dist/docs/assets/proxy-cli_components-stats.md.B90esaNa.lean.js +1 -0
  115. package/dist/docs/assets/proxy-cli_components-status.md.C5lAzS2c.js +42 -0
  116. package/dist/docs/assets/proxy-cli_components-status.md.C5lAzS2c.lean.js +1 -0
  117. package/dist/docs/assets/proxy-cli_data-hooks.md.w9Oe1OD3.js +87 -0
  118. package/dist/docs/assets/proxy-cli_data-hooks.md.w9Oe1OD3.lean.js +1 -0
  119. package/dist/docs/assets/proxy-cli_index.md.BA6g8QD-.js +34 -0
  120. package/dist/docs/assets/proxy-cli_index.md.BA6g8QD-.lean.js +1 -0
  121. package/dist/docs/assets/proxy-cli_utils-and-i18n.md.Ch_e-g_o.js +34 -0
  122. package/dist/docs/assets/proxy-cli_utils-and-i18n.md.Ch_e-g_o.lean.js +1 -0
  123. package/dist/docs/assets/proxy-core_chat-api.md.DHihiBxR.js +152 -0
  124. package/dist/docs/assets/proxy-core_chat-api.md.DHihiBxR.lean.js +1 -0
  125. package/dist/docs/assets/proxy-core_cli.md.DCFYX4Bd.js +37 -0
  126. package/dist/docs/assets/proxy-core_cli.md.DCFYX4Bd.lean.js +1 -0
  127. package/dist/docs/assets/proxy-core_config.md.BXSOyxYE.js +83 -0
  128. package/dist/docs/assets/proxy-core_config.md.BXSOyxYE.lean.js +1 -0
  129. package/dist/docs/assets/proxy-core_data-layer.md.Cdomb3Gz.js +85 -0
  130. package/dist/docs/assets/proxy-core_data-layer.md.Cdomb3Gz.lean.js +1 -0
  131. package/dist/docs/assets/proxy-core_entry.md.BZmIcCUM.js +90 -0
  132. package/dist/docs/assets/proxy-core_entry.md.BZmIcCUM.lean.js +1 -0
  133. package/dist/docs/assets/proxy-core_index.md.BM6VV5Qe.js +55 -0
  134. package/dist/docs/assets/proxy-core_index.md.BM6VV5Qe.lean.js +1 -0
  135. package/dist/docs/assets/proxy-core_pm2.md.DUhWEtgn.js +79 -0
  136. package/dist/docs/assets/proxy-core_pm2.md.DUhWEtgn.lean.js +1 -0
  137. package/dist/docs/assets/proxy-core_providers.md.CbDZ6b_7.js +1 -0
  138. package/dist/docs/assets/proxy-core_providers.md.CbDZ6b_7.lean.js +1 -0
  139. package/dist/docs/assets/proxy-core_proxy.md.CzQYmX6X.js +46 -0
  140. package/dist/docs/assets/proxy-core_proxy.md.CzQYmX6X.lean.js +1 -0
  141. package/dist/docs/assets/proxy-core_stats.md.BsM6wuK_.js +42 -0
  142. package/dist/docs/assets/proxy-core_stats.md.BsM6wuK_.lean.js +1 -0
  143. package/dist/docs/assets/proxy-core_tool.md.B6Le1nQr.js +100 -0
  144. package/dist/docs/assets/proxy-core_tool.md.B6Le1nQr.lean.js +1 -0
  145. package/dist/docs/assets/proxy-core_ui-routes.md.Dyqkeoiv.js +27 -0
  146. package/dist/docs/assets/proxy-core_ui-routes.md.Dyqkeoiv.lean.js +1 -0
  147. package/dist/docs/assets/proxy-core_utilities.md.C18pjnkz.js +63 -0
  148. package/dist/docs/assets/proxy-core_utilities.md.C18pjnkz.lean.js +1 -0
  149. package/dist/docs/assets/quickstart.md.Cy_FmXIY.js +38 -0
  150. package/dist/docs/assets/quickstart.md.Cy_FmXIY.lean.js +1 -0
  151. package/dist/docs/assets/request-flow.md.C1fyxdPE.js +146 -0
  152. package/dist/docs/assets/request-flow.md.C1fyxdPE.lean.js +1 -0
  153. package/dist/docs/assets/style.DU_kNMWy.css +1 -0
  154. package/dist/docs/hashmap.json +1 -0
  155. package/dist/docs/index.html +25 -0
  156. package/dist/docs/overview.html +94 -0
  157. package/dist/docs/packages-utils.html +55 -0
  158. package/dist/docs/proxy-admin/env-and-build.html +64 -0
  159. package/dist/docs/proxy-admin/index.html +62 -0
  160. package/dist/docs/proxy-admin/layout-and-menu.html +72 -0
  161. package/dist/docs/proxy-admin/pages.html +75 -0
  162. package/dist/docs/proxy-admin/routing-and-auth.html +130 -0
  163. package/dist/docs/proxy-admin/services-and-mock.html +90 -0
  164. package/dist/docs/proxy-cli/api-layer.html +38 -0
  165. package/dist/docs/proxy-cli/app-shell.html +107 -0
  166. package/dist/docs/proxy-cli/components-common.html +47 -0
  167. package/dist/docs/proxy-cli/components-config.html +70 -0
  168. package/dist/docs/proxy-cli/components-requests.html +108 -0
  169. package/dist/docs/proxy-cli/components-stats.html +38 -0
  170. package/dist/docs/proxy-cli/components-status.html +66 -0
  171. package/dist/docs/proxy-cli/data-hooks.html +111 -0
  172. package/dist/docs/proxy-cli/index.html +58 -0
  173. package/dist/docs/proxy-cli/utils-and-i18n.html +58 -0
  174. package/dist/docs/proxy-core/chat-api.html +176 -0
  175. package/dist/docs/proxy-core/cli.html +61 -0
  176. package/dist/docs/proxy-core/config.html +107 -0
  177. package/dist/docs/proxy-core/data-layer.html +109 -0
  178. package/dist/docs/proxy-core/entry.html +114 -0
  179. package/dist/docs/proxy-core/index.html +79 -0
  180. package/dist/docs/proxy-core/pm2.html +103 -0
  181. package/dist/docs/proxy-core/providers.html +39 -0
  182. package/dist/docs/proxy-core/proxy.html +70 -0
  183. package/dist/docs/proxy-core/stats.html +66 -0
  184. package/dist/docs/proxy-core/tool.html +124 -0
  185. package/dist/docs/proxy-core/ui-routes.html +51 -0
  186. package/dist/docs/proxy-core/utilities.html +87 -0
  187. package/dist/docs/quickstart.html +62 -0
  188. package/dist/docs/request-flow.html +170 -0
  189. package/dist/docs/vp-icons.css +0 -0
  190. package/dist/server/proxy.js +2 -1
  191. package/dist/ui/assets/{1c-KmWe8RWs.js → 1c-DPsrzNHI.js} +1 -1
  192. package/dist/ui/assets/{abnf-BKQ6qIuo.js → abnf-DNkBIQRO.js} +1 -1
  193. package/dist/ui/assets/{abnfDiagram-VRR7QNED-CkRuDPu1.js → abnfDiagram-VRR7QNED-BqvHvzR8.js} +1 -1
  194. package/dist/ui/assets/{accesslog-DD9H5Ktc.js → accesslog-D5NxQ43Q.js} +1 -1
  195. package/dist/ui/assets/{actionscript-CAjf2Qtd.js → actionscript-DLr-LB2m.js} +1 -1
  196. package/dist/ui/assets/{ada-BXkXW16O.js → ada-BRSz3tHX.js} +1 -1
  197. package/dist/ui/assets/{angelscript-BxT7o0Up.js → angelscript-DMtEGgIa.js} +1 -1
  198. package/dist/ui/assets/{apache-C5z_tmVm.js → apache-C4gn4cSd.js} +1 -1
  199. package/dist/ui/assets/{applescript-DdIxl8rr.js → applescript-DoodcTwg.js} +1 -1
  200. package/dist/ui/assets/{arc-hSdFaqKn.js → arc-HmnzaGf9.js} +1 -1
  201. package/dist/ui/assets/{arcade-D5m0roat.js → arcade-RJZZSHSl.js} +1 -1
  202. package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-DOSHSqzf.js → architectureDiagram-ZJ3FMSHR-BUfDpSIw.js} +1 -1
  203. package/dist/ui/assets/{arduino-FDap8kq-.js → arduino-n6Dpx6Ig.js} +1 -1
  204. package/dist/ui/assets/{armasm-Kzp-Jr1v.js → armasm-DzCVITGB.js} +1 -1
  205. package/dist/ui/assets/{asciidoc-DbGMW3EE.js → asciidoc-CaqMsApq.js} +1 -1
  206. package/dist/ui/assets/{aspectj-CVYMmBCO.js → aspectj-B0kIcV0v.js} +1 -1
  207. package/dist/ui/assets/{autohotkey-9PmBGTPd.js → autohotkey-xUEXewap.js} +1 -1
  208. package/dist/ui/assets/{autoit-B4F86jgh.js → autoit-D3OfN2VX.js} +1 -1
  209. package/dist/ui/assets/{avrasm-CSzv2eHX.js → avrasm-Cbf0F4Kf.js} +1 -1
  210. package/dist/ui/assets/{awk-CjsvYvZE.js → awk-Cc0rWEwe.js} +1 -1
  211. package/dist/ui/assets/{axapta-BVgMoNRY.js → axapta-BKEeoUEe.js} +1 -1
  212. package/dist/ui/assets/{bash-IeBjW3pt.js → bash-D6JH6L3m.js} +1 -1
  213. package/dist/ui/assets/{basic-BTFJfmV1.js → basic-ka6JXc9C.js} +1 -1
  214. package/dist/ui/assets/{blockDiagram-677ZJIJ3-DLw3Bbhf.js → blockDiagram-677ZJIJ3-BHXRSjnM.js} +1 -1
  215. package/dist/ui/assets/{bnf-rCkeRYk0.js → bnf-Bxclk5tZ.js} +1 -1
  216. package/dist/ui/assets/{brainfuck-DBHuB3uZ.js → brainfuck--s_Fd8b9.js} +1 -1
  217. package/dist/ui/assets/{coq-TwFFolHa.js → c-BsgdDna0.js} +1 -1
  218. package/dist/ui/assets/{c-like-CK1xGeX_.js → c-like-CNkOkbqh.js} +1 -1
  219. package/dist/ui/assets/{c4Diagram-LMCZKHZV-cqY51yJw.js → c4Diagram-LMCZKHZV-Bp1uSrW8.js} +1 -1
  220. package/dist/ui/assets/{cal-BxGPpEZK.js → cal-LVlIOy9W.js} +1 -1
  221. package/dist/ui/assets/{capnproto-Bo2fgXF9.js → capnproto-r9DiQ1H8.js} +1 -1
  222. package/dist/ui/assets/{ceylon-C4Bb4pNB.js → ceylon-CTNzyZJX.js} +1 -1
  223. package/dist/ui/assets/channel-_rFUXR2i.js +1 -0
  224. package/dist/ui/assets/{chunk-2Q5K7J3B-CGTiTBmo.js → chunk-2Q5K7J3B-nnLVtUW3.js} +1 -1
  225. package/dist/ui/assets/{chunk-32BRIVSS-DWagYBp9.js → chunk-32BRIVSS-BDNS6igp.js} +1 -1
  226. package/dist/ui/assets/{chunk-5VM5RSS4-BzSBMKJX.js → chunk-5VM5RSS4-D713xBhI.js} +1 -1
  227. package/dist/ui/assets/{chunk-EX3LRPZG-4-aKwCgZ.js → chunk-EX3LRPZG-DExsU6Rd.js} +1 -1
  228. package/dist/ui/assets/{chunk-JWPE2WC7-CPC_cBN0.js → chunk-JWPE2WC7-DcpW5RnW.js} +1 -1
  229. package/dist/ui/assets/{chunk-MOJQB5TN-DrDE4H9w.js → chunk-MOJQB5TN-BQiSZNTn.js} +1 -1
  230. package/dist/ui/assets/{chunk-RYQCIY6F-DkdXe_kU.js → chunk-RYQCIY6F-DfblgZPd.js} +1 -1
  231. package/dist/ui/assets/{chunk-V7JOEXUC-Da6EWcQt.js → chunk-V7JOEXUC-np--VgmN.js} +1 -1
  232. package/dist/ui/assets/{chunk-VR4S4FIN-nP6dstD5.js → chunk-VR4S4FIN-BG0IhjO6.js} +1 -1
  233. package/dist/ui/assets/{chunk-XXDRQBXY-Bi_rRAPA.js → chunk-XXDRQBXY-DHuoh-RB.js} +1 -1
  234. package/dist/ui/assets/classDiagram-OUVF2IWQ-DqgbMzM1.js +1 -0
  235. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-DqgbMzM1.js +1 -0
  236. package/dist/ui/assets/{clean-cc1m9AxK.js → clean-CtVj0-EB.js} +1 -1
  237. package/dist/ui/assets/{clojure-DX5V8QA8.js → clojure-CZwle60-.js} +1 -1
  238. package/dist/ui/assets/{clojure-repl-FzjnVNWQ.js → clojure-repl-DJXWH00I.js} +1 -1
  239. package/dist/ui/assets/{cmake-COZZyrKs.js → cmake-Boxf0e7r.js} +1 -1
  240. package/dist/ui/assets/{coffeescript-DBsnOmC4.js → coffeescript-h85ZW4Gm.js} +1 -1
  241. package/dist/ui/assets/{c-C95V0zHL.js → coq-CVLui3m8.js} +1 -1
  242. package/dist/ui/assets/{cos-Dm5g-IQT.js → cos-CL0igafw.js} +1 -1
  243. package/dist/ui/assets/{cose-bilkent-JH36ORCC-B3-weOQF.js → cose-bilkent-JH36ORCC-CnXyotYB.js} +1 -1
  244. package/dist/ui/assets/{cpp-_RZxQjg7.js → cpp-vite1NvJ.js} +1 -1
  245. package/dist/ui/assets/{crmsh-DGPJ11Gt.js → crmsh-DqT9g0Iq.js} +1 -1
  246. package/dist/ui/assets/{crystal-BOMSPGge.js → crystal-Oans-K8G.js} +1 -1
  247. package/dist/ui/assets/{csharp-DZXiHH72.js → csharp-sCaDAzIB.js} +1 -1
  248. package/dist/ui/assets/{csp-DDSIMUoU.js → csp-rMcp93pK.js} +1 -1
  249. package/dist/ui/assets/{css-Bjye-ZWr.js → css-BwDLHi_h.js} +1 -1
  250. package/dist/ui/assets/{cynefin-VYW2F7L2-Cj5c4L3y.js → cynefin-VYW2F7L2-D8Bmecdd.js} +1 -1
  251. package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-BYsfTeNX.js → cynefinDiagram-TSTJHNR4-BT2YFmPZ.js} +1 -1
  252. package/dist/ui/assets/{d-22pfurOx.js → d-BFgZm0RV.js} +1 -1
  253. package/dist/ui/assets/{dagre-VKFMJZFB-DiEob-by.js → dagre-VKFMJZFB-BeJU73ex.js} +1 -1
  254. package/dist/ui/assets/{dart-Doiu8cDW.js → dart-rIo85iL3.js} +1 -1
  255. package/dist/ui/assets/{delphi-CQ7epp84.js → delphi-Bi2Rfp1o.js} +1 -1
  256. package/dist/ui/assets/{diagram-FQU43EPY-BOPbQcL4.js → diagram-FQU43EPY-CHQiS5Fr.js} +1 -1
  257. package/dist/ui/assets/{diagram-G47NLZAW-C1UWDJTx.js → diagram-G47NLZAW-EVerd4V8.js} +1 -1
  258. package/dist/ui/assets/{diagram-NH7WQ7WH-CYsBqW3J.js → diagram-NH7WQ7WH-DMP0VOAs.js} +1 -1
  259. package/dist/ui/assets/{diagram-OA4YK3LP-Dnag0x_3.js → diagram-OA4YK3LP-CAur5jK9.js} +1 -1
  260. package/dist/ui/assets/{diagram-WEI45ONY-Bo4CsDoj.js → diagram-WEI45ONY-DvmKkPH7.js} +1 -1
  261. package/dist/ui/assets/{diff-Cs6VQQZt.js → diff-CZZCIG00.js} +1 -1
  262. package/dist/ui/assets/{django-Bo3okOrw.js → django-D88PKHy-.js} +1 -1
  263. package/dist/ui/assets/{dns-BpG60eIX.js → dns-DX4hzjUh.js} +1 -1
  264. package/dist/ui/assets/{dockerfile-BWyH8SlV.js → dockerfile-1lgzEXn1.js} +1 -1
  265. package/dist/ui/assets/{dos-DWlNbaB9.js → dos-CwrC1ROy.js} +1 -1
  266. package/dist/ui/assets/{dsconfig-D_8y8YrJ.js → dsconfig-tvVdBv4w.js} +1 -1
  267. package/dist/ui/assets/{dts-Cz4SyMYR.js → dts-DTgQkdRs.js} +1 -1
  268. package/dist/ui/assets/{dust-Cu4qLkeH.js → dust-BbLlyCpf.js} +1 -1
  269. package/dist/ui/assets/{ebnf-CTVHui3r.js → ebnf-D6Dc4oRr.js} +1 -1
  270. package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-epcXQLEj.js → ebnfDiagram-CCIWWBDH-Kvilk1RF.js} +1 -1
  271. package/dist/ui/assets/{elixir-MAlwXhfU.js → elixir-CnMolQVs.js} +1 -1
  272. package/dist/ui/assets/{elm-Bdmwbvef.js → elm-BQ7VQFn7.js} +1 -1
  273. package/dist/ui/assets/{erDiagram-Q63AITRT-Bb60TqAM.js → erDiagram-Q63AITRT-C-S9oHZd.js} +1 -1
  274. package/dist/ui/assets/{erb-Ce9TpP4g.js → erb-B_1g6fXE.js} +1 -1
  275. package/dist/ui/assets/{erlang-CN2GEiqk.js → erlang-3b3ITXJu.js} +1 -1
  276. package/dist/ui/assets/{erlang-repl-D8K4O_cp.js → erlang-repl-Cy6Z3TdH.js} +1 -1
  277. package/dist/ui/assets/{excel-eVZU1r0f.js → excel-DtkATto8.js} +1 -1
  278. package/dist/ui/assets/{fix-BzKerEv0.js → fix-DsEG7TDI.js} +1 -1
  279. package/dist/ui/assets/{flix-B9CE3skV.js → flix-CQ-rKwGO.js} +1 -1
  280. package/dist/ui/assets/{flowDiagram-23GEKE2U-DzMLZIyt.js → flowDiagram-23GEKE2U-EbHDNMCC.js} +1 -1
  281. package/dist/ui/assets/{fortran-B4__3vos.js → fortran-AqzaRCEt.js} +1 -1
  282. package/dist/ui/assets/{fsharp-BJ3-ARHz.js → fsharp-CCzWGasu.js} +1 -1
  283. package/dist/ui/assets/{gams-Cu43oSYT.js → gams-Bqa6CB_r.js} +1 -1
  284. package/dist/ui/assets/{ganttDiagram-NO4QXBWP-D_aAoMRP.js → ganttDiagram-NO4QXBWP-B6jvc6O7.js} +1 -1
  285. package/dist/ui/assets/{gauss-T8vk_TpE.js → gauss-D4Utubeh.js} +1 -1
  286. package/dist/ui/assets/{gcode-9j3BicpZ.js → gcode-By3KwWjb.js} +1 -1
  287. package/dist/ui/assets/{gherkin-Dyh5KFG-.js → gherkin-PXOPjT7Y.js} +1 -1
  288. package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-CMxCHC-Z.js → gitGraphDiagram-IHSO6WYX-C5l6rHvK.js} +1 -1
  289. package/dist/ui/assets/{glsl-DWWjN4ts.js → glsl-KmmyBk93.js} +1 -1
  290. package/dist/ui/assets/{gml-BcYE-D5A.js → gml-C1Qw_Nrt.js} +1 -1
  291. package/dist/ui/assets/{go-DUnUzOEI.js → go-DaBQtdp1.js} +1 -1
  292. package/dist/ui/assets/{golo-BDoc1QQL.js → golo-D7PDzNpb.js} +1 -1
  293. package/dist/ui/assets/{gradle-B_WRa_bT.js → gradle-nXueCYH-.js} +1 -1
  294. package/dist/ui/assets/{groovy-CgjqFq1e.js → groovy-DFDsQDhl.js} +1 -1
  295. package/dist/ui/assets/{haml-DCqcg7Ti.js → haml-B_zxHzy_.js} +1 -1
  296. package/dist/ui/assets/{handlebars-DSDUQrnw.js → handlebars-BdMY-8KA.js} +1 -1
  297. package/dist/ui/assets/{haskell-DPVnctVi.js → haskell-CftsIPps.js} +1 -1
  298. package/dist/ui/assets/{haxe-BuCGXBa4.js → haxe-BFZb0OIE.js} +1 -1
  299. package/dist/ui/assets/{hsp-BTKpS_u0.js → hsp-EPTuqwtZ.js} +1 -1
  300. package/dist/ui/assets/{htmlbars-Cql3Jvy2.js → htmlbars-B7ZSC-iN.js} +1 -1
  301. package/dist/ui/assets/{http-BB8I9jUh.js → http-BxSd_aa1.js} +1 -1
  302. package/dist/ui/assets/{hy-DG7xkZNz.js → hy-D-rBN9MQ.js} +1 -1
  303. package/dist/ui/assets/index-CWFn1h-J.css +10 -0
  304. package/dist/ui/assets/{index-CfTIGTiY.js → index-DSGZBcd1.js} +166 -171
  305. package/dist/ui/assets/{index-DqIiCkSD.js → index-Dlp8uGHu.js} +3 -3
  306. package/dist/ui/assets/{infoDiagram-FWYZ7A6U-DIzEV-BJ.js → infoDiagram-FWYZ7A6U-BOF_kBqe.js} +1 -1
  307. package/dist/ui/assets/{inform7-BWNpVEkA.js → inform7-OjpbRXZf.js} +1 -1
  308. package/dist/ui/assets/{ini-BMw_C8EP.js → ini-Dc-QApXQ.js} +1 -1
  309. package/dist/ui/assets/{irpf90-Cy42ibFZ.js → irpf90-C4OfYiST.js} +1 -1
  310. package/dist/ui/assets/{isbl-CjFSc0hz.js → isbl-9km6K6Sf.js} +1 -1
  311. package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-BZcxp5am.js → ishikawaDiagram-FXEZZL3T-BvKSD8LY.js} +1 -1
  312. package/dist/ui/assets/{java-BDxe9dp1.js → java-C2mOf3QX.js} +1 -1
  313. package/dist/ui/assets/{javascript-CgLkkj7h.js → javascript-_i0Q5MkQ.js} +1 -1
  314. package/dist/ui/assets/{jboss-cli-C8biclrb.js → jboss-cli-BS5ipQOv.js} +1 -1
  315. package/dist/ui/assets/{journeyDiagram-5HDEW3XC-BbJu6m6Q.js → journeyDiagram-5HDEW3XC-yKdSl63P.js} +1 -1
  316. package/dist/ui/assets/{json-BjJKhmM6.js → json-Dci0MO4x.js} +1 -1
  317. package/dist/ui/assets/{julia-DvKEpg-R.js → julia-bEqo4nlV.js} +1 -1
  318. package/dist/ui/assets/{julia-repl-BDJWZxkU.js → julia-repl-Co6hf47q.js} +1 -1
  319. package/dist/ui/assets/{kanban-definition-HUTT4EX6-DeIVPlbv.js → kanban-definition-HUTT4EX6-B7BbZCd6.js} +1 -1
  320. package/dist/ui/assets/{kotlin-DCoXcnEb.js → kotlin-krx8WewB.js} +1 -1
  321. package/dist/ui/assets/{lasso-C7m0QmV2.js → lasso-d3ZTv9Tj.js} +1 -1
  322. package/dist/ui/assets/{latex-SHnTG9Eq.js → latex-BNWbHYxK.js} +1 -1
  323. package/dist/ui/assets/{ldif-_6hUnKPV.js → ldif-Bs8eb63L.js} +1 -1
  324. package/dist/ui/assets/{leaf-Co9qxlaF.js → leaf-BTbRDVWB.js} +1 -1
  325. package/dist/ui/assets/{less-CJRDPwNA.js → less-DH5cqJTD.js} +1 -1
  326. package/dist/ui/assets/{lisp-JEHGYbiW.js → lisp-CBUvBYtR.js} +1 -1
  327. package/dist/ui/assets/{livecodeserver-BSYaUj4k.js → livecodeserver-CkM7-E4a.js} +1 -1
  328. package/dist/ui/assets/{livescript-WQMCQeuz.js → livescript-DomXyXUO.js} +1 -1
  329. package/dist/ui/assets/{llvm-DnAHqj5I.js → llvm-e_-ff59-.js} +1 -1
  330. package/dist/ui/assets/{lsl--k-ghYia.js → lsl-BNDsGOmv.js} +1 -1
  331. package/dist/ui/assets/{lua-CXb23hbC.js → lua-_ZmkXwc_.js} +1 -1
  332. package/dist/ui/assets/{makefile-CM7o86yn.js → makefile-BhG7cThe.js} +1 -1
  333. package/dist/ui/assets/{markdown-HB3HvChQ.js → markdown-ClW2SRy6.js} +1 -1
  334. package/dist/ui/assets/{mathematica-9NTuf22N.js → mathematica-kqoCR611.js} +1 -1
  335. package/dist/ui/assets/{matlab-CWv-ik4r.js → matlab-DqawyK3q.js} +1 -1
  336. package/dist/ui/assets/{maxima-CqYiKCrw.js → maxima-B0qzCXe1.js} +1 -1
  337. package/dist/ui/assets/{mel-BbsRpUm5.js → mel-BZaSas3B.js} +1 -1
  338. package/dist/ui/assets/{mercury-Cz2j4HhU.js → mercury-ByD0wyJH.js} +1 -1
  339. package/dist/ui/assets/{mindmap-definition-LN4V7U3C-WyJS8oye.js → mindmap-definition-LN4V7U3C-Ce6QsaH5.js} +1 -1
  340. package/dist/ui/assets/{mipsasm-BqWSRbQV.js → mipsasm-B08lqZSo.js} +1 -1
  341. package/dist/ui/assets/{mizar-JLBfQ6vt.js → mizar-7iaUqWPq.js} +1 -1
  342. package/dist/ui/assets/{mojolicious-D0LbMmyk.js → mojolicious-CbH-d8Wh.js} +1 -1
  343. package/dist/ui/assets/{monkey-DAGL6-JN.js → monkey-D5z6-hFH.js} +1 -1
  344. package/dist/ui/assets/{moonscript-DzbwNSKy.js → moonscript-DuLd7pdm.js} +1 -1
  345. package/dist/ui/assets/{n1ql-dkgKq6Yv.js → n1ql-EbVfQMfD.js} +1 -1
  346. package/dist/ui/assets/{nginx-AUoaDPV4.js → nginx-D-4AxpHP.js} +1 -1
  347. package/dist/ui/assets/{nim-CdqYmVrl.js → nim-wPHQEX5v.js} +1 -1
  348. package/dist/ui/assets/{nix-CxmVjwwo.js → nix-6SVkxAXi.js} +1 -1
  349. package/dist/ui/assets/{node-repl-B1Z3zUAh.js → node-repl-CaFKEOyj.js} +1 -1
  350. package/dist/ui/assets/{nsis-CTAuPWhe.js → nsis-BmqbwVv_.js} +1 -1
  351. package/dist/ui/assets/{objectivec-CvbKeAPz.js → objectivec-BX0R-sI2.js} +1 -1
  352. package/dist/ui/assets/{ocaml-DCiyXKOH.js → ocaml-CyfdrIqo.js} +1 -1
  353. package/dist/ui/assets/{openscad-CPGUwmeR.js → openscad-B5qfaF1E.js} +1 -1
  354. package/dist/ui/assets/{oxygene-CI_bD1Gw.js → oxygene-CmlCgXLr.js} +1 -1
  355. package/dist/ui/assets/{parser3-C91CVs85.js → parser3-DdpPyZkn.js} +1 -1
  356. package/dist/ui/assets/{pegDiagram-2B236MQR-yF8AW7GR.js → pegDiagram-2B236MQR-ByyVqaXh.js} +1 -1
  357. package/dist/ui/assets/{perl-ChxfKl-n.js → perl-D3qc2wEe.js} +1 -1
  358. package/dist/ui/assets/{pf-CKCHkzIA.js → pf-Bv3zza37.js} +1 -1
  359. package/dist/ui/assets/{pgsql-BwOP20uH.js → pgsql-BZIppw1a.js} +1 -1
  360. package/dist/ui/assets/{php-B7Rs2tM5.js → php-D1ScecZC.js} +1 -1
  361. package/dist/ui/assets/{php-template-Cx-Fh4AR.js → php-template-sEqzzKWJ.js} +1 -1
  362. package/dist/ui/assets/{pieDiagram-ENE6RG2P-BS4hnGNX.js → pieDiagram-ENE6RG2P-T1OgWN3l.js} +1 -1
  363. package/dist/ui/assets/{plaintext-U7qkdtgS.js → plaintext-DO7Jy_T2.js} +1 -1
  364. package/dist/ui/assets/{pony-_fGYgePh.js → pony-CTXTp2Tb.js} +1 -1
  365. package/dist/ui/assets/{powershell-CFBTcUce.js → powershell-C9lzZsbj.js} +1 -1
  366. package/dist/ui/assets/{processing-BWHneU0K.js → processing-hzJAP_Li.js} +1 -1
  367. package/dist/ui/assets/{profile-BJ-HxhzS.js → profile-bFiAkh7e.js} +1 -1
  368. package/dist/ui/assets/{prolog-ChHo7n6L.js → prolog-CE0trHSn.js} +1 -1
  369. package/dist/ui/assets/{properties-e_DOYclC.js → properties-MeANnTVc.js} +1 -1
  370. package/dist/ui/assets/{protobuf-5aGSIv7w.js → protobuf-S-rp7SK0.js} +1 -1
  371. package/dist/ui/assets/{puppet-D2vQatzX.js → puppet-B5YT8Ct1.js} +1 -1
  372. package/dist/ui/assets/{purebasic-n6krfaeF.js → purebasic-DO-5HeDl.js} +1 -1
  373. package/dist/ui/assets/{python-CbIo0XxP.js → python-DVGTQbwU.js} +1 -1
  374. package/dist/ui/assets/{python-repl-BpIq9kyr.js → python-repl-CQ4VlKLC.js} +1 -1
  375. package/dist/ui/assets/{q-jntnvcCx.js → q-nS96imov.js} +1 -1
  376. package/dist/ui/assets/{qml-BafQlZNV.js → qml-BkzkCgUU.js} +1 -1
  377. package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-C3Th8mUJ.js → quadrantDiagram-ABIIQ3AL-BkaCzlXD.js} +1 -1
  378. package/dist/ui/assets/{r-CHgvQFLK.js → r-y4Q5t85r.js} +1 -1
  379. package/dist/ui/assets/{railroadDiagram-RFXS5EU6-CMQkbGJl.js → railroadDiagram-RFXS5EU6-C1lbwk19.js} +1 -1
  380. package/dist/ui/assets/{reasonml-DNwlPD_T.js → reasonml-Bzhzc5Ao.js} +1 -1
  381. package/dist/ui/assets/{requirementDiagram-TGXJPOKE-B70_oR7v.js → requirementDiagram-TGXJPOKE-C8Rw6N2I.js} +1 -1
  382. package/dist/ui/assets/{rib-CX4e9JSF.js → rib-BP3Y9dW3.js} +1 -1
  383. package/dist/ui/assets/{roboconf-ee4qsPGf.js → roboconf-87QE7cIh.js} +1 -1
  384. package/dist/ui/assets/{routeros-BJSwvu2L.js → routeros-BV3nt8wW.js} +1 -1
  385. package/dist/ui/assets/{rsl-BiKdMl_F.js → rsl-DfQf4CW_.js} +1 -1
  386. package/dist/ui/assets/{ruby-CAXTU5LY.js → ruby-DQxFKbgX.js} +1 -1
  387. package/dist/ui/assets/{ruleslanguage-C1kgDGXM.js → ruleslanguage-B8oCm_aw.js} +1 -1
  388. package/dist/ui/assets/{rust-DyEf_GXL.js → rust-DzZgPf9W.js} +1 -1
  389. package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-CvUfseMg.js → sankeyDiagram-HTMAVEWB-Dxiuo8Hz.js} +1 -1
  390. package/dist/ui/assets/{sas-Q1rlUxPH.js → sas-CFh-Rsrv.js} +1 -1
  391. package/dist/ui/assets/{scala-Dg6KNmge.js → scala-3UDyJBiS.js} +1 -1
  392. package/dist/ui/assets/{scheme-D9iooUxI.js → scheme-KaUTge9W.js} +1 -1
  393. package/dist/ui/assets/{scilab-CztEJXJY.js → scilab-CLSBZzuh.js} +1 -1
  394. package/dist/ui/assets/{scss-BMh-JkdE.js → scss-DaEkfHWX.js} +1 -1
  395. package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DB0c9kf4.js → sequenceDiagram-DBY2YBRQ-Cv__zR2v.js} +1 -1
  396. package/dist/ui/assets/{shell-DWo6z0MG.js → shell-B0d4cZTk.js} +1 -1
  397. package/dist/ui/assets/{sizeCapture-X5ZJPWSS-BcQlgjfD.js → sizeCapture-X5ZJPWSS-C4nD-ShQ.js} +1 -1
  398. package/dist/ui/assets/{smali-Cijeb6pL.js → smali-CLhfky4R.js} +1 -1
  399. package/dist/ui/assets/{smalltalk-D0lvqa_d.js → smalltalk-B4aaTMO5.js} +1 -1
  400. package/dist/ui/assets/{sml-B-vqWZ3b.js → sml-x4CTxWEZ.js} +1 -1
  401. package/dist/ui/assets/{sqf-BJ-1Q583.js → sqf-G_0vdVVs.js} +1 -1
  402. package/dist/ui/assets/{sql-CMGLxEYV.js → sql-C--WH0Fo.js} +1 -1
  403. package/dist/ui/assets/{sql_more-gsRmbNCH.js → sql_more-B4LrzCtd.js} +1 -1
  404. package/dist/ui/assets/{stan-D1AlTSpf.js → stan-CACDFOA0.js} +1 -1
  405. package/dist/ui/assets/{stata-DnEYviI0.js → stata-BP9M7sZt.js} +1 -1
  406. package/dist/ui/assets/{stateDiagram-2N3HPSRC-BSRgVsHO.js → stateDiagram-2N3HPSRC-z3-31Cr2.js} +1 -1
  407. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-BKIXFHzO.js +1 -0
  408. package/dist/ui/assets/{step21-DbQV9sMo.js → step21-MAOu4dNb.js} +1 -1
  409. package/dist/ui/assets/{stylus-Cyc7vdUc.js → stylus-CpuP3pvE.js} +1 -1
  410. package/dist/ui/assets/{subunit-16ipyMie.js → subunit-NWzuqFhT.js} +1 -1
  411. package/dist/ui/assets/{swift-DTNnw4qS.js → swift-DuFKNmKv.js} +1 -1
  412. package/dist/ui/assets/{swimlanes-5IMT3BWC-DgOdcc4_.js → swimlanes-5IMT3BWC-E463-rXd.js} +2 -2
  413. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-CkQvBOYs.js +8 -0
  414. package/dist/ui/assets/{taggerscript-DM6pvUWE.js → taggerscript-BDnv2jvg.js} +1 -1
  415. package/dist/ui/assets/{tap-Ch-uyKZq.js → tap-aB2cLXdf.js} +1 -1
  416. package/dist/ui/assets/{tcl-D0T_V5dA.js → tcl-7WepIaIa.js} +1 -1
  417. package/dist/ui/assets/{thrift-D9xJjYw4.js → thrift-BLh6pdjc.js} +1 -1
  418. package/dist/ui/assets/{timeline-definition-FHXFAJF6-BBeDMHxb.js → timeline-definition-FHXFAJF6-FA_RNhFQ.js} +1 -1
  419. package/dist/ui/assets/{tp-kUrCGo9X.js → tp-D1rt5u_j.js} +1 -1
  420. package/dist/ui/assets/{twig-Cgub6rxA.js → twig-DgfeYg4W.js} +1 -1
  421. package/dist/ui/assets/{typescript-BxNP9Ap9.js → typescript-oU560Q8V.js} +1 -1
  422. package/dist/ui/assets/{vala-DF9ZZagU.js → vala-DlXsaz2B.js} +1 -1
  423. package/dist/ui/assets/{vbnet-Cf46ypDg.js → vbnet-BjpxjeMZ.js} +1 -1
  424. package/dist/ui/assets/{vbscript-DNs-QKLH.js → vbscript-DfNdtdO3.js} +1 -1
  425. package/dist/ui/assets/{vbscript-html-DyS6I5L1.js → vbscript-html-D09WPsgK.js} +1 -1
  426. package/dist/ui/assets/{vennDiagram-L72KCM5P-8WpWycE-.js → vennDiagram-L72KCM5P-zaCDWwTs.js} +1 -1
  427. package/dist/ui/assets/{verilog-CF5wC4X-.js → verilog-B9vENtLK.js} +1 -1
  428. package/dist/ui/assets/{vhdl-Dm0jpDMn.js → vhdl-CJLTZOu1.js} +1 -1
  429. package/dist/ui/assets/{vim-nyO2DRAx.js → vim-FuPhupu9.js} +1 -1
  430. package/dist/ui/assets/{wardleyDiagram-EHGQE667-UeIOK-jv.js → wardleyDiagram-EHGQE667-BS8ApwmV.js} +1 -1
  431. package/dist/ui/assets/{x86asm-BNw2-6GG.js → x86asm-kX_Cp6wB.js} +1 -1
  432. package/dist/ui/assets/{xl-D-YHxr6V.js → xl-MuHNmLUj.js} +1 -1
  433. package/dist/ui/assets/{xml-BijAlrow.js → xml-Mbn2z12n.js} +1 -1
  434. package/dist/ui/assets/{xquery-z0wxWBKz.js → xquery-Dy4lt-m-.js} +1 -1
  435. package/dist/ui/assets/{xychartDiagram-FW5EYKEG-BNzHLweN.js → xychartDiagram-FW5EYKEG-DoNZtZus.js} +1 -1
  436. package/dist/ui/assets/{yaml-n5TIQArR.js → yaml-CxxAisfE.js} +1 -1
  437. package/dist/ui/assets/{zephir-DrGhH8jG.js → zephir-WWG8qyld.js} +1 -1
  438. package/dist/ui/index.html +2 -2
  439. package/package.json +2 -2
  440. package/dist/ui/assets/channel-D9Y4iN1l.js +0 -1
  441. package/dist/ui/assets/classDiagram-OUVF2IWQ-C4UVH6RI.js +0 -1
  442. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-C4UVH6RI.js +0 -1
  443. package/dist/ui/assets/index-CK_lJsTu.css +0 -10
  444. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-BLdfpGJO.js +0 -1
  445. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DRVnkg3M.js +0 -8
@@ -0,0 +1,103 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN" dir="ltr">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <title>proxy-core / PM2 集成 | CC Monitoring</title>
7
+ <meta name="description" content="Claude Code 代理 + 监控系统文档">
8
+ <meta name="generator" content="VitePress v1.6.4">
9
+ <link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
10
+ <link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
11
+
12
+ <script type="module" src="/docs/assets/app.BxFOH0P1.js"></script>
13
+ <link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
14
+ <link rel="modulepreload" href="/docs/assets/chunks/theme.BLEczZWC.js">
15
+ <link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
16
+ <link rel="modulepreload" href="/docs/assets/proxy-core_pm2.md.DUhWEtgn.lean.js">
17
+ <script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
18
+ <script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
19
+ </head>
20
+ <body>
21
+ <div id="app"><div class="Layout" data-v-0fd5f79a><!--[--><!--]--><!--[--><span tabindex="-1" data-v-13bcab17></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-13bcab17>Skip to content</a><!--]--><!----><header class="VPNav" data-v-0fd5f79a data-v-221ddc7b><div class="VPNavBar" data-v-221ddc7b data-v-6a82b350><div class="wrapper" data-v-6a82b350><div class="container" data-v-6a82b350><div class="title" data-v-6a82b350><div class="VPNavBarTitle has-sidebar" data-v-6a82b350 data-v-98825d79><a class="title" href="/docs/" data-v-98825d79><!--[--><!--]--><!----><span data-v-98825d79>CC Monitoring</span><!--[--><!--]--></a></div></div><div class="content" data-v-6a82b350><div class="content-body" data-v-6a82b350><!--[--><!--]--><div class="VPNavBarSearch search" data-v-6a82b350><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-6a82b350 data-v-2fa375b4><span id="main-nav-aria-label" class="visually-hidden" data-v-2fa375b4> Main Navigation </span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/overview.html" tabindex="0" data-v-2fa375b4 data-v-88169469><!--[--><span data-v-88169469>概览</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/quickstart.html" tabindex="0" data-v-2fa375b4 data-v-88169469><!--[--><span data-v-88169469>快速开始</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/proxy-core/" tabindex="0" data-v-2fa375b4 data-v-88169469><!--[--><span data-v-88169469>Proxy Core</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/proxy-cli/" tabindex="0" data-v-2fa375b4 data-v-88169469><!--[--><span data-v-88169469>Proxy CLI</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/proxy-admin/" tabindex="0" data-v-2fa375b4 data-v-88169469><!--[--><span data-v-88169469>Proxy Admin</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-6a82b350 data-v-c7859fea><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-c7859fea data-v-458e2939 data-v-2fadb15f><span class="check" data-v-2fadb15f><span class="icon" data-v-2fadb15f><!--[--><span class="vpi-sun sun" data-v-458e2939></span><span class="vpi-moon moon" data-v-458e2939></span><!--]--></span></span></button></div><!----><div class="VPFlyout VPNavBarExtra extra" data-v-6a82b350 data-v-4a332738 data-v-3416cc30><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-3416cc30><span class="vpi-more-horizontal icon" data-v-3416cc30></span></button><div class="menu" data-v-3416cc30><div class="VPMenu" data-v-3416cc30 data-v-70b241a4><!----><!--[--><!--[--><!----><div class="group" data-v-4a332738><div class="item appearance" data-v-4a332738><p class="label" data-v-4a332738>Appearance</p><div class="appearance-action" data-v-4a332738><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-4a332738 data-v-458e2939 data-v-2fadb15f><span class="check" data-v-2fadb15f><span class="icon" data-v-2fadb15f><!--[--><span class="vpi-sun sun" data-v-458e2939></span><span class="vpi-moon moon" data-v-458e2939></span><!--]--></span></span></button></div></div></div><!----><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-6a82b350 data-v-2b9279da><span class="container" data-v-2b9279da><span class="top" data-v-2b9279da></span><span class="middle" data-v-2b9279da></span><span class="bottom" data-v-2b9279da></span></span></button></div></div></div></div><div class="divider" data-v-6a82b350><div class="divider-line" data-v-6a82b350></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-0fd5f79a data-v-751e8533><div class="container" data-v-751e8533><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-751e8533><span class="vpi-align-left menu-icon" data-v-751e8533></span><span class="menu-text" data-v-751e8533>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-751e8533 data-v-afd8288e><button data-v-afd8288e>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-0fd5f79a data-v-711af969><div class="curtain" data-v-711af969></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-711af969><span class="visually-hidden" id="sidebar-aria-label" data-v-711af969> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-4ebb8294><section class="VPSidebarItem level-0 has-active" data-v-4ebb8294 data-v-04203d25><div class="item" role="button" tabindex="0" data-v-04203d25><div class="indicator" data-v-04203d25></div><h2 class="text" data-v-04203d25>Proxy Core</h2><!----></div><div class="items" data-v-04203d25><!--[--><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/" data-v-04203d25><!--[--><p class="text" data-v-04203d25>模块概览</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/entry.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>入口与启动</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/cli.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>CLI 命令</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/proxy.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>代理转发</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/ui-routes.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>UI 路由</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/providers.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>供应商管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/config.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>配置与日志</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/data-layer.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>数据层</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/stats.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>统计与历史</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/tool.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>工具注入</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/pm2.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>PM2 集成</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/utilities.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>工具函数</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/chat-api.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>Chat API</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-0fd5f79a data-v-3aa167b9><div class="VPDoc has-sidebar has-aside" data-v-3aa167b9 data-v-b2c5ca34><!--[--><!--]--><div class="container" data-v-b2c5ca34><div class="aside" data-v-b2c5ca34><div class="aside-curtain" data-v-b2c5ca34></div><div class="aside-container" data-v-b2c5ca34><div class="aside-content" data-v-b2c5ca34><div class="VPDocAside" data-v-b2c5ca34 data-v-af7efbb6><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-af7efbb6 data-v-db542fa8><div class="content" data-v-db542fa8><div class="outline-marker" data-v-db542fa8></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-db542fa8>On this page</div><ul class="VPDocOutlineItem root" data-v-db542fa8 data-v-1d036821><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-af7efbb6></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-b2c5ca34><div class="content-container" data-v-b2c5ca34><!--[--><!--]--><main class="main" data-v-b2c5ca34><div style="position:relative;" class="vp-doc _docs_proxy-core_pm2" data-v-b2c5ca34><div><h1 id="proxy-core-pm2-集成" tabindex="-1">proxy-core / PM2 集成 <a class="header-anchor" href="#proxy-core-pm2-集成" aria-label="Permalink to &quot;proxy-core / PM2 集成&quot;">​</a></h1><h2 id="本文档覆盖的源文件" tabindex="-1">本文档覆盖的源文件 <a class="header-anchor" href="#本文档覆盖的源文件" aria-label="Permalink to &quot;本文档覆盖的源文件&quot;">​</a></h2><ul><li><code>apps/proxy-core/ecosystem.config.cjs</code></li><li><code>apps/proxy-core/src/utils/pm2.ts</code></li><li><code>apps/proxy-core/src/utils/esm-dirname.ts</code></li><li><code>apps/proxy-core/src/server/index.ts:42-60</code>(入口守卫)</li></ul><h2 id="挑战" tabindex="-1">挑战 <a class="header-anchor" href="#挑战" aria-label="Permalink to &quot;挑战&quot;">​</a></h2><p>项目根 <code>package.json</code> 声明了 <code>&quot;type&quot;: &quot;module&quot;</code>,因此所有 <code>.js</code> 文件默认按 ESM 加载。而 PM2 是 CJS 库,<code>ecosystem.config.js</code> 会被解析成 ESM,报 <code>Cannot use import statement / module.exports is not defined</code>。同时 PM2 fork 模式启动脚本时会替换 <code>process.argv[1]</code>,导致 ESM <code>import.meta.url === main module url</code> 判定失败。</p><p>三个应对:</p><ol><li><code>ecosystem.config.cjs</code> 用 <code>.cjs</code> 扩展名,绕过 <code>type: module</code> 全局设定</li><li><code>utils/pm2.ts</code> 用 <code>createRequire(import.meta.url)</code> 加载 PM2 库</li><li><code>server/index.ts</code> 用 <code>pm_id</code> / <code>NODE_APP_INSTANCE</code> 环境变量补检测</li></ol><h2 id="ecosystem-config-cjs-逐行" tabindex="-1"><code>ecosystem.config.cjs</code> 逐行 <a class="header-anchor" href="#ecosystem-config-cjs-逐行" aria-label="Permalink to &quot;`ecosystem.config.cjs` 逐行&quot;">​</a></h2><div class="language-js vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> path</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> require</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;path&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
22
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> os</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> require</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;os&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
23
+ <span class="line"></span>
24
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> dataDir</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process.env.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">CC_DATA_DIR</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ||</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(os.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">homedir</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(), </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;.cc-monitoring&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
25
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> logsDir</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(dataDir, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;logs&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
26
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> configPath</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process.env.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">CONFIG_PATH</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ||</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(dataDir, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;config.json&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
27
+ <span class="line"></span>
28
+ <span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">module</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">exports</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
29
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> apps: [{</span></span>
30
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;cc-monitoring&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
31
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> script: path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(__dirname, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;dist/server/index.js&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
32
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> cwd: dataDir,</span></span>
33
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> instances: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
34
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> exec_mode: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;fork&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
35
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> autorestart: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
36
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> watch: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">false</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
37
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> max_memory_restart: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;200M&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
38
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> env: {</span></span>
39
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> NODE_ENV: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;production&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
40
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CONFIG_PATH: configPath</span></span>
41
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
42
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> env_development: {</span></span>
43
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> NODE_ENV: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;development&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
44
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CONFIG_PATH: configPath</span></span>
45
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
46
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> log_date_format: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;YYYY-MM-DD HH:mm:ss Z&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
47
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> error_file: path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(logsDir, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;error.log&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
48
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> out_file: path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(logsDir, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;out.log&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">),</span></span>
49
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> merge_logs: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span></span>
50
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }]</span></span>
51
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>关键点:</p><ul><li><code>name: &#39;cc-monitoring&#39;</code>:CLI 里所有 PM2 操作都用这个进程名(<code>utils/pm2.ts</code>、<code>ui-route.ts</code> 的 <code>getProcessStatus(&#39;cc-monitoring&#39;)</code> 等)</li><li><code>script</code>:<code>path.join(__dirname, ...)</code>——<code>__dirname</code> 是 CJS 全局,在 <code>.cjs</code> 里可用。相对包内绝对路径,不依赖 <code>process.cwd()</code></li><li><code>cwd: dataDir</code>:让子进程的相对路径日志/DB 落到用户目录</li><li><code>instances: 1</code> + <code>exec_mode: &#39;fork&#39;</code>:cluster 模式基于 worker 复制主进程内存,ESM 会在 worker 里报错;fork 是干净的 spawn Node</li><li><code>autorestart: true</code> + <code>max_memory_restart: &#39;200M&#39;</code>:内存超 200M 自动重启(应用层代理有大响应缓冲的可能)</li><li><code>watch: false</code>:不监控文件变动重启(生产模式)</li><li><code>env</code> / <code>env_development</code>:<code>NODE_ENV</code> 切换;<code>CONFIG_PATH</code> 覆盖 <code>loadConfig</code> 的读取路径</li><li><code>log_date_format</code>:PM2 自己的日志时间戳(区别于 pino 的 ISO time)</li><li><code>error_file / out_file</code>:PM2 fork 子进程的 stderr/stdout 落盘位置</li><li><code>merge_logs: true</code>:多实例合并(虽然本项目 instances=1,属默认合理设置)</li></ul><h2 id="node-侧-pm2-封装-utils-pm2-ts" tabindex="-1">Node 侧 PM2 封装 <code>utils/pm2.ts</code> <a class="header-anchor" href="#node-侧-pm2-封装-utils-pm2-ts" aria-label="Permalink to &quot;Node 侧 PM2 封装 `utils/pm2.ts`&quot;">​</a></h2><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> requireCjs</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> NodeRequire</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
52
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createRequire</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getCurrentModuleUrl</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()) } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> require }</span></span>
53
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})()</span></span>
54
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> pm2</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> requireCjs</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;pm2&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">as</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> any</span></span></code></pre></div><ul><li><code>createRequire(getCurrentModuleUrl())</code>:ESM 环境下让 CJS <code>require</code> 可用</li><li><code>getCurrentModuleUrl()</code>(<code>esm-dirname.ts:52</code>)包装 <code>import.meta.url</code>——<code>__mocks__/esm-dirname.ts</code> 里被 Jest 覆盖成静态字符串,因为 ts-jest 编译 CJS 时无法解析 <code>import.meta</code></li><li>若 <code>createRequire</code> 也不可用(比如某种测试环境),fallback 到全局 <code>require</code>(此时应用其实已在 CJS 环境)</li></ul><p>内部 promisify 六个 PM2 API:</p><table tabindex="0"><thead><tr><th>内部</th><th>说明</th></tr></thead><tbody><tr><td><code>pm2Connect()</code></td><td>建立与 PM2 daemon 的 IPC</td></tr><tr><td><code>pm2Disconnect()</code></td><td>释放(<strong>必须调</strong>否则 daemon 认为客户端仍连着,其它 CLI 会等待)</td></tr><tr><td><code>pm2Start(options)</code></td><td>options 可以是 ecosystem 路径字符串或对象</td></tr><tr><td><code>pm2Stop(name)</code></td><td></td></tr><tr><td><code>pm2Reload(name)</code></td><td>优雅(零停机)重启</td></tr><tr><td><code>pm2List()</code></td><td>返回所有进程数组</td></tr></tbody></table><p>对外 5 个函数:</p><ul><li><code>startProcess(ecosystemPath)</code> = connect + start + disconnect</li><li><code>stopProcess(name)</code> = 同上</li><li><code>reloadProcess(name)</code> = 同上</li><li><code>waitForOnline(name, timeoutMs=8000, intervalMs=300)</code>:单次 connect + 轮询 list + disconnect(finally 保证释放)</li><li><code>getProcessStatus(name)</code>:单次 connect + list + disconnect,映射到 <code>Pm2ProcessStatus</code> 简洁形状</li></ul><p><strong>pm2Start 的错误可能是数组</strong>:PM2 有时候多个 app 同时失败,回调 <code>err</code> 是 <code>Error[]</code>:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> error</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Array.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">isArray</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(err)</span></span>
55
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ?</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(err.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">map</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">e</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> e.message).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">join</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;; &#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">))</span></span>
56
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> :</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> err</span></span></code></pre></div><p>合成成单个 Error 抛出。</p><h2 id="双入口守卫-server-index-ts" tabindex="-1">双入口守卫 <code>server/index.ts</code> <a class="header-anchor" href="#双入口守卫-server-index-ts" aria-label="Permalink to &quot;双入口守卫 `server/index.ts`&quot;">​</a></h2><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> _isPm2</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process.env.pm_id </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!==</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> undefined</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ||</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process.env.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">NODE_APP_INSTANCE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> !==</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> undefined</span></span>
57
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> _currentModuleUrl</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getCurrentModuleUrl</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
58
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> _mainModulePath</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process.argv[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">] </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">resolve</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(process.argv[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;&#39;</span></span>
59
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> _mainModuleUrl</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _mainModulePath </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">?</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> `file://${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">_mainModulePath</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}`</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> :</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;&#39;</span></span>
60
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> _isDirectExecution</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _currentModuleUrl </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">===</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _mainModuleUrl</span></span>
61
+ <span class="line"></span>
62
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (_isPm2 </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">||</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> _isDirectExecution) {</span></span>
63
+ <span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> startServer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">().</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">err</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">); process.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">exit</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) })</span></span>
64
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><ul><li><strong>PM2 fork 特殊性</strong>:PM2 用 <code>child_process.fork(ProcessContainerFork.js)</code> 拉起进程,<code>process.argv[1]</code> 是 <code>ProcessContainerFork.js</code> 而非 <code>dist/server/index.js</code>。所以 <code>_isDirectExecution</code> 判定为 false。用 <code>pm_id</code> env 补检测</li><li><strong>直接执行</strong>:<code>tsx src/server/index.ts</code> 或 <code>node dist/server/index.js</code>,<code>argv[1]</code> 就是本文件,URL 相等</li><li><strong>测试 / import</strong>:既不是 PM2 也不是直接执行时(例如从测试文件 import),两个判定都是 false,<code>startServer</code> 不自动跑,测试可以控制生命周期</li></ul><p><strong>注释里说明</strong>:<code>server/index.ts:42-45</code> 明确指出为什么不能用 <code>require.main === module</code>——那是 CJS 模式的判定,ESM 里 <code>require</code> 不存在。</p><h2 id="esm-dirname-替代-esm-dirname-ts" tabindex="-1">ESM __dirname 替代 <code>esm-dirname.ts</code> <a class="header-anchor" href="#esm-dirname-替代-esm-dirname-ts" aria-label="Permalink to &quot;ESM __dirname 替代 `esm-dirname.ts`&quot;">​</a></h2><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> thisDirname</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (() </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
65
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">dirname</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">new</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> URL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">meta</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.url).pathname) }</span></span>
66
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">return</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> typeof</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> __dirname </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!==</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;undefined&#39;</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ?</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> __dirname </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">cwd</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">() }</span></span>
67
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})()</span></span>
68
+ <span class="line"></span>
69
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getCallerDirname</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">relativePath</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
70
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> path.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">resolve</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(thisDirname, relativePath)</span></span>
71
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
72
+ <span class="line"></span>
73
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> function</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> getCurrentModuleUrl</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> string</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
74
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">meta</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.url</span></span>
75
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><ul><li><code>thisDirname</code>:本模块自身的 __dirname 等价物(编译后位于 <code>dist/utils/</code>)</li><li><code>getCallerDirname(&#39;../server&#39;)</code>:调用方直接算出 <code>dist/server</code> 目录,不用自己 fiddle import.meta.url。多处使用(<code>ui-route.ts:396</code> 静态资源、<code>start.ts:32</code> ecosystem 路径、<code>ui.ts:9</code> UI dist 路径、<code>utils/version.ts:14</code> 版本文件)</li><li>三重 fallback(ESM → CJS <code>__dirname</code> → <code>process.cwd()</code>)覆盖所有环境</li></ul><p><strong>注释里明确</strong>:<code>getCurrentModuleUrl</code> 是包装函数而非直接内联 <code>import.meta.url</code>——因为 ts-jest 编译 CJS 时会遇到语法错误,<code>__mocks__/esm-dirname.ts</code> 可以在测试里替换整个模块返回固定值。</p><h2 id="冷启动全流程" tabindex="-1">冷启动全流程 <a class="header-anchor" href="#冷启动全流程" aria-label="Permalink to &quot;冷启动全流程&quot;">​</a></h2><div class="language-mermaid vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">mermaid</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">sequenceDiagram</span></span>
76
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> actor U as 用户</span></span>
77
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant CLI as bin/proxy-cli.ts (ESM)</span></span>
78
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant CI as cli/index.ts</span></span>
79
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant SC as commands/start.ts</span></span>
80
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant PM as utils/pm2.ts</span></span>
81
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant D as PM2 daemon</span></span>
82
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant PC as ProcessContainerFork.js (CJS wrapper)</span></span>
83
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> participant S as dist/server/index.js (ESM)</span></span>
84
+ <span class="line"></span>
85
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> U-&gt;&gt;CLI: proxy start</span></span>
86
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CLI-&gt;&gt;CI: import</span></span>
87
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> CI-&gt;&gt;SC: startCommand</span></span>
88
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SC-&gt;&gt;PM: startProcess(ecosystemPath)</span></span>
89
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PM-&gt;&gt;PM: createRequire(import.meta.url)(&#39;pm2&#39;)</span></span>
90
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PM-&gt;&gt;D: pm2.connect + pm2.start(ecosystem.config.cjs)</span></span>
91
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> D-&gt;&gt;PC: fork</span></span>
92
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PC-&gt;&gt;S: 加载 script</span></span>
93
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> S-&gt;&gt;S: 检测 pm_id → startServer()</span></span>
94
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> S-&gt;&gt;S: loadConfig → configureDbPath → createLogger → Fastify → setupUi → setupProxy → listen</span></span>
95
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PM-&gt;&gt;D: pm2.disconnect</span></span>
96
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PM--&gt;&gt;SC: return</span></span>
97
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SC-&gt;&gt;SC: waitForOnline (再 connect/disconnect)</span></span>
98
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SC-&gt;&gt;SC: waitForPort (递增退避)</span></span>
99
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> SC--&gt;&gt;U: 打印 summary</span></span></code></pre></div><h2 id="相关文档" tabindex="-1">相关文档 <a class="header-anchor" href="#相关文档" aria-label="Permalink to &quot;相关文档&quot;">​</a></h2><ul><li>CLI 命令细节 → <a href="./cli.html">cli.md</a></li><li>启动链 → <a href="./entry.html">entry.md</a></li></ul></div></div></main><footer class="VPDocFooter" data-v-b2c5ca34 data-v-2cae581d><!--[--><!--]--><!----><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-2cae581d><span class="visually-hidden" id="doc-footer-aria-label" data-v-2cae581d>Pager</span><div class="pager" data-v-2cae581d><a class="VPLink link pager-link prev" href="/docs/proxy-core/tool.html" data-v-2cae581d><!--[--><span class="desc" data-v-2cae581d>Previous page</span><span class="title" data-v-2cae581d>工具注入</span><!--]--></a></div><div class="pager" data-v-2cae581d><a class="VPLink link pager-link next" href="/docs/proxy-core/utilities.html" data-v-2cae581d><!--[--><span class="desc" data-v-2cae581d>Next page</span><span class="title" data-v-2cae581d>工具函数</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>
100
+ <script>window.__VP_HASH_MAP__=JSON.parse("{\"index.md\":\"p9floL_p\",\"overview.md\":\"BKVdLT3o\",\"packages-utils.md\":\"CvgYp5Ll\",\"proxy-admin_env-and-build.md\":\"xkeQNYS3\",\"proxy-admin_index.md\":\"DBLI0n0G\",\"proxy-admin_layout-and-menu.md\":\"BKGcu49p\",\"proxy-admin_pages.md\":\"m_fGvvOH\",\"proxy-admin_routing-and-auth.md\":\"DZsdFese\",\"proxy-admin_services-and-mock.md\":\"sdNPcf25\",\"proxy-cli_api-layer.md\":\"GfdbtEUx\",\"proxy-cli_app-shell.md\":\"Do18CYhW\",\"proxy-cli_components-common.md\":\"Dd6Yazvz\",\"proxy-cli_components-config.md\":\"B81Y3ta2\",\"proxy-cli_components-requests.md\":\"vN8IrwL_\",\"proxy-cli_components-stats.md\":\"B90esaNa\",\"proxy-cli_components-status.md\":\"C5lAzS2c\",\"proxy-cli_data-hooks.md\":\"w9Oe1OD3\",\"proxy-cli_index.md\":\"BA6g8QD-\",\"proxy-cli_utils-and-i18n.md\":\"Ch_e-g_o\",\"proxy-core_chat-api.md\":\"DHihiBxR\",\"proxy-core_cli.md\":\"DCFYX4Bd\",\"proxy-core_config.md\":\"BXSOyxYE\",\"proxy-core_data-layer.md\":\"Cdomb3Gz\",\"proxy-core_entry.md\":\"BZmIcCUM\",\"proxy-core_index.md\":\"BM6VV5Qe\",\"proxy-core_pm2.md\":\"DUhWEtgn\",\"proxy-core_providers.md\":\"CbDZ6b_7\",\"proxy-core_proxy.md\":\"CzQYmX6X\",\"proxy-core_stats.md\":\"BsM6wuK_\",\"proxy-core_tool.md\":\"B6Le1nQr\",\"proxy-core_ui-routes.md\":\"Dyqkeoiv\",\"proxy-core_utilities.md\":\"C18pjnkz\",\"quickstart.md\":\"Cy_FmXIY\",\"request-flow.md\":\"C1fyxdPE\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"zh-CN\",\"dir\":\"ltr\",\"title\":\"CC Monitoring\",\"description\":\"Claude Code 代理 + 监控系统文档\",\"base\":\"/docs/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"概览\",\"link\":\"/overview\"},{\"text\":\"快速开始\",\"link\":\"/quickstart\"},{\"text\":\"Proxy Core\",\"link\":\"/proxy-core/\"},{\"text\":\"Proxy CLI\",\"link\":\"/proxy-cli/\"},{\"text\":\"Proxy Admin\",\"link\":\"/proxy-admin/\"}],\"sidebar\":{\"/proxy-core/\":[{\"text\":\"Proxy Core\",\"items\":[{\"text\":\"模块概览\",\"link\":\"/proxy-core/\"},{\"text\":\"入口与启动\",\"link\":\"/proxy-core/entry\"},{\"text\":\"CLI 命令\",\"link\":\"/proxy-core/cli\"},{\"text\":\"代理转发\",\"link\":\"/proxy-core/proxy\"},{\"text\":\"UI 路由\",\"link\":\"/proxy-core/ui-routes\"},{\"text\":\"供应商管理\",\"link\":\"/proxy-core/providers\"},{\"text\":\"配置与日志\",\"link\":\"/proxy-core/config\"},{\"text\":\"数据层\",\"link\":\"/proxy-core/data-layer\"},{\"text\":\"统计与历史\",\"link\":\"/proxy-core/stats\"},{\"text\":\"工具注入\",\"link\":\"/proxy-core/tool\"},{\"text\":\"PM2 集成\",\"link\":\"/proxy-core/pm2\"},{\"text\":\"工具函数\",\"link\":\"/proxy-core/utilities\"},{\"text\":\"Chat API\",\"link\":\"/proxy-core/chat-api\"}]}],\"/proxy-cli/\":[{\"text\":\"Proxy CLI\",\"items\":[{\"text\":\"模块概览\",\"link\":\"/proxy-cli/\"},{\"text\":\"应用外壳\",\"link\":\"/proxy-cli/app-shell\"},{\"text\":\"数据 Hooks\",\"link\":\"/proxy-cli/data-hooks\"},{\"text\":\"API 层\",\"link\":\"/proxy-cli/api-layer\"},{\"text\":\"状态组件\",\"link\":\"/proxy-cli/components-status\"},{\"text\":\"统计组件\",\"link\":\"/proxy-cli/components-stats\"},{\"text\":\"请求组件\",\"link\":\"/proxy-cli/components-requests\"},{\"text\":\"配置组件\",\"link\":\"/proxy-cli/components-config\"},{\"text\":\"通用组件\",\"link\":\"/proxy-cli/components-common\"},{\"text\":\"工具与国际化\",\"link\":\"/proxy-cli/utils-and-i18n\"}]}],\"/proxy-admin/\":[{\"text\":\"Proxy Admin\",\"items\":[{\"text\":\"模块概览\",\"link\":\"/proxy-admin/\"},{\"text\":\"路由与认证\",\"link\":\"/proxy-admin/routing-and-auth\"},{\"text\":\"布局与菜单\",\"link\":\"/proxy-admin/layout-and-menu\"},{\"text\":\"页面\",\"link\":\"/proxy-admin/pages\"},{\"text\":\"服务与 Mock\",\"link\":\"/proxy-admin/services-and-mock\"},{\"text\":\"环境与构建\",\"link\":\"/proxy-admin/env-and-build\"}]}]},\"siteTitle\":\"CC Monitoring\",\"search\":{\"provider\":\"local\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
101
+
102
+ </body>
103
+ </html>
@@ -0,0 +1,39 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN" dir="ltr">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <title>proxy-core / 供应商管理 | CC Monitoring</title>
7
+ <meta name="description" content="Claude Code 代理 + 监控系统文档">
8
+ <meta name="generator" content="VitePress v1.6.4">
9
+ <link rel="preload stylesheet" href="/docs/assets/style.DU_kNMWy.css" as="style">
10
+ <link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
11
+
12
+ <script type="module" src="/docs/assets/app.BxFOH0P1.js"></script>
13
+ <link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
14
+ <link rel="modulepreload" href="/docs/assets/chunks/theme.BLEczZWC.js">
15
+ <link rel="modulepreload" href="/docs/assets/chunks/framework.D_Xv2a7c.js">
16
+ <link rel="modulepreload" href="/docs/assets/proxy-core_providers.md.CbDZ6b_7.lean.js">
17
+ <script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
18
+ <script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
19
+ </head>
20
+ <body>
21
+ <div id="app"><div class="Layout" data-v-0fd5f79a><!--[--><!--]--><!--[--><span tabindex="-1" data-v-13bcab17></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-13bcab17>Skip to content</a><!--]--><!----><header class="VPNav" data-v-0fd5f79a data-v-221ddc7b><div class="VPNavBar" data-v-221ddc7b data-v-6a82b350><div class="wrapper" data-v-6a82b350><div class="container" data-v-6a82b350><div class="title" data-v-6a82b350><div class="VPNavBarTitle has-sidebar" data-v-6a82b350 data-v-98825d79><a class="title" href="/docs/" data-v-98825d79><!--[--><!--]--><!----><span data-v-98825d79>CC Monitoring</span><!--[--><!--]--></a></div></div><div class="content" data-v-6a82b350><div class="content-body" data-v-6a82b350><!--[--><!--]--><div class="VPNavBarSearch search" data-v-6a82b350><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-6a82b350 data-v-2fa375b4><span id="main-nav-aria-label" class="visually-hidden" data-v-2fa375b4> Main Navigation </span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/overview.html" tabindex="0" data-v-2fa375b4 data-v-88169469><!--[--><span data-v-88169469>概览</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/quickstart.html" tabindex="0" data-v-2fa375b4 data-v-88169469><!--[--><span data-v-88169469>快速开始</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/proxy-core/" tabindex="0" data-v-2fa375b4 data-v-88169469><!--[--><span data-v-88169469>Proxy Core</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/proxy-cli/" tabindex="0" data-v-2fa375b4 data-v-88169469><!--[--><span data-v-88169469>Proxy CLI</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/docs/proxy-admin/" tabindex="0" data-v-2fa375b4 data-v-88169469><!--[--><span data-v-88169469>Proxy Admin</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-6a82b350 data-v-c7859fea><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-c7859fea data-v-458e2939 data-v-2fadb15f><span class="check" data-v-2fadb15f><span class="icon" data-v-2fadb15f><!--[--><span class="vpi-sun sun" data-v-458e2939></span><span class="vpi-moon moon" data-v-458e2939></span><!--]--></span></span></button></div><!----><div class="VPFlyout VPNavBarExtra extra" data-v-6a82b350 data-v-4a332738 data-v-3416cc30><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-3416cc30><span class="vpi-more-horizontal icon" data-v-3416cc30></span></button><div class="menu" data-v-3416cc30><div class="VPMenu" data-v-3416cc30 data-v-70b241a4><!----><!--[--><!--[--><!----><div class="group" data-v-4a332738><div class="item appearance" data-v-4a332738><p class="label" data-v-4a332738>Appearance</p><div class="appearance-action" data-v-4a332738><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-4a332738 data-v-458e2939 data-v-2fadb15f><span class="check" data-v-2fadb15f><span class="icon" data-v-2fadb15f><!--[--><span class="vpi-sun sun" data-v-458e2939></span><span class="vpi-moon moon" data-v-458e2939></span><!--]--></span></span></button></div></div></div><!----><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-6a82b350 data-v-2b9279da><span class="container" data-v-2b9279da><span class="top" data-v-2b9279da></span><span class="middle" data-v-2b9279da></span><span class="bottom" data-v-2b9279da></span></span></button></div></div></div></div><div class="divider" data-v-6a82b350><div class="divider-line" data-v-6a82b350></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-0fd5f79a data-v-751e8533><div class="container" data-v-751e8533><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-751e8533><span class="vpi-align-left menu-icon" data-v-751e8533></span><span class="menu-text" data-v-751e8533>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-751e8533 data-v-afd8288e><button data-v-afd8288e>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-0fd5f79a data-v-711af969><div class="curtain" data-v-711af969></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-711af969><span class="visually-hidden" id="sidebar-aria-label" data-v-711af969> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-4ebb8294><section class="VPSidebarItem level-0 has-active" data-v-4ebb8294 data-v-04203d25><div class="item" role="button" tabindex="0" data-v-04203d25><div class="indicator" data-v-04203d25></div><h2 class="text" data-v-04203d25>Proxy Core</h2><!----></div><div class="items" data-v-04203d25><!--[--><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/" data-v-04203d25><!--[--><p class="text" data-v-04203d25>模块概览</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/entry.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>入口与启动</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/cli.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>CLI 命令</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/proxy.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>代理转发</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/ui-routes.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>UI 路由</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/providers.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>供应商管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/config.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>配置与日志</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/data-layer.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>数据层</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/stats.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>统计与历史</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/tool.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>工具注入</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/pm2.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>PM2 集成</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/utilities.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>工具函数</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-04203d25><div class="item" data-v-04203d25><div class="indicator" data-v-04203d25></div><a class="VPLink link link" href="/docs/proxy-core/chat-api.html" data-v-04203d25><!--[--><p class="text" data-v-04203d25>Chat API</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-0fd5f79a data-v-3aa167b9><div class="VPDoc has-sidebar has-aside" data-v-3aa167b9 data-v-b2c5ca34><!--[--><!--]--><div class="container" data-v-b2c5ca34><div class="aside" data-v-b2c5ca34><div class="aside-curtain" data-v-b2c5ca34></div><div class="aside-container" data-v-b2c5ca34><div class="aside-content" data-v-b2c5ca34><div class="VPDocAside" data-v-b2c5ca34 data-v-af7efbb6><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-af7efbb6 data-v-db542fa8><div class="content" data-v-db542fa8><div class="outline-marker" data-v-db542fa8></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-db542fa8>On this page</div><ul class="VPDocOutlineItem root" data-v-db542fa8 data-v-1d036821><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-af7efbb6></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-b2c5ca34><div class="content-container" data-v-b2c5ca34><!--[--><!--]--><main class="main" data-v-b2c5ca34><div style="position:relative;" class="vp-doc _docs_proxy-core_providers" data-v-b2c5ca34><div><h1 id="proxy-core-供应商管理" tabindex="-1">proxy-core / 供应商管理 <a class="header-anchor" href="#proxy-core-供应商管理" aria-label="Permalink to &quot;proxy-core / 供应商管理&quot;">​</a></h1><h2 id="本文档覆盖的源文件" tabindex="-1">本文档覆盖的源文件 <a class="header-anchor" href="#本文档覆盖的源文件" aria-label="Permalink to &quot;本文档覆盖的源文件&quot;">​</a></h2><ul><li><code>apps/proxy-core/src/server/providers-route.ts</code></li><li><code>apps/proxy-core/src/utils/providers-db.ts</code></li><li><code>apps/proxy-core/src/server/proxy.ts:40-88</code>(<code>resolveProxyTarget</code>)</li><li><code>apps/proxy-core/src/server/proxy.ts:98-115</code>(<code>getProxyModel</code>)</li><li><code>apps/proxy-core/src/utils/db.ts:68-131</code>(v2/v3/v4 schema)</li></ul><h2 id="用途" tabindex="-1">用途 <a class="header-anchor" href="#用途" aria-label="Permalink to &quot;用途&quot;">​</a></h2><p>「供应商」= 一组可切换的上游 AI API 配置(base_url + api_key + 多档模型)。用户可以在 UI 里维护多个 provider,激活其中一个作为「当前」,proxy 转发时会按激活项覆盖 <code>config.json</code> 的对应字段。</p><h2 id="数据模型" tabindex="-1">数据模型 <a class="header-anchor" href="#数据模型" aria-label="Permalink to &quot;数据模型&quot;">​</a></h2><p>SQLite <code>providers</code> 表(<code>db.ts:68-131</code>,v2 建表、v3 加 <code>is_default</code>、v4 放开 NOT NULL):</p><table tabindex="0"><thead><tr><th>字段</th><th>类型</th><th>备注</th></tr></thead><tbody><tr><td><code>id</code></td><td>INTEGER PK AUTOINCREMENT</td><td></td></tr><tr><td><code>name</code></td><td>TEXT UNIQUE NOT NULL</td><td>主键之外的唯一键</td></tr><tr><td><code>base_url</code></td><td>TEXT (nullable)</td><td>完整 URL,含 API 前缀</td></tr><tr><td><code>api_key</code></td><td>TEXT (nullable)</td><td></td></tr><tr><td><code>model</code></td><td>TEXT (nullable)</td><td>主 model 覆盖</td></tr><tr><td><code>haiku_model</code></td><td>TEXT (nullable)</td><td>Anthropic 分档预留</td></tr><tr><td><code>sonnet_model</code></td><td>TEXT (nullable)</td><td></td></tr><tr><td><code>opus_model</code></td><td>TEXT (nullable)</td><td></td></tr><tr><td><code>subagent_model</code></td><td>TEXT (nullable)</td><td>子 agent 单独 model 预留</td></tr><tr><td><code>provider</code></td><td>TEXT NOT NULL</td><td>分类标签(&quot;anthropic&quot;/&quot;aliyun&quot;/&quot;volces&quot;...)</td></tr><tr><td><code>is_default</code></td><td>INTEGER NOT NULL DEFAULT 0</td><td>激活标记,全表最多 1 个为 1</td></tr><tr><td><code>created_at</code></td><td>TEXT DEFAULT CURRENT_TIMESTAMP</td><td></td></tr><tr><td><code>updated_at</code></td><td>TEXT DEFAULT CURRENT_TIMESTAMP</td><td></td></tr></tbody></table><p>索引:<code>idx_providers_name</code> UNIQUE。</p><p><code>haiku_model / sonnet_model / opus_model</code> <strong>现已参与转发</strong>:<code>resolveProxyTarget</code> 读取 tier models 并返回,由 <code>getProxyModel</code> 根据请求的原始 model 按 tier 映射替换。<code>subagent_model</code> 目前仅存储,不参与转发——为将来子 agent 单独 model 预留。</p><h2 id="schema-迁移的三步" tabindex="-1">Schema 迁移的三步 <a class="header-anchor" href="#schema-迁移的三步" aria-label="Permalink to &quot;Schema 迁移的三步&quot;">​</a></h2><p><code>applySchemaV2</code>:建表 + 唯一索引,NOT NULL 约束加在 <code>base_url / api_key / model</code>(<code>db.ts:68-86</code>)。</p><p><code>applySchemaV3</code>:<code>PRAGMA table_info</code> 检测 <code>is_default</code> 是否存在,缺失则 <code>ALTER TABLE ADD COLUMN is_default INTEGER NOT NULL DEFAULT 0</code>(<code>db.ts:88-95</code>)。ADD COLUMN 是 SQLite 支持的少数原地变更之一,且带 DEFAULT 时不阻塞。</p><p><code>applySchemaV4</code>:SQLite 不能直接 <code>ALTER COLUMN</code> 去除 NOT NULL,只能<strong>重建表</strong>:新建 <code>providers_new</code>(无 NOT NULL) → <code>INSERT INTO providers_new SELECT ... FROM providers</code> → <code>DROP TABLE providers</code> → <code>ALTER TABLE providers_new RENAME TO providers</code> → 重建索引(<code>db.ts:97-132</code>)。整个过程带条件(仅当检测到 NOT NULL 列时才触发),idempotent-safe。</p><p>放开 NOT NULL 是为支持「部分覆盖」:一个 provider 只需要指定要替换的字段,其它字段留 NULL 表示「用 config.json 默认」。</p><h2 id="resolveproxytarget" tabindex="-1"><code>resolveProxyTarget</code> <a class="header-anchor" href="#resolveproxytarget" aria-label="Permalink to &quot;`resolveProxyTarget`&quot;">​</a></h2><p><code>apps/proxy-core/src/server/proxy.ts:40-88</code>。每次业务请求进入 handler 都同步跑一次:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> active</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> db.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">prepare</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
22
+ <span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;SELECT base_url, api_key, model, haiku_model, sonnet_model, opus_model FROM providers WHERE is_default = 1 LIMIT 1&#39;</span></span>
23
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
24
+ <span class="line"></span>
25
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (active) {</span></span>
26
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (active.base_url?.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">trim</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()) { </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">/* 覆盖 baseUrl/targetPath */</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
27
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (active.api_key?.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">trim</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()) { apiKey </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> active.api_key }</span></span>
28
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (active.model?.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">trim</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()) { model </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> active.model }</span></span>
29
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (active.haiku_model?.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">trim</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()) { haiku_model </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> active.haiku_model }</span></span>
30
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (active.sonnet_model?.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">trim</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()) { sonnet_model </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> active.sonnet_model }</span></span>
31
+ <span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (active.opus_model?.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">trim</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()) { opus_model </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> active.opus_model }</span></span>
32
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>返回 <code>{ baseUrl, targetPath, apiKey?, model?, haiku_model?, sonnet_model?, opus_model? }</code>。</p><p><strong>部分覆盖语义</strong>:</p><ul><li>只填 <code>base_url</code> → 换目标但复用 config.json 的 key(多数场景:切上游 endpoint)</li><li>只填 <code>api_key</code> → 换 key 但复用 target(多账户轮换)</li><li>只填 <code>model</code> → 强制所有请求跑同一 model(灰度、成本控制)</li><li>填 tier models(如 <code>sonnet_model</code>)→ 按 <code>getProxyModel</code> 映射,haiku/sonnet/opus 分别走不同模型</li><li>三者组合 → 完全独立的 provider</li></ul><h2 id="getproxymodel" tabindex="-1"><code>getProxyModel</code> <a class="header-anchor" href="#getproxymodel" aria-label="Permalink to &quot;`getProxyModel`&quot;">​</a></h2><p><code>apps/proxy-core/src/server/proxy.ts:98-115</code>。根据请求的原始 model 和 provider tier 配置选择替换 model:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">claude</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">haiku</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> → </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">haiku_model</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (fallback: model → </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">undefined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
33
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">claude</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">sonnet</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> → </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">sonnet_model</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (fallback: model → </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">undefined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
34
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">claude</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">opus</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> → </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">opus_model</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (fallback: model → </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">undefined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
35
+ <span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">其它 → </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">model</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (fallback: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">undefined</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><p><strong>fallback 链</strong>:tier 专属 model → 通用 <code>model</code> → undefined(不替换)。这让一个 provider 可以只配一个通用 model(所有 tier 都用它),也可以精细到每个 tier 不同 model。</p><p><strong>使用场景</strong>:国内模型通常不区分 tier,一个 <code>model</code> 字段就够了。但如果用 Anthropic 直连或不同 tier 跑不同供应商,<code>haiku_model / sonnet_model / opus_model</code> 让一次切换覆盖所有 tier。</p><p><strong>同步查询开销</strong>:better-sqlite3 是同步 API,单行 UNIQUE 索引 SELECT 微秒级,无缓存。热切换时下一次请求立即生效,不需要重启进程。</p><p><strong>异常兜底</strong>:<code>try/catch</code> 内部若 DB 未 initDatabase / URL 解析失败 / 表不存在,直接 fallback 到 <code>config.proxy.target</code> 的解析结果。</p><h2 id="node-层-utils-providers-db-ts" tabindex="-1">Node 层:<code>utils/providers-db.ts</code> <a class="header-anchor" href="#node-层-utils-providers-db-ts" aria-label="Permalink to &quot;Node 层:`utils/providers-db.ts`&quot;">​</a></h2><p>三类函数:</p><h3 id="listproviders-db" tabindex="-1"><code>listProviders(db)</code> <a class="header-anchor" href="#listproviders-db" aria-label="Permalink to &quot;`listProviders(db)`&quot;">​</a></h3><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">SELECT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> FROM</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> providers </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">ORDER</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> BY</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> created_at </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">DESC</span></span></code></pre></div><p>每行把 <code>is_default: number</code> 转为 <code>default: boolean</code> 后返回。</p><h3 id="saveproviders-db-providers" tabindex="-1"><code>saveProviders(db, providers[])</code> <a class="header-anchor" href="#saveproviders-db-providers" aria-label="Permalink to &quot;`saveProviders(db, providers[])`&quot;">​</a></h3><p><strong>Destructive full replacement</strong>:先 <code>DELETE FROM providers</code>,再逐行 INSERT,全部在一个 SQLite transaction 内。空数组 → 清空全表。</p><p><code>INSERT</code> 中每个可选字段:<code>p.base_url?.trim() ? p.base_url : null</code> — 空串统一转 NULL,避免 UNIQUE / 逻辑判断上「非空空串」和「NULL」混淆。</p><p><code>is_default</code> 从 boolean 转 <code>1 | 0</code>。</p><p><strong>为什么全量替换而不是 upsert</strong>:前端 UI 是「一张表格 → 保存整表」的模式,实现上更简单,避免局部同步的边界(同一 id 改名、id 冲突等)。</p><p><strong>开销</strong>:只在用户点「保存」时触发(低频运维操作),准备语句每次 new 也无性能问题。</p><h3 id="validateprovider-validateproviders" tabindex="-1"><code>validateProvider</code> / <code>validateProviders</code> <a class="header-anchor" href="#validateprovider-validateproviders" aria-label="Permalink to &quot;`validateProvider` / `validateProviders`&quot;">​</a></h3><p><strong>单个校验</strong>(<code>providers-db.ts:85-126</code>):</p><ul><li>必填字段:<code>name</code>、<code>provider</code>(trim 后非空)</li><li>「至少填一个可选字段」:<code>base_url / api_key / model / haiku_model / sonnet_model / opus_model / subagent_model</code> 至少有一个非空——防止用户建一个只有名字的空 provider</li><li><code>base_url</code> 若填了必须是 <code>http:</code> 或 <code>https:</code> 协议的合法 URL</li></ul><p><strong>批量校验</strong>(<code>providers-db.ts:128-156</code>):</p><ul><li>逐个跑 <code>validateProvider</code>,错误项挂 <code>index</code></li><li>检查 <code>name</code> 重复</li><li>检查 <code>default: true</code> 最多 1 个</li></ul><p>任何一条不通过就整批拒绝,返回 <code>ProviderValidationError[]</code>。</p><h2 id="rest-端点" tabindex="-1">REST 端点 <a class="header-anchor" href="#rest-端点" aria-label="Permalink to &quot;REST 端点&quot;">​</a></h2><p><code>apps/proxy-core/src/server/providers-route.ts</code>:</p><h3 id="get-ui-api-providers" tabindex="-1">GET /ui/api/providers <a class="header-anchor" href="#get-ui-api-providers" aria-label="Permalink to &quot;GET /ui/api/providers&quot;">​</a></h3><p>无认证。<code>listProviders</code> 结果封装到 <code>{ providers }</code>。异常返回 500。</p><h3 id="post-ui-api-providers" tabindex="-1">POST /ui/api/providers <a class="header-anchor" href="#post-ui-api-providers" aria-label="Permalink to &quot;POST /ui/api/providers&quot;">​</a></h3><p><strong>认证</strong>(<code>checkAuth</code>)。请求体:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{ </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">providers</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: ProviderInput[] }</span></span></code></pre></div><p>流程:</p><ol><li>Bearer 认证</li><li>请求体存在 + <code>providers</code> 是数组</li><li><code>validateProviders(providers)</code> → 错误列表非空 → 400 + <code>{ errors }</code></li><li><code>saveProviders(db, providers)</code>(事务)</li><li><code>{ success: true }</code></li></ol><h2 id="前端交互" tabindex="-1">前端交互 <a class="header-anchor" href="#前端交互" aria-label="Permalink to &quot;前端交互&quot;">​</a></h2><p><code>ProviderManagerModal</code>(<code>apps/proxy-cli/src/components/ProviderManagerModal.tsx</code>):</p><ul><li>打开时 <code>fetchProviders()</code> 装填表格</li><li>每行 9 个字段 + 「激活 / 删除」按钮;「激活」把该行 <code>default = true</code>、其它行 <code>default = false</code></li><li>「保存」调 <code>saveProviders(rows)</code>:全量提交</li><li>错误分两种:<code>errors[]</code>(字段级)分行显示;<code>error</code>(顶层字符串)单条显示</li></ul><p>详见 <a href="./../proxy-cli/components-config.html">../proxy-cli/components-config</a>。</p><h2 id="切换与广播" tabindex="-1">切换与广播 <a class="header-anchor" href="#切换与广播" aria-label="Permalink to &quot;切换与广播&quot;">​</a></h2><p>供应商切换<strong>不广播事件</strong>。前端保存成功后无 WebSocket 通知,其它连接需要手动刷新 <code>ProviderManagerModal</code>。业务请求端不受影响:<code>resolveProxyTarget</code> 下次 SELECT 就拿到新的激活项。</p><h2 id="相关文档" tabindex="-1">相关文档 <a class="header-anchor" href="#相关文档" aria-label="Permalink to &quot;相关文档&quot;">​</a></h2><ul><li>Schema 迁移全景 → <a href="./data-layer.html">data-layer.md</a></li><li>前端管理界面 → <a href="./../proxy-cli/components-config.html">../proxy-cli/components-config</a></li><li><code>resolveProxyTarget</code> 在 handler 中的位置 → <a href="./proxy.html#公用步骤">proxy.md</a></li></ul></div></div></main><footer class="VPDocFooter" data-v-b2c5ca34 data-v-2cae581d><!--[--><!--]--><!----><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-2cae581d><span class="visually-hidden" id="doc-footer-aria-label" data-v-2cae581d>Pager</span><div class="pager" data-v-2cae581d><a class="VPLink link pager-link prev" href="/docs/proxy-core/ui-routes.html" data-v-2cae581d><!--[--><span class="desc" data-v-2cae581d>Previous page</span><span class="title" data-v-2cae581d>UI 路由</span><!--]--></a></div><div class="pager" data-v-2cae581d><a class="VPLink link pager-link next" href="/docs/proxy-core/config.html" data-v-2cae581d><!--[--><span class="desc" data-v-2cae581d>Next page</span><span class="title" data-v-2cae581d>配置与日志</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>
36
+ <script>window.__VP_HASH_MAP__=JSON.parse("{\"index.md\":\"p9floL_p\",\"overview.md\":\"BKVdLT3o\",\"packages-utils.md\":\"CvgYp5Ll\",\"proxy-admin_env-and-build.md\":\"xkeQNYS3\",\"proxy-admin_index.md\":\"DBLI0n0G\",\"proxy-admin_layout-and-menu.md\":\"BKGcu49p\",\"proxy-admin_pages.md\":\"m_fGvvOH\",\"proxy-admin_routing-and-auth.md\":\"DZsdFese\",\"proxy-admin_services-and-mock.md\":\"sdNPcf25\",\"proxy-cli_api-layer.md\":\"GfdbtEUx\",\"proxy-cli_app-shell.md\":\"Do18CYhW\",\"proxy-cli_components-common.md\":\"Dd6Yazvz\",\"proxy-cli_components-config.md\":\"B81Y3ta2\",\"proxy-cli_components-requests.md\":\"vN8IrwL_\",\"proxy-cli_components-stats.md\":\"B90esaNa\",\"proxy-cli_components-status.md\":\"C5lAzS2c\",\"proxy-cli_data-hooks.md\":\"w9Oe1OD3\",\"proxy-cli_index.md\":\"BA6g8QD-\",\"proxy-cli_utils-and-i18n.md\":\"Ch_e-g_o\",\"proxy-core_chat-api.md\":\"DHihiBxR\",\"proxy-core_cli.md\":\"DCFYX4Bd\",\"proxy-core_config.md\":\"BXSOyxYE\",\"proxy-core_data-layer.md\":\"Cdomb3Gz\",\"proxy-core_entry.md\":\"BZmIcCUM\",\"proxy-core_index.md\":\"BM6VV5Qe\",\"proxy-core_pm2.md\":\"DUhWEtgn\",\"proxy-core_providers.md\":\"CbDZ6b_7\",\"proxy-core_proxy.md\":\"CzQYmX6X\",\"proxy-core_stats.md\":\"BsM6wuK_\",\"proxy-core_tool.md\":\"B6Le1nQr\",\"proxy-core_ui-routes.md\":\"Dyqkeoiv\",\"proxy-core_utilities.md\":\"C18pjnkz\",\"quickstart.md\":\"Cy_FmXIY\",\"request-flow.md\":\"C1fyxdPE\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"zh-CN\",\"dir\":\"ltr\",\"title\":\"CC Monitoring\",\"description\":\"Claude Code 代理 + 监控系统文档\",\"base\":\"/docs/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"概览\",\"link\":\"/overview\"},{\"text\":\"快速开始\",\"link\":\"/quickstart\"},{\"text\":\"Proxy Core\",\"link\":\"/proxy-core/\"},{\"text\":\"Proxy CLI\",\"link\":\"/proxy-cli/\"},{\"text\":\"Proxy Admin\",\"link\":\"/proxy-admin/\"}],\"sidebar\":{\"/proxy-core/\":[{\"text\":\"Proxy Core\",\"items\":[{\"text\":\"模块概览\",\"link\":\"/proxy-core/\"},{\"text\":\"入口与启动\",\"link\":\"/proxy-core/entry\"},{\"text\":\"CLI 命令\",\"link\":\"/proxy-core/cli\"},{\"text\":\"代理转发\",\"link\":\"/proxy-core/proxy\"},{\"text\":\"UI 路由\",\"link\":\"/proxy-core/ui-routes\"},{\"text\":\"供应商管理\",\"link\":\"/proxy-core/providers\"},{\"text\":\"配置与日志\",\"link\":\"/proxy-core/config\"},{\"text\":\"数据层\",\"link\":\"/proxy-core/data-layer\"},{\"text\":\"统计与历史\",\"link\":\"/proxy-core/stats\"},{\"text\":\"工具注入\",\"link\":\"/proxy-core/tool\"},{\"text\":\"PM2 集成\",\"link\":\"/proxy-core/pm2\"},{\"text\":\"工具函数\",\"link\":\"/proxy-core/utilities\"},{\"text\":\"Chat API\",\"link\":\"/proxy-core/chat-api\"}]}],\"/proxy-cli/\":[{\"text\":\"Proxy CLI\",\"items\":[{\"text\":\"模块概览\",\"link\":\"/proxy-cli/\"},{\"text\":\"应用外壳\",\"link\":\"/proxy-cli/app-shell\"},{\"text\":\"数据 Hooks\",\"link\":\"/proxy-cli/data-hooks\"},{\"text\":\"API 层\",\"link\":\"/proxy-cli/api-layer\"},{\"text\":\"状态组件\",\"link\":\"/proxy-cli/components-status\"},{\"text\":\"统计组件\",\"link\":\"/proxy-cli/components-stats\"},{\"text\":\"请求组件\",\"link\":\"/proxy-cli/components-requests\"},{\"text\":\"配置组件\",\"link\":\"/proxy-cli/components-config\"},{\"text\":\"通用组件\",\"link\":\"/proxy-cli/components-common\"},{\"text\":\"工具与国际化\",\"link\":\"/proxy-cli/utils-and-i18n\"}]}],\"/proxy-admin/\":[{\"text\":\"Proxy Admin\",\"items\":[{\"text\":\"模块概览\",\"link\":\"/proxy-admin/\"},{\"text\":\"路由与认证\",\"link\":\"/proxy-admin/routing-and-auth\"},{\"text\":\"布局与菜单\",\"link\":\"/proxy-admin/layout-and-menu\"},{\"text\":\"页面\",\"link\":\"/proxy-admin/pages\"},{\"text\":\"服务与 Mock\",\"link\":\"/proxy-admin/services-and-mock\"},{\"text\":\"环境与构建\",\"link\":\"/proxy-admin/env-and-build\"}]}]},\"siteTitle\":\"CC Monitoring\",\"search\":{\"provider\":\"local\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
37
+
38
+ </body>
39
+ </html>