@cc-monitoring/proxy-core 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (389) hide show
  1. package/dist/cli/__tests__/commands.test.js +1 -1
  2. package/dist/cli/commands/exec.js +31 -42
  3. package/dist/docs/404.html +2 -2
  4. package/dist/docs/assets/{app.Dc46Hlqp.js → app.DtYNT5zS.js} +1 -1
  5. package/dist/docs/assets/chunks/@localSearchIndexroot.C4sjikMO.js +1 -0
  6. package/dist/docs/assets/chunks/{VPLocalSearchBox.Snq5jR6J.js → VPLocalSearchBox.DpXF9ZAI.js} +1 -1
  7. package/dist/docs/assets/chunks/{theme.XLtxGM-l.js → theme.TS_gUyc7.js} +2 -2
  8. package/dist/docs/assets/{proxy-cli_data-hooks.md.w9Oe1OD3.js → proxy-cli_data-hooks.md.Bz8CVbxO.js} +1 -1
  9. package/dist/docs/assets/{proxy-core_ui-routes.md.Dyqkeoiv.js → proxy-core_ui-routes.md.B21t1p7R.js} +1 -1
  10. package/dist/docs/hashmap.json +1 -1
  11. package/dist/docs/index.html +3 -3
  12. package/dist/docs/overview.html +3 -3
  13. package/dist/docs/packages-utils.html +3 -3
  14. package/dist/docs/proxy-admin/env-and-build.html +3 -3
  15. package/dist/docs/proxy-admin/index.html +3 -3
  16. package/dist/docs/proxy-admin/layout-and-menu.html +3 -3
  17. package/dist/docs/proxy-admin/pages.html +3 -3
  18. package/dist/docs/proxy-admin/routing-and-auth.html +3 -3
  19. package/dist/docs/proxy-admin/services-and-mock.html +3 -3
  20. package/dist/docs/proxy-cli/api-layer.html +3 -3
  21. package/dist/docs/proxy-cli/app-shell.html +3 -3
  22. package/dist/docs/proxy-cli/components-common.html +3 -3
  23. package/dist/docs/proxy-cli/components-config.html +3 -3
  24. package/dist/docs/proxy-cli/components-requests.html +3 -3
  25. package/dist/docs/proxy-cli/components-stats.html +3 -3
  26. package/dist/docs/proxy-cli/components-status.html +3 -3
  27. package/dist/docs/proxy-cli/data-hooks.html +5 -5
  28. package/dist/docs/proxy-cli/index.html +3 -3
  29. package/dist/docs/proxy-cli/utils-and-i18n.html +3 -3
  30. package/dist/docs/proxy-core/chat-api.html +3 -3
  31. package/dist/docs/proxy-core/cli.html +3 -3
  32. package/dist/docs/proxy-core/config.html +3 -3
  33. package/dist/docs/proxy-core/data-layer.html +3 -3
  34. package/dist/docs/proxy-core/entry.html +3 -3
  35. package/dist/docs/proxy-core/index.html +3 -3
  36. package/dist/docs/proxy-core/pm2.html +3 -3
  37. package/dist/docs/proxy-core/providers.html +3 -3
  38. package/dist/docs/proxy-core/proxy.html +3 -3
  39. package/dist/docs/proxy-core/stats.html +3 -3
  40. package/dist/docs/proxy-core/tool.html +3 -3
  41. package/dist/docs/proxy-core/ui-routes.html +5 -5
  42. package/dist/docs/proxy-core/utilities.html +3 -3
  43. package/dist/docs/quickstart.html +3 -3
  44. package/dist/docs/request-flow.html +3 -3
  45. package/dist/logger/index.d.ts +0 -3
  46. package/dist/logger/index.js +0 -1
  47. package/dist/mcp-server/index.js +5 -3
  48. package/dist/mcp-server/tools.js +31 -10
  49. package/dist/server/__tests__/providers-route.test.js +1 -0
  50. package/dist/server/auth.d.ts +0 -1
  51. package/dist/server/auth.js +1 -1
  52. package/dist/server/chat-route.js +48 -156
  53. package/dist/server/data-push.d.ts +0 -1
  54. package/dist/server/data-push.js +0 -7
  55. package/dist/server/proxy.js +128 -219
  56. package/dist/server/ui-route.js +76 -59
  57. package/dist/tools/index.d.ts +1 -1
  58. package/dist/tools/index.js +1 -1
  59. package/dist/tools/registry.d.ts +0 -4
  60. package/dist/tools/registry.js +0 -8
  61. package/dist/types/config.d.ts +0 -13
  62. package/dist/types/pm2.d.ts +1 -2
  63. package/dist/ui/assets/{1c-Bx3CHH-I.js → 1c-CCx-FOtz.js} +1 -1
  64. package/dist/ui/assets/{abnf-NN4-iXDM.js → abnf-Bwbi42Z8.js} +1 -1
  65. package/dist/ui/assets/{abnfDiagram-VRR7QNED-CXFZgDk7.js → abnfDiagram-VRR7QNED-Dm1-8q0E.js} +1 -1
  66. package/dist/ui/assets/{accesslog-Bq9x4vSZ.js → accesslog-DCytz_-m.js} +1 -1
  67. package/dist/ui/assets/{actionscript-CeaB6gjT.js → actionscript-3udf15oh.js} +1 -1
  68. package/dist/ui/assets/{ada-DObFDSC6.js → ada-M5Xa74xG.js} +1 -1
  69. package/dist/ui/assets/{angelscript-4pIbuWPH.js → angelscript-qlrFxfW-.js} +1 -1
  70. package/dist/ui/assets/{apache-w0LzP4me.js → apache-B-sF-DQH.js} +1 -1
  71. package/dist/ui/assets/{applescript-DXpD6Cc9.js → applescript-4FdcBnbI.js} +1 -1
  72. package/dist/ui/assets/{arc-Dtt1H4m8.js → arc-BB3K1enp.js} +1 -1
  73. package/dist/ui/assets/{arcade-D_zU9Djr.js → arcade-B_yqWaaG.js} +1 -1
  74. package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-C0E_eQDM.js → architectureDiagram-ZJ3FMSHR-B39vkY8V.js} +1 -1
  75. package/dist/ui/assets/{arduino-BnmN_xp_.js → arduino-yAcBoTWU.js} +1 -1
  76. package/dist/ui/assets/{armasm-CH_xJaHf.js → armasm-wIcY84bI.js} +1 -1
  77. package/dist/ui/assets/{asciidoc-BlvZZ-hO.js → asciidoc-Bxnu28-Z.js} +1 -1
  78. package/dist/ui/assets/{aspectj-DP5DdFKQ.js → aspectj-B2cKJA_O.js} +1 -1
  79. package/dist/ui/assets/{autohotkey-Cy7dy_B1.js → autohotkey-B_rMWTtE.js} +1 -1
  80. package/dist/ui/assets/{autoit-BmQwjQdM.js → autoit-DwcuvMwv.js} +1 -1
  81. package/dist/ui/assets/{avrasm-fcPy4w1X.js → avrasm-heGX1PXK.js} +1 -1
  82. package/dist/ui/assets/{awk-AlcwGSdk.js → awk-BiqCQAEf.js} +1 -1
  83. package/dist/ui/assets/{axapta-NyMN6Mvz.js → axapta-Cv8M-Ih6.js} +1 -1
  84. package/dist/ui/assets/{bash-Bn3yyTUs.js → bash-Divgn3JV.js} +1 -1
  85. package/dist/ui/assets/{basic-gp9eOjjv.js → basic-B9dnAP55.js} +1 -1
  86. package/dist/ui/assets/{blockDiagram-677ZJIJ3-BHAadGGo.js → blockDiagram-677ZJIJ3-DQ1mf7A_.js} +1 -1
  87. package/dist/ui/assets/{bnf-DRAiK-_J.js → bnf-kIL5mSsP.js} +1 -1
  88. package/dist/ui/assets/{brainfuck-IYgPavhh.js → brainfuck-DqB7xDjH.js} +1 -1
  89. package/dist/ui/assets/{coq-BYVsAo31.js → c-HmsCM6sx.js} +1 -1
  90. package/dist/ui/assets/{c-like-B7T39dtK.js → c-like-De5MhE7G.js} +1 -1
  91. package/dist/ui/assets/{c4Diagram-LMCZKHZV-4cXT8R9f.js → c4Diagram-LMCZKHZV-DQxtYsAx.js} +1 -1
  92. package/dist/ui/assets/{cal-DmXm_WLX.js → cal-mYdfz9en.js} +1 -1
  93. package/dist/ui/assets/{capnproto-Cb-rKd-Z.js → capnproto-D04CRlOt.js} +1 -1
  94. package/dist/ui/assets/{ceylon-Bn2aNwEq.js → ceylon-pi9lFCja.js} +1 -1
  95. package/dist/ui/assets/channel-ChTtxQDg.js +1 -0
  96. package/dist/ui/assets/{chunk-2Q5K7J3B-B3N_AddF.js → chunk-2Q5K7J3B-BDD1nPt8.js} +1 -1
  97. package/dist/ui/assets/{chunk-32BRIVSS-CW7iU3gE.js → chunk-32BRIVSS-DgeQFBb5.js} +1 -1
  98. package/dist/ui/assets/{chunk-5VM5RSS4-M8Ep3dJD.js → chunk-5VM5RSS4-C7Xf2SnI.js} +1 -1
  99. package/dist/ui/assets/{chunk-EX3LRPZG-t2hCXH-v.js → chunk-EX3LRPZG-B_3p1HEv.js} +1 -1
  100. package/dist/ui/assets/{chunk-JWPE2WC7-rQK8maXo.js → chunk-JWPE2WC7-Dvs7u8eY.js} +1 -1
  101. package/dist/ui/assets/{chunk-MOJQB5TN-BpU7vp3L.js → chunk-MOJQB5TN-By21wDCN.js} +1 -1
  102. package/dist/ui/assets/{chunk-RYQCIY6F-CJVNOulR.js → chunk-RYQCIY6F-6NC700r1.js} +1 -1
  103. package/dist/ui/assets/{chunk-V7JOEXUC-B--maww3.js → chunk-V7JOEXUC-vEUqZ3rh.js} +1 -1
  104. package/dist/ui/assets/{chunk-VR4S4FIN-QJ5u9nSh.js → chunk-VR4S4FIN-6tX2dNN9.js} +1 -1
  105. package/dist/ui/assets/{chunk-XXDRQBXY-BcM9JOXa.js → chunk-XXDRQBXY-qDb2jxAR.js} +1 -1
  106. package/dist/ui/assets/classDiagram-OUVF2IWQ-Ccbvamlu.js +1 -0
  107. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-Ccbvamlu.js +1 -0
  108. package/dist/ui/assets/{clean-BCfhFoON.js → clean-CLCsDUl1.js} +1 -1
  109. package/dist/ui/assets/{clojure-DtnBj8eB.js → clojure-dVi5Xifj.js} +1 -1
  110. package/dist/ui/assets/{clojure-repl-D8X-urCW.js → clojure-repl-BO_FpFmF.js} +1 -1
  111. package/dist/ui/assets/{cmake-BH2RXBgt.js → cmake-CP5aJbyK.js} +1 -1
  112. package/dist/ui/assets/{coffeescript-CuoLiQ_d.js → coffeescript-ZEfu_9pF.js} +1 -1
  113. package/dist/ui/assets/{c-Dht0EgwX.js → coq-6aKUn3zn.js} +1 -1
  114. package/dist/ui/assets/{cos-t-cDfrf6.js → cos-BohCnRN2.js} +1 -1
  115. package/dist/ui/assets/{cose-bilkent-JH36ORCC-CYip_9u7.js → cose-bilkent-JH36ORCC-DyXCbbro.js} +1 -1
  116. package/dist/ui/assets/{cpp-Cgv0dQ7g.js → cpp-FOgPWPEt.js} +1 -1
  117. package/dist/ui/assets/{crmsh-7pr1Pq_e.js → crmsh-B0OYb-Oe.js} +1 -1
  118. package/dist/ui/assets/{crystal-BHZFifeV.js → crystal-CuWb_dXm.js} +1 -1
  119. package/dist/ui/assets/{csharp-CVMfBRGF.js → csharp-BbcqM09j.js} +1 -1
  120. package/dist/ui/assets/{csp-NEBRDuZY.js → csp-rgHnTaDq.js} +1 -1
  121. package/dist/ui/assets/{css-B0fbMkoQ.js → css-C-ibh7ZG.js} +1 -1
  122. package/dist/ui/assets/{cynefin-VYW2F7L2-CycR2u2l.js → cynefin-VYW2F7L2-CkuBhgC4.js} +1 -1
  123. package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-CvXYb5em.js → cynefinDiagram-TSTJHNR4-eycFyDao.js} +1 -1
  124. package/dist/ui/assets/{d-AzA6F7Ab.js → d-C0gXxJ0O.js} +1 -1
  125. package/dist/ui/assets/{dagre-VKFMJZFB-6NuSYMRG.js → dagre-VKFMJZFB-DzqX9e49.js} +1 -1
  126. package/dist/ui/assets/{dart-D0VXSwKi.js → dart-C-fTpuUV.js} +1 -1
  127. package/dist/ui/assets/{delphi-B-bkLmCx.js → delphi-Chm0B9xv.js} +1 -1
  128. package/dist/ui/assets/{diagram-FQU43EPY-CNNW_5O7.js → diagram-FQU43EPY-BEgCqfg1.js} +1 -1
  129. package/dist/ui/assets/{diagram-G47NLZAW-C60bRph-.js → diagram-G47NLZAW-Cw11Vs2v.js} +1 -1
  130. package/dist/ui/assets/{diagram-NH7WQ7WH-CwERNWac.js → diagram-NH7WQ7WH-DSG_UWpP.js} +1 -1
  131. package/dist/ui/assets/{diagram-OA4YK3LP-9XSTmf1Z.js → diagram-OA4YK3LP-CJz-WOaJ.js} +1 -1
  132. package/dist/ui/assets/{diagram-WEI45ONY-h8K41_YA.js → diagram-WEI45ONY-CBXjBCvc.js} +1 -1
  133. package/dist/ui/assets/{diff-Ch9RlEn8.js → diff-C-vyuMSL.js} +1 -1
  134. package/dist/ui/assets/{django-C00rhzcB.js → django-CJK7lReT.js} +1 -1
  135. package/dist/ui/assets/{dns-C5MKVde0.js → dns-D02SHjSy.js} +1 -1
  136. package/dist/ui/assets/{dockerfile-BpRaVDMB.js → dockerfile-trKL1Bqu.js} +1 -1
  137. package/dist/ui/assets/{dos-CjQOJ_vn.js → dos-C52dy-sK.js} +1 -1
  138. package/dist/ui/assets/{dsconfig-3zd3UkyN.js → dsconfig-MzHgzVrt.js} +1 -1
  139. package/dist/ui/assets/{dts-Bb6PtK5T.js → dts-B137dHyX.js} +1 -1
  140. package/dist/ui/assets/{dust-BEJKezIa.js → dust-BcbM0r5C.js} +1 -1
  141. package/dist/ui/assets/{ebnf-5-TvfsoC.js → ebnf-DkbpI7bK.js} +1 -1
  142. package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-CRmIjeas.js → ebnfDiagram-CCIWWBDH-aI5uQ7w1.js} +1 -1
  143. package/dist/ui/assets/{elixir-B6gSEyen.js → elixir-BOtDuqQy.js} +1 -1
  144. package/dist/ui/assets/{elm-rR0aqyyf.js → elm-DS8Tyyu-.js} +1 -1
  145. package/dist/ui/assets/{erDiagram-Q63AITRT-DS3jYOq8.js → erDiagram-Q63AITRT-2vCbd4Mm.js} +1 -1
  146. package/dist/ui/assets/{erb-DUu22Jxg.js → erb-CSXECRbn.js} +1 -1
  147. package/dist/ui/assets/{erlang-C0m-R-6W.js → erlang-BMxlgKPJ.js} +1 -1
  148. package/dist/ui/assets/{erlang-repl-B7O2MhlI.js → erlang-repl-DPzlolPg.js} +1 -1
  149. package/dist/ui/assets/{excel-CIqnqFs1.js → excel-CW2Uxed3.js} +1 -1
  150. package/dist/ui/assets/{fix-Ds9tcTzQ.js → fix-UW84SlCs.js} +1 -1
  151. package/dist/ui/assets/{flix-ByzuevTB.js → flix-4UGiPULd.js} +1 -1
  152. package/dist/ui/assets/{flowDiagram-23GEKE2U-B9F3S_Hl.js → flowDiagram-23GEKE2U-R5PbCbZI.js} +1 -1
  153. package/dist/ui/assets/{fortran-DieSVGx5.js → fortran-nhHsngdu.js} +1 -1
  154. package/dist/ui/assets/{fsharp-DGP8m6H3.js → fsharp-CDyZ1ST5.js} +1 -1
  155. package/dist/ui/assets/{gams-BiLGBohb.js → gams-DHzkkUie.js} +1 -1
  156. package/dist/ui/assets/{ganttDiagram-NO4QXBWP-CHiCWnJt.js → ganttDiagram-NO4QXBWP-CGcq4Ie_.js} +1 -1
  157. package/dist/ui/assets/{gauss-Btl1fjJ0.js → gauss-DdhFGyBv.js} +1 -1
  158. package/dist/ui/assets/{gcode-DWl2YoL_.js → gcode-ImHh8OLA.js} +1 -1
  159. package/dist/ui/assets/{gherkin-D42ESIJ2.js → gherkin-CTWAW-XR.js} +1 -1
  160. package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-0pEKZnJg.js → gitGraphDiagram-IHSO6WYX-8nM2Z9lD.js} +1 -1
  161. package/dist/ui/assets/{glsl-Dx1QhGIM.js → glsl-0_W_27G2.js} +1 -1
  162. package/dist/ui/assets/{gml-f0noEVTB.js → gml-BoDggu2z.js} +1 -1
  163. package/dist/ui/assets/{go-DXT6c-0g.js → go-DYfFygwl.js} +1 -1
  164. package/dist/ui/assets/{golo-D3NuJxTg.js → golo-Mlq-TCg9.js} +1 -1
  165. package/dist/ui/assets/{gradle-CUsTLc_e.js → gradle-BALAinEB.js} +1 -1
  166. package/dist/ui/assets/{groovy-BIkOcIpQ.js → groovy-Dht--dWU.js} +1 -1
  167. package/dist/ui/assets/{haml-C5jI7YVN.js → haml-DpMrxg0d.js} +1 -1
  168. package/dist/ui/assets/{handlebars-UOvbWwDx.js → handlebars-DqHzujNj.js} +1 -1
  169. package/dist/ui/assets/{haskell-DuO_Av2n.js → haskell-DZSchhkY.js} +1 -1
  170. package/dist/ui/assets/{haxe-C0Cg5Hjh.js → haxe-C0zBRjdy.js} +1 -1
  171. package/dist/ui/assets/{hsp-CTDajZig.js → hsp-D_PwbSv2.js} +1 -1
  172. package/dist/ui/assets/{htmlbars-_ITuCkOs.js → htmlbars-DxAFMG8u.js} +1 -1
  173. package/dist/ui/assets/{http-Dr26PHfb.js → http-DvTRF0Do.js} +1 -1
  174. package/dist/ui/assets/{hy-B-ThgV4T.js → hy-lVO-kNyp.js} +1 -1
  175. package/dist/ui/assets/{index-CpQr158p.js → index-BbMRVVGt.js} +3 -3
  176. package/dist/ui/assets/{index-CwcnuNUs.js → index-Ci23SMK2.js} +242 -242
  177. package/dist/ui/assets/index-DlsVXaHT.css +10 -0
  178. package/dist/ui/assets/{infoDiagram-FWYZ7A6U-ClKPOdlx.js → infoDiagram-FWYZ7A6U-C7WYDlvc.js} +1 -1
  179. package/dist/ui/assets/{inform7-D7JYYkX9.js → inform7-B8Tf2n8v.js} +1 -1
  180. package/dist/ui/assets/{ini-BZwCkFAf.js → ini-DSoYMaLF.js} +1 -1
  181. package/dist/ui/assets/{irpf90-omMve0rd.js → irpf90-RCPdkB14.js} +1 -1
  182. package/dist/ui/assets/{isbl-C4xosfum.js → isbl-C2p75PPj.js} +1 -1
  183. package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-PtbNBMgh.js → ishikawaDiagram-FXEZZL3T-Cm6jsPlc.js} +1 -1
  184. package/dist/ui/assets/{java-CWjWDe7Q.js → java-DeY4Yuia.js} +1 -1
  185. package/dist/ui/assets/{javascript-C3dxrGuA.js → javascript-3uX1CO-H.js} +1 -1
  186. package/dist/ui/assets/{jboss-cli-CJE7m0Y-.js → jboss-cli-DgnD8mEc.js} +1 -1
  187. package/dist/ui/assets/{journeyDiagram-5HDEW3XC-DgK9V4yg.js → journeyDiagram-5HDEW3XC-DEGV1uA5.js} +1 -1
  188. package/dist/ui/assets/{json-DFUiNV7v.js → json-BV2PmJJp.js} +1 -1
  189. package/dist/ui/assets/{julia-CUTHpx8X.js → julia-B-m8kQm7.js} +1 -1
  190. package/dist/ui/assets/{julia-repl-_ZaQqdrz.js → julia-repl-C51atU2X.js} +1 -1
  191. package/dist/ui/assets/{kanban-definition-HUTT4EX6-BFrDfKdv.js → kanban-definition-HUTT4EX6-BJ4k5iTX.js} +1 -1
  192. package/dist/ui/assets/{kotlin-CrYjQYp8.js → kotlin-CYBziIgl.js} +1 -1
  193. package/dist/ui/assets/{lasso-CAiVg9m2.js → lasso-Dw2SBMDW.js} +1 -1
  194. package/dist/ui/assets/{latex-BkxnXIrT.js → latex-Dpd35yke.js} +1 -1
  195. package/dist/ui/assets/{ldif-CBOqxiN7.js → ldif-Ce9EZU__.js} +1 -1
  196. package/dist/ui/assets/{leaf-CbBZyOGH.js → leaf-CpkZzQtC.js} +1 -1
  197. package/dist/ui/assets/{less-Ca6uLPP0.js → less-Uzo7M0FD.js} +1 -1
  198. package/dist/ui/assets/{lisp-0Cm7_Bzv.js → lisp-DWXDlJYm.js} +1 -1
  199. package/dist/ui/assets/{livecodeserver-B7ka0vFT.js → livecodeserver-uEyPEgVJ.js} +1 -1
  200. package/dist/ui/assets/{livescript-CGmWmcLd.js → livescript-BQ5f07oK.js} +1 -1
  201. package/dist/ui/assets/{llvm-DCVMvkrH.js → llvm-BAvP-skE.js} +1 -1
  202. package/dist/ui/assets/{lsl-PVrTScpn.js → lsl-DhbiIKu6.js} +1 -1
  203. package/dist/ui/assets/{lua-BTo3z2Ux.js → lua-COxeUeLx.js} +1 -1
  204. package/dist/ui/assets/{makefile-DJGh9r9C.js → makefile-DhDx-IgL.js} +1 -1
  205. package/dist/ui/assets/{markdown-BOloL-q7.js → markdown-DX5_kSxq.js} +1 -1
  206. package/dist/ui/assets/{mathematica-CtMMQM2V.js → mathematica-D351ZddB.js} +1 -1
  207. package/dist/ui/assets/{matlab-Bfg_AWdR.js → matlab-CELqIiwF.js} +1 -1
  208. package/dist/ui/assets/{maxima-B2cdS7BY.js → maxima-B_YljrMm.js} +1 -1
  209. package/dist/ui/assets/{mel-BvfPvpYI.js → mel-DltsbNS8.js} +1 -1
  210. package/dist/ui/assets/{mercury-B6KgNIai.js → mercury-axX-5Vjj.js} +1 -1
  211. package/dist/ui/assets/{mindmap-definition-LN4V7U3C-BkeXo5If.js → mindmap-definition-LN4V7U3C-Bl1EJo6p.js} +1 -1
  212. package/dist/ui/assets/{mipsasm-Csras-cD.js → mipsasm-BxmerVwX.js} +1 -1
  213. package/dist/ui/assets/{mizar-C3WDI1-X.js → mizar-XNHfbpL2.js} +1 -1
  214. package/dist/ui/assets/{mojolicious-MnD2Whic.js → mojolicious-BR0U_7zk.js} +1 -1
  215. package/dist/ui/assets/{monkey-DLvUPYTI.js → monkey-lLuu9_f-.js} +1 -1
  216. package/dist/ui/assets/{moonscript-B0XEb3R3.js → moonscript-DoaZ3DRQ.js} +1 -1
  217. package/dist/ui/assets/{n1ql-BMRF54sY.js → n1ql-C6TId6Iu.js} +1 -1
  218. package/dist/ui/assets/{nginx-DqUyeHb8.js → nginx-BezSG-JT.js} +1 -1
  219. package/dist/ui/assets/{nim-3xwg8mOL.js → nim-Bb0rfXie.js} +1 -1
  220. package/dist/ui/assets/{nix-ByTkLdcH.js → nix-o3sJ5-54.js} +1 -1
  221. package/dist/ui/assets/{node-repl-sGSuIUFG.js → node-repl-Sv5hhcTf.js} +1 -1
  222. package/dist/ui/assets/{nsis-Dng5mFSM.js → nsis-B45BJFhF.js} +1 -1
  223. package/dist/ui/assets/{objectivec-DSQ8vb7n.js → objectivec-CzS6zVgh.js} +1 -1
  224. package/dist/ui/assets/{ocaml-BHOhEgRu.js → ocaml-Bqux7PyP.js} +1 -1
  225. package/dist/ui/assets/{openscad-DcUxQ-FQ.js → openscad-4Wf6mF84.js} +1 -1
  226. package/dist/ui/assets/{oxygene-DNlmqhsR.js → oxygene-Fvwqgkkt.js} +1 -1
  227. package/dist/ui/assets/{parser3-DIR98Q6n.js → parser3-zEfzT5wv.js} +1 -1
  228. package/dist/ui/assets/{pegDiagram-2B236MQR-BrXp_1_9.js → pegDiagram-2B236MQR-Dd4rIztM.js} +1 -1
  229. package/dist/ui/assets/{perl-16cY7fyu.js → perl-CsS1Gs6o.js} +1 -1
  230. package/dist/ui/assets/{pf-KrAq2BW7.js → pf-BNH1jO0R.js} +1 -1
  231. package/dist/ui/assets/{pgsql-BV1Z2bjp.js → pgsql-DqPigHrq.js} +1 -1
  232. package/dist/ui/assets/{php-FGjYSZqs.js → php-CdOl9bRs.js} +1 -1
  233. package/dist/ui/assets/{php-template-B1OW86WT.js → php-template-DPfirJg2.js} +1 -1
  234. package/dist/ui/assets/{pieDiagram-ENE6RG2P-Bh0bhWSa.js → pieDiagram-ENE6RG2P-DGaJNf4S.js} +1 -1
  235. package/dist/ui/assets/{plaintext-Cvn_UgSv.js → plaintext-EHbgBKzw.js} +1 -1
  236. package/dist/ui/assets/{pony-CRWnA3MR.js → pony-DmJajtp2.js} +1 -1
  237. package/dist/ui/assets/{powershell-Cwn155MZ.js → powershell-DfGzdWR6.js} +1 -1
  238. package/dist/ui/assets/{processing-BS6-1lrQ.js → processing-BT0ETgPG.js} +1 -1
  239. package/dist/ui/assets/{profile-C45OLQrv.js → profile-B3I-x5Lt.js} +1 -1
  240. package/dist/ui/assets/{prolog-C5YafSzY.js → prolog-B_4QJIvI.js} +1 -1
  241. package/dist/ui/assets/{properties-BULd-Zhg.js → properties-BFVI8weS.js} +1 -1
  242. package/dist/ui/assets/{protobuf-Qf1IuG5l.js → protobuf-PaF39oZZ.js} +1 -1
  243. package/dist/ui/assets/{puppet-93XdQvnn.js → puppet-BDC6Q8VF.js} +1 -1
  244. package/dist/ui/assets/{purebasic-DlYNScQP.js → purebasic-B2ejrOZK.js} +1 -1
  245. package/dist/ui/assets/{python-D-Do6-F0.js → python-BOxtIk9H.js} +1 -1
  246. package/dist/ui/assets/{python-repl-DGutP04w.js → python-repl-BslBh_Mx.js} +1 -1
  247. package/dist/ui/assets/{q-lmgfrySy.js → q-BPe8WLGW.js} +1 -1
  248. package/dist/ui/assets/{qml-BbjX_mSU.js → qml-BazRR6fz.js} +1 -1
  249. package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-B891FOO8.js → quadrantDiagram-ABIIQ3AL-BQ7aPkHk.js} +1 -1
  250. package/dist/ui/assets/{r--x8NzO9N.js → r-C09pGNJC.js} +1 -1
  251. package/dist/ui/assets/{railroadDiagram-RFXS5EU6-R3O-GKNe.js → railroadDiagram-RFXS5EU6-sCO9VGvE.js} +1 -1
  252. package/dist/ui/assets/{reasonml-DwHsAflh.js → reasonml-S7dzwVL9.js} +1 -1
  253. package/dist/ui/assets/{requirementDiagram-TGXJPOKE-D4l_xEXt.js → requirementDiagram-TGXJPOKE-CfT5aVZg.js} +1 -1
  254. package/dist/ui/assets/{rib-DMJNtDwV.js → rib-fM2EwQd4.js} +1 -1
  255. package/dist/ui/assets/{roboconf-BNNGTvHr.js → roboconf-D7AaeyrW.js} +1 -1
  256. package/dist/ui/assets/{routeros-BF7SVruD.js → routeros-c6Q7mKuq.js} +1 -1
  257. package/dist/ui/assets/{rsl-1EHeIZqp.js → rsl-sCpEQBxh.js} +1 -1
  258. package/dist/ui/assets/{ruby-B-v_BYYp.js → ruby-lcKhz2w9.js} +1 -1
  259. package/dist/ui/assets/{ruleslanguage-GFeEMSdK.js → ruleslanguage-BW4ATOuX.js} +1 -1
  260. package/dist/ui/assets/{rust-ApqGtMhh.js → rust-BbpU-0VY.js} +1 -1
  261. package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-Dc-2lhBq.js → sankeyDiagram-HTMAVEWB-CaweCpvN.js} +1 -1
  262. package/dist/ui/assets/{sas-YkxX6N9_.js → sas-BPt5R0dx.js} +1 -1
  263. package/dist/ui/assets/{scala-BpHi86GZ.js → scala-DxW_vqXs.js} +1 -1
  264. package/dist/ui/assets/{scheme-D889qY8Y.js → scheme-T2Q_jWzT.js} +1 -1
  265. package/dist/ui/assets/{scilab-C3l-bcRx.js → scilab-DMORg9lV.js} +1 -1
  266. package/dist/ui/assets/{scss-D0iGASxm.js → scss-t0VsosqT.js} +1 -1
  267. package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DvppgciC.js → sequenceDiagram-DBY2YBRQ-o-H_R4zb.js} +1 -1
  268. package/dist/ui/assets/{shell-PUnaEPCO.js → shell-CnCDa1s9.js} +1 -1
  269. package/dist/ui/assets/{sizeCapture-X5ZJPWSS-DhvIbxXs.js → sizeCapture-X5ZJPWSS-BNLkHGDS.js} +1 -1
  270. package/dist/ui/assets/{smali-Du_dF9hl.js → smali-_n-BxJyG.js} +1 -1
  271. package/dist/ui/assets/{smalltalk-CSr2Gc1v.js → smalltalk-B90PXJwK.js} +1 -1
  272. package/dist/ui/assets/{sml-D3zkvzP2.js → sml-fuY7bj-n.js} +1 -1
  273. package/dist/ui/assets/{sqf-BZQ34qEZ.js → sqf-COpwkyuo.js} +1 -1
  274. package/dist/ui/assets/{sql-BFKScMsf.js → sql-CXIT0j-x.js} +1 -1
  275. package/dist/ui/assets/{sql_more-C2Lc_Qqq.js → sql_more-C1Oxq4rx.js} +1 -1
  276. package/dist/ui/assets/{stan-CzY8VdxU.js → stan-BZEpaHeC.js} +1 -1
  277. package/dist/ui/assets/{stata-9GxyhPpV.js → stata-CkBwaiZM.js} +1 -1
  278. package/dist/ui/assets/{stateDiagram-2N3HPSRC-CM63y6f0.js → stateDiagram-2N3HPSRC-BkdnNF7I.js} +1 -1
  279. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-0JnZ1VSQ.js +1 -0
  280. package/dist/ui/assets/{step21-BpK_Zw3v.js → step21-fs9N_U3O.js} +1 -1
  281. package/dist/ui/assets/{stylus-DQ4k28M4.js → stylus-Bs_9cvKZ.js} +1 -1
  282. package/dist/ui/assets/{subunit-C6ciOPNF.js → subunit-DvgcOCqJ.js} +1 -1
  283. package/dist/ui/assets/{swift-CJfqqSbT.js → swift-BE4ONsur.js} +1 -1
  284. package/dist/ui/assets/{swimlanes-5IMT3BWC-DS6_HNF7.js → swimlanes-5IMT3BWC-uqTAc7o7.js} +2 -2
  285. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DQRIIEmi.js +8 -0
  286. package/dist/ui/assets/{taggerscript-VouMmJ_v.js → taggerscript-BhmPJ64C.js} +1 -1
  287. package/dist/ui/assets/{tap-wXCy18ot.js → tap-DkueIVKV.js} +1 -1
  288. package/dist/ui/assets/{tcl-ewDOmCFX.js → tcl-DyXOOkFi.js} +1 -1
  289. package/dist/ui/assets/{thrift-BfFA03rE.js → thrift-Dhgbk56T.js} +1 -1
  290. package/dist/ui/assets/{timeline-definition-FHXFAJF6-Dz2m6S6x.js → timeline-definition-FHXFAJF6-DBAk9Ouc.js} +1 -1
  291. package/dist/ui/assets/{tp-HGBcpNf9.js → tp-BsXyrRGH.js} +1 -1
  292. package/dist/ui/assets/{twig-nrQZ0pw8.js → twig-J0HqIuHw.js} +1 -1
  293. package/dist/ui/assets/{typescript-B7tNYFEQ.js → typescript-Dkwvul39.js} +1 -1
  294. package/dist/ui/assets/{vala-BIjQtoo6.js → vala-CRGnf8aY.js} +1 -1
  295. package/dist/ui/assets/{vbnet-Bbspccm6.js → vbnet-BtJAUe3z.js} +1 -1
  296. package/dist/ui/assets/{vbscript-C45_QgOy.js → vbscript-RgFFNuM3.js} +1 -1
  297. package/dist/ui/assets/{vbscript-html-DlF2QBc7.js → vbscript-html-DO32Io9Y.js} +1 -1
  298. package/dist/ui/assets/{vennDiagram-L72KCM5P-BPEphYtX.js → vennDiagram-L72KCM5P-BJi6y0hh.js} +1 -1
  299. package/dist/ui/assets/{verilog-BSitd8W0.js → verilog-C4h6MLcI.js} +1 -1
  300. package/dist/ui/assets/{vhdl-C1bbeiC4.js → vhdl-DOafePyU.js} +1 -1
  301. package/dist/ui/assets/{vim-DchwbT8X.js → vim-BAdTA9TY.js} +1 -1
  302. package/dist/ui/assets/{wardleyDiagram-EHGQE667-BttTCoBT.js → wardleyDiagram-EHGQE667-C7c_4IJ6.js} +1 -1
  303. package/dist/ui/assets/{x86asm-vARxMUvn.js → x86asm-BCL6__QH.js} +1 -1
  304. package/dist/ui/assets/{xl-dx63vvXo.js → xl-qIzE4HOe.js} +1 -1
  305. package/dist/ui/assets/{xml-BUnj27wL.js → xml-DE2sJXYU.js} +1 -1
  306. package/dist/ui/assets/{xquery-T7gpnf0e.js → xquery-CQ35t92y.js} +1 -1
  307. package/dist/ui/assets/{xychartDiagram-FW5EYKEG-BfrNhdrG.js → xychartDiagram-FW5EYKEG-D2ILn0jL.js} +1 -1
  308. package/dist/ui/assets/{yaml-xRgQKzeL.js → yaml-5KaAvG5C.js} +1 -1
  309. package/dist/ui/assets/{zephir-Yu6l5qJj.js → zephir-CbR3Ryfq.js} +1 -1
  310. package/dist/ui/index.html +2 -2
  311. package/dist/utils/__tests__/abort-signals.test.js +67 -0
  312. package/dist/utils/__tests__/inject-loop.test.js +1 -53
  313. package/dist/utils/__tests__/learn-tasks-db.test.js +82 -0
  314. package/dist/utils/__tests__/openai-converter.test.js +25 -0
  315. package/dist/utils/__tests__/pi-crawl-tools.test.js +15 -4
  316. package/dist/utils/__tests__/pi-dedup-reconcile.test.js +11 -9
  317. package/dist/utils/__tests__/pi-events.test.js +172 -0
  318. package/dist/utils/__tests__/pi-learn-orchestrator.test.js +216 -6
  319. package/dist/utils/__tests__/pi-runtime-json.test.js +38 -3
  320. package/dist/utils/__tests__/providers-db.test.js +40 -2
  321. package/dist/utils/__tests__/request-writer.test.js +271 -39
  322. package/dist/utils/__tests__/sse-protocol.test.d.ts +1 -0
  323. package/dist/utils/__tests__/sse-protocol.test.js +115 -0
  324. package/dist/utils/__tests__/vault.test.d.ts +1 -0
  325. package/dist/utils/__tests__/{knowledge-store.test.js → vault.test.js} +16 -16
  326. package/dist/utils/abort-signals.d.ts +13 -0
  327. package/dist/utils/abort-signals.js +33 -0
  328. package/dist/utils/db.d.ts +2 -0
  329. package/dist/utils/db.js +42 -0
  330. package/dist/utils/esm-dirname.d.ts +0 -15
  331. package/dist/utils/esm-dirname.js +0 -4
  332. package/dist/utils/inject-loop.d.ts +0 -27
  333. package/dist/utils/inject-loop.js +2 -56
  334. package/dist/utils/learn-tasks-db.d.ts +15 -0
  335. package/dist/utils/learn-tasks-db.js +35 -0
  336. package/dist/utils/openai-converter.js +88 -78
  337. package/dist/utils/pi-browser-tools.d.ts +0 -2
  338. package/dist/utils/pi-browser-tools.js +0 -174
  339. package/dist/utils/pi-crawl-tools.d.ts +2 -1
  340. package/dist/utils/pi-crawl-tools.js +16 -11
  341. package/dist/utils/pi-dedup.d.ts +8 -30
  342. package/dist/utils/pi-dedup.js +32 -67
  343. package/dist/utils/pi-events.d.ts +65 -0
  344. package/dist/utils/pi-events.js +98 -0
  345. package/dist/utils/pi-learn-orchestrator.d.ts +6 -5
  346. package/dist/utils/pi-learn-orchestrator.js +71 -106
  347. package/dist/utils/pi-runtime.d.ts +5 -6
  348. package/dist/utils/pi-runtime.js +38 -42
  349. package/dist/utils/pi-sandbox-ops.d.ts +0 -36
  350. package/dist/utils/pi-sandbox-ops.js +5 -190
  351. package/dist/utils/providers-db.d.ts +3 -0
  352. package/dist/utils/providers-db.js +21 -7
  353. package/dist/utils/request-writer.d.ts +60 -30
  354. package/dist/utils/request-writer.js +182 -61
  355. package/dist/utils/sse-protocol.d.ts +34 -0
  356. package/dist/utils/sse-protocol.js +121 -0
  357. package/dist/utils/sse-stream-processor.d.ts +4 -9
  358. package/dist/utils/sse-stream-processor.js +13 -104
  359. package/dist/utils/sse-writer.d.ts +1 -1
  360. package/dist/utils/sse-writer.js +3 -2
  361. package/dist/utils/stats-aggregator.js +3 -0
  362. package/dist/utils/tool-injector.js +7 -0
  363. package/dist/utils/vault.d.ts +111 -0
  364. package/dist/utils/vault.js +434 -0
  365. package/package.json +1 -1
  366. package/dist/docs/assets/chunks/@localSearchIndexroot.BN6hB8Jr.js +0 -1
  367. package/dist/types/api.d.ts +0 -20
  368. package/dist/types/index.d.ts +0 -4
  369. package/dist/types/index.js +0 -4
  370. package/dist/types/log.d.ts +0 -13
  371. package/dist/ui/assets/channel-BgAIihW-.js +0 -1
  372. package/dist/ui/assets/classDiagram-OUVF2IWQ-0fsnUoNI.js +0 -1
  373. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-0fsnUoNI.js +0 -1
  374. package/dist/ui/assets/index-C0fxlU9d.css +0 -10
  375. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-OA9dcuA9.js +0 -1
  376. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-BLEnJU_R.js +0 -8
  377. package/dist/utils/__tests__/sse-accumulator.test.js +0 -83
  378. package/dist/utils/knowledge-store.d.ts +0 -44
  379. package/dist/utils/knowledge-store.js +0 -193
  380. package/dist/utils/migrate-files-to-db.d.ts +0 -1
  381. package/dist/utils/migrate-files-to-db.js +0 -138
  382. package/dist/utils/sse-accumulator.d.ts +0 -9
  383. package/dist/utils/sse-accumulator.js +0 -59
  384. /package/dist/docs/assets/{proxy-cli_data-hooks.md.w9Oe1OD3.lean.js → proxy-cli_data-hooks.md.Bz8CVbxO.lean.js} +0 -0
  385. /package/dist/docs/assets/{proxy-core_ui-routes.md.Dyqkeoiv.lean.js → proxy-core_ui-routes.md.B21t1p7R.lean.js} +0 -0
  386. /package/dist/{types/api.js → utils/__tests__/abort-signals.test.d.ts} +0 -0
  387. /package/dist/{types/log.js → utils/__tests__/learn-tasks-db.test.d.ts} +0 -0
  388. /package/dist/utils/__tests__/{knowledge-store.test.d.ts → openai-converter.test.d.ts} +0 -0
  389. /package/dist/utils/__tests__/{sse-accumulator.test.d.ts → pi-events.test.d.ts} +0 -0
@@ -0,0 +1,98 @@
1
+ // pi-events: pi SDK 原始事件 → 会话领域事件的映射原语。
2
+ // learn orchestrator / chat SSE / runJsonPrompt 三处订阅共用同一套映射规则。
3
+ //
4
+ // "轮次" = 一次 assistant 交互(assistant message_start → message_end),
5
+ // 轮次索引 1-based。
6
+ /**
7
+ * 是否 assistant 消息边界(message_start / message_end 分支内调用)。
8
+ * message_start 对 user / assistant / toolResult 三种消息都会触发,
9
+ * 只有 assistant 对应一次 LLM 回复轮次。
10
+ */
11
+ export function isAssistantMessage(ev) {
12
+ return ev?.message?.role === 'assistant';
13
+ }
14
+ /**
15
+ * 从 message_update 事件解包 assistant 流 delta:
16
+ * ae.type 为 text_delta / thinking_delta 且 delta 为 string 时返回,否则 null。
17
+ */
18
+ export function extractAssistantDelta(ev) {
19
+ if (ev?.type !== 'message_update')
20
+ return null;
21
+ const ae = ev.assistantMessageEvent;
22
+ if ((ae?.type === 'text_delta' || ae?.type === 'thinking_delta') && typeof ae.delta === 'string') {
23
+ return { kind: ae.type === 'text_delta' ? 'text' : 'thinking', delta: ae.delta };
24
+ }
25
+ return null;
26
+ }
27
+ /**
28
+ * 提取工具结果文本:result.content 为数组时,各项 type === 'text' 取 text
29
+ * (非 text 项以空串占位),以 '\n' 拼接;否则 ''。
30
+ */
31
+ export function extractToolResultText(result) {
32
+ if (!Array.isArray(result?.content))
33
+ return '';
34
+ return result.content
35
+ .map((c) => (c?.type === 'text' ? c.text : ''))
36
+ .join('\n');
37
+ }
38
+ /**
39
+ * 有状态映射器:内部维护 1-based 轮次计数(assistant message_start 先自增再发
40
+ * round_start,message_end 带当前值),把原始事件映射为 PiSessionEvent 交给 emit。
41
+ * agent_end 等终态事件不在这里处理(由调用方自行监听)。
42
+ *
43
+ * 跨连接复用语义:同一 pi session 可能被多个 SSE 连接先后复用(多次追问),
44
+ * 调用方应通过 initialIndex 传入上次累计的轮次、并在 onIndexChange 中持久化新值,
45
+ * 否则每个连接的 roundIndex 都会从 1 重来,导致前端按 roundIndex 去重时串轮。
46
+ */
47
+ export function createPiEventEmitter(emit, options) {
48
+ let roundIndex = options?.initialIndex ?? 0;
49
+ return {
50
+ write(rawEvent) {
51
+ try {
52
+ const ev = rawEvent;
53
+ if (ev.type === 'message_start') {
54
+ if (isAssistantMessage(ev)) {
55
+ roundIndex += 1;
56
+ options?.onIndexChange?.(roundIndex);
57
+ emit({ type: 'round_start', roundIndex });
58
+ }
59
+ }
60
+ else if (ev.type === 'message_end') {
61
+ if (isAssistantMessage(ev)) {
62
+ emit({ type: 'round_end', roundIndex });
63
+ }
64
+ }
65
+ else if (ev.type === 'message_update') {
66
+ const d = extractAssistantDelta(ev);
67
+ if (d) {
68
+ emit(d.kind === 'text'
69
+ ? { type: 'text_delta', content: d.delta }
70
+ : { type: 'thinking_delta', content: d.delta });
71
+ }
72
+ }
73
+ else if (ev.type === 'tool_execution_start') {
74
+ emit({
75
+ type: 'tool_start',
76
+ toolCallId: ev.toolCallId,
77
+ toolName: ev.toolName,
78
+ args: ev.args,
79
+ });
80
+ }
81
+ else if (ev.type === 'tool_execution_end') {
82
+ emit({
83
+ type: 'tool_end',
84
+ toolCallId: ev.toolCallId,
85
+ toolName: ev.toolName,
86
+ isError: !!ev.isError,
87
+ durationMs: ev.durationMs ?? 0,
88
+ result: extractToolResultText(ev.result),
89
+ });
90
+ }
91
+ // 其他事件(agent_end / 未知类型)忽略
92
+ }
93
+ catch {
94
+ // 映射或 emit 抛错不影响 SDK 事件分发(参照 orchestrator 既有约定)
95
+ }
96
+ },
97
+ };
98
+ }
@@ -1,8 +1,5 @@
1
- export interface OutlineItem {
2
- id: string;
3
- title: string;
4
- oneLine: string;
5
- }
1
+ import type { OutlineItem } from './vault.js';
2
+ export type { OutlineItem };
6
3
  export interface LearnPipelineEvents {
7
4
  stageStart(stage: 'outline' | 'refine' | 'tag', totalItems?: number): void;
8
5
  stageItemStart(index: number, total: number, title: string): void;
@@ -34,8 +31,12 @@ export interface RunLearnPipelineOptions {
34
31
  label?: string;
35
32
  port: number;
36
33
  events: LearnPipelineEvents;
34
+ /** 外部取消信号:客户端断开(关窗)时 abort,流水线各阶段随之中止 */
35
+ signal: AbortSignal;
37
36
  /** 注入式 docsDir(测试用);默认 ~/.cc-monitoring/docs */
38
37
  docsDir?: string;
38
+ /** slug 算出后、任何文件改动前同步调用(落 running 行用);抛错直接传播 */
39
+ onStart?: (slug: string) => void;
39
40
  }
40
41
  export declare function runLearnPipeline(opts: RunLearnPipelineOptions): Promise<{
41
42
  slug: string;
@@ -7,42 +7,23 @@
7
7
  //
8
8
  // "轮次" = 一次 assistant 交互(assistant message_start → message_end);
9
9
  // slug 由入口 URL / 文件名确定性生成。
10
- import fs from 'node:fs';
11
10
  import path from 'node:path';
12
11
  import { dataDir } from './paths.js';
13
12
  import { createPiSession } from './pi-runtime.js';
14
13
  import { CrawlGuard } from './pi-crawl-tools.js';
14
+ import { createTimeoutSignal, bindAbort } from './abort-signals.js';
15
15
  import { slugFromUrl, slugFromLabel } from './web-crawler.js';
16
16
  import { assertNoOldDirs, readAllTopics, readSidecarDetail, readTopicDetail, reconcileTopics, mergeTopics, mintSlug } from './pi-dedup.js';
17
+ import { isAssistantMessage, extractAssistantDelta, extractToolResultText } from './pi-events.js';
18
+ import { createVault } from './vault.js';
17
19
  // 每阶段(含 S2 每个 item prompt)独立超时:5 分钟。
18
20
  // 防止 pi session 在 stuck LLM 响应上无限挂起,导致 SSE 通道常开、前端永久转圈。
19
21
  const STAGE_TIMEOUT_MS = 5 * 60 * 1000;
20
- /**
21
- * Promise.race 包一层超时。超时触发时调用 abortFn(session.abort()),
22
- * 然后 reject;正常 settle 时清掉 timer,避免泄漏。
23
- */
24
- function withTimeout(p, ms, abortFn) {
25
- let timer;
26
- const timeoutP = new Promise((_, reject) => {
27
- timer = setTimeout(() => {
28
- // 触发 abort,尽量让底层 fetch/pi session 提前收尾;reject 用明确错误
29
- abortFn().catch(() => { });
30
- reject(new Error(`stage 超时 ${ms}ms`));
31
- }, ms);
32
- });
33
- return Promise.race([
34
- p.finally(() => {
35
- if (timer)
36
- clearTimeout(timer);
37
- }),
38
- timeoutP,
39
- ]);
40
- }
41
22
  /**
42
23
  * 跑一次 prompt,透传 text/tool 事件到 events;resolve 当 prompt 自然结束。
43
24
  * 同时返回本 session 内关键工具调用的标志位(用于 S3 成功判定)。
44
25
  */
45
- async function runPrompt(session, promptText, events, roundCounter) {
26
+ async function runPrompt(session, promptText, events, roundCounter, signal) {
46
27
  const result = { addTopicCalled: false, readSourceOk: false };
47
28
  // Finding 1:tool_execution_start 时只记录「即将调 add_topic 且 tags 非空」,
48
29
  // 真正置位必须等 tool_execution_end 且 isError=false。否则工具执行失败(upsert
@@ -55,23 +36,24 @@ async function runPrompt(session, promptText, events, roundCounter) {
55
36
  let roundOpen = false;
56
37
  const unsub = session.subscribe((ev) => {
57
38
  try {
58
- if (ev.type === 'message_start' && ev.message?.role === 'assistant') {
59
- currentRound = roundCounter.index;
39
+ if (ev.type === 'message_start' && isAssistantMessage(ev)) {
40
+ // 轮次 1-based:先自增后用;roundCounter 跨 session 全局单调
60
41
  roundCounter.index += 1;
42
+ currentRound = roundCounter.index;
61
43
  roundOpen = true;
62
44
  events.roundStart(currentRound);
63
45
  }
64
- else if (ev.type === 'message_end' && ev.message?.role === 'assistant') {
46
+ else if (ev.type === 'message_end' && isAssistantMessage(ev)) {
65
47
  roundOpen = false;
66
48
  events.roundEnd(currentRound);
67
49
  }
68
50
  else if (ev.type === 'message_update') {
69
- const ae = ev.assistantMessageEvent;
70
- if (ae?.type === 'text_delta' && typeof ae.delta === 'string') {
71
- events.textDelta(ae.delta);
51
+ const d = extractAssistantDelta(ev);
52
+ if (d?.kind === 'text') {
53
+ events.textDelta(d.delta);
72
54
  }
73
- else if (ae?.type === 'thinking_delta' && typeof ae.delta === 'string') {
74
- events.thinkingDelta(ae.delta);
55
+ else if (d?.kind === 'thinking') {
56
+ events.thinkingDelta(d.delta);
75
57
  }
76
58
  }
77
59
  else if (ev.type === 'tool_execution_start') {
@@ -86,9 +68,6 @@ async function runPrompt(session, promptText, events, roundCounter) {
86
68
  }
87
69
  }
88
70
  else if (ev.type === 'tool_execution_end') {
89
- const resultText = Array.isArray(ev.result?.content)
90
- ? ev.result.content.map((c) => (c?.type === 'text' ? c.text : '')).join('\n')
91
- : '';
92
71
  if (ev.toolName === 'add_topic' && pendingAddTopicWithTags && !ev.isError) {
93
72
  result.addTopicCalled = true;
94
73
  }
@@ -100,7 +79,7 @@ async function runPrompt(session, promptText, events, roundCounter) {
100
79
  toolName: ev.toolName,
101
80
  isError: !!ev.isError,
102
81
  durationMs: ev.durationMs ?? 0,
103
- result: resultText,
82
+ result: extractToolResultText(ev.result),
104
83
  });
105
84
  }
106
85
  }
@@ -108,12 +87,16 @@ async function runPrompt(session, promptText, events, roundCounter) {
108
87
  // 事件转发失败不中断流水线
109
88
  }
110
89
  });
90
+ // 5 分钟超时 + 外部取消:任一触发都调 session.abort();SDK abort 后 prompt/waitForIdle
91
+ // 会正常 resolve(不 reject),故 await 后需检查 combined.aborted 主动抛错中止
92
+ const combined = createTimeoutSignal(STAGE_TIMEOUT_MS, signal);
93
+ bindAbort(combined, () => session.abort());
111
94
  try {
112
- // Finding 3:整个 prompt + waitForIdle 包 5 分钟超时;超时 abort 并抛错。
113
- await withTimeout((async () => {
114
- await session.prompt(promptText);
115
- await session.waitForIdle();
116
- })(), STAGE_TIMEOUT_MS, () => session.abort());
95
+ await session.prompt(promptText);
96
+ await session.waitForIdle();
97
+ if (combined.aborted) {
98
+ throw new Error('learn 运行已中止');
99
+ }
117
100
  }
118
101
  finally {
119
102
  unsub();
@@ -130,75 +113,54 @@ async function runPrompt(session, promptText, events, roundCounter) {
130
113
  // ============================================================
131
114
  // 原料准备 + outline 阶段
132
115
  // ============================================================
133
- /** 重建 topic 目录:sources/(抓取/上传原料)+ chunks/(后续产物) */
134
- function prepareTopicDir(docsDir, slug) {
135
- const dir = path.join(docsDir, slug);
136
- fs.rmSync(dir, { recursive: true, force: true });
137
- fs.mkdirSync(path.join(dir, 'sources'), { recursive: true });
138
- fs.mkdirSync(path.join(dir, 'chunks'), { recursive: true });
139
- }
140
- /** 写一份原料到 <slug>/sources/source-NNN.md */
141
- function writeSourceFile(docsDir, slug, index, url, text) {
142
- const name = `source-${String(index + 1).padStart(3, '0')}.md`;
143
- fs.writeFileSync(path.join(docsDir, slug, 'sources', name), `Source: ${url}\n\n${text}`, 'utf8');
144
- }
145
- /** 数 <slug>/sources 下 .md 文件数量;目录不存在按 0 */
146
- function countSourceFiles(docsDir, slug) {
147
- try {
148
- return fs.readdirSync(path.join(docsDir, slug, 'sources')).filter((f) => f.endsWith('.md')).length;
149
- }
150
- catch {
151
- return 0;
152
- }
153
- }
154
116
  async function runOutlineStage(opts, events, roundCounter) {
117
+ const { vault } = opts;
155
118
  // 抓取必须在 stageStart 之后:crawl 的 round/tool 事件才能落进前端已建好的 outline 阶段
156
119
  events.stageStart('outline');
157
120
  let guard = null;
158
121
  try {
159
122
  if (opts.sourceType === 'url') {
160
123
  // crawl agent 在阶段内自己驱动渐进抓取;0 页则全新 guard+session 重试 1 次
161
- guard = new CrawlGuard({ entryUrl: opts.input, docsDir: opts.docsDir, slug: opts.slug });
124
+ guard = new CrawlGuard({ entryUrl: opts.input, docsDir: vault.root, slug: opts.slug });
162
125
  let crawlSession = (await createPiSession({
163
126
  port: opts.port,
164
127
  mode: 'crawl',
165
128
  crawlGuard: guard,
129
+ signal: opts.signal,
166
130
  }));
167
131
  const crawlPrompt = `Entry URL: ${opts.input}\n` +
168
132
  `Topic slug: ${opts.slug}\n` +
169
133
  `Call crawl_open to start, save every useful page with save_source, then call crawl_finish.`;
170
- await runPrompt(crawlSession, crawlPrompt, events, roundCounter);
171
- if (countSourceFiles(opts.docsDir, opts.slug) === 0) {
134
+ await runPrompt(crawlSession, crawlPrompt, events, roundCounter, opts.signal);
135
+ if (vault.countSourceFiles(opts.slug) === 0) {
172
136
  // 替换前关闭旧 guard(close 容错),再全新 guard + session 重试一次
173
137
  await guard.close();
174
- guard = new CrawlGuard({ entryUrl: opts.input, docsDir: opts.docsDir, slug: opts.slug });
138
+ guard = new CrawlGuard({ entryUrl: opts.input, docsDir: vault.root, slug: opts.slug });
175
139
  crawlSession = (await createPiSession({
176
140
  port: opts.port,
177
141
  mode: 'crawl',
178
142
  crawlGuard: guard,
143
+ signal: opts.signal,
179
144
  }));
180
- await runPrompt(crawlSession, crawlPrompt, events, roundCounter);
181
- if (countSourceFiles(opts.docsDir, opts.slug) === 0) {
145
+ await runPrompt(crawlSession, crawlPrompt, events, roundCounter, opts.signal);
146
+ if (vault.countSourceFiles(opts.slug) === 0) {
182
147
  throw new Error('crawl 未收集到页面');
183
148
  }
184
149
  }
185
150
  }
186
151
  else {
187
- writeSourceFile(opts.docsDir, opts.slug, 0, opts.label ?? 'uploaded-file', opts.input);
152
+ vault.writeSourceFile(opts.slug, 0, opts.label ?? 'uploaded-file', opts.input);
188
153
  }
189
154
  // crawl 完成后的 outline session(流程不变)
190
155
  const session = (await createPiSession({ port: opts.port, mode: 'outline' }));
191
156
  const prompt = `Topic slug: ${opts.slug}\n` +
192
157
  `Call read_source(${JSON.stringify(opts.slug)}) to read the prepared sources, then call add_outline with this EXACT slug (${JSON.stringify(opts.slug)}). ` +
193
158
  `Provide an appropriate title and the outline items.`;
194
- await runPrompt(session, prompt, events, roundCounter);
195
- const outlinePath = path.join(opts.docsDir, opts.slug, 'outline.json');
196
- if (!fs.existsSync(outlinePath))
197
- throw new Error('outline 未生成');
198
- const outline = JSON.parse(fs.readFileSync(outlinePath, 'utf8'));
159
+ await runPrompt(session, prompt, events, roundCounter, opts.signal);
160
+ const items = vault.readOutlineItems(opts.slug);
199
161
  // title 取 S1 seed 的 index.json(查重门需要候选标题)
200
- const seedIdx = JSON.parse(fs.readFileSync(path.join(opts.docsDir, opts.slug, 'index.json'), 'utf8'));
201
- return { slug: opts.slug, items: outline.items, title: seedIdx.title };
162
+ const title = vault.readEntryIndexSync(opts.slug).title;
163
+ return { slug: opts.slug, items, title };
202
164
  }
203
165
  finally {
204
166
  // 兜底关闭当前 guard(crawl_finish 已关时 close 也安全)
@@ -212,6 +174,7 @@ async function runOutlineStage(opts, events, roundCounter) {
212
174
  async function runRefineStage(opts, slug, items, events, roundCounter,
213
175
  /** chunk id 起始偏移:合并进已有主题时从目标现有 chunk 数后续号 */
214
176
  startOffset = 0) {
177
+ const { vault } = opts;
215
178
  events.stageStart('refine', items.length);
216
179
  let chunksWritten = 0;
217
180
  let itemsFailed = 0;
@@ -229,15 +192,14 @@ startOffset = 0) {
229
192
  let failReason = 'chunk 文件未生成';
230
193
  for (let attempt = 0; attempt < 2 && !ok; attempt++) {
231
194
  const session = (await createPiSession({ port: opts.port, mode: 'refine' }));
232
- const res = await runPrompt(session, prompt, events, roundCounter);
195
+ const res = await runPrompt(session, prompt, events, roundCounter, opts.signal);
233
196
  if (!res.readSourceOk) {
234
197
  failReason = 'read_source 未成功读取';
235
198
  continue;
236
199
  }
237
- const chunkPath = path.join(opts.docsDir, slug, 'chunks', `${chunkId}.md`);
238
200
  try {
239
- const stat = fs.statSync(chunkPath);
240
- if (stat.size > 0)
201
+ const body = vault.readEntryFile(slug, 'chunks', `${chunkId}.md`);
202
+ if (body.length > 0)
241
203
  ok = true;
242
204
  }
243
205
  catch {
@@ -249,9 +211,7 @@ startOffset = 0) {
249
211
  if (ok) {
250
212
  let chunkRegistered = false;
251
213
  try {
252
- const idxPath = path.join(opts.docsDir, slug, 'index.json');
253
- const idx = JSON.parse(fs.readFileSync(idxPath, 'utf8'));
254
- chunkRegistered = (idx.chunks ?? []).some((c) => c.id === chunkId);
214
+ chunkRegistered = vault.readEntryIndexSync(slug).chunks.some((c) => c.id === chunkId);
255
215
  }
256
216
  catch {
257
217
  // index.json 读失败/JSON 坏 → 当作未注册
@@ -289,10 +249,10 @@ startOffset = 0) {
289
249
  async function runTagStage(opts, slug, events, roundCounter,
290
250
  /** 合并场景:查重门裁定的合并后 title/summary,要求 add_topic 设置为该精确值 */
291
251
  override) {
252
+ const { vault } = opts;
292
253
  events.stageStart('tag');
293
254
  try {
294
- const topicIdxPath = path.join(opts.docsDir, slug, 'index.json');
295
- const topicIdx = JSON.parse(fs.readFileSync(topicIdxPath, 'utf8'));
255
+ const topicIdx = vault.readEntryIndexSync(slug);
296
256
  // 合并后重跑 tag:title/summary 取 override 精确值;否则沿用现有值
297
257
  const title = override?.title ?? topicIdx.title;
298
258
  const summary = override?.summary ?? topicIdx.summary;
@@ -310,7 +270,7 @@ override) {
310
270
  let tagged = false;
311
271
  for (let attempt = 0; attempt < 2 && !tagged; attempt++) {
312
272
  const session = (await createPiSession({ port: opts.port, mode: 'tag' }));
313
- const res = await runPrompt(session, prompt, events, roundCounter);
273
+ const res = await runPrompt(session, prompt, events, roundCounter, opts.signal);
314
274
  if (res.addTopicCalled) {
315
275
  tagged = true;
316
276
  break;
@@ -329,7 +289,10 @@ override) {
329
289
  // ============================================================
330
290
  export async function runLearnPipeline(opts) {
331
291
  const docsDir = opts.docsDir ?? path.join(dataDir, 'docs');
292
+ const vault = createVault(docsDir);
332
293
  const slug = opts.sourceType === 'url' ? slugFromUrl(opts.input) : slugFromLabel(opts.label ?? 'topic');
294
+ // 状态机落库钩子:任何文件/目录改动之前调用,抛错直接传播(此时无任何改动)
295
+ opts.onStart?.(slug);
333
296
  // 阻断:存在未清理的 .old 旁挂目录时直接拒绝,必须在一切写入之前
334
297
  assertNoOldDirs(docsDir);
335
298
  // 全局轮次计数器:所有 session 共享,轮次索引全流水线单调递增
@@ -340,9 +303,9 @@ export async function runLearnPipeline(opts) {
340
303
  // 门0:slug 精确命中——已有同 slug 主题时先旁挂旧 topic(含点号不被识别为 topic),再全新建并跑 S1
341
304
  const collision = (await readAllTopics(docsDir)).some((t) => t.slug === slug);
342
305
  if (collision) {
343
- fs.renameSync(path.join(docsDir, slug), path.join(docsDir, `${slug}.old`));
344
- prepareTopicDir(docsDir, slug);
345
- outline = await runOutlineStage({ ...opts, docsDir, slug }, opts.events, roundCounter);
306
+ vault.parkTopic(slug);
307
+ vault.prepareTopic(slug);
308
+ outline = await runOutlineStage({ sourceType: opts.sourceType, input: opts.input, label: opts.label, port: opts.port, vault, slug, signal: opts.signal }, opts.events, roundCounter);
346
309
  const sidecar = await readSidecarDetail(docsDir, slug);
347
310
  const r0 = await reconcileTopics({
348
311
  port: opts.port,
@@ -350,12 +313,13 @@ export async function runLearnPipeline(opts) {
350
313
  candidate: { slug, title: outline.title, tags: [], items: outline.items },
351
314
  targets: sidecar ? [sidecar] : [],
352
315
  wantItems: true,
316
+ signal: opts.signal,
353
317
  });
354
318
  if (r0.match) {
355
319
  // dst=canonical:旧 chunks 续号并入,再补新增条目,最后带 merged 打 tag
356
320
  const off = mergeTopics(docsDir, `${slug}.old`, slug);
357
- const refine = await runRefineStage({ port: opts.port, docsDir }, slug, r0.itemsToAdd, opts.events, roundCounter, off);
358
- await runTagStage({ port: opts.port, docsDir }, slug, opts.events, roundCounter, { title: r0.mergedTitle, summary: r0.mergedSummary });
321
+ const refine = await runRefineStage({ port: opts.port, vault, signal: opts.signal }, slug, r0.itemsToAdd, opts.events, roundCounter, off);
322
+ await runTagStage({ port: opts.port, vault, signal: opts.signal }, slug, opts.events, roundCounter, { title: r0.mergedTitle, summary: r0.mergedSummary });
359
323
  return { slug, chunksWritten: refine.chunksWritten, itemsFailed: refine.itemsFailed };
360
324
  }
361
325
  // slug 真碰撞:新内容另铸 ns,旧 topic 还原
@@ -363,22 +327,21 @@ export async function runLearnPipeline(opts) {
363
327
  port: opts.port,
364
328
  title: outline.title,
365
329
  existing: (await readAllTopics(docsDir)).map((t) => t.slug),
330
+ signal: opts.signal,
366
331
  });
367
332
  // 新 canonical → ns,更正其 index.slug
368
- fs.renameSync(path.join(docsDir, slug), path.join(docsDir, ns));
369
- const nsIdxPath = path.join(docsDir, ns, 'index.json');
370
- const nsIdx = JSON.parse(fs.readFileSync(nsIdxPath, 'utf8'));
333
+ vault.renameTopic(slug, ns);
334
+ const nsIdx = vault.readEntryIndexSync(ns);
371
335
  nsIdx.slug = ns;
372
- fs.writeFileSync(nsIdxPath, JSON.stringify(nsIdx, null, 2), 'utf8');
336
+ vault.writeEntryIndexSync(ns, nsIdx);
373
337
  // 根 index:把 S1 为新内容登记的 slug 条目改挂 ns
374
- const rootPath = path.join(docsDir, 'index.json');
375
- const rootIdx = JSON.parse(fs.readFileSync(rootPath, 'utf8'));
338
+ const rootIdx = vault.readRootIndexSync();
376
339
  const newEntry = rootIdx.topics.find((t) => t.slug === slug);
377
340
  if (newEntry)
378
341
  newEntry.slug = ns;
379
342
  // 旧 topic 还原:.old → slug
380
- fs.renameSync(path.join(docsDir, `${slug}.old`), path.join(docsDir, slug));
381
- const oldIdx = JSON.parse(fs.readFileSync(path.join(docsDir, slug, 'index.json'), 'utf8'));
343
+ vault.restoreTopic(slug);
344
+ const oldIdx = vault.readEntryIndexSync(slug);
382
345
  const oldRoot = rootIdx.topics.find((t) => t.slug === slug);
383
346
  if (oldRoot) {
384
347
  oldRoot.title = oldIdx.title;
@@ -388,12 +351,12 @@ export async function runLearnPipeline(opts) {
388
351
  else {
389
352
  rootIdx.topics.push({ slug, title: oldIdx.title, summary: oldIdx.summary, tags: oldIdx.tags });
390
353
  }
391
- fs.writeFileSync(rootPath, JSON.stringify(rootIdx, null, 2), 'utf8');
354
+ vault.writeRootIndexSync(rootIdx);
392
355
  activeSlug = ns;
393
356
  }
394
357
  else {
395
- prepareTopicDir(docsDir, slug);
396
- outline = await runOutlineStage({ ...opts, docsDir, slug }, opts.events, roundCounter);
358
+ vault.prepareTopic(slug);
359
+ outline = await runOutlineStage({ sourceType: opts.sourceType, input: opts.input, label: opts.label, port: opts.port, vault, slug, signal: opts.signal }, opts.events, roundCounter);
397
360
  }
398
361
  // 门1:outline 后、refine 前,基于大纲条目查重(命中则只要需新增的条目)
399
362
  const r1 = await reconcileTopics({
@@ -401,18 +364,19 @@ export async function runLearnPipeline(opts) {
401
364
  docsDir,
402
365
  candidate: { slug: activeSlug, title: outline.title, tags: [], items: outline.items },
403
366
  wantItems: true,
367
+ signal: opts.signal,
404
368
  });
405
369
  if (r1.match) {
406
370
  const targetSlug = r1.targetSlug;
407
371
  // 先物理并入(返回目标现有 chunk 总数作为续号偏移),再只写新增条目,最后带 override 打 tag
408
372
  const off = mergeTopics(docsDir, activeSlug, targetSlug);
409
- const refine = await runRefineStage({ port: opts.port, docsDir }, targetSlug, r1.itemsToAdd, opts.events, roundCounter, off);
410
- await runTagStage({ port: opts.port, docsDir }, targetSlug, opts.events, roundCounter, { title: r1.mergedTitle, summary: r1.mergedSummary });
373
+ const refine = await runRefineStage({ port: opts.port, vault, signal: opts.signal }, targetSlug, r1.itemsToAdd, opts.events, roundCounter, off);
374
+ await runTagStage({ port: opts.port, vault, signal: opts.signal }, targetSlug, opts.events, roundCounter, { title: r1.mergedTitle, summary: r1.mergedSummary });
411
375
  return { slug: targetSlug, chunksWritten: refine.chunksWritten, itemsFailed: refine.itemsFailed };
412
376
  }
413
377
  // 门1 未命中:常规 refine(从头编号)+ 常规 tag
414
- const refine = await runRefineStage({ port: opts.port, docsDir }, activeSlug, outline.items, opts.events, roundCounter, 0);
415
- await runTagStage({ port: opts.port, docsDir }, activeSlug, opts.events, roundCounter);
378
+ const refine = await runRefineStage({ port: opts.port, vault, signal: opts.signal }, activeSlug, outline.items, opts.events, roundCounter, 0);
379
+ await runTagStage({ port: opts.port, vault, signal: opts.signal }, activeSlug, opts.events, roundCounter);
416
380
  // 门2:tag 后基于富 tags 再查一次(不需要新增条目)
417
381
  const detail = await readTopicDetail(docsDir, activeSlug);
418
382
  const r2 = await reconcileTopics({
@@ -420,11 +384,12 @@ export async function runLearnPipeline(opts) {
420
384
  docsDir,
421
385
  candidate: { slug: activeSlug, title: outline.title, tags: detail?.tags ?? [], items: undefined },
422
386
  wantItems: false,
387
+ signal: opts.signal,
423
388
  });
424
389
  if (r2.match) {
425
390
  const targetSlug = r2.targetSlug;
426
391
  mergeTopics(docsDir, activeSlug, targetSlug);
427
- await runTagStage({ port: opts.port, docsDir }, targetSlug, opts.events, roundCounter, { title: r2.mergedTitle, summary: r2.mergedSummary });
392
+ await runTagStage({ port: opts.port, vault, signal: opts.signal }, targetSlug, opts.events, roundCounter, { title: r2.mergedTitle, summary: r2.mergedSummary });
428
393
  return { slug: targetSlug, chunksWritten: refine.chunksWritten, itemsFailed: refine.itemsFailed };
429
394
  }
430
395
  return { slug: activeSlug, chunksWritten: refine.chunksWritten, itemsFailed: refine.itemsFailed };
@@ -1,18 +1,15 @@
1
1
  import { type AgentSession } from '@earendil-works/pi-coding-agent';
2
2
  import { type CrawlGuard } from './pi-crawl-tools.js';
3
3
  export type PiSessionMode = 'chat' | 'outline' | 'refine' | 'tag' | 'crawl' | 'reconcile';
4
- export interface CreatePiSessionOptions {
4
+ interface CreatePiSessionOptions {
5
5
  cwd?: string;
6
6
  port: number;
7
7
  mode: PiSessionMode;
8
8
  /** mode='crawl' 时必填:渐进抓取状态守卫 */
9
9
  crawlGuard?: CrawlGuard;
10
+ /** 外部取消信号(mode='crawl' 时接到抓取工具上) */
11
+ signal?: AbortSignal;
10
12
  }
11
- export declare const CHAT_SYSTEM_PROMPT = "You are a knowledge management AI operating inside a sandbox.\nYour knowledge directory (~/.cc-monitoring/docs) stores a **dictionary**: concise, distilled entries a future reader can look up. You do NOT copy source text \u2014 you digest it.\n\nSTRUCTURE (all paths below are RELATIVE TO the knowledge root ~/.cc-monitoring/docs \u2014 the write tool's working directory IS this root, so NEVER prefix a path with \"docs/\"):\n- Each topic is a subfolder: <topic-slug>/\n- Each topic has <slug>/index.json (metadata + chunk list, NO body)\n- Bodies live in <topic-slug>/chunks/chunk-NNN.md\n- Root index.json lists all topics as JSON\n- Fetched source pages for a topic are already prepared in <slug>/sources/ \u2014 you only READ them, never write or modify them\n\nANSWERING QUESTIONS:\n1. Call list_topics to see available topics\n2. If topic is unclear, call search_chunks(query) to find relevant chunks across topics\n3. Call get_topic(topic) to see that topic's chunk list\n4. Call read_chunk(topic, chunk_id) for relevant chunks \u2014 only read chunks you need\n5. Prefer answering from knowledge base chunks when relevant content exists; cite which chunks you used\n6. If no relevant chunk exists, answer from your general knowledge; if you truly don't know, say so";
12
- export declare const OUTLINE_SYSTEM_PROMPT = "You are an outline-phase worker. The relevant web pages have ALREADY been fetched and saved to sources/ for your assigned topic. Your job: read them and propose an outline of dictionary entries. Do NOT write chunks.\n\nYour knowledge directory (~/.cc-monitoring/docs) stores a **dictionary**: concise, distilled entries a future reader can look up. You do NOT copy source text \u2014 you digest it.\n\nSTRUCTURE (all paths below are RELATIVE TO the knowledge root ~/.cc-monitoring/docs \u2014 the write tool's working directory IS this root, so NEVER prefix a path with \"docs/\"):\n- Each topic is a subfolder: <topic-slug>/\n- Each topic has <slug>/index.json (metadata + chunk list, NO body)\n- Bodies live in <topic-slug>/chunks/chunk-NNN.md\n- Root index.json lists all topics as JSON\n- Fetched source pages for a topic are already prepared in <slug>/sources/ \u2014 you only READ them, never write or modify them\n\nWORKFLOW:\n1. Call read_source(topic) to load ALL fetched source pages (multiple pages are separated by ---).\n2. Outline the DISTINCT concepts actually present across these pages. One concept = one future chunk. Do not bundle unrelated ideas.\n3. Call add_outline(slug, title, items) ONCE at the end:\n - slug: the EXACT slug given in your task\n - title: human-readable topic title\n - items: array of { id, title, oneLine } \u2014 id is a short stable slug per item (e.g. \"use-state\"), oneLine is a single-sentence definition\n\nHARD RULES:\n- Use ONLY content present in the fetched sources. Do NOT add concepts from training-data memory. If the sources are thin, outline only what is there.\n- read_source MUST be your first call. If it returns an error, STOP and report it immediately.\n- Do NOT write chunk files, source files, or index.json.\n- Do NOT summarize prematurely \u2014 outline only; distillation happens later.\n- After add_outline succeeds, print the returned slug and item count. Stop.";
13
- export declare const CRAWL_SYSTEM_PROMPT = "You are a crawl-phase worker. You drive the browser YOURSELF to incrementally fetch web pages for your assigned topic and save every useful page into sources/. Do NOT outline or write chunks.\n\nWORKFLOW:\n1. Call crawl_open to open the entry URL given in your task.\n2. Call save_source(url) to save the CURRENT page.\n3. From the page's links, pick same-site, valuable CONTENT pages \u2014 skip login/signup, navigation chrome, language switchers, pagination, and pure anchors. Call crawl_visit(url), then save_source(url) for each page.\n4. When there are no more useful links, or the page/depth limit is reached, call crawl_finish, print the returned stats, and stop.\n\nHARD RULES:\n- Write ONLY into sources/ via save_source. Never write other files.\n- Never visit cross-site URLs.\n- If a tool returns an error, do NOT retry the same URL; pick another link or finish.\n- At most ~20 pages. Prefer a few dense pages over many thin ones.\n- After crawl_finish succeeds, stop.";
14
- export declare const REFINE_SYSTEM_PROMPT = "You are a refine-phase worker. For ONE item from the topic's outline, produce a single dictionary chunk.\n\nYour knowledge directory (~/.cc-monitoring/docs) stores a **dictionary**: concise, distilled entries a future reader can look up. You do NOT copy source text \u2014 you digest it.\n\nSTRUCTURE (all paths below are RELATIVE TO the knowledge root ~/.cc-monitoring/docs \u2014 the write tool's working directory IS this root, so NEVER prefix a path with \"docs/\"):\n- Each topic is a subfolder: <topic-slug>/\n- Each topic has <slug>/index.json (metadata + chunk list, NO body)\n- Bodies live in <topic-slug>/chunks/chunk-NNN.md\n- Root index.json lists all topics as JSON\n- Fetched source pages for a topic are already prepared in <slug>/sources/ \u2014 you only READ them, never write or modify them\n\nWORKFLOW:\n1. Call read_source(topic) to load ALL fetched source pages (multiple pages separated by ---).\n2. Focus on your assigned item. Do NOT distill other items.\n3. Write ONE chunk file <topic>/chunks/chunk-NNN.md (number sequentially from 001; path RELATIVE TO the knowledge root, no \"docs/\" prefix) using the write tool, in the source document's language, with this structure:\n\n```\n# <term or concept name>\n\n- \u5B9A\u4E49 / Definition: <one sentence, in your own words>\n- \u662F\u4EC0\u4E48 / What it is: <2-4 bullets, the core idea>\n- \u4E0D\u662F\u4EC0\u4E48 / What it is NOT: <common confusions, if any>\n- \u5173\u952E\u70B9 / Key points: <3-6 bullets, the load-bearing facts>\n- \u9002\u7528\u573A\u666F / When to use: <where this applies>\n- \u8BEF\u533A / Pitfalls: <common mistakes, edge cases>\n- \u6765\u6E90 / Source: <url(s) of the page(s) you actually used \u2014 copy them from the \"Source:\" headers at the top of each fetched page; list several URLs if the chunk draws on several pages>\n```\n\n4. Call add_chunk(topic, chunk_id, title, summary, tags) to register it.\n - tags: 3-6 lowercase hyphenated tags describing the concept (synonyms, key terms).\n\nHARD RULES:\n- read_source MUST be your first call. If it returns an error, STOP and report it immediately. Do NOT write a placeholder source.md yourself, and do NOT write the chunk from memory.\n- Every fact must come from the fetched sources. If a claim is not supported by them, omit it. Never fill gaps from memory.\n- NO large quotes. A short quote (\u22642 sentences) is allowed ONLY as evidence under a bullet you already wrote in your own words.\n- Every bullet must be YOU re-expressing the idea. If you find yourself copying sentences, stop and rephrase.\n- One concept per chunk.\n- If the material is thin on a concept, write what exists; do NOT invent content. Omit empty sections.\n- Do NOT call add_topic. Do NOT write index.json.";
15
- export declare const TAG_SYSTEM_PROMPT = "You are a tag-phase worker. Enrich an existing topic with rich, retrieval-friendly tags.\n\nYour knowledge directory (~/.cc-monitoring/docs) stores a **dictionary**: concise, distilled entries a future reader can look up. You do NOT copy source text \u2014 you digest it.\n\nSTRUCTURE (all paths below are RELATIVE TO the knowledge root ~/.cc-monitoring/docs \u2014 the write tool's working directory IS this root, so NEVER prefix a path with \"docs/\"):\n- Each topic is a subfolder: <topic-slug>/\n- Each topic has <slug>/index.json (metadata + chunk list, NO body)\n- Bodies live in <topic-slug>/chunks/chunk-NNN.md\n- Root index.json lists all topics as JSON\n- Fetched source pages for a topic are already prepared in <slug>/sources/ \u2014 you only READ them, never write or modify them\n\nWORKFLOW:\n1. Call get_topic(slug) to list this topic's chunks.\n2. Call read_chunk for the chunks to understand the actual content.\n3. Generate 5 categories of tags (10-20 total), all lowercase hyphenated:\n - synonyms: alternate names / aliases\n - hypernym: broader parent concept (e.g. \"state-management\" for redux)\n - trigger-scenarios: situations where a reader would reach for this (e.g. \"form-validation\")\n - confusable: things this is often mixed up with\n - typical-questions: questions a reader might search (e.g. \"how-does-usestate-work\")\n4. Call add_topic(slug, title, summary, tags) to OVERWRITE the topic's tags + metadata. Reuse the existing title and summary from get_topic; do not change them.\n\nHARD RULES:\n- Do NOT write chunk files. Do NOT call add_chunk.\n- Do NOT invent tags the content does not support.";
16
13
  export declare function createPiSession(options: CreatePiSessionOptions): Promise<AgentSession>;
17
14
  /**
18
15
  * 从任意文本截取第一个 `{` 到最后一个 `}` 之间的子串并解析为 JSON 对象。
@@ -27,4 +24,6 @@ export declare function runJsonPrompt(opts: {
27
24
  port: number;
28
25
  instructions: string;
29
26
  prompt: string;
27
+ signal?: AbortSignal;
30
28
  }): Promise<unknown>;
29
+ export {};