@cc-monitoring/proxy-core 0.2.3 → 0.3.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 (335) hide show
  1. package/dist/docs/404.html +1 -1
  2. package/dist/docs/assets/{app.6_CicOIJ.js → app.B9A39uFv.js} +1 -1
  3. package/dist/docs/assets/chunks/@localSearchIndexroot.B6Qfxe6W.js +1 -0
  4. package/dist/docs/assets/chunks/{VPLocalSearchBox.ZMWZsg8z.js → VPLocalSearchBox.DdhC696L.js} +1 -1
  5. package/dist/docs/assets/chunks/{theme.BkvhsjzH.js → theme.CfB2tOFi.js} +2 -2
  6. package/dist/docs/index.html +2 -2
  7. package/dist/docs/overview.html +2 -2
  8. package/dist/docs/packages-utils.html +2 -2
  9. package/dist/docs/proxy-admin/env-and-build.html +2 -2
  10. package/dist/docs/proxy-admin/index.html +2 -2
  11. package/dist/docs/proxy-admin/layout-and-menu.html +2 -2
  12. package/dist/docs/proxy-admin/pages.html +2 -2
  13. package/dist/docs/proxy-admin/routing-and-auth.html +2 -2
  14. package/dist/docs/proxy-admin/services-and-mock.html +2 -2
  15. package/dist/docs/proxy-cli/api-layer.html +2 -2
  16. package/dist/docs/proxy-cli/app-shell.html +2 -2
  17. package/dist/docs/proxy-cli/components-common.html +2 -2
  18. package/dist/docs/proxy-cli/components-config.html +2 -2
  19. package/dist/docs/proxy-cli/components-requests.html +2 -2
  20. package/dist/docs/proxy-cli/components-stats.html +2 -2
  21. package/dist/docs/proxy-cli/components-status.html +2 -2
  22. package/dist/docs/proxy-cli/data-hooks.html +2 -2
  23. package/dist/docs/proxy-cli/index.html +2 -2
  24. package/dist/docs/proxy-cli/utils-and-i18n.html +2 -2
  25. package/dist/docs/proxy-core/chat-api.html +2 -2
  26. package/dist/docs/proxy-core/cli.html +2 -2
  27. package/dist/docs/proxy-core/config.html +2 -2
  28. package/dist/docs/proxy-core/data-layer.html +2 -2
  29. package/dist/docs/proxy-core/entry.html +2 -2
  30. package/dist/docs/proxy-core/index.html +2 -2
  31. package/dist/docs/proxy-core/pm2.html +2 -2
  32. package/dist/docs/proxy-core/providers.html +2 -2
  33. package/dist/docs/proxy-core/proxy.html +2 -2
  34. package/dist/docs/proxy-core/stats.html +2 -2
  35. package/dist/docs/proxy-core/tool.html +2 -2
  36. package/dist/docs/proxy-core/ui-routes.html +2 -2
  37. package/dist/docs/proxy-core/utilities.html +2 -2
  38. package/dist/docs/quickstart.html +2 -2
  39. package/dist/docs/request-flow.html +2 -2
  40. package/dist/mcp-server/index.js +5 -3
  41. package/dist/mcp-server/tools.js +24 -2
  42. package/dist/server/__tests__/server.test.js +9 -1
  43. package/dist/server/__tests__/ui-route.test.js +8 -0
  44. package/dist/server/chat-route.js +6 -0
  45. package/dist/server/proxy.js +5 -0
  46. package/dist/server/ui-route.js +113 -7
  47. package/dist/ui/assets/{1c-HTPXddJd.js → 1c-DAu68mP4.js} +1 -1
  48. package/dist/ui/assets/{abnf-bINSkl_m.js → abnf-Cu8RHCHK.js} +1 -1
  49. package/dist/ui/assets/{abnfDiagram-VRR7QNED-ClDzCbvw.js → abnfDiagram-VRR7QNED-BUBToPXF.js} +1 -1
  50. package/dist/ui/assets/{accesslog-BAnIWzpe.js → accesslog-BG-34XOy.js} +1 -1
  51. package/dist/ui/assets/{actionscript-DVcm6F_C.js → actionscript-iw0HHMGM.js} +1 -1
  52. package/dist/ui/assets/{ada-Cxn-QX4j.js → ada-qRqj6VGQ.js} +1 -1
  53. package/dist/ui/assets/{angelscript-BAwAPvBQ.js → angelscript-BeaXyx_P.js} +1 -1
  54. package/dist/ui/assets/{apache-CjjovgUx.js → apache-CU8d-z9X.js} +1 -1
  55. package/dist/ui/assets/{applescript-VUcyXoVh.js → applescript-d1Wxkqz1.js} +1 -1
  56. package/dist/ui/assets/{arc-3Nou_aku.js → arc-BMsPIm3j.js} +1 -1
  57. package/dist/ui/assets/{arcade-Dz2VAk7O.js → arcade-CtbgrWTM.js} +1 -1
  58. package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-DhwSsCdN.js → architectureDiagram-ZJ3FMSHR-CVjC5TrS.js} +1 -1
  59. package/dist/ui/assets/{arduino-B-Ptb1K1.js → arduino-Bc9L39Hr.js} +1 -1
  60. package/dist/ui/assets/{armasm-DU_6qZlW.js → armasm-DuWmpjWR.js} +1 -1
  61. package/dist/ui/assets/{asciidoc-DYbYiWKT.js → asciidoc-CDIhFTnx.js} +1 -1
  62. package/dist/ui/assets/{aspectj-CmdNkqAs.js → aspectj-SYj-57Es.js} +1 -1
  63. package/dist/ui/assets/{autohotkey-if9QUvYo.js → autohotkey-hBi5dq37.js} +1 -1
  64. package/dist/ui/assets/{autoit-DGU3G1s6.js → autoit-BSawXzhg.js} +1 -1
  65. package/dist/ui/assets/{avrasm-1zsEtPJ6.js → avrasm-CwYom8Np.js} +1 -1
  66. package/dist/ui/assets/{awk-CvmeshSq.js → awk-BvBRfGo2.js} +1 -1
  67. package/dist/ui/assets/{axapta-CbJGb5cN.js → axapta-CqUavA8k.js} +1 -1
  68. package/dist/ui/assets/{bash-CFXg_i2e.js → bash-BS_ZnmEu.js} +1 -1
  69. package/dist/ui/assets/{basic-6atic5cT.js → basic-xbP4IXrN.js} +1 -1
  70. package/dist/ui/assets/{blockDiagram-677ZJIJ3-BKXinDkB.js → blockDiagram-677ZJIJ3-CmpI3f5p.js} +1 -1
  71. package/dist/ui/assets/{bnf-DydAtPHV.js → bnf-BECwu6uW.js} +1 -1
  72. package/dist/ui/assets/{brainfuck-CnHx1vO0.js → brainfuck-QQgu4j4N.js} +1 -1
  73. package/dist/ui/assets/{coq-BShzwzh7.js → c-BRJEPYra.js} +1 -1
  74. package/dist/ui/assets/{c-like-XpQV9S6j.js → c-like-DYrFOtXy.js} +1 -1
  75. package/dist/ui/assets/{c4Diagram-LMCZKHZV-D5EmWl5d.js → c4Diagram-LMCZKHZV-B6Hgngz9.js} +1 -1
  76. package/dist/ui/assets/{cal-D-orUuBW.js → cal-CNMrJ6v5.js} +1 -1
  77. package/dist/ui/assets/{capnproto-TdI6NT8O.js → capnproto-DYCKl6oY.js} +1 -1
  78. package/dist/ui/assets/{ceylon-Dji8eqtG.js → ceylon-mb8tRPl0.js} +1 -1
  79. package/dist/ui/assets/channel-Bc4Td8eZ.js +1 -0
  80. package/dist/ui/assets/{chunk-2Q5K7J3B-CaIvwVWl.js → chunk-2Q5K7J3B-LxvQ-G67.js} +1 -1
  81. package/dist/ui/assets/{chunk-32BRIVSS-C7oMpoeu.js → chunk-32BRIVSS-DxzKK6Aw.js} +1 -1
  82. package/dist/ui/assets/{chunk-5VM5RSS4-BQ0aVGl-.js → chunk-5VM5RSS4-CZEoYJ2W.js} +1 -1
  83. package/dist/ui/assets/{chunk-EX3LRPZG-D-_EqojZ.js → chunk-EX3LRPZG-DS2PytrN.js} +1 -1
  84. package/dist/ui/assets/{chunk-JWPE2WC7-B0OLx2rk.js → chunk-JWPE2WC7-UX0Sr1Ie.js} +1 -1
  85. package/dist/ui/assets/{chunk-MOJQB5TN-Be8IXTUE.js → chunk-MOJQB5TN-YbJgT9t4.js} +1 -1
  86. package/dist/ui/assets/{chunk-RYQCIY6F-DceCW2mS.js → chunk-RYQCIY6F-DS2VH_U9.js} +1 -1
  87. package/dist/ui/assets/{chunk-V7JOEXUC-Cbhq5qgO.js → chunk-V7JOEXUC-CZr0pkI1.js} +1 -1
  88. package/dist/ui/assets/{chunk-VR4S4FIN-D6WJuaS1.js → chunk-VR4S4FIN-50opPAD3.js} +1 -1
  89. package/dist/ui/assets/{chunk-XXDRQBXY-CKrih4pC.js → chunk-XXDRQBXY-DAAX9l7U.js} +1 -1
  90. package/dist/ui/assets/classDiagram-OUVF2IWQ-BicxhZFq.js +1 -0
  91. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-BicxhZFq.js +1 -0
  92. package/dist/ui/assets/{clean-0frlVN_A.js → clean-C4X7dSkh.js} +1 -1
  93. package/dist/ui/assets/{clojure-D0q_yQDf.js → clojure-DSg9gUa7.js} +1 -1
  94. package/dist/ui/assets/{clojure-repl-DgYhEzOe.js → clojure-repl-CagRYx7h.js} +1 -1
  95. package/dist/ui/assets/{cmake-WF5tF5xU.js → cmake-CFdBn53c.js} +1 -1
  96. package/dist/ui/assets/{coffeescript-CyWYgeyv.js → coffeescript-CJZtMOPx.js} +1 -1
  97. package/dist/ui/assets/{c-DarYnPBd.js → coq-IDMIFfem.js} +1 -1
  98. package/dist/ui/assets/{cos-C5i3_TIB.js → cos-Bx2VJuzG.js} +1 -1
  99. package/dist/ui/assets/{cose-bilkent-JH36ORCC-BCwilS6I.js → cose-bilkent-JH36ORCC-zWRLsZpZ.js} +1 -1
  100. package/dist/ui/assets/{cpp-F1mRQFyw.js → cpp-CsG6DlC4.js} +1 -1
  101. package/dist/ui/assets/{crmsh-BAkHUu-B.js → crmsh-DTy9MnmJ.js} +1 -1
  102. package/dist/ui/assets/{crystal-CwUaomfj.js → crystal-BwgrLrZ1.js} +1 -1
  103. package/dist/ui/assets/{csharp-B1gHIdjK.js → csharp-B2VeTPAF.js} +1 -1
  104. package/dist/ui/assets/{csp-CblCTMvV.js → csp-CTpydNhH.js} +1 -1
  105. package/dist/ui/assets/{css-CXg7kJV3.js → css-B0mMUbpY.js} +1 -1
  106. package/dist/ui/assets/{cynefin-VYW2F7L2-BdgMlR5e.js → cynefin-VYW2F7L2-BmjQEj6q.js} +1 -1
  107. package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-Bozdux8p.js → cynefinDiagram-TSTJHNR4-Dr0Zrke0.js} +1 -1
  108. package/dist/ui/assets/{d-Cs5yNCaM.js → d-DjuDZnbI.js} +1 -1
  109. package/dist/ui/assets/{dagre-VKFMJZFB-tI_mjNMn.js → dagre-VKFMJZFB-xoTPT2Uu.js} +1 -1
  110. package/dist/ui/assets/{dart-BqgylVkh.js → dart-xR3GU9TJ.js} +1 -1
  111. package/dist/ui/assets/{delphi-CbnfHpIi.js → delphi-bJas5QnG.js} +1 -1
  112. package/dist/ui/assets/{diagram-FQU43EPY-DmyL3OJT.js → diagram-FQU43EPY-rL_IU7gU.js} +1 -1
  113. package/dist/ui/assets/{diagram-G47NLZAW-BEi9GZlZ.js → diagram-G47NLZAW-EcDiCVGj.js} +1 -1
  114. package/dist/ui/assets/{diagram-NH7WQ7WH-Bct44Oh1.js → diagram-NH7WQ7WH-CGGXOjev.js} +1 -1
  115. package/dist/ui/assets/{diagram-OA4YK3LP-VWAgZxPK.js → diagram-OA4YK3LP-DnE7hDjD.js} +1 -1
  116. package/dist/ui/assets/{diagram-WEI45ONY-CxcHsE6q.js → diagram-WEI45ONY-CTJH5eD8.js} +1 -1
  117. package/dist/ui/assets/{diff-CMJ2hGQW.js → diff-doJFF3fv.js} +1 -1
  118. package/dist/ui/assets/{django-Cq_XIhVZ.js → django-D3b-owa_.js} +1 -1
  119. package/dist/ui/assets/{dns-CJs3z6-E.js → dns-C42KYV-Z.js} +1 -1
  120. package/dist/ui/assets/{dockerfile-ehs0ogry.js → dockerfile-9KUINc2j.js} +1 -1
  121. package/dist/ui/assets/{dos-DXOYESf1.js → dos-CxnlJ6qp.js} +1 -1
  122. package/dist/ui/assets/{dsconfig-Cs2hs3Bl.js → dsconfig-6CMMCwmY.js} +1 -1
  123. package/dist/ui/assets/{dts-Dk8yoweb.js → dts-D78rdUIB.js} +1 -1
  124. package/dist/ui/assets/{dust-BMK9e-Ss.js → dust-Dv1uTfJU.js} +1 -1
  125. package/dist/ui/assets/{ebnf-DlyBI5m6.js → ebnf-BGbG1cFK.js} +1 -1
  126. package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-DBp9JHEq.js → ebnfDiagram-CCIWWBDH-z2VgRSUV.js} +1 -1
  127. package/dist/ui/assets/{elixir-BThlsblT.js → elixir-ZgAQVY1J.js} +1 -1
  128. package/dist/ui/assets/{elm-DrmZwmcc.js → elm-CudiFuNu.js} +1 -1
  129. package/dist/ui/assets/{erDiagram-Q63AITRT-BhK4NKvx.js → erDiagram-Q63AITRT-X1TODuRv.js} +1 -1
  130. package/dist/ui/assets/{erb-BQM7j3K9.js → erb-Bz_NZh6W.js} +1 -1
  131. package/dist/ui/assets/{erlang-CuUaWEXv.js → erlang-DNuj1nb2.js} +1 -1
  132. package/dist/ui/assets/{erlang-repl-DB0uphao.js → erlang-repl-SP1Gan9W.js} +1 -1
  133. package/dist/ui/assets/{excel-DmsuWUss.js → excel-0K77uECF.js} +1 -1
  134. package/dist/ui/assets/{fix-D-Uzxpz_.js → fix-CalJq7JD.js} +1 -1
  135. package/dist/ui/assets/{flix-B_7EHWiA.js → flix-BlIs11_w.js} +1 -1
  136. package/dist/ui/assets/{flowDiagram-23GEKE2U-DtMG1G-h.js → flowDiagram-23GEKE2U-DA2dnmc0.js} +1 -1
  137. package/dist/ui/assets/{fortran-Djp5tH9W.js → fortran-ZCobXY2R.js} +1 -1
  138. package/dist/ui/assets/{fsharp-Pj_2ZEa4.js → fsharp-Be8rwUtc.js} +1 -1
  139. package/dist/ui/assets/{gams-B2i3v2ec.js → gams-DUat8frQ.js} +1 -1
  140. package/dist/ui/assets/{ganttDiagram-NO4QXBWP-C7M-JA0W.js → ganttDiagram-NO4QXBWP-DdFwaIGZ.js} +1 -1
  141. package/dist/ui/assets/{gauss-DaV8sHLU.js → gauss-BB4U88dy.js} +1 -1
  142. package/dist/ui/assets/{gcode-0Jvrh6HY.js → gcode-DzeUZuZg.js} +1 -1
  143. package/dist/ui/assets/{gherkin-DoOl28D6.js → gherkin-B_8vW_BO.js} +1 -1
  144. package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-D3HB5mow.js → gitGraphDiagram-IHSO6WYX-B-Dn8x6I.js} +1 -1
  145. package/dist/ui/assets/{glsl-DEbk7rH5.js → glsl-DGHGjPC1.js} +1 -1
  146. package/dist/ui/assets/{gml-CBcqXBNV.js → gml-BYEku8Yh.js} +1 -1
  147. package/dist/ui/assets/{go-DqesmqF8.js → go-D8aSgQMc.js} +1 -1
  148. package/dist/ui/assets/{golo-9U1oO0b5.js → golo-CDjCU_jh.js} +1 -1
  149. package/dist/ui/assets/{gradle-DZliBXTY.js → gradle-BeUw7tl_.js} +1 -1
  150. package/dist/ui/assets/{groovy-Dys3GQwv.js → groovy-5iCQOtR3.js} +1 -1
  151. package/dist/ui/assets/{haml-CrtAODl1.js → haml-BEdL8FJi.js} +1 -1
  152. package/dist/ui/assets/{handlebars-CueXuqSj.js → handlebars-BuYQNzoK.js} +1 -1
  153. package/dist/ui/assets/{haskell-CRungOQt.js → haskell-I4FCBcW0.js} +1 -1
  154. package/dist/ui/assets/{haxe-aMz7L4gD.js → haxe-yigyKfFr.js} +1 -1
  155. package/dist/ui/assets/{hsp-Cw75yqGb.js → hsp-ZUk4j7d1.js} +1 -1
  156. package/dist/ui/assets/{htmlbars-e_mpUZNH.js → htmlbars-QYP3lT3u.js} +1 -1
  157. package/dist/ui/assets/{http-Di7E_m1o.js → http-BJpD1O71.js} +1 -1
  158. package/dist/ui/assets/{hy-CwlvsNj6.js → hy-CIJ1bP6S.js} +1 -1
  159. package/dist/ui/assets/{index-BdSumlU0.js → index-BDXWttnT.js} +3 -3
  160. package/dist/ui/assets/index-C0fxlU9d.css +10 -0
  161. package/dist/ui/assets/{index-BVM6YOjH.js → index-COAgrx1J.js} +256 -256
  162. package/dist/ui/assets/{infoDiagram-FWYZ7A6U-_r-6eAzx.js → infoDiagram-FWYZ7A6U-fTg9eLNt.js} +1 -1
  163. package/dist/ui/assets/{inform7-dwg1imm1.js → inform7-DAsu-lC2.js} +1 -1
  164. package/dist/ui/assets/{ini-DEXL1rCA.js → ini-Bhz-zHCg.js} +1 -1
  165. package/dist/ui/assets/{irpf90-Ccs_8Sp-.js → irpf90-BunhbwBl.js} +1 -1
  166. package/dist/ui/assets/{isbl-B9d1nYmL.js → isbl-q9L6hOhP.js} +1 -1
  167. package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-lNCezpU4.js → ishikawaDiagram-FXEZZL3T-B8G0sdgd.js} +1 -1
  168. package/dist/ui/assets/{java-5fv2smM6.js → java-Iks5Pkau.js} +1 -1
  169. package/dist/ui/assets/{javascript-TAWm0NK8.js → javascript-C4vltXPw.js} +1 -1
  170. package/dist/ui/assets/{jboss-cli-dM1kcsbR.js → jboss-cli-BQBvd2X2.js} +1 -1
  171. package/dist/ui/assets/{journeyDiagram-5HDEW3XC-CBYHux8i.js → journeyDiagram-5HDEW3XC-Crbzgrum.js} +1 -1
  172. package/dist/ui/assets/{json-CtCzm6jF.js → json-DXK0_jUK.js} +1 -1
  173. package/dist/ui/assets/{julia-Co7H3kzk.js → julia-CCYoBiYK.js} +1 -1
  174. package/dist/ui/assets/{julia-repl-BT1ar5VS.js → julia-repl-y8v2Oorl.js} +1 -1
  175. package/dist/ui/assets/{kanban-definition-HUTT4EX6-B8x8eQyo.js → kanban-definition-HUTT4EX6-C8sCOsBX.js} +1 -1
  176. package/dist/ui/assets/{kotlin-W6mVKIj9.js → kotlin-Bnjk7_fw.js} +1 -1
  177. package/dist/ui/assets/{lasso-DJG4luGz.js → lasso-B-al6x63.js} +1 -1
  178. package/dist/ui/assets/{latex-DbBOxO7u.js → latex-BUmqlb9r.js} +1 -1
  179. package/dist/ui/assets/{ldif-CVS189JA.js → ldif-D42RWj6Q.js} +1 -1
  180. package/dist/ui/assets/{leaf-eYNiXTKP.js → leaf-CrH4BZ0m.js} +1 -1
  181. package/dist/ui/assets/{less-DxhvWM95.js → less-upmRlQQW.js} +1 -1
  182. package/dist/ui/assets/{lisp-SC7AwnXC.js → lisp-DHYS22SA.js} +1 -1
  183. package/dist/ui/assets/{livecodeserver-CR2eHihF.js → livecodeserver-CeQNmFP3.js} +1 -1
  184. package/dist/ui/assets/{livescript-DBZ-GaVK.js → livescript-PJWpY1JI.js} +1 -1
  185. package/dist/ui/assets/{llvm-BzURO4tt.js → llvm-BKtKWwCt.js} +1 -1
  186. package/dist/ui/assets/{lsl-DGoJxEUu.js → lsl-RWRLRjk7.js} +1 -1
  187. package/dist/ui/assets/{lua-qgG9gdiw.js → lua-BFUDiPGm.js} +1 -1
  188. package/dist/ui/assets/{makefile-D0kZ6SOe.js → makefile-CUDyOz5D.js} +1 -1
  189. package/dist/ui/assets/{markdown-DRQWgMxk.js → markdown-zZCLypc6.js} +1 -1
  190. package/dist/ui/assets/{mathematica-DIBvZyEZ.js → mathematica-BHbxKxnq.js} +1 -1
  191. package/dist/ui/assets/{matlab-BNg0BR0b.js → matlab-DlGtg--p.js} +1 -1
  192. package/dist/ui/assets/{maxima-Bpga3G1G.js → maxima-BBBeS3Ra.js} +1 -1
  193. package/dist/ui/assets/{mel-CMOJa9Mg.js → mel-nh8j7W_6.js} +1 -1
  194. package/dist/ui/assets/{mercury-uvrRzupw.js → mercury-DyyD-pqr.js} +1 -1
  195. package/dist/ui/assets/{mindmap-definition-LN4V7U3C-DK8j_8Ap.js → mindmap-definition-LN4V7U3C-CJlhDHqM.js} +1 -1
  196. package/dist/ui/assets/{mipsasm-p1gWpDuw.js → mipsasm-hiEhRRiq.js} +1 -1
  197. package/dist/ui/assets/{mizar-DV1ENOOU.js → mizar-BZa3iAAL.js} +1 -1
  198. package/dist/ui/assets/{mojolicious-tg5XQSro.js → mojolicious-BCIm2V_y.js} +1 -1
  199. package/dist/ui/assets/{monkey-D8mYa31Q.js → monkey-zmK-7N8b.js} +1 -1
  200. package/dist/ui/assets/{moonscript-1d_rtlyv.js → moonscript-BsS_Mn3D.js} +1 -1
  201. package/dist/ui/assets/{n1ql-C5srRxme.js → n1ql-D7xVgDP0.js} +1 -1
  202. package/dist/ui/assets/{nginx-xS1muaWm.js → nginx-ct2q4dtd.js} +1 -1
  203. package/dist/ui/assets/{nim-CGGiMQfp.js → nim-RO0UOmW3.js} +1 -1
  204. package/dist/ui/assets/{nix-C77HsR7m.js → nix-BcRJxPKH.js} +1 -1
  205. package/dist/ui/assets/{node-repl-CSeYusSM.js → node-repl-DgIefwxW.js} +1 -1
  206. package/dist/ui/assets/{nsis-BffC7mSW.js → nsis-DqHs9QhB.js} +1 -1
  207. package/dist/ui/assets/{objectivec-WpjnmlJB.js → objectivec-BBcWqc7Y.js} +1 -1
  208. package/dist/ui/assets/{ocaml-CHUkJkjB.js → ocaml-BExfw7D6.js} +1 -1
  209. package/dist/ui/assets/{openscad-BvImqFT0.js → openscad-CHPRELQb.js} +1 -1
  210. package/dist/ui/assets/{oxygene-BMBykbf5.js → oxygene-DpS9uMJW.js} +1 -1
  211. package/dist/ui/assets/{parser3-lRbuZW0M.js → parser3-CjJ_QdBp.js} +1 -1
  212. package/dist/ui/assets/{pegDiagram-2B236MQR-C4DWmrja.js → pegDiagram-2B236MQR-GM70woGy.js} +1 -1
  213. package/dist/ui/assets/{perl-B0DjfKoO.js → perl-BSNM2Kt8.js} +1 -1
  214. package/dist/ui/assets/{pf-Aor6NyYJ.js → pf-Z-hKf_88.js} +1 -1
  215. package/dist/ui/assets/{pgsql-CVKcjjNR.js → pgsql-DDgznxBg.js} +1 -1
  216. package/dist/ui/assets/{php-CZ7geHZt.js → php-BzAhxF-l.js} +1 -1
  217. package/dist/ui/assets/{php-template-DiFuW2dF.js → php-template-DkgcKHRc.js} +1 -1
  218. package/dist/ui/assets/{pieDiagram-ENE6RG2P-BO7AmF5j.js → pieDiagram-ENE6RG2P-Bst7mPyz.js} +1 -1
  219. package/dist/ui/assets/{plaintext-DcvmOuNc.js → plaintext-BYEppD0R.js} +1 -1
  220. package/dist/ui/assets/{pony-DGPeAcOc.js → pony-BT_kQd1K.js} +1 -1
  221. package/dist/ui/assets/{powershell-DsrPyJdK.js → powershell-BfRsuSsf.js} +1 -1
  222. package/dist/ui/assets/{processing-Co2VRXN1.js → processing-DpzWe5Iu.js} +1 -1
  223. package/dist/ui/assets/{profile-D4PjpLUf.js → profile-BCOhS5cM.js} +1 -1
  224. package/dist/ui/assets/{prolog-DEbkeg9r.js → prolog-OxaCCaW8.js} +1 -1
  225. package/dist/ui/assets/{properties-Cxqcuj1s.js → properties-DMFlA2Ca.js} +1 -1
  226. package/dist/ui/assets/{protobuf-C-zdlrww.js → protobuf-CRDFkXvZ.js} +1 -1
  227. package/dist/ui/assets/{puppet-BPX3SrOx.js → puppet-DnrVyLzx.js} +1 -1
  228. package/dist/ui/assets/{purebasic-BdQnNJS3.js → purebasic-Dht4Hniv.js} +1 -1
  229. package/dist/ui/assets/{python-D067_Gj8.js → python-B0aMirWu.js} +1 -1
  230. package/dist/ui/assets/{python-repl-DCqNVlc0.js → python-repl-BlYDBGa7.js} +1 -1
  231. package/dist/ui/assets/{q-kABXYW-8.js → q-DzrtW9kT.js} +1 -1
  232. package/dist/ui/assets/{qml-Iao-Whg7.js → qml-DnfQsR3i.js} +1 -1
  233. package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-DetQn-0l.js → quadrantDiagram-ABIIQ3AL-DNRYurBT.js} +1 -1
  234. package/dist/ui/assets/{r-BnwpapnO.js → r-DGI_ZuTD.js} +1 -1
  235. package/dist/ui/assets/{railroadDiagram-RFXS5EU6-DFaFKHAH.js → railroadDiagram-RFXS5EU6-CmbC3Vz4.js} +1 -1
  236. package/dist/ui/assets/{reasonml-Cn_Y03uT.js → reasonml-3SohMgh2.js} +1 -1
  237. package/dist/ui/assets/{requirementDiagram-TGXJPOKE-Dg1LrT-T.js → requirementDiagram-TGXJPOKE-8CxrXHco.js} +1 -1
  238. package/dist/ui/assets/{rib-ByAqQn0v.js → rib-DfRSd4Qa.js} +1 -1
  239. package/dist/ui/assets/{roboconf-BJPu6NC5.js → roboconf-CQczGdGW.js} +1 -1
  240. package/dist/ui/assets/{routeros-CL3Jm0Zq.js → routeros-DCka-T2i.js} +1 -1
  241. package/dist/ui/assets/{rsl-DaXy7KaD.js → rsl-Dr8MOwMo.js} +1 -1
  242. package/dist/ui/assets/{ruby-DI6awte_.js → ruby-C2zFSkh_.js} +1 -1
  243. package/dist/ui/assets/{ruleslanguage-DoTVEZE9.js → ruleslanguage-C97YsgQq.js} +1 -1
  244. package/dist/ui/assets/{rust-ULEd75wO.js → rust-H3h8kd9A.js} +1 -1
  245. package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-DQtFl110.js → sankeyDiagram-HTMAVEWB-DBXLWjEq.js} +1 -1
  246. package/dist/ui/assets/{sas-f7ATFuJk.js → sas-04z0Xu8P.js} +1 -1
  247. package/dist/ui/assets/{scala-Dha1zro2.js → scala-DyB9Aoiv.js} +1 -1
  248. package/dist/ui/assets/{scheme-BcaFHKeF.js → scheme-DBj6nxUi.js} +1 -1
  249. package/dist/ui/assets/{scilab-CIiiyD4z.js → scilab-Btj7AD9s.js} +1 -1
  250. package/dist/ui/assets/{scss-CkBomL0n.js → scss-BXZJyXt7.js} +1 -1
  251. package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DIbNQtCn.js → sequenceDiagram-DBY2YBRQ-DXIkBFKC.js} +1 -1
  252. package/dist/ui/assets/{shell-Cxu8Py1z.js → shell-BsreQR1Z.js} +1 -1
  253. package/dist/ui/assets/{sizeCapture-X5ZJPWSS-Cj7PglQv.js → sizeCapture-X5ZJPWSS-ocS9jxAQ.js} +1 -1
  254. package/dist/ui/assets/{smali-C4EYyWYz.js → smali-D9wQw9zm.js} +1 -1
  255. package/dist/ui/assets/{smalltalk-BlPTprP4.js → smalltalk-Dku6G_H3.js} +1 -1
  256. package/dist/ui/assets/{sml-DEPzhlr4.js → sml-BknyU6ya.js} +1 -1
  257. package/dist/ui/assets/{sqf-CRu3asu9.js → sqf-DRYMaOg8.js} +1 -1
  258. package/dist/ui/assets/{sql-DK-YfQqg.js → sql-Cw3Ax4KA.js} +1 -1
  259. package/dist/ui/assets/{sql_more-BuMEOcjj.js → sql_more-vWdslLE0.js} +1 -1
  260. package/dist/ui/assets/{stan-DMr13kyD.js → stan-8XH5bDS6.js} +1 -1
  261. package/dist/ui/assets/{stata-Bt6E2zQi.js → stata-4e77wgfe.js} +1 -1
  262. package/dist/ui/assets/{stateDiagram-2N3HPSRC-Bk-gF72D.js → stateDiagram-2N3HPSRC-RMmL9jMG.js} +1 -1
  263. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-QvaEO5U6.js +1 -0
  264. package/dist/ui/assets/{step21-Bi954ur4.js → step21-ByIeDMY3.js} +1 -1
  265. package/dist/ui/assets/{stylus-CQwwMaLm.js → stylus-ZAhJyWsw.js} +1 -1
  266. package/dist/ui/assets/{subunit-BkixDEMH.js → subunit-pPW2UGkj.js} +1 -1
  267. package/dist/ui/assets/{swift-DS1DWNAE.js → swift-CX3BB5az.js} +1 -1
  268. package/dist/ui/assets/{swimlanes-5IMT3BWC-C-AZKO5z.js → swimlanes-5IMT3BWC-C2zAuJ56.js} +2 -2
  269. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DPgCOY0D.js +8 -0
  270. package/dist/ui/assets/{taggerscript-DZHi1hoc.js → taggerscript-BHcjbWIC.js} +1 -1
  271. package/dist/ui/assets/{tap-CXxSD8bM.js → tap-BOl1lBlS.js} +1 -1
  272. package/dist/ui/assets/{tcl-CdoAAMbn.js → tcl-DZjeOBDh.js} +1 -1
  273. package/dist/ui/assets/{thrift-DM086HVt.js → thrift-BxboWg4x.js} +1 -1
  274. package/dist/ui/assets/{timeline-definition-FHXFAJF6-DcrcjFwq.js → timeline-definition-FHXFAJF6-BOxsxyq_.js} +1 -1
  275. package/dist/ui/assets/{tp-Y-w3S3ES.js → tp-BNM6ql3J.js} +1 -1
  276. package/dist/ui/assets/{twig-C5c_nAus.js → twig-Dj9ZiXD4.js} +1 -1
  277. package/dist/ui/assets/{typescript-fc7SMhJu.js → typescript-7MEJlu_6.js} +1 -1
  278. package/dist/ui/assets/{vala-BV-GlwLI.js → vala-DNqOAgHJ.js} +1 -1
  279. package/dist/ui/assets/{vbnet-BIqQmnKr.js → vbnet-T0mNKVc_.js} +1 -1
  280. package/dist/ui/assets/{vbscript-h186Lnrz.js → vbscript-CeuwVMAI.js} +1 -1
  281. package/dist/ui/assets/{vbscript-html-DcuP7lTb.js → vbscript-html-BbJSt2w6.js} +1 -1
  282. package/dist/ui/assets/{vennDiagram-L72KCM5P-Dnh11y2e.js → vennDiagram-L72KCM5P-BX9mWeiT.js} +1 -1
  283. package/dist/ui/assets/{verilog-Cbgb_XnR.js → verilog-DYuhYfkX.js} +1 -1
  284. package/dist/ui/assets/{vhdl-COP7w5IC.js → vhdl-Cf9aT-t7.js} +1 -1
  285. package/dist/ui/assets/{vim-COGwKzgS.js → vim-DciP44K1.js} +1 -1
  286. package/dist/ui/assets/{wardleyDiagram-EHGQE667-BeiD8fPz.js → wardleyDiagram-EHGQE667-CDj2rOzu.js} +1 -1
  287. package/dist/ui/assets/{x86asm-BdBqPPf4.js → x86asm-E-AN_LXO.js} +1 -1
  288. package/dist/ui/assets/{xl-BmCQT7Vj.js → xl-CxYLJelN.js} +1 -1
  289. package/dist/ui/assets/{xml-DM0NxGiJ.js → xml-yz1SRLuU.js} +1 -1
  290. package/dist/ui/assets/{xquery-BUaYHDJM.js → xquery-BLzBF3tV.js} +1 -1
  291. package/dist/ui/assets/{xychartDiagram-FW5EYKEG-CnwvTrkm.js → xychartDiagram-FW5EYKEG-Czapk9-Z.js} +1 -1
  292. package/dist/ui/assets/{yaml-DMs8lGDt.js → yaml-Cv4Y7iN_.js} +1 -1
  293. package/dist/ui/assets/{zephir-BvjoPdmg.js → zephir-KRcdQfEX.js} +1 -1
  294. package/dist/ui/index.html +2 -2
  295. package/dist/utils/__tests__/knowledge-store.test.js +86 -5
  296. package/dist/utils/__tests__/pi-browser-tools.test.d.ts +1 -0
  297. package/dist/utils/__tests__/pi-browser-tools.test.js +30 -0
  298. package/dist/utils/__tests__/pi-crawl-tools.test.d.ts +1 -0
  299. package/dist/utils/__tests__/pi-crawl-tools.test.js +315 -0
  300. package/dist/utils/__tests__/pi-dedup-reconcile.test.d.ts +1 -0
  301. package/dist/utils/__tests__/pi-dedup-reconcile.test.js +89 -0
  302. package/dist/utils/__tests__/pi-dedup.test.d.ts +1 -0
  303. package/dist/utils/__tests__/pi-dedup.test.js +106 -0
  304. package/dist/utils/__tests__/pi-learn-orchestrator.test.d.ts +1 -0
  305. package/dist/utils/__tests__/pi-learn-orchestrator.test.js +885 -0
  306. package/dist/utils/__tests__/pi-runtime-json.test.d.ts +1 -0
  307. package/dist/utils/__tests__/pi-runtime-json.test.js +11 -0
  308. package/dist/utils/__tests__/web-crawler.test.d.ts +1 -0
  309. package/dist/utils/__tests__/web-crawler.test.js +69 -0
  310. package/dist/utils/db.d.ts +1 -0
  311. package/dist/utils/db.js +18 -0
  312. package/dist/utils/knowledge-store.d.ts +9 -0
  313. package/dist/utils/knowledge-store.js +85 -11
  314. package/dist/utils/pi-browser-tools.d.ts +2 -0
  315. package/dist/utils/pi-browser-tools.js +9 -2
  316. package/dist/utils/pi-crawl-tools.d.ts +62 -0
  317. package/dist/utils/pi-crawl-tools.js +298 -0
  318. package/dist/utils/pi-dedup.d.ts +62 -0
  319. package/dist/utils/pi-dedup.js +218 -0
  320. package/dist/utils/pi-learn-orchestrator.d.ts +44 -0
  321. package/dist/utils/pi-learn-orchestrator.js +431 -0
  322. package/dist/utils/pi-runtime.d.ts +23 -1
  323. package/dist/utils/pi-runtime.js +255 -68
  324. package/dist/utils/request-writer.d.ts +1 -0
  325. package/dist/utils/request-writer.js +5 -4
  326. package/dist/utils/web-crawler.d.ts +13 -0
  327. package/dist/utils/web-crawler.js +64 -0
  328. package/package.json +1 -1
  329. package/dist/docs/assets/chunks/@localSearchIndexroot.CHyuB7c8.js +0 -1
  330. package/dist/ui/assets/channel-BdcV3Ykv.js +0 -1
  331. package/dist/ui/assets/classDiagram-OUVF2IWQ-CAZR5rAv.js +0 -1
  332. package/dist/ui/assets/classDiagram-v2-EOCWNBFH-CAZR5rAv.js +0 -1
  333. package/dist/ui/assets/index-WPLwx8h5.css +0 -10
  334. package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-BFJCYsLY.js +0 -1
  335. package/dist/ui/assets/swimlanesDiagram-G3AALYLV-BZd1Gt4_.js +0 -8
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
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';
5
+ test('extractJsonObject: 从含 prose/代码围栏文本取出第一个 JSON 对象', () => {
6
+ const raw = 'Here:\n```json\n{"a":1,"b":[2,3]}\n```\ndone';
7
+ expect(extractJsonObject(raw)).toEqual({ a: 1, b: [2, 3] });
8
+ });
9
+ test('extractJsonObject: 无 JSON → throw', () => {
10
+ expect(() => extractJsonObject('no json here')).toThrow(/no json object/);
11
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,69 @@
1
+ import { slugFromUrl, slugFromLabel, isSameSite, normalizeCandidate, } from '../web-crawler.js';
2
+ describe('slugFromUrl', () => {
3
+ it('bare host without path', () => {
4
+ expect(slugFromUrl('https://pi.dev')).toBe('pi');
5
+ });
6
+ it('drops generic docs segment', () => {
7
+ expect(slugFromUrl('https://pi.dev/docs/intro')).toBe('pi-intro');
8
+ });
9
+ it('strips www and keeps at most 3 path segments', () => {
10
+ expect(slugFromUrl('https://www.example.com/a/b/c/d')).toBe('example-a-b-c');
11
+ });
12
+ it('ignores query and hash', () => {
13
+ expect(slugFromUrl('https://pi.dev/x?y=1#z')).toBe('pi-x');
14
+ });
15
+ it('throws on invalid url', () => {
16
+ expect(() => slugFromUrl('not a url')).toThrow();
17
+ });
18
+ });
19
+ describe('slugFromLabel', () => {
20
+ it('strips extension from ascii filename', () => {
21
+ expect(slugFromLabel('react-hooks.md')).toBe('react-hooks');
22
+ });
23
+ it('keeps the ascii stem and washes non-ascii chars away', () => {
24
+ expect(slugFromLabel('Pi 介绍.docx')).toBe('pi');
25
+ });
26
+ it('falls back to topic when nothing ascii remains', () => {
27
+ expect(slugFromLabel('介绍.docx')).toBe('topic');
28
+ });
29
+ it('takes basename and cleans spaces case-insensitively', () => {
30
+ expect(slugFromLabel('/tmp/dir/My Note.TXT')).toBe('my-note');
31
+ });
32
+ });
33
+ describe('isSameSite', () => {
34
+ it('subdomain is same site', () => {
35
+ expect(isSameSite('blog.pi.dev', 'pi.dev')).toBe(true);
36
+ });
37
+ it('www is equivalent to bare host', () => {
38
+ expect(isSameSite('www.pi.dev', 'pi.dev')).toBe(true);
39
+ });
40
+ it('cross domain is not same site', () => {
41
+ expect(isSameSite('other.com', 'pi.dev')).toBe(false);
42
+ });
43
+ it('suffix-without-dot is not same site', () => {
44
+ expect(isSameSite('notpi.dev', 'pi.dev')).toBe(false);
45
+ });
46
+ });
47
+ describe('normalizeCandidate', () => {
48
+ const entry = new URL('https://pi.dev/');
49
+ it('passes a normal http(s) link', () => {
50
+ const u = normalizeCandidate('https://pi.dev/a', entry);
51
+ expect(u?.href).toBe('https://pi.dev/a');
52
+ });
53
+ it('resolves relative links against entry', () => {
54
+ const u = normalizeCandidate('/about', entry);
55
+ expect(u?.href).toBe('https://pi.dev/about');
56
+ });
57
+ it('rejects non-http protocols like mailto', () => {
58
+ expect(normalizeCandidate('mailto:a@b.com', entry)).toBeNull();
59
+ });
60
+ it('excludes binary/document extensions', () => {
61
+ expect(normalizeCandidate('https://pi.dev/file.pdf', entry)).toBeNull();
62
+ expect(normalizeCandidate('https://pi.dev/PIC.JPG', entry)).toBeNull();
63
+ });
64
+ it('clears the hash', () => {
65
+ const u = normalizeCandidate('https://pi.dev/a#section', entry);
66
+ expect(u?.href).toBe('https://pi.dev/a');
67
+ expect(u?.hash).toBe('');
68
+ });
69
+ });
@@ -9,5 +9,6 @@ export declare function applySchemaV6(db: Database.Database): void;
9
9
  export declare function applySchemaV7(db: Database.Database): void;
10
10
  export declare function applySchemaV8(db: Database.Database): void;
11
11
  export declare function applySchemaV9(db: Database.Database): void;
12
+ export declare function applySchemaV10(db: Database.Database): void;
12
13
  export declare function closeDatabase(): void;
13
14
  export declare function getDatabase(): Database.Database;
package/dist/utils/db.js CHANGED
@@ -68,6 +68,10 @@ export function initDatabase() {
68
68
  applySchemaV9(db);
69
69
  db.prepare('INSERT OR REPLACE INTO schema_version (version) VALUES (9)').run();
70
70
  }
71
+ if (currentVersion < 10) {
72
+ applySchemaV10(db);
73
+ db.prepare('INSERT OR REPLACE INTO schema_version (version) VALUES (10)').run();
74
+ }
71
75
  return db;
72
76
  }
73
77
  export function applySchemaV2(db) {
@@ -146,6 +150,7 @@ function applySchemaV1(db) {
146
150
  proxy_api_key TEXT,
147
151
  base_url TEXT,
148
152
  model TEXT,
153
+ user_agent TEXT,
149
154
  input_tokens INTEGER,
150
155
  output_tokens INTEGER,
151
156
  cache_read_tokens INTEGER,
@@ -262,6 +267,19 @@ export function applySchemaV9(db) {
262
267
  db.exec("ALTER TABLE providers ADD COLUMN auth_style TEXT NOT NULL DEFAULT 'bearer'");
263
268
  }
264
269
  }
270
+ export function applySchemaV10(db) {
271
+ // Add user_agent column to requests table
272
+ // ALTER TABLE ADD COLUMN is idempotent-safe via column-existence check
273
+ const columns = db.prepare("PRAGMA table_info(requests)").all();
274
+ if (!columns.some(c => c.name === 'user_agent')) {
275
+ db.exec('ALTER TABLE requests ADD COLUMN user_agent TEXT');
276
+ }
277
+ // Backfill historical rows from request_headers JSON (idempotent)
278
+ db.prepare(`
279
+ UPDATE requests SET user_agent = json_extract(request_headers, '$.user-agent')
280
+ WHERE user_agent IS NULL AND request_headers IS NOT NULL
281
+ `).run();
282
+ }
265
283
  export function closeDatabase() {
266
284
  if (db) {
267
285
  db.close();
@@ -8,6 +8,7 @@ export interface ChunkRef {
8
8
  id: string;
9
9
  title: string;
10
10
  summary: string;
11
+ tags: string[];
11
12
  }
12
13
  export interface TopicDetail {
13
14
  title: string;
@@ -20,10 +21,17 @@ export interface ChunkHit {
20
21
  chunkId: string;
21
22
  title: string;
22
23
  }
24
+ export interface QueryHit {
25
+ topic: string;
26
+ chunkId: string;
27
+ title: string;
28
+ body: string;
29
+ }
23
30
  export interface KnowledgeStore {
24
31
  listTopics(): Promise<TopicSummary[]>;
25
32
  getTopic(topic: string): Promise<TopicDetail>;
26
33
  searchChunks(query: string): Promise<ChunkHit[]>;
34
+ queryKnowledge(query: string, limit?: number): Promise<QueryHit[]>;
27
35
  readChunk(topic: string, chunkId: string): Promise<string>;
28
36
  upsertTopic(input: {
29
37
  slug: string;
@@ -36,6 +44,7 @@ export interface KnowledgeStore {
36
44
  chunkId: string;
37
45
  title: string;
38
46
  summary: string;
47
+ tags: string[];
39
48
  }): Promise<void>;
40
49
  }
41
50
  export declare function createKnowledgeStore(root: string): KnowledgeStore;
@@ -53,7 +53,14 @@ export function createKnowledgeStore(root) {
53
53
  title: meta.title || topic,
54
54
  tags: Array.isArray(meta.tags) ? meta.tags : [],
55
55
  sources: [],
56
- chunks: Array.isArray(meta.chunks) ? meta.chunks : [],
56
+ chunks: Array.isArray(meta.chunks)
57
+ ? meta.chunks.map(c => ({
58
+ id: c.id,
59
+ title: c.title,
60
+ summary: c.summary,
61
+ tags: Array.isArray(c.tags) ? c.tags : [],
62
+ }))
63
+ : [],
57
64
  };
58
65
  }
59
66
  async function upsertTopic(input) {
@@ -90,7 +97,7 @@ export function createKnowledgeStore(root) {
90
97
  async function upsertChunkRef(input) {
91
98
  assertTopic(input.topic);
92
99
  assertChunkId(input.chunkId);
93
- const { topic, chunkId, title, summary } = input;
100
+ const { topic, chunkId, title, summary, tags } = input;
94
101
  const topicPath = path.join(root, topic, 'index.json');
95
102
  let topicIdx;
96
103
  try {
@@ -109,17 +116,32 @@ export function createKnowledgeStore(root) {
109
116
  if (existing) {
110
117
  existing.title = title;
111
118
  existing.summary = summary;
119
+ existing.tags = tags;
112
120
  }
113
121
  else {
114
- topicIdx.chunks.push({ id: chunkId, title, summary });
122
+ topicIdx.chunks.push({ id: chunkId, title, summary, tags });
115
123
  }
116
124
  await fs.writeFile(topicPath, JSON.stringify(topicIdx, null, 2), 'utf8');
117
125
  }
118
- async function searchChunks(query) {
119
- if (!query.trim())
120
- return [];
121
- const hits = [];
126
+ /** 匹配词集合:整体 query + whitespace 分割的长度 >1 的 token,去重 */
127
+ function buildTerms(query) {
122
128
  const q = query.toLowerCase();
129
+ const terms = new Set([q]);
130
+ for (const tok of q.split(/\s+/)) {
131
+ if (tok.length > 1)
132
+ terms.add(tok);
133
+ }
134
+ return [...terms];
135
+ }
136
+ /** 扫描所有 topic/chunk,返回打分候选(searchChunks / queryKnowledge 共用) */
137
+ async function scanChunks(query) {
138
+ const q = query.toLowerCase();
139
+ if (!q.trim())
140
+ return [];
141
+ const terms = buildTerms(query);
142
+ const candidates = [];
143
+ // topic index 本函数作用域缓存,避免每个 chunk 重复读
144
+ const topicIndexCache = new Map();
123
145
  let entries;
124
146
  try {
125
147
  entries = await fs.readdir(root);
@@ -130,6 +152,14 @@ export function createKnowledgeStore(root) {
130
152
  for (const topic of entries) {
131
153
  if (!TOPIC_RE.test(topic))
132
154
  continue;
155
+ if (!topicIndexCache.has(topic)) {
156
+ const idx = await readJsonOr(path.join(root, topic, 'index.json'), null);
157
+ topicIndexCache.set(topic, idx);
158
+ }
159
+ const topicIdx = topicIndexCache.get(topic) ?? null;
160
+ const topicTags = topicIdx && Array.isArray(topicIdx.tags) ? topicIdx.tags : [];
161
+ const chunkRefs = topicIdx && Array.isArray(topicIdx.chunks) ? topicIdx.chunks : [];
162
+ const topicTagHit = (term) => topicTags.some(t => t.toLowerCase().includes(term));
133
163
  const chunksDir = path.join(root, topic, 'chunks');
134
164
  let files;
135
165
  try {
@@ -139,14 +169,58 @@ export function createKnowledgeStore(root) {
139
169
  continue;
140
170
  }
141
171
  for (const file of files) {
142
- if (!CHUNK_RE.test(file.replace(/\.md$/, '')))
172
+ const chunkId = file.replace(/\.md$/, '');
173
+ if (!CHUNK_RE.test(chunkId))
143
174
  continue;
144
175
  const text = await fs.readFile(path.join(chunksDir, file), 'utf8');
145
- if (text.toLowerCase().includes(q)) {
146
- hits.push({ topic, chunkId: file.replace(/\.md$/, ''), title: parseChunkTitle(text) });
176
+ const textLc = text.toLowerCase();
177
+ const ref = chunkRefs.find(c => c.id === chunkId);
178
+ const refTitle = (ref?.title ?? '').toLowerCase();
179
+ const refSummary = (ref?.summary ?? '').toLowerCase();
180
+ const refTags = ref && Array.isArray(ref.tags) ? ref.tags : [];
181
+ let score = 0;
182
+ for (const term of terms) {
183
+ // 每个字段每词只计一次分,body 不按出现次数刷分
184
+ if (refTitle.includes(term))
185
+ score += 3;
186
+ if (refTags.some(t => t.toLowerCase().includes(term)))
187
+ score += 2;
188
+ if (topicTagHit(term))
189
+ score += 2;
190
+ if (refSummary.includes(term))
191
+ score += 1;
192
+ if (textLc.includes(term))
193
+ score += 1;
147
194
  }
195
+ if (score === 0)
196
+ continue;
197
+ const wholeQueryHit = textLc.includes(q) ||
198
+ refTitle.includes(q) ||
199
+ refSummary.includes(q) ||
200
+ topicTagHit(q) ||
201
+ refTags.some(t => t.toLowerCase().includes(q));
202
+ candidates.push({ topic, chunkId, title: parseChunkTitle(text), score, wholeQueryHit });
148
203
  }
149
204
  }
205
+ return candidates;
206
+ }
207
+ async function searchChunks(query) {
208
+ if (!query.trim())
209
+ return [];
210
+ return (await scanChunks(query))
211
+ .filter(c => c.wholeQueryHit)
212
+ .map(({ topic, chunkId, title }) => ({ topic, chunkId, title }));
213
+ }
214
+ async function queryKnowledge(query, limit = 3) {
215
+ const capped = Math.min(Math.max(limit, 1), 5);
216
+ const candidates = (await scanChunks(query))
217
+ .sort((a, b) => b.score - a.score)
218
+ .slice(0, capped);
219
+ const hits = [];
220
+ for (const c of candidates) {
221
+ const body = await readChunk(c.topic, c.chunkId);
222
+ hits.push({ topic: c.topic, chunkId: c.chunkId, title: c.title, body });
223
+ }
150
224
  return hits;
151
225
  }
152
226
  async function readChunk(topic, chunkId) {
@@ -161,7 +235,7 @@ export function createKnowledgeStore(root) {
161
235
  }
162
236
  return fs.readFile(resolved, 'utf8');
163
237
  }
164
- return { listTopics, getTopic, searchChunks, readChunk, upsertTopic, upsertChunkRef };
238
+ return { listTopics, getTopic, searchChunks, queryKnowledge, readChunk, upsertTopic, upsertChunkRef };
165
239
  }
166
240
  // 默认单例:绑生产 docsDir
167
241
  export const knowledgeStore = createKnowledgeStore(docsDir);
@@ -7,4 +7,6 @@ export declare function runEgoBrowser(scriptBody: string, opts?: {
7
7
  timeoutMs?: number;
8
8
  signal?: AbortSignal;
9
9
  }): Promise<string>;
10
+ /** 过滤 ego-browser 自身打到输出流的横幅行(如升级 notice),保留脚本 cliLog 的真实输出 */
11
+ export declare function stripCliBanners(text: string): string;
10
12
  export declare const browserTools: ToolDefinition[];
@@ -8,7 +8,7 @@ export function runEgoBrowser(scriptBody, opts = {}) {
8
8
  const timeoutMs = opts.timeoutMs ?? 30000;
9
9
  return new Promise((resolve, reject) => {
10
10
  // 头部自动注入 task space 复用调用
11
- const script = `const task = await useOrCreateTaskSpace('knowledge-learn')\n${scriptBody}`;
11
+ const script = `const task = await taskSpace('knowledge-learn')\n${scriptBody}`;
12
12
  const child = spawn('ego-browser', ['nodejs'], {
13
13
  stdio: ['pipe', 'pipe', 'pipe'],
14
14
  });
@@ -61,7 +61,7 @@ export function runEgoBrowser(scriptBody, opts = {}) {
61
61
  return;
62
62
  if (code === 0) {
63
63
  // 新版 ego cliLog 走 stderr;stdout 非空用 stdout,否则回退 stderr(新旧兼容)
64
- const out = stdout.trim() ? stdout : stderr;
64
+ const out = stripCliBanners(stdout.trim() ? stdout : stderr);
65
65
  finish(null, out);
66
66
  }
67
67
  else {
@@ -73,6 +73,13 @@ export function runEgoBrowser(scriptBody, opts = {}) {
73
73
  child.stdin.end(script, 'utf-8');
74
74
  });
75
75
  }
76
+ /** 过滤 ego-browser 自身打到输出流的横幅行(如升级 notice),保留脚本 cliLog 的真实输出 */
77
+ export function stripCliBanners(text) {
78
+ return text
79
+ .split('\n')
80
+ .filter((line) => !line.startsWith('[ego-browser:notice]'))
81
+ .join('\n');
82
+ }
76
83
  // ---------- 工具实现辅助 ----------
77
84
  /** 把字符串参数安全注入脚本:JSON.stringify 自动处理引号 / 反斜杠 / 换行 */
78
85
  const jsLit = (v) => JSON.stringify(v);
@@ -0,0 +1,62 @@
1
+ import type { ToolDefinition } from '@earendil-works/pi-coding-agent';
2
+ export interface NavigatedPage {
3
+ title: string;
4
+ text: string;
5
+ links: string[];
6
+ }
7
+ interface PageData extends NavigatedPage {
8
+ url: string;
9
+ }
10
+ export interface CrawlGuardOptions {
11
+ entryUrl: string;
12
+ docsDir: string;
13
+ slug: string;
14
+ maxPages?: number;
15
+ maxDepth?: number;
16
+ /** 可注入的单页抓取(测试用);默认调 runEgoBrowser;signal 用于中断在途抓取 */
17
+ navigate?: (url: string, signal?: AbortSignal) => Promise<NavigatedPage>;
18
+ }
19
+ export interface SaveSourceResult {
20
+ savedCount: number;
21
+ reused: boolean;
22
+ }
23
+ export declare class CrawlGuard {
24
+ private readonly opts;
25
+ private readonly maxPages;
26
+ private readonly maxDepth;
27
+ private readonly navigate;
28
+ private entry;
29
+ private readonly seen;
30
+ private readonly depthByUrl;
31
+ private readonly rawCache;
32
+ private readonly savedUrls;
33
+ private _savedCount;
34
+ private currentDepth;
35
+ constructor(opts: CrawlGuardOptions);
36
+ /** 默认单页抓取:跑 ego 脚本,JSON parse 失败硬抛错;signal 透传中断在途进程 */
37
+ private defaultNavigate;
38
+ /** 打开入口页:URL 校验 + 初始状态;signal 用于中断在途抓取 */
39
+ open(signal?: AbortSignal): Promise<PageData>;
40
+ /**
41
+ * 解析候选页的 BFS 最短深度:扫描每个已抓来源页的 links,
42
+ * 凡归一后命中候选页的来源,候选深度 = 来源深度 + 1,取所有命中的最小值。
43
+ * 一个来源都没查到(幻觉 URL)时硬抛错,绝不放行。
44
+ */
45
+ private resolveDepth;
46
+ /** 访问子页:同站/seen/链接来源/深度/页数硬校验(原因 cross-site/seen/not linked/max-depth/max-pages) */
47
+ visit(rawUrl: string, signal?: AbortSignal): Promise<PageData>;
48
+ /**
49
+ * 保存已抓取页原文到 <slug>/sources/source-NNN.md;必须先 open/visit 过该 URL。
50
+ * 同页重复保存不写新文件,返回已有编号 + reused=true;空正文页判失败。
51
+ */
52
+ saveSource(rawUrl: string): SaveSourceResult;
53
+ get savedCount(): number;
54
+ /**
55
+ * 抓取结束清理:no-op。
56
+ * 不能调 task.finish()——它会关闭全部 page 并把 space 所有权交还 user,
57
+ * 导致下一次 learn 的 taskSpace() resume 失败;持久 space 与 tab 留给后续复用。
58
+ */
59
+ close(): Promise<void>;
60
+ }
61
+ export declare function createCrawlTools(guard: CrawlGuard): ToolDefinition[];
62
+ export {};