@cc-monitoring/proxy-core 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (409) hide show
  1. package/dist/cli/__tests__/commands.test.js +20 -1
  2. package/dist/cli/commands/exec.js +31 -42
  3. package/dist/cli/commands/repair.d.ts +1 -0
  4. package/dist/cli/commands/repair.js +15 -0
  5. package/dist/cli/index.js +30 -0
  6. package/dist/docs/404.html +2 -2
  7. package/dist/docs/assets/{app.B9A39uFv.js → app.g7N9jkzn.js} +1 -1
  8. package/dist/docs/assets/chunks/@localSearchIndexroot.IHxQqfJH.js +1 -0
  9. package/dist/docs/assets/chunks/{VPLocalSearchBox.DdhC696L.js → VPLocalSearchBox.BHwI475_.js} +1 -1
  10. package/dist/docs/assets/chunks/{theme.CfB2tOFi.js → theme.FhAJSNDh.js} +2 -2
  11. package/dist/docs/assets/{proxy-cli_data-hooks.md.w9Oe1OD3.js → proxy-cli_data-hooks.md.Bz8CVbxO.js} +1 -1
  12. package/dist/docs/assets/{proxy-core_ui-routes.md.Dyqkeoiv.js → proxy-core_ui-routes.md.B21t1p7R.js} +1 -1
  13. package/dist/docs/hashmap.json +1 -1
  14. package/dist/docs/index.html +3 -3
  15. package/dist/docs/overview.html +3 -3
  16. package/dist/docs/packages-utils.html +3 -3
  17. package/dist/docs/proxy-admin/env-and-build.html +3 -3
  18. package/dist/docs/proxy-admin/index.html +3 -3
  19. package/dist/docs/proxy-admin/layout-and-menu.html +3 -3
  20. package/dist/docs/proxy-admin/pages.html +3 -3
  21. package/dist/docs/proxy-admin/routing-and-auth.html +3 -3
  22. package/dist/docs/proxy-admin/services-and-mock.html +3 -3
  23. package/dist/docs/proxy-cli/api-layer.html +3 -3
  24. package/dist/docs/proxy-cli/app-shell.html +3 -3
  25. package/dist/docs/proxy-cli/components-common.html +3 -3
  26. package/dist/docs/proxy-cli/components-config.html +3 -3
  27. package/dist/docs/proxy-cli/components-requests.html +3 -3
  28. package/dist/docs/proxy-cli/components-stats.html +3 -3
  29. package/dist/docs/proxy-cli/components-status.html +3 -3
  30. package/dist/docs/proxy-cli/data-hooks.html +5 -5
  31. package/dist/docs/proxy-cli/index.html +3 -3
  32. package/dist/docs/proxy-cli/utils-and-i18n.html +3 -3
  33. package/dist/docs/proxy-core/chat-api.html +3 -3
  34. package/dist/docs/proxy-core/cli.html +3 -3
  35. package/dist/docs/proxy-core/config.html +3 -3
  36. package/dist/docs/proxy-core/data-layer.html +3 -3
  37. package/dist/docs/proxy-core/entry.html +3 -3
  38. package/dist/docs/proxy-core/index.html +3 -3
  39. package/dist/docs/proxy-core/pm2.html +3 -3
  40. package/dist/docs/proxy-core/providers.html +3 -3
  41. package/dist/docs/proxy-core/proxy.html +3 -3
  42. package/dist/docs/proxy-core/stats.html +3 -3
  43. package/dist/docs/proxy-core/tool.html +3 -3
  44. package/dist/docs/proxy-core/ui-routes.html +5 -5
  45. package/dist/docs/proxy-core/utilities.html +3 -3
  46. package/dist/docs/quickstart.html +3 -3
  47. package/dist/docs/request-flow.html +3 -3
  48. package/dist/logger/index.d.ts +0 -3
  49. package/dist/logger/index.js +0 -1
  50. package/dist/mcp-server/tools.js +8 -9
  51. package/dist/server/__tests__/data-push.test.js +44 -0
  52. package/dist/server/__tests__/providers-route.test.js +1 -0
  53. package/dist/server/__tests__/proxy.test.js +281 -2
  54. package/dist/server/__tests__/server.test.js +15 -10
  55. package/dist/server/__tests__/ui-route.test.js +43 -0
  56. package/dist/server/auth.d.ts +0 -1
  57. package/dist/server/auth.js +1 -1
  58. package/dist/server/chat-route.js +48 -162
  59. package/dist/server/data-push.d.ts +2 -1
  60. package/dist/server/data-push.js +22 -7
  61. package/dist/server/index.js +4 -3
  62. package/dist/server/proxy.js +193 -229
  63. package/dist/server/ui-route.js +84 -60
  64. package/dist/tools/index.d.ts +1 -1
  65. package/dist/tools/index.js +1 -1
  66. package/dist/tools/registry.d.ts +0 -4
  67. package/dist/tools/registry.js +0 -8
  68. package/dist/types/config.d.ts +0 -13
  69. package/dist/types/pm2.d.ts +1 -2
  70. package/dist/ui/assets/{1c-DAu68mP4.js → 1c-CaPSZBmB.js} +1 -1
  71. package/dist/ui/assets/{abnf-Cu8RHCHK.js → abnf-DBDOsmne.js} +1 -1
  72. package/dist/ui/assets/{abnfDiagram-VRR7QNED-BUBToPXF.js → abnfDiagram-VRR7QNED-D8zK__Mj.js} +1 -1
  73. package/dist/ui/assets/{accesslog-BG-34XOy.js → accesslog-BOLs2Kig.js} +1 -1
  74. package/dist/ui/assets/{actionscript-iw0HHMGM.js → actionscript-BZYKhS1B.js} +1 -1
  75. package/dist/ui/assets/{ada-qRqj6VGQ.js → ada-DyacnMpg.js} +1 -1
  76. package/dist/ui/assets/{angelscript-BeaXyx_P.js → angelscript-CAN6j0H3.js} +1 -1
  77. package/dist/ui/assets/{apache-CU8d-z9X.js → apache-BE4vouiQ.js} +1 -1
  78. package/dist/ui/assets/{applescript-d1Wxkqz1.js → applescript-CS88I1yz.js} +1 -1
  79. package/dist/ui/assets/{arc-BMsPIm3j.js → arc-CTMmdrSV.js} +1 -1
  80. package/dist/ui/assets/{arcade-CtbgrWTM.js → arcade-B0f0f5SD.js} +1 -1
  81. package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-CVjC5TrS.js → architectureDiagram-ZJ3FMSHR-Dtvpnopp.js} +1 -1
  82. package/dist/ui/assets/{arduino-Bc9L39Hr.js → arduino-Bhm-OSb2.js} +1 -1
  83. package/dist/ui/assets/{armasm-DuWmpjWR.js → armasm-CEy-mDHc.js} +1 -1
  84. package/dist/ui/assets/{asciidoc-CDIhFTnx.js → asciidoc-CrZqQBTj.js} +1 -1
  85. package/dist/ui/assets/{aspectj-SYj-57Es.js → aspectj-B4IlFyyJ.js} +1 -1
  86. package/dist/ui/assets/{autohotkey-hBi5dq37.js → autohotkey-Cihy-FjA.js} +1 -1
  87. package/dist/ui/assets/{autoit-BSawXzhg.js → autoit-Dis_JVJq.js} +1 -1
  88. package/dist/ui/assets/{avrasm-CwYom8Np.js → avrasm-CVhMycHj.js} +1 -1
  89. package/dist/ui/assets/{awk-BvBRfGo2.js → awk-BCViwLf5.js} +1 -1
  90. package/dist/ui/assets/{axapta-CqUavA8k.js → axapta-pWB4JVB_.js} +1 -1
  91. package/dist/ui/assets/{bash-BS_ZnmEu.js → bash-B6Giryub.js} +1 -1
  92. package/dist/ui/assets/{basic-xbP4IXrN.js → basic-DcrjcHB0.js} +1 -1
  93. package/dist/ui/assets/{blockDiagram-677ZJIJ3-CmpI3f5p.js → blockDiagram-677ZJIJ3-DfhtgI1r.js} +1 -1
  94. package/dist/ui/assets/{bnf-BECwu6uW.js → bnf-cpKU0967.js} +1 -1
  95. package/dist/ui/assets/{brainfuck-QQgu4j4N.js → brainfuck-CFFdk4cM.js} +1 -1
  96. package/dist/ui/assets/{coq-IDMIFfem.js → c-CW6KPMeI.js} +1 -1
  97. package/dist/ui/assets/{c-like-DYrFOtXy.js → c-like-CWn59vrg.js} +1 -1
  98. package/dist/ui/assets/{c4Diagram-LMCZKHZV-B6Hgngz9.js → c4Diagram-LMCZKHZV-D1Oh6k37.js} +1 -1
  99. package/dist/ui/assets/{cal-CNMrJ6v5.js → cal-8i26_L39.js} +1 -1
  100. package/dist/ui/assets/{capnproto-DYCKl6oY.js → capnproto-CviwnFBf.js} +1 -1
  101. package/dist/ui/assets/{ceylon-mb8tRPl0.js → ceylon-CQyc4rWs.js} +1 -1
  102. package/dist/ui/assets/channel-Da2MvpNG.js +1 -0
  103. package/dist/ui/assets/{chunk-2Q5K7J3B-LxvQ-G67.js → chunk-2Q5K7J3B-oswPBwIn.js} +1 -1
  104. package/dist/ui/assets/{chunk-32BRIVSS-DxzKK6Aw.js → chunk-32BRIVSS-B5pU_9b9.js} +1 -1
  105. package/dist/ui/assets/{chunk-5VM5RSS4-CZEoYJ2W.js → chunk-5VM5RSS4-gvtfMc4w.js} +1 -1
  106. package/dist/ui/assets/{chunk-EX3LRPZG-DS2PytrN.js → chunk-EX3LRPZG-BkBaDMy4.js} +1 -1
  107. package/dist/ui/assets/{chunk-JWPE2WC7-UX0Sr1Ie.js → chunk-JWPE2WC7-Ch-C75ar.js} +1 -1
  108. package/dist/ui/assets/{chunk-MOJQB5TN-YbJgT9t4.js → chunk-MOJQB5TN-BfYhj1jN.js} +1 -1
  109. package/dist/ui/assets/{chunk-RYQCIY6F-DS2VH_U9.js → chunk-RYQCIY6F-D8izfruP.js} +1 -1
  110. package/dist/ui/assets/{chunk-V7JOEXUC-CZr0pkI1.js → chunk-V7JOEXUC-CbzHnW90.js} +1 -1
  111. package/dist/ui/assets/{chunk-VR4S4FIN-50opPAD3.js → chunk-VR4S4FIN-Dr4M5qZA.js} +1 -1
  112. package/dist/ui/assets/{chunk-XXDRQBXY-DAAX9l7U.js → chunk-XXDRQBXY-QE-R8dRe.js} +1 -1
  113. package/dist/ui/assets/classDiagram-OUVF2IWQ-mHUiWjcC.js +1 -0
  114. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-mHUiWjcC.js +1 -0
  115. package/dist/ui/assets/{clean-C4X7dSkh.js → clean-DZeAtQ7H.js} +1 -1
  116. package/dist/ui/assets/{clojure-DSg9gUa7.js → clojure-U4ebZ7NQ.js} +1 -1
  117. package/dist/ui/assets/{clojure-repl-CagRYx7h.js → clojure-repl-B4QSIzUI.js} +1 -1
  118. package/dist/ui/assets/{cmake-CFdBn53c.js → cmake-UHexZySb.js} +1 -1
  119. package/dist/ui/assets/{coffeescript-CJZtMOPx.js → coffeescript-Dg56H9Mr.js} +1 -1
  120. package/dist/ui/assets/{c-BRJEPYra.js → coq-C1g3mm0X.js} +1 -1
  121. package/dist/ui/assets/{cos-Bx2VJuzG.js → cos-BL4DdyGh.js} +1 -1
  122. package/dist/ui/assets/{cose-bilkent-JH36ORCC-zWRLsZpZ.js → cose-bilkent-JH36ORCC-BHQslHP3.js} +1 -1
  123. package/dist/ui/assets/{cpp-CsG6DlC4.js → cpp-keZI-XAd.js} +1 -1
  124. package/dist/ui/assets/{crmsh-DTy9MnmJ.js → crmsh-DdXYVeeA.js} +1 -1
  125. package/dist/ui/assets/{crystal-BwgrLrZ1.js → crystal-C4AN0m0I.js} +1 -1
  126. package/dist/ui/assets/{csharp-B2VeTPAF.js → csharp-COUyKsNR.js} +1 -1
  127. package/dist/ui/assets/{csp-CTpydNhH.js → csp-DBc-rgSJ.js} +1 -1
  128. package/dist/ui/assets/{css-B0mMUbpY.js → css-B8m6O_Pw.js} +1 -1
  129. package/dist/ui/assets/{cynefin-VYW2F7L2-BmjQEj6q.js → cynefin-VYW2F7L2-B3L-WcKn.js} +1 -1
  130. package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-Dr0Zrke0.js → cynefinDiagram-TSTJHNR4-fzaM4qcZ.js} +1 -1
  131. package/dist/ui/assets/{d-DjuDZnbI.js → d-dgQN4Rko.js} +1 -1
  132. package/dist/ui/assets/{dagre-VKFMJZFB-xoTPT2Uu.js → dagre-VKFMJZFB-DJHj16mR.js} +1 -1
  133. package/dist/ui/assets/{dart-xR3GU9TJ.js → dart-D2Y7LOq-.js} +1 -1
  134. package/dist/ui/assets/{delphi-bJas5QnG.js → delphi-DaGcSk5A.js} +1 -1
  135. package/dist/ui/assets/{diagram-FQU43EPY-rL_IU7gU.js → diagram-FQU43EPY-iZEZ1f-R.js} +1 -1
  136. package/dist/ui/assets/{diagram-G47NLZAW-EcDiCVGj.js → diagram-G47NLZAW-rkQb3r-C.js} +1 -1
  137. package/dist/ui/assets/{diagram-NH7WQ7WH-CGGXOjev.js → diagram-NH7WQ7WH-B4Fy72tP.js} +1 -1
  138. package/dist/ui/assets/{diagram-OA4YK3LP-DnE7hDjD.js → diagram-OA4YK3LP-BndmuIBq.js} +1 -1
  139. package/dist/ui/assets/{diagram-WEI45ONY-CTJH5eD8.js → diagram-WEI45ONY-CwlAiqOe.js} +1 -1
  140. package/dist/ui/assets/{diff-doJFF3fv.js → diff-prcRV1Y3.js} +1 -1
  141. package/dist/ui/assets/{django-D3b-owa_.js → django-B1zIoGSx.js} +1 -1
  142. package/dist/ui/assets/{dns-C42KYV-Z.js → dns-ZxI_aTwc.js} +1 -1
  143. package/dist/ui/assets/{dockerfile-9KUINc2j.js → dockerfile-Dp_fT6E-.js} +1 -1
  144. package/dist/ui/assets/{dos-CxnlJ6qp.js → dos-Cuu5c8vv.js} +1 -1
  145. package/dist/ui/assets/{dsconfig-6CMMCwmY.js → dsconfig-DcGTOhbS.js} +1 -1
  146. package/dist/ui/assets/{dts-D78rdUIB.js → dts-DCF8VaRk.js} +1 -1
  147. package/dist/ui/assets/{dust-Dv1uTfJU.js → dust-DeCmZWMK.js} +1 -1
  148. package/dist/ui/assets/{ebnf-BGbG1cFK.js → ebnf-BHQQcuF_.js} +1 -1
  149. package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-z2VgRSUV.js → ebnfDiagram-CCIWWBDH-DJ_RuhTm.js} +1 -1
  150. package/dist/ui/assets/{elixir-ZgAQVY1J.js → elixir-BHmweJ4d.js} +1 -1
  151. package/dist/ui/assets/{elm-CudiFuNu.js → elm-v76Hd2B3.js} +1 -1
  152. package/dist/ui/assets/{erDiagram-Q63AITRT-X1TODuRv.js → erDiagram-Q63AITRT-DVZkY5RZ.js} +1 -1
  153. package/dist/ui/assets/{erb-Bz_NZh6W.js → erb-xvWF5bfx.js} +1 -1
  154. package/dist/ui/assets/{erlang-DNuj1nb2.js → erlang-CKBMURym.js} +1 -1
  155. package/dist/ui/assets/{erlang-repl-SP1Gan9W.js → erlang-repl-BjcfXt3Z.js} +1 -1
  156. package/dist/ui/assets/{excel-0K77uECF.js → excel-Cdrtxhml.js} +1 -1
  157. package/dist/ui/assets/{fix-CalJq7JD.js → fix-CB-So5So.js} +1 -1
  158. package/dist/ui/assets/{flix-BlIs11_w.js → flix-VM9AOrq6.js} +1 -1
  159. package/dist/ui/assets/{flowDiagram-23GEKE2U-DA2dnmc0.js → flowDiagram-23GEKE2U-vyGW67Xm.js} +1 -1
  160. package/dist/ui/assets/{fortran-ZCobXY2R.js → fortran-CcwJVO8H.js} +1 -1
  161. package/dist/ui/assets/{fsharp-Be8rwUtc.js → fsharp-DiATpw1u.js} +1 -1
  162. package/dist/ui/assets/{gams-DUat8frQ.js → gams-Csg9YNPz.js} +1 -1
  163. package/dist/ui/assets/{ganttDiagram-NO4QXBWP-DdFwaIGZ.js → ganttDiagram-NO4QXBWP-C2TRbwLw.js} +1 -1
  164. package/dist/ui/assets/{gauss-BB4U88dy.js → gauss-Bc4TC8Wh.js} +1 -1
  165. package/dist/ui/assets/{gcode-DzeUZuZg.js → gcode-Rig_2OoA.js} +1 -1
  166. package/dist/ui/assets/{gherkin-B_8vW_BO.js → gherkin-ByBU06QB.js} +1 -1
  167. package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-B-Dn8x6I.js → gitGraphDiagram-IHSO6WYX-CEiqfFIF.js} +1 -1
  168. package/dist/ui/assets/{glsl-DGHGjPC1.js → glsl-C8D6y2Tn.js} +1 -1
  169. package/dist/ui/assets/{gml-BYEku8Yh.js → gml-PHpGPHbT.js} +1 -1
  170. package/dist/ui/assets/{go-D8aSgQMc.js → go-BL_o_3ez.js} +1 -1
  171. package/dist/ui/assets/{golo-CDjCU_jh.js → golo-CWQ6dTUz.js} +1 -1
  172. package/dist/ui/assets/{gradle-BeUw7tl_.js → gradle-Y_I2KN2z.js} +1 -1
  173. package/dist/ui/assets/{groovy-5iCQOtR3.js → groovy-JnIv8p2l.js} +1 -1
  174. package/dist/ui/assets/{haml-BEdL8FJi.js → haml-B8W_h6mZ.js} +1 -1
  175. package/dist/ui/assets/{handlebars-BuYQNzoK.js → handlebars-DVm8mJuD.js} +1 -1
  176. package/dist/ui/assets/{haskell-I4FCBcW0.js → haskell-DlDi2Ty7.js} +1 -1
  177. package/dist/ui/assets/{haxe-yigyKfFr.js → haxe-CftFNVE-.js} +1 -1
  178. package/dist/ui/assets/{hsp-ZUk4j7d1.js → hsp-C67xnq9C.js} +1 -1
  179. package/dist/ui/assets/{htmlbars-QYP3lT3u.js → htmlbars-CmJCm67U.js} +1 -1
  180. package/dist/ui/assets/{http-BJpD1O71.js → http-b-FPEcHP.js} +1 -1
  181. package/dist/ui/assets/{hy-CIJ1bP6S.js → hy-BWD3ncpN.js} +1 -1
  182. package/dist/ui/assets/{index-COAgrx1J.js → index-C7s1zgJb.js} +242 -242
  183. package/dist/ui/assets/{index-BDXWttnT.js → index-D2UBwfSG.js} +3 -3
  184. package/dist/ui/assets/index-DlsVXaHT.css +10 -0
  185. package/dist/ui/assets/{infoDiagram-FWYZ7A6U-fTg9eLNt.js → infoDiagram-FWYZ7A6U-C0Px17IN.js} +1 -1
  186. package/dist/ui/assets/{inform7-DAsu-lC2.js → inform7-C-OYaMO5.js} +1 -1
  187. package/dist/ui/assets/{ini-Bhz-zHCg.js → ini-CVyYmykw.js} +1 -1
  188. package/dist/ui/assets/{irpf90-BunhbwBl.js → irpf90-BcpjWXIz.js} +1 -1
  189. package/dist/ui/assets/{isbl-q9L6hOhP.js → isbl-ZraBBeEr.js} +1 -1
  190. package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-B8G0sdgd.js → ishikawaDiagram-FXEZZL3T-BjmTMgpO.js} +1 -1
  191. package/dist/ui/assets/{java-Iks5Pkau.js → java-D_mE2DT6.js} +1 -1
  192. package/dist/ui/assets/{javascript-C4vltXPw.js → javascript-akXESsox.js} +1 -1
  193. package/dist/ui/assets/{jboss-cli-BQBvd2X2.js → jboss-cli-CFe3gTDt.js} +1 -1
  194. package/dist/ui/assets/{journeyDiagram-5HDEW3XC-Crbzgrum.js → journeyDiagram-5HDEW3XC-BpgJUvs6.js} +1 -1
  195. package/dist/ui/assets/{json-DXK0_jUK.js → json-sjN7AzRC.js} +1 -1
  196. package/dist/ui/assets/{julia-CCYoBiYK.js → julia-BJJYbUMV.js} +1 -1
  197. package/dist/ui/assets/{julia-repl-y8v2Oorl.js → julia-repl-BwruD8Ix.js} +1 -1
  198. package/dist/ui/assets/{kanban-definition-HUTT4EX6-C8sCOsBX.js → kanban-definition-HUTT4EX6-DFlE9edA.js} +1 -1
  199. package/dist/ui/assets/{kotlin-Bnjk7_fw.js → kotlin-CAIQsLCF.js} +1 -1
  200. package/dist/ui/assets/{lasso-B-al6x63.js → lasso-sU67h-5u.js} +1 -1
  201. package/dist/ui/assets/{latex-BUmqlb9r.js → latex-CVX-jP88.js} +1 -1
  202. package/dist/ui/assets/{ldif-D42RWj6Q.js → ldif-DGM9xbFZ.js} +1 -1
  203. package/dist/ui/assets/{leaf-CrH4BZ0m.js → leaf-AlB_zmwz.js} +1 -1
  204. package/dist/ui/assets/{less-upmRlQQW.js → less-CKwfEdZQ.js} +1 -1
  205. package/dist/ui/assets/{lisp-DHYS22SA.js → lisp-CXYLaAPw.js} +1 -1
  206. package/dist/ui/assets/{livecodeserver-CeQNmFP3.js → livecodeserver-C02fGGTS.js} +1 -1
  207. package/dist/ui/assets/{livescript-PJWpY1JI.js → livescript-CBMa8QF_.js} +1 -1
  208. package/dist/ui/assets/{llvm-BKtKWwCt.js → llvm-WXTIohTC.js} +1 -1
  209. package/dist/ui/assets/{lsl-RWRLRjk7.js → lsl-4obd2U_I.js} +1 -1
  210. package/dist/ui/assets/{lua-BFUDiPGm.js → lua-DTSy-TjF.js} +1 -1
  211. package/dist/ui/assets/{makefile-CUDyOz5D.js → makefile-Bf2UEO0i.js} +1 -1
  212. package/dist/ui/assets/{markdown-zZCLypc6.js → markdown-BgoGmFfJ.js} +1 -1
  213. package/dist/ui/assets/{mathematica-BHbxKxnq.js → mathematica-CSiA8KQh.js} +1 -1
  214. package/dist/ui/assets/{matlab-DlGtg--p.js → matlab-DoMvLsGB.js} +1 -1
  215. package/dist/ui/assets/{maxima-BBBeS3Ra.js → maxima-BFO4dfZO.js} +1 -1
  216. package/dist/ui/assets/{mel-nh8j7W_6.js → mel-DyBpmDxt.js} +1 -1
  217. package/dist/ui/assets/{mercury-DyyD-pqr.js → mercury-OL5G5uU6.js} +1 -1
  218. package/dist/ui/assets/{mindmap-definition-LN4V7U3C-CJlhDHqM.js → mindmap-definition-LN4V7U3C-s-nUZuCs.js} +1 -1
  219. package/dist/ui/assets/{mipsasm-hiEhRRiq.js → mipsasm-KQwdm39j.js} +1 -1
  220. package/dist/ui/assets/{mizar-BZa3iAAL.js → mizar-BqndJ30I.js} +1 -1
  221. package/dist/ui/assets/{mojolicious-BCIm2V_y.js → mojolicious-Bvc1uJd-.js} +1 -1
  222. package/dist/ui/assets/{monkey-zmK-7N8b.js → monkey-Dl_gLm7-.js} +1 -1
  223. package/dist/ui/assets/{moonscript-BsS_Mn3D.js → moonscript-BL6R6eAz.js} +1 -1
  224. package/dist/ui/assets/{n1ql-D7xVgDP0.js → n1ql-C09iOJfQ.js} +1 -1
  225. package/dist/ui/assets/{nginx-ct2q4dtd.js → nginx-C7W01nBr.js} +1 -1
  226. package/dist/ui/assets/{nim-RO0UOmW3.js → nim-Dj78szvD.js} +1 -1
  227. package/dist/ui/assets/{nix-BcRJxPKH.js → nix-BOtGyPmd.js} +1 -1
  228. package/dist/ui/assets/{node-repl-DgIefwxW.js → node-repl-19nZvZ4A.js} +1 -1
  229. package/dist/ui/assets/{nsis-DqHs9QhB.js → nsis-ByCl1zIm.js} +1 -1
  230. package/dist/ui/assets/{objectivec-BBcWqc7Y.js → objectivec-BhdaT_Jr.js} +1 -1
  231. package/dist/ui/assets/{ocaml-BExfw7D6.js → ocaml-D_NXvSO7.js} +1 -1
  232. package/dist/ui/assets/{openscad-CHPRELQb.js → openscad-DOhagvnA.js} +1 -1
  233. package/dist/ui/assets/{oxygene-DpS9uMJW.js → oxygene-5BnkqMRH.js} +1 -1
  234. package/dist/ui/assets/{parser3-CjJ_QdBp.js → parser3-jSWlxi8m.js} +1 -1
  235. package/dist/ui/assets/{pegDiagram-2B236MQR-GM70woGy.js → pegDiagram-2B236MQR-CideH-XT.js} +1 -1
  236. package/dist/ui/assets/{perl-BSNM2Kt8.js → perl-CfsqjZ4b.js} +1 -1
  237. package/dist/ui/assets/{pf-Z-hKf_88.js → pf-kOewxO29.js} +1 -1
  238. package/dist/ui/assets/{pgsql-DDgznxBg.js → pgsql-CXm2Xd-Z.js} +1 -1
  239. package/dist/ui/assets/{php-BzAhxF-l.js → php-CRiA_dH8.js} +1 -1
  240. package/dist/ui/assets/{php-template-DkgcKHRc.js → php-template-ByMrxqSd.js} +1 -1
  241. package/dist/ui/assets/{pieDiagram-ENE6RG2P-Bst7mPyz.js → pieDiagram-ENE6RG2P-CJkCdB38.js} +1 -1
  242. package/dist/ui/assets/{plaintext-BYEppD0R.js → plaintext-BJx0R6A5.js} +1 -1
  243. package/dist/ui/assets/{pony-BT_kQd1K.js → pony-CozCHtz4.js} +1 -1
  244. package/dist/ui/assets/{powershell-BfRsuSsf.js → powershell-BT7gMMgn.js} +1 -1
  245. package/dist/ui/assets/{processing-DpzWe5Iu.js → processing-FOIxn_W_.js} +1 -1
  246. package/dist/ui/assets/{profile-BCOhS5cM.js → profile-BsoUuD9w.js} +1 -1
  247. package/dist/ui/assets/{prolog-OxaCCaW8.js → prolog-Bd3gvQ2N.js} +1 -1
  248. package/dist/ui/assets/{properties-DMFlA2Ca.js → properties-BWGFdny9.js} +1 -1
  249. package/dist/ui/assets/{protobuf-CRDFkXvZ.js → protobuf-pQSKoOOY.js} +1 -1
  250. package/dist/ui/assets/{puppet-DnrVyLzx.js → puppet-DnEN_mgS.js} +1 -1
  251. package/dist/ui/assets/{purebasic-Dht4Hniv.js → purebasic-BqoOGoRw.js} +1 -1
  252. package/dist/ui/assets/{python-B0aMirWu.js → python-TeVYomkE.js} +1 -1
  253. package/dist/ui/assets/{python-repl-BlYDBGa7.js → python-repl-zqu5igFS.js} +1 -1
  254. package/dist/ui/assets/{q-DzrtW9kT.js → q-CZC9Dltd.js} +1 -1
  255. package/dist/ui/assets/{qml-DnfQsR3i.js → qml-ZNInP45Q.js} +1 -1
  256. package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-DNRYurBT.js → quadrantDiagram-ABIIQ3AL-Dd7PwxsF.js} +1 -1
  257. package/dist/ui/assets/{r-DGI_ZuTD.js → r-B39DAmkC.js} +1 -1
  258. package/dist/ui/assets/{railroadDiagram-RFXS5EU6-CmbC3Vz4.js → railroadDiagram-RFXS5EU6-DtO5PVFZ.js} +1 -1
  259. package/dist/ui/assets/{reasonml-3SohMgh2.js → reasonml-B-ZWFJt_.js} +1 -1
  260. package/dist/ui/assets/{requirementDiagram-TGXJPOKE-8CxrXHco.js → requirementDiagram-TGXJPOKE-DihF4OTj.js} +1 -1
  261. package/dist/ui/assets/{rib-DfRSd4Qa.js → rib-CnGG0qMF.js} +1 -1
  262. package/dist/ui/assets/{roboconf-CQczGdGW.js → roboconf-Ewtfps4u.js} +1 -1
  263. package/dist/ui/assets/{routeros-DCka-T2i.js → routeros-CPcmP1c7.js} +1 -1
  264. package/dist/ui/assets/{rsl-Dr8MOwMo.js → rsl-NbjWFbPH.js} +1 -1
  265. package/dist/ui/assets/{ruby-C2zFSkh_.js → ruby-DWDdy5yE.js} +1 -1
  266. package/dist/ui/assets/{ruleslanguage-C97YsgQq.js → ruleslanguage-Cv_DZe2r.js} +1 -1
  267. package/dist/ui/assets/{rust-H3h8kd9A.js → rust-NZnsfER5.js} +1 -1
  268. package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-DBXLWjEq.js → sankeyDiagram-HTMAVEWB-D6i-Mzte.js} +1 -1
  269. package/dist/ui/assets/{sas-04z0Xu8P.js → sas-C4wv0P6G.js} +1 -1
  270. package/dist/ui/assets/{scala-DyB9Aoiv.js → scala-DUdTOIgx.js} +1 -1
  271. package/dist/ui/assets/{scheme-DBj6nxUi.js → scheme-DEdFa14t.js} +1 -1
  272. package/dist/ui/assets/{scilab-Btj7AD9s.js → scilab-xY51J2bR.js} +1 -1
  273. package/dist/ui/assets/{scss-BXZJyXt7.js → scss-BEYp1sXc.js} +1 -1
  274. package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DXIkBFKC.js → sequenceDiagram-DBY2YBRQ-njQlqy_J.js} +1 -1
  275. package/dist/ui/assets/{shell-BsreQR1Z.js → shell-fq6bkhOw.js} +1 -1
  276. package/dist/ui/assets/{sizeCapture-X5ZJPWSS-ocS9jxAQ.js → sizeCapture-X5ZJPWSS-tLn70-Fb.js} +1 -1
  277. package/dist/ui/assets/{smali-D9wQw9zm.js → smali-CsSAuSYg.js} +1 -1
  278. package/dist/ui/assets/{smalltalk-Dku6G_H3.js → smalltalk-DJ7zrd87.js} +1 -1
  279. package/dist/ui/assets/{sml-BknyU6ya.js → sml-CnDwl0nH.js} +1 -1
  280. package/dist/ui/assets/{sqf-DRYMaOg8.js → sqf-Cc2SX4Zy.js} +1 -1
  281. package/dist/ui/assets/{sql-Cw3Ax4KA.js → sql-DUQA_V_4.js} +1 -1
  282. package/dist/ui/assets/{sql_more-vWdslLE0.js → sql_more-BHoH-8oO.js} +1 -1
  283. package/dist/ui/assets/{stan-8XH5bDS6.js → stan-D-7F5jH6.js} +1 -1
  284. package/dist/ui/assets/{stata-4e77wgfe.js → stata-xKD_DnDE.js} +1 -1
  285. package/dist/ui/assets/{stateDiagram-2N3HPSRC-RMmL9jMG.js → stateDiagram-2N3HPSRC-B4O8weor.js} +1 -1
  286. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-CO881_ht.js +1 -0
  287. package/dist/ui/assets/{step21-ByIeDMY3.js → step21-obc_kzQY.js} +1 -1
  288. package/dist/ui/assets/{stylus-ZAhJyWsw.js → stylus-CkAUSRd-.js} +1 -1
  289. package/dist/ui/assets/{subunit-pPW2UGkj.js → subunit-BDv8PGo1.js} +1 -1
  290. package/dist/ui/assets/{swift-CX3BB5az.js → swift-CHsYyW-p.js} +1 -1
  291. package/dist/ui/assets/{swimlanes-5IMT3BWC-C2zAuJ56.js → swimlanes-5IMT3BWC-DSr9Ty4A.js} +2 -2
  292. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DFMCDs8b.js +8 -0
  293. package/dist/ui/assets/{taggerscript-BHcjbWIC.js → taggerscript-C_2JQgO9.js} +1 -1
  294. package/dist/ui/assets/{tap-BOl1lBlS.js → tap-Bi497Z2c.js} +1 -1
  295. package/dist/ui/assets/{tcl-DZjeOBDh.js → tcl-B1XMvLaD.js} +1 -1
  296. package/dist/ui/assets/{thrift-BxboWg4x.js → thrift-D9X0Hmmc.js} +1 -1
  297. package/dist/ui/assets/{timeline-definition-FHXFAJF6-BOxsxyq_.js → timeline-definition-FHXFAJF6-C4_gj50B.js} +1 -1
  298. package/dist/ui/assets/{tp-BNM6ql3J.js → tp-CJG4Odbx.js} +1 -1
  299. package/dist/ui/assets/{twig-Dj9ZiXD4.js → twig-flj72_wc.js} +1 -1
  300. package/dist/ui/assets/{typescript-7MEJlu_6.js → typescript-CWPwVoLd.js} +1 -1
  301. package/dist/ui/assets/{vala-DNqOAgHJ.js → vala-LuCNWNuU.js} +1 -1
  302. package/dist/ui/assets/{vbnet-T0mNKVc_.js → vbnet-CGUT6ss0.js} +1 -1
  303. package/dist/ui/assets/{vbscript-CeuwVMAI.js → vbscript-CNiUBJhn.js} +1 -1
  304. package/dist/ui/assets/{vbscript-html-BbJSt2w6.js → vbscript-html-CJGgjjbc.js} +1 -1
  305. package/dist/ui/assets/{vennDiagram-L72KCM5P-BX9mWeiT.js → vennDiagram-L72KCM5P-BxcAUnYo.js} +1 -1
  306. package/dist/ui/assets/{verilog-DYuhYfkX.js → verilog-C4f9ZBTK.js} +1 -1
  307. package/dist/ui/assets/{vhdl-Cf9aT-t7.js → vhdl-CyDQIZve.js} +1 -1
  308. package/dist/ui/assets/{vim-DciP44K1.js → vim-XAUBqa0M.js} +1 -1
  309. package/dist/ui/assets/{wardleyDiagram-EHGQE667-CDj2rOzu.js → wardleyDiagram-EHGQE667-DlwSH77q.js} +1 -1
  310. package/dist/ui/assets/{x86asm-E-AN_LXO.js → x86asm-Cp6vHuUx.js} +1 -1
  311. package/dist/ui/assets/{xl-CxYLJelN.js → xl-BHgDofIM.js} +1 -1
  312. package/dist/ui/assets/{xml-yz1SRLuU.js → xml-QloVn4s_.js} +1 -1
  313. package/dist/ui/assets/{xquery-BLzBF3tV.js → xquery-spJZLmyM.js} +1 -1
  314. package/dist/ui/assets/{xychartDiagram-FW5EYKEG-Czapk9-Z.js → xychartDiagram-FW5EYKEG-BxGVZcnb.js} +1 -1
  315. package/dist/ui/assets/{yaml-Cv4Y7iN_.js → yaml-CUju4iq0.js} +1 -1
  316. package/dist/ui/assets/{zephir-KRcdQfEX.js → zephir-ChVpmD0Y.js} +1 -1
  317. package/dist/ui/index.html +2 -2
  318. package/dist/utils/__tests__/abort-signals.test.js +67 -0
  319. package/dist/utils/__tests__/db-maintenance.test.js +55 -0
  320. package/dist/utils/__tests__/db-migration.test.js +79 -1
  321. package/dist/utils/__tests__/inject-loop.test.js +1 -53
  322. package/dist/utils/__tests__/learn-tasks-db.test.js +82 -0
  323. package/dist/utils/__tests__/openai-converter.test.js +25 -0
  324. package/dist/utils/__tests__/pi-crawl-tools.test.js +15 -4
  325. package/dist/utils/__tests__/pi-dedup-reconcile.test.js +11 -9
  326. package/dist/utils/__tests__/pi-events.test.d.ts +1 -0
  327. package/dist/utils/__tests__/pi-events.test.js +172 -0
  328. package/dist/utils/__tests__/pi-learn-orchestrator.test.js +216 -6
  329. package/dist/utils/__tests__/pi-runtime-json.test.js +38 -3
  330. package/dist/utils/__tests__/providers-db.test.js +40 -2
  331. package/dist/utils/__tests__/request-writer.test.js +532 -39
  332. package/dist/utils/__tests__/sse-protocol.test.d.ts +1 -0
  333. package/dist/utils/__tests__/sse-protocol.test.js +115 -0
  334. package/dist/utils/__tests__/stats-aggregator.test.d.ts +1 -0
  335. package/dist/utils/__tests__/stats-aggregator.test.js +114 -0
  336. package/dist/utils/__tests__/vault.test.d.ts +1 -0
  337. package/dist/utils/__tests__/{knowledge-store.test.js → vault.test.js} +16 -16
  338. package/dist/utils/abort-signals.d.ts +13 -0
  339. package/dist/utils/abort-signals.js +33 -0
  340. package/dist/utils/db-maintenance.d.ts +8 -0
  341. package/dist/utils/db-maintenance.js +18 -0
  342. package/dist/utils/db.d.ts +2 -0
  343. package/dist/utils/db.js +86 -0
  344. package/dist/utils/esm-dirname.d.ts +0 -15
  345. package/dist/utils/esm-dirname.js +0 -4
  346. package/dist/utils/inject-loop.d.ts +0 -27
  347. package/dist/utils/inject-loop.js +2 -56
  348. package/dist/utils/learn-tasks-db.d.ts +15 -0
  349. package/dist/utils/learn-tasks-db.js +35 -0
  350. package/dist/utils/openai-converter.js +88 -78
  351. package/dist/utils/pi-browser-tools.d.ts +0 -2
  352. package/dist/utils/pi-browser-tools.js +0 -174
  353. package/dist/utils/pi-crawl-tools.d.ts +2 -1
  354. package/dist/utils/pi-crawl-tools.js +16 -11
  355. package/dist/utils/pi-dedup.d.ts +8 -30
  356. package/dist/utils/pi-dedup.js +32 -67
  357. package/dist/utils/pi-events.d.ts +65 -0
  358. package/dist/utils/pi-events.js +98 -0
  359. package/dist/utils/pi-learn-orchestrator.d.ts +6 -5
  360. package/dist/utils/pi-learn-orchestrator.js +71 -106
  361. package/dist/utils/pi-runtime.d.ts +5 -6
  362. package/dist/utils/pi-runtime.js +38 -42
  363. package/dist/utils/pi-sandbox-ops.d.ts +0 -36
  364. package/dist/utils/pi-sandbox-ops.js +5 -190
  365. package/dist/utils/providers-db.d.ts +3 -0
  366. package/dist/utils/providers-db.js +21 -7
  367. package/dist/utils/request-writer.d.ts +77 -26
  368. package/dist/utils/request-writer.js +362 -56
  369. package/dist/utils/sse-protocol.d.ts +34 -0
  370. package/dist/utils/sse-protocol.js +121 -0
  371. package/dist/utils/sse-stream-processor.d.ts +4 -9
  372. package/dist/utils/sse-stream-processor.js +13 -104
  373. package/dist/utils/sse-writer.d.ts +1 -1
  374. package/dist/utils/sse-writer.js +3 -2
  375. package/dist/utils/stats-aggregator.d.ts +1 -1
  376. package/dist/utils/stats-aggregator.js +44 -24
  377. package/dist/utils/tool-injector.js +7 -0
  378. package/dist/utils/vault.d.ts +111 -0
  379. package/dist/utils/vault.js +434 -0
  380. package/ecosystem.config.cjs +2 -1
  381. package/package.json +1 -1
  382. package/dist/docs/assets/chunks/@localSearchIndexroot.B6Qfxe6W.js +0 -1
  383. package/dist/server/middleware/__tests__/request-id.test.js +0 -28
  384. package/dist/server/middleware/request-id.d.ts +0 -2
  385. package/dist/server/middleware/request-id.js +0 -12
  386. package/dist/types/api.d.ts +0 -20
  387. package/dist/types/index.d.ts +0 -4
  388. package/dist/types/index.js +0 -4
  389. package/dist/types/log.d.ts +0 -13
  390. package/dist/ui/assets/channel-Bc4Td8eZ.js +0 -1
  391. package/dist/ui/assets/classDiagram-OUVF2IWQ-BicxhZFq.js +0 -1
  392. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-BicxhZFq.js +0 -1
  393. package/dist/ui/assets/index-C0fxlU9d.css +0 -10
  394. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-QvaEO5U6.js +0 -1
  395. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DPgCOY0D.js +0 -8
  396. package/dist/utils/__tests__/sse-accumulator.test.js +0 -83
  397. package/dist/utils/knowledge-store.d.ts +0 -51
  398. package/dist/utils/knowledge-store.js +0 -241
  399. package/dist/utils/migrate-files-to-db.d.ts +0 -1
  400. package/dist/utils/migrate-files-to-db.js +0 -138
  401. package/dist/utils/sse-accumulator.d.ts +0 -9
  402. package/dist/utils/sse-accumulator.js +0 -59
  403. /package/dist/docs/assets/{proxy-cli_data-hooks.md.w9Oe1OD3.lean.js → proxy-cli_data-hooks.md.Bz8CVbxO.lean.js} +0 -0
  404. /package/dist/docs/assets/{proxy-core_ui-routes.md.Dyqkeoiv.lean.js → proxy-core_ui-routes.md.B21t1p7R.lean.js} +0 -0
  405. /package/dist/server/{middleware/__tests__/request-id.test.d.ts → __tests__/data-push.test.d.ts} +0 -0
  406. /package/dist/{types/api.js → utils/__tests__/abort-signals.test.d.ts} +0 -0
  407. /package/dist/{types/log.js → utils/__tests__/db-maintenance.test.d.ts} +0 -0
  408. /package/dist/utils/__tests__/{knowledge-store.test.d.ts → learn-tasks-db.test.d.ts} +0 -0
  409. /package/dist/utils/__tests__/{sse-accumulator.test.d.ts → openai-converter.test.d.ts} +0 -0
@@ -261,6 +261,8 @@ function tagCaptureHandler(captured) {
261
261
  }
262
262
  // ---------- Test scaffolding ----------
263
263
  let tmpDir;
264
+ // 现有用例不触发取消,复用一个常驻 signal(同一引用贯穿各阶段)
265
+ const externalSignal = new AbortController().signal;
264
266
  beforeEach(async () => {
265
267
  tmpDir = await fsp.mkdtemp(path.join(os.tmpdir(), 'learn-pipe-'));
266
268
  mockCreatePiSession.mockReset();
@@ -307,6 +309,7 @@ describe('pi-learn-orchestrator', () => {
307
309
  port: 9999,
308
310
  events: makeEvents(),
309
311
  docsDir: tmpDir,
312
+ signal: externalSignal,
310
313
  })).rejects.toThrow(/outline 未生成/);
311
314
  expect(mockCreatePiSession).toHaveBeenCalledTimes(1);
312
315
  expect(mockCreatePiSession.mock.calls[0][0].mode).toBe('outline');
@@ -350,6 +353,7 @@ describe('pi-learn-orchestrator', () => {
350
353
  port: 9999,
351
354
  events,
352
355
  docsDir: tmpDir,
356
+ signal: externalSignal,
353
357
  });
354
358
  expect(result.slug).toBe('my-topic');
355
359
  expect(result.chunksWritten).toBe(2);
@@ -387,6 +391,7 @@ describe('pi-learn-orchestrator', () => {
387
391
  port: 9999,
388
392
  events,
389
393
  docsDir: tmpDir,
394
+ signal: externalSignal,
390
395
  });
391
396
  expect(result.slug).toBe(slug);
392
397
  expect(events.calls).toContain('stageEnd:outline');
@@ -408,6 +413,7 @@ describe('pi-learn-orchestrator', () => {
408
413
  port: 9999,
409
414
  events,
410
415
  docsDir: tmpDir,
416
+ signal: externalSignal,
411
417
  })).rejects.toThrow();
412
418
  // stageEnd 必须在 throw 之前发出
413
419
  expect(events.calls).toContain('stageEnd:outline');
@@ -450,6 +456,7 @@ describe('pi-learn-orchestrator', () => {
450
456
  port: 9999,
451
457
  events,
452
458
  docsDir: tmpDir,
459
+ signal: externalSignal,
453
460
  });
454
461
  // item0 失败(port down),item1 成功
455
462
  expect(result.itemsFailed).toBe(1);
@@ -493,6 +500,7 @@ describe('pi-learn-orchestrator', () => {
493
500
  port: 9999,
494
501
  events,
495
502
  docsDir: tmpDir,
503
+ signal: externalSignal,
496
504
  });
497
505
  expect(result.slug).toBe(slug);
498
506
  expect(events.calls).toContain('stageEnd:tag');
@@ -529,6 +537,7 @@ describe('pi-learn-orchestrator', () => {
529
537
  port: 9999,
530
538
  events,
531
539
  docsDir: tmpDir,
540
+ signal: externalSignal,
532
541
  });
533
542
  expect(result.slug).toBe(slug);
534
543
  expect(events.calls).toContain('stageEnd:tag');
@@ -564,6 +573,7 @@ describe('pi-learn-orchestrator', () => {
564
573
  port: 9999,
565
574
  events,
566
575
  docsDir: tmpDir,
576
+ signal: externalSignal,
567
577
  });
568
578
  expect(result.chunksWritten).toBe(0);
569
579
  expect(result.itemsFailed).toBe(1);
@@ -597,10 +607,11 @@ describe('pi-learn-orchestrator', () => {
597
607
  port: 9999,
598
608
  events,
599
609
  docsDir: tmpDir,
610
+ signal: externalSignal,
600
611
  })).rejects.toThrow();
601
- // 轮次必须闭合:roundStart:0 有且仅有一次配对的 roundEnd:0
602
- expect(events.calls).toContain('roundStart:0');
603
- expect(events.calls.filter((c) => c === 'roundEnd:0')).toHaveLength(1);
612
+ // 轮次必须闭合:roundStart:1 有且仅有一次配对的 roundEnd:1
613
+ expect(events.calls).toContain('roundStart:1');
614
+ expect(events.calls.filter((c) => c === 'roundEnd:1')).toHaveLength(1);
604
615
  });
605
616
  // ============================================================
606
617
  // url 模式:crawl 阶段由 LLM agent 驱动
@@ -617,18 +628,19 @@ describe('pi-learn-orchestrator', () => {
617
628
  port: 9999,
618
629
  events,
619
630
  docsDir: tmpDir,
631
+ signal: externalSignal,
620
632
  });
621
633
  // sources:入口 + 同站子页共 2 份
622
634
  const files = await fsp.readdir(path.join(tmpDir, 'pi', 'sources'));
623
635
  expect(files.filter((f) => f.endsWith('.md'))).toHaveLength(2);
624
636
  expect(result.slug).toBe('pi');
625
637
  expect(result.chunksWritten).toBe(1);
626
- // round:crawl + outline + refine + tag = 4 轮,起止索引严格配对
638
+ // round:crawl + outline + refine + tag = 4 轮,起止索引严格配对(1-based)
627
639
  expect(events.calls.filter((c) => c.startsWith('roundStart:'))).toEqual([
628
- 'roundStart:0', 'roundStart:1', 'roundStart:2', 'roundStart:3',
640
+ 'roundStart:1', 'roundStart:2', 'roundStart:3', 'roundStart:4',
629
641
  ]);
630
642
  expect(events.calls.filter((c) => c.startsWith('roundEnd:'))).toEqual([
631
- 'roundEnd:0', 'roundEnd:1', 'roundEnd:2', 'roundEnd:3',
643
+ 'roundEnd:1', 'roundEnd:2', 'roundEnd:3', 'roundEnd:4',
632
644
  ]);
633
645
  });
634
646
  test('url 首轮 0 页 → 全新 guard+session 重试 1 次后成功', async () => {
@@ -645,6 +657,7 @@ describe('pi-learn-orchestrator', () => {
645
657
  port: 9999,
646
658
  events,
647
659
  docsDir: tmpDir,
660
+ signal: externalSignal,
648
661
  });
649
662
  // 两个 crawl session(guard 也重建)+ outline/refine/tag
650
663
  const crawlSessions = mockCreatePiSession.mock.calls.filter(([o]) => o.mode === 'crawl');
@@ -669,6 +682,7 @@ describe('pi-learn-orchestrator', () => {
669
682
  port: 9999,
670
683
  events,
671
684
  docsDir: tmpDir,
685
+ signal: externalSignal,
672
686
  })).rejects.toThrow(/crawl 未收集到页面/);
673
687
  // 建了 2 个 guard 且都被 close(finally 关闭当前 guard;首个 guard 在替换时关闭)
674
688
  expect(crawlToolsMock.CrawlGuard).toHaveBeenCalledTimes(2);
@@ -710,6 +724,7 @@ describe('pi-learn-orchestrator', () => {
710
724
  port: 9999,
711
725
  events: makeEvents(),
712
726
  docsDir: tmpDir,
727
+ signal: externalSignal,
713
728
  });
714
729
  // 返回目标 slug;refine 只写了 1 个新增 chunk
715
730
  expect(result.slug).toBe('oldt');
@@ -764,6 +779,7 @@ describe('pi-learn-orchestrator', () => {
764
779
  port: 9999,
765
780
  events: makeEvents(),
766
781
  docsDir: tmpDir,
782
+ signal: externalSignal,
767
783
  });
768
784
  expect(result.slug).toBe('oldt');
769
785
  expect(result.chunksWritten).toBe(1);
@@ -810,6 +826,7 @@ describe('pi-learn-orchestrator', () => {
810
826
  port: 9999,
811
827
  events: makeEvents(),
812
828
  docsDir: tmpDir,
829
+ signal: externalSignal,
813
830
  });
814
831
  expect(result.slug).toBe('dup');
815
832
  expect(result.chunksWritten).toBe(1);
@@ -848,6 +865,7 @@ describe('pi-learn-orchestrator', () => {
848
865
  port: 9999,
849
866
  events: makeEvents(),
850
867
  docsDir: tmpDir,
868
+ signal: externalSignal,
851
869
  });
852
870
  expect(result.slug).toBe('dup-new');
853
871
  expect(result.chunksWritten).toBe(1);
@@ -879,7 +897,199 @@ describe('pi-learn-orchestrator', () => {
879
897
  port: 9999,
880
898
  events: makeEvents(),
881
899
  docsDir: tmpDir,
900
+ signal: externalSignal,
882
901
  })).rejects.toThrow(/检测到未清理的旁挂目录/);
883
902
  expect(mockCreatePiSession).not.toHaveBeenCalled();
884
903
  });
904
+ // ============================================================
905
+ // 贯穿式 AbortSignal
906
+ // ============================================================
907
+ /**
908
+ * prompt 挂起直到 abort 被调。模拟真实 pi SDK:abort 被吞成 stopReason="aborted"
909
+ * 的 assistant 消息,在途 prompt 正常 resolve(不 reject)。
910
+ */
911
+ function makeBlockingSession() {
912
+ const listeners = new Set();
913
+ let resolvePrompt;
914
+ let aborted = false;
915
+ return {
916
+ sessionId: 'blocking',
917
+ subscribe: (fn) => {
918
+ listeners.add(fn);
919
+ return () => { listeners.delete(fn); };
920
+ },
921
+ prompt: jest.fn(async () => {
922
+ for (const l of listeners)
923
+ l({ type: 'message_start', message: { role: 'assistant' } });
924
+ await new Promise((resolve) => { resolvePrompt = resolve; });
925
+ }),
926
+ waitForIdle: jest.fn(async () => { }),
927
+ abort: jest.fn(async () => {
928
+ if (aborted)
929
+ return;
930
+ aborted = true;
931
+ // 真实 SDK:resolve 在途 prompt,不 rethrow
932
+ resolvePrompt?.();
933
+ }),
934
+ };
935
+ }
936
+ /** 等到 mock 被首次调用(prompt 真正在途) */
937
+ async function waitForCalled(mock) {
938
+ await new Promise((resolve) => {
939
+ const tick = () => (mock.mock.calls.length > 0 ? resolve() : setImmediate(tick));
940
+ tick();
941
+ });
942
+ }
943
+ test('signal 预先 abort:prompt 仍 resolve,runLearnPipeline 靠信号检查 reject', async () => {
944
+ const preAborted = new AbortController();
945
+ preAborted.abort();
946
+ const session = new FakeSession(async () => { });
947
+ const abortSpy = jest.spyOn(session, 'abort');
948
+ mockCreatePiSession.mockImplementation(async () => session);
949
+ await expect(runLearnPipeline({
950
+ sourceType: 'file',
951
+ input: '# body',
952
+ label: 'x.md',
953
+ port: 9999,
954
+ events: makeEvents(),
955
+ docsDir: tmpDir,
956
+ signal: preAborted.signal,
957
+ })).rejects.toThrow(/learn 运行已中止/);
958
+ // bindAbort 对已 abort signal 立即触发 session.abort();prompt 本身正常 resolve
959
+ expect(abortSpy).toHaveBeenCalledTimes(1);
960
+ // 只发生 outline 一个 session 的尝试,后续阶段/查重零调用
961
+ expect(mockCreatePiSession).toHaveBeenCalledTimes(1);
962
+ expect(mockReconcile).not.toHaveBeenCalled();
963
+ });
964
+ test('运行中 abort:prompt 正常 resolve,runLearnPipeline 靠信号检查 reject、后续阶段不执行', async () => {
965
+ const session = makeBlockingSession();
966
+ mockCreatePiSession.mockImplementation(async () => session);
967
+ const controller = new AbortController();
968
+ const events = makeEvents();
969
+ const p = runLearnPipeline({
970
+ sourceType: 'file',
971
+ input: '# body',
972
+ label: 'x.md',
973
+ port: 9999,
974
+ events,
975
+ docsDir: tmpDir,
976
+ signal: controller.signal,
977
+ });
978
+ // 等 prompt 真正在途后再 abort(验证非"预先 abort"路径)
979
+ await waitForCalled(session.prompt);
980
+ expect(session.abort).not.toHaveBeenCalled();
981
+ controller.abort();
982
+ // 不是靠 prompt reject,而是 await 后 combined.aborted 检查主动抛错
983
+ await expect(p).rejects.toThrow(/learn 运行已中止/);
984
+ expect(session.abort).toHaveBeenCalledTimes(1);
985
+ // refine/tag 阶段零启动;查重也不执行
986
+ expect(mockCreatePiSession).toHaveBeenCalledTimes(1);
987
+ expect(events.calls).not.toContain('stageStart:refine');
988
+ expect(events.calls).not.toContain('stageStart:tag');
989
+ expect(mockReconcile).not.toHaveBeenCalled();
990
+ });
991
+ test('signal 透传到 reconcileTopics:门1 收到同一 signal 引用', async () => {
992
+ const mySignal = new AbortController().signal;
993
+ await runLearnPipeline({
994
+ sourceType: 'file',
995
+ input: '# body',
996
+ label: 'sig.md',
997
+ port: 9999,
998
+ events: makeEvents(),
999
+ docsDir: tmpDir,
1000
+ signal: mySignal,
1001
+ });
1002
+ expect(mockReconcile.mock.calls[0][0].signal).toBe(mySignal);
1003
+ });
1004
+ test('signal 透传到 mintSlug:门0 slug 碰撞未合并时收到同一 signal 引用', async () => {
1005
+ await seedDupTopic();
1006
+ const mySignal = new AbortController().signal;
1007
+ await runLearnPipeline({
1008
+ sourceType: 'file',
1009
+ input: '# new body',
1010
+ label: 'dup.md',
1011
+ port: 9999,
1012
+ events: makeEvents(),
1013
+ docsDir: tmpDir,
1014
+ signal: mySignal,
1015
+ });
1016
+ expect(mockMintSlug).toHaveBeenCalledTimes(1);
1017
+ expect(mockMintSlug.mock.calls[0][0].signal).toBe(mySignal);
1018
+ });
1019
+ test('onStart 钩子被调用,参数为算出的 slug', async () => {
1020
+ const slug = 'hook-topic';
1021
+ // S1: 写 outline.json + seed index.json + chunk(同 S3 happy path 模式)
1022
+ mockCreatePiSession.mockImplementationOnce(async () => {
1023
+ return new FakeSession(async () => {
1024
+ await fsp.mkdir(path.join(tmpDir, slug, 'chunks'), { recursive: true });
1025
+ await fsp.writeFile(path.join(tmpDir, slug, 'outline.json'), JSON.stringify({ slug, source: 'sources/', items: [{ id: 'a', title: '概念A', oneLine: 'aaa' }] }, null, 2));
1026
+ await fsp.writeFile(path.join(tmpDir, slug, 'index.json'), JSON.stringify({ slug, title: 'Hook', summary: '(refining)', tags: [], chunks: [
1027
+ { id: 'chunk-001', title: '概念A', summary: 'aaa', tags: [] },
1028
+ ] }, null, 2));
1029
+ await fsp.writeFile(path.join(tmpDir, slug, 'chunks', 'chunk-001.md'), '# 概念A');
1030
+ });
1031
+ });
1032
+ mockCreatePiSession.mockImplementationOnce(async () => new FakeSession(FakeSession.readSourceThen(async () => { })));
1033
+ mockCreatePiSession.mockImplementationOnce(async () => {
1034
+ return new FakeSession(FakeSession.addTopicHandler(['a-tag']));
1035
+ });
1036
+ const onStart = jest.fn();
1037
+ const result = await runLearnPipeline({
1038
+ sourceType: 'file',
1039
+ input: '# body',
1040
+ label: `${slug}.md`,
1041
+ port: 9999,
1042
+ events: makeEvents(),
1043
+ docsDir: tmpDir,
1044
+ signal: externalSignal,
1045
+ onStart,
1046
+ });
1047
+ expect(result.slug).toBe(slug);
1048
+ expect(onStart).toHaveBeenCalledTimes(1);
1049
+ expect(onStart).toHaveBeenCalledWith(slug);
1050
+ });
1051
+ test('onStart 抛错 → pipeline reject,docs 目录无任何改动且不创建 session', async () => {
1052
+ const onStart = jest.fn(() => {
1053
+ throw new Error('已有同主题的学习任务在运行');
1054
+ });
1055
+ await expect(runLearnPipeline({
1056
+ sourceType: 'file',
1057
+ input: '# body',
1058
+ label: 'boom.md',
1059
+ port: 9999,
1060
+ events: makeEvents(),
1061
+ docsDir: tmpDir,
1062
+ signal: externalSignal,
1063
+ onStart,
1064
+ })).rejects.toThrow(/已有同主题的学习任务在运行/);
1065
+ expect(await fsp.readdir(tmpDir)).toEqual([]);
1066
+ expect(mockCreatePiSession).not.toHaveBeenCalled();
1067
+ });
1068
+ test('超时路径:5 分钟超时 signal 触发 → session.abort 调用、pipeline reject', async () => {
1069
+ // Node 的 AbortSignal.timeout 内部 timer 不受 fake clock 控制,且 fake timers 下
1070
+ // fs.promises IO 不 settle;mock 成等价 signal,prompt 在途后手动触发(模拟 5 分钟到点)
1071
+ const timeoutController = new AbortController();
1072
+ const timeoutSpy = jest
1073
+ .spyOn(AbortSignal, 'timeout')
1074
+ .mockReturnValue(timeoutController.signal);
1075
+ const session = makeBlockingSession();
1076
+ mockCreatePiSession.mockImplementation(async () => session);
1077
+ const p = runLearnPipeline({
1078
+ sourceType: 'file',
1079
+ input: '# body',
1080
+ label: 'x.md',
1081
+ port: 9999,
1082
+ events: makeEvents(),
1083
+ docsDir: tmpDir,
1084
+ signal: new AbortController().signal,
1085
+ });
1086
+ await waitForCalled(session.prompt);
1087
+ expect(session.abort).not.toHaveBeenCalled();
1088
+ // 模拟 5 分钟超时触发
1089
+ timeoutController.abort();
1090
+ expect(timeoutSpy).toHaveBeenCalledWith(5 * 60 * 1000);
1091
+ expect(session.abort).toHaveBeenCalledTimes(1);
1092
+ // prompt 正常 resolve,靠 combined.aborted 检查抛错中止
1093
+ await expect(p).rejects.toThrow(/learn 运行已中止/);
1094
+ });
885
1095
  });
@@ -1,7 +1,32 @@
1
1
  // pi-coding-agent 为 ESM-only(无 require 导出),jest CJS 无法加载;
2
- // mock 掉以加载真实 pi-runtime 模块测试纯函数(同 pi-browser-tools.test.ts 的 typebox mock 做法)
3
- jest.mock('@earendil-works/pi-coding-agent', () => ({ createWriteToolDefinition: () => ({}) }), { virtual: true });
4
- import { extractJsonObject } from '../pi-runtime.js';
2
+ // mock 掉以加载真实 pi-runtime 模块测试纯函数 + runJsonPrompt 中止语义
3
+ // (同 pi-browser-tools.test.ts 的 typebox mock 做法)
4
+ jest.mock('@earendil-works/pi-coding-agent', () => {
5
+ // fake session:模拟真实 SDK——abort 后在途 prompt/waitForIdle 正常 resolve
6
+ const fakeSession = {
7
+ sessionId: 'fake-reconcile',
8
+ subscribe: jest.fn(() => () => { }),
9
+ prompt: jest.fn(async () => { }),
10
+ waitForIdle: jest.fn(async () => { }),
11
+ abort: jest.fn(async () => { }),
12
+ };
13
+ return {
14
+ createWriteToolDefinition: () => ({}),
15
+ createAgentSession: jest.fn(async () => ({ session: fakeSession })),
16
+ DefaultResourceLoader: function () {
17
+ this.reload = async () => { };
18
+ },
19
+ ModelRuntime: {
20
+ create: jest.fn(async () => ({
21
+ registerProvider: jest.fn(),
22
+ getModel: () => ({}),
23
+ })),
24
+ },
25
+ fakeSession,
26
+ };
27
+ }, { virtual: true });
28
+ import { extractJsonObject, runJsonPrompt } from '../pi-runtime.js';
29
+ const { fakeSession } = jest.requireMock('@earendil-works/pi-coding-agent');
5
30
  test('extractJsonObject: 从含 prose/代码围栏文本取出第一个 JSON 对象', () => {
6
31
  const raw = 'Here:\n```json\n{"a":1,"b":[2,3]}\n```\ndone';
7
32
  expect(extractJsonObject(raw)).toEqual({ a: 1, b: [2, 3] });
@@ -9,3 +34,13 @@ test('extractJsonObject: 从含 prose/代码围栏文本取出第一个 JSON 对
9
34
  test('extractJsonObject: 无 JSON → throw', () => {
10
35
  expect(() => extractJsonObject('no json here')).toThrow(/no json object/);
11
36
  });
37
+ test('runJsonPrompt:abort 后 prompt/waitForIdle 正常 resolve → 靠 combined.aborted 检查 reject,不返回 JSON', async () => {
38
+ const external = new AbortController();
39
+ external.abort();
40
+ // combined 因外部 signal 立即 abort,bindAbort 立即调 session.abort();不等 300s 超时
41
+ await expect(runJsonPrompt({ port: 1, instructions: 'return json', prompt: '{}', signal: external.signal })).rejects.toThrow(/json prompt 已中止/);
42
+ expect(fakeSession.abort).toHaveBeenCalledTimes(1);
43
+ // prompt 确实被调用且正常 resolve(证明不是靠 prompt reject)
44
+ expect(fakeSession.prompt).toHaveBeenCalledTimes(1);
45
+ expect(fakeSession.waitForIdle).toHaveBeenCalledTimes(1);
46
+ });
@@ -1,6 +1,6 @@
1
1
  import Database from 'better-sqlite3';
2
- import { applySchemaV2, applySchemaV3, applySchemaV7 } from '../db.js';
3
- import { listProviders, saveProviders, validateProvider, validateProviders } from '../providers-db.js';
2
+ import { applySchemaV2, applySchemaV3, applySchemaV7, applySchemaV9 } from '../db.js';
3
+ import { listProviders, saveProviders, getActiveProvider, validateProvider, validateProviders } from '../providers-db.js';
4
4
  describe('providers-db', () => {
5
5
  let db;
6
6
  beforeEach(() => {
@@ -10,6 +10,7 @@ describe('providers-db', () => {
10
10
  applySchemaV2(db);
11
11
  applySchemaV3(db);
12
12
  applySchemaV7(db);
13
+ applySchemaV9(db);
13
14
  });
14
15
  afterEach(() => {
15
16
  db.close();
@@ -41,6 +42,27 @@ describe('providers-db', () => {
41
42
  expect(inactive?.default).toBe(false);
42
43
  });
43
44
  });
45
+ describe('getActiveProvider', () => {
46
+ test('returns the is_default row with mapped auth_style', () => {
47
+ db.prepare(`INSERT INTO providers (name, base_url, api_key, model, provider, is_default, auth_style)
48
+ VALUES (?, ?, ?, ?, ?, ?, ?)`).run('active', 'https://a.com', 'key', 'm', 'anthropic', 1, 'x-api-key');
49
+ db.prepare(`INSERT INTO providers (name, base_url, api_key, model, provider, is_default)
50
+ VALUES (?, ?, ?, ?, ?, ?)`).run('inactive', 'https://b.com', 'key2', 'm2', 'anthropic', 0);
51
+ const result = getActiveProvider(db);
52
+ expect(result).not.toBeNull();
53
+ expect(result?.name).toBe('active');
54
+ expect(result?.default).toBe(true);
55
+ expect(result?.auth_style).toBe('x-api-key');
56
+ });
57
+ test('returns null when no default row exists', () => {
58
+ db.prepare(`INSERT INTO providers (name, base_url, api_key, model, provider, is_default)
59
+ VALUES (?, ?, ?, ?, ?, ?)`).run('inactive', 'https://b.com', 'key2', 'm2', 'anthropic', 0);
60
+ expect(getActiveProvider(db)).toBeNull();
61
+ });
62
+ test('returns null on empty table', () => {
63
+ expect(getActiveProvider(db)).toBeNull();
64
+ });
65
+ });
44
66
  describe('saveProviders', () => {
45
67
  test('overwrites existing data', () => {
46
68
  db.prepare(`INSERT INTO providers (name, base_url, api_key, model, provider)
@@ -113,6 +135,22 @@ describe('providers-db', () => {
113
135
  expect(p1?.default).toBe(false);
114
136
  expect(p2?.default).toBe(true);
115
137
  });
138
+ test('preserves auth_style x-api-key after save', () => {
139
+ const input = [
140
+ { name: 'p1', base_url: 'https://p1.com', api_key: 'k1', model: 'm', provider: 'anthropic', auth_style: 'x-api-key' }
141
+ ];
142
+ saveProviders(db, input);
143
+ const result = listProviders(db);
144
+ expect(result[0].auth_style).toBe('x-api-key');
145
+ });
146
+ test('defaults auth_style to bearer when not provided', () => {
147
+ const input = [
148
+ { name: 'p1', base_url: 'https://p1.com', api_key: 'k1', model: 'm', provider: 'anthropic' }
149
+ ];
150
+ saveProviders(db, input);
151
+ const result = listProviders(db);
152
+ expect(result[0].auth_style).toBe('bearer');
153
+ });
116
154
  });
117
155
  describe('validateProvider', () => {
118
156
  test('accepts valid data', () => {