@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.
- package/dist/docs/404.html +1 -1
- package/dist/docs/assets/{app.6_CicOIJ.js → app.B9A39uFv.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.B6Qfxe6W.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.ZMWZsg8z.js → VPLocalSearchBox.DdhC696L.js} +1 -1
- package/dist/docs/assets/chunks/{theme.BkvhsjzH.js → theme.CfB2tOFi.js} +2 -2
- package/dist/docs/index.html +2 -2
- package/dist/docs/overview.html +2 -2
- package/dist/docs/packages-utils.html +2 -2
- package/dist/docs/proxy-admin/env-and-build.html +2 -2
- package/dist/docs/proxy-admin/index.html +2 -2
- package/dist/docs/proxy-admin/layout-and-menu.html +2 -2
- package/dist/docs/proxy-admin/pages.html +2 -2
- package/dist/docs/proxy-admin/routing-and-auth.html +2 -2
- package/dist/docs/proxy-admin/services-and-mock.html +2 -2
- package/dist/docs/proxy-cli/api-layer.html +2 -2
- package/dist/docs/proxy-cli/app-shell.html +2 -2
- package/dist/docs/proxy-cli/components-common.html +2 -2
- package/dist/docs/proxy-cli/components-config.html +2 -2
- package/dist/docs/proxy-cli/components-requests.html +2 -2
- package/dist/docs/proxy-cli/components-stats.html +2 -2
- package/dist/docs/proxy-cli/components-status.html +2 -2
- package/dist/docs/proxy-cli/data-hooks.html +2 -2
- package/dist/docs/proxy-cli/index.html +2 -2
- package/dist/docs/proxy-cli/utils-and-i18n.html +2 -2
- package/dist/docs/proxy-core/chat-api.html +2 -2
- package/dist/docs/proxy-core/cli.html +2 -2
- package/dist/docs/proxy-core/config.html +2 -2
- package/dist/docs/proxy-core/data-layer.html +2 -2
- package/dist/docs/proxy-core/entry.html +2 -2
- package/dist/docs/proxy-core/index.html +2 -2
- package/dist/docs/proxy-core/pm2.html +2 -2
- package/dist/docs/proxy-core/providers.html +2 -2
- package/dist/docs/proxy-core/proxy.html +2 -2
- package/dist/docs/proxy-core/stats.html +2 -2
- package/dist/docs/proxy-core/tool.html +2 -2
- package/dist/docs/proxy-core/ui-routes.html +2 -2
- package/dist/docs/proxy-core/utilities.html +2 -2
- package/dist/docs/quickstart.html +2 -2
- package/dist/docs/request-flow.html +2 -2
- package/dist/mcp-server/index.js +5 -3
- package/dist/mcp-server/tools.js +24 -2
- package/dist/server/__tests__/server.test.js +9 -1
- package/dist/server/__tests__/ui-route.test.js +8 -0
- package/dist/server/chat-route.js +6 -0
- package/dist/server/proxy.js +5 -0
- package/dist/server/ui-route.js +113 -7
- package/dist/ui/assets/{1c-HTPXddJd.js → 1c-DAu68mP4.js} +1 -1
- package/dist/ui/assets/{abnf-bINSkl_m.js → abnf-Cu8RHCHK.js} +1 -1
- package/dist/ui/assets/{abnfDiagram-VRR7QNED-ClDzCbvw.js → abnfDiagram-VRR7QNED-BUBToPXF.js} +1 -1
- package/dist/ui/assets/{accesslog-BAnIWzpe.js → accesslog-BG-34XOy.js} +1 -1
- package/dist/ui/assets/{actionscript-DVcm6F_C.js → actionscript-iw0HHMGM.js} +1 -1
- package/dist/ui/assets/{ada-Cxn-QX4j.js → ada-qRqj6VGQ.js} +1 -1
- package/dist/ui/assets/{angelscript-BAwAPvBQ.js → angelscript-BeaXyx_P.js} +1 -1
- package/dist/ui/assets/{apache-CjjovgUx.js → apache-CU8d-z9X.js} +1 -1
- package/dist/ui/assets/{applescript-VUcyXoVh.js → applescript-d1Wxkqz1.js} +1 -1
- package/dist/ui/assets/{arc-3Nou_aku.js → arc-BMsPIm3j.js} +1 -1
- package/dist/ui/assets/{arcade-Dz2VAk7O.js → arcade-CtbgrWTM.js} +1 -1
- package/dist/ui/assets/{architectureDiagram-ZJ3FMSHR-DhwSsCdN.js → architectureDiagram-ZJ3FMSHR-CVjC5TrS.js} +1 -1
- package/dist/ui/assets/{arduino-B-Ptb1K1.js → arduino-Bc9L39Hr.js} +1 -1
- package/dist/ui/assets/{armasm-DU_6qZlW.js → armasm-DuWmpjWR.js} +1 -1
- package/dist/ui/assets/{asciidoc-DYbYiWKT.js → asciidoc-CDIhFTnx.js} +1 -1
- package/dist/ui/assets/{aspectj-CmdNkqAs.js → aspectj-SYj-57Es.js} +1 -1
- package/dist/ui/assets/{autohotkey-if9QUvYo.js → autohotkey-hBi5dq37.js} +1 -1
- package/dist/ui/assets/{autoit-DGU3G1s6.js → autoit-BSawXzhg.js} +1 -1
- package/dist/ui/assets/{avrasm-1zsEtPJ6.js → avrasm-CwYom8Np.js} +1 -1
- package/dist/ui/assets/{awk-CvmeshSq.js → awk-BvBRfGo2.js} +1 -1
- package/dist/ui/assets/{axapta-CbJGb5cN.js → axapta-CqUavA8k.js} +1 -1
- package/dist/ui/assets/{bash-CFXg_i2e.js → bash-BS_ZnmEu.js} +1 -1
- package/dist/ui/assets/{basic-6atic5cT.js → basic-xbP4IXrN.js} +1 -1
- package/dist/ui/assets/{blockDiagram-677ZJIJ3-BKXinDkB.js → blockDiagram-677ZJIJ3-CmpI3f5p.js} +1 -1
- package/dist/ui/assets/{bnf-DydAtPHV.js → bnf-BECwu6uW.js} +1 -1
- package/dist/ui/assets/{brainfuck-CnHx1vO0.js → brainfuck-QQgu4j4N.js} +1 -1
- package/dist/ui/assets/{coq-BShzwzh7.js → c-BRJEPYra.js} +1 -1
- package/dist/ui/assets/{c-like-XpQV9S6j.js → c-like-DYrFOtXy.js} +1 -1
- package/dist/ui/assets/{c4Diagram-LMCZKHZV-D5EmWl5d.js → c4Diagram-LMCZKHZV-B6Hgngz9.js} +1 -1
- package/dist/ui/assets/{cal-D-orUuBW.js → cal-CNMrJ6v5.js} +1 -1
- package/dist/ui/assets/{capnproto-TdI6NT8O.js → capnproto-DYCKl6oY.js} +1 -1
- package/dist/ui/assets/{ceylon-Dji8eqtG.js → ceylon-mb8tRPl0.js} +1 -1
- package/dist/ui/assets/channel-Bc4Td8eZ.js +1 -0
- package/dist/ui/assets/{chunk-2Q5K7J3B-CaIvwVWl.js → chunk-2Q5K7J3B-LxvQ-G67.js} +1 -1
- package/dist/ui/assets/{chunk-32BRIVSS-C7oMpoeu.js → chunk-32BRIVSS-DxzKK6Aw.js} +1 -1
- package/dist/ui/assets/{chunk-5VM5RSS4-BQ0aVGl-.js → chunk-5VM5RSS4-CZEoYJ2W.js} +1 -1
- package/dist/ui/assets/{chunk-EX3LRPZG-D-_EqojZ.js → chunk-EX3LRPZG-DS2PytrN.js} +1 -1
- package/dist/ui/assets/{chunk-JWPE2WC7-B0OLx2rk.js → chunk-JWPE2WC7-UX0Sr1Ie.js} +1 -1
- package/dist/ui/assets/{chunk-MOJQB5TN-Be8IXTUE.js → chunk-MOJQB5TN-YbJgT9t4.js} +1 -1
- package/dist/ui/assets/{chunk-RYQCIY6F-DceCW2mS.js → chunk-RYQCIY6F-DS2VH_U9.js} +1 -1
- package/dist/ui/assets/{chunk-V7JOEXUC-Cbhq5qgO.js → chunk-V7JOEXUC-CZr0pkI1.js} +1 -1
- package/dist/ui/assets/{chunk-VR4S4FIN-D6WJuaS1.js → chunk-VR4S4FIN-50opPAD3.js} +1 -1
- package/dist/ui/assets/{chunk-XXDRQBXY-CKrih4pC.js → chunk-XXDRQBXY-DAAX9l7U.js} +1 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-BicxhZFq.js +1 -0
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-BicxhZFq.js +1 -0
- package/dist/ui/assets/{clean-0frlVN_A.js → clean-C4X7dSkh.js} +1 -1
- package/dist/ui/assets/{clojure-D0q_yQDf.js → clojure-DSg9gUa7.js} +1 -1
- package/dist/ui/assets/{clojure-repl-DgYhEzOe.js → clojure-repl-CagRYx7h.js} +1 -1
- package/dist/ui/assets/{cmake-WF5tF5xU.js → cmake-CFdBn53c.js} +1 -1
- package/dist/ui/assets/{coffeescript-CyWYgeyv.js → coffeescript-CJZtMOPx.js} +1 -1
- package/dist/ui/assets/{c-DarYnPBd.js → coq-IDMIFfem.js} +1 -1
- package/dist/ui/assets/{cos-C5i3_TIB.js → cos-Bx2VJuzG.js} +1 -1
- package/dist/ui/assets/{cose-bilkent-JH36ORCC-BCwilS6I.js → cose-bilkent-JH36ORCC-zWRLsZpZ.js} +1 -1
- package/dist/ui/assets/{cpp-F1mRQFyw.js → cpp-CsG6DlC4.js} +1 -1
- package/dist/ui/assets/{crmsh-BAkHUu-B.js → crmsh-DTy9MnmJ.js} +1 -1
- package/dist/ui/assets/{crystal-CwUaomfj.js → crystal-BwgrLrZ1.js} +1 -1
- package/dist/ui/assets/{csharp-B1gHIdjK.js → csharp-B2VeTPAF.js} +1 -1
- package/dist/ui/assets/{csp-CblCTMvV.js → csp-CTpydNhH.js} +1 -1
- package/dist/ui/assets/{css-CXg7kJV3.js → css-B0mMUbpY.js} +1 -1
- package/dist/ui/assets/{cynefin-VYW2F7L2-BdgMlR5e.js → cynefin-VYW2F7L2-BmjQEj6q.js} +1 -1
- package/dist/ui/assets/{cynefinDiagram-TSTJHNR4-Bozdux8p.js → cynefinDiagram-TSTJHNR4-Dr0Zrke0.js} +1 -1
- package/dist/ui/assets/{d-Cs5yNCaM.js → d-DjuDZnbI.js} +1 -1
- package/dist/ui/assets/{dagre-VKFMJZFB-tI_mjNMn.js → dagre-VKFMJZFB-xoTPT2Uu.js} +1 -1
- package/dist/ui/assets/{dart-BqgylVkh.js → dart-xR3GU9TJ.js} +1 -1
- package/dist/ui/assets/{delphi-CbnfHpIi.js → delphi-bJas5QnG.js} +1 -1
- package/dist/ui/assets/{diagram-FQU43EPY-DmyL3OJT.js → diagram-FQU43EPY-rL_IU7gU.js} +1 -1
- package/dist/ui/assets/{diagram-G47NLZAW-BEi9GZlZ.js → diagram-G47NLZAW-EcDiCVGj.js} +1 -1
- package/dist/ui/assets/{diagram-NH7WQ7WH-Bct44Oh1.js → diagram-NH7WQ7WH-CGGXOjev.js} +1 -1
- package/dist/ui/assets/{diagram-OA4YK3LP-VWAgZxPK.js → diagram-OA4YK3LP-DnE7hDjD.js} +1 -1
- package/dist/ui/assets/{diagram-WEI45ONY-CxcHsE6q.js → diagram-WEI45ONY-CTJH5eD8.js} +1 -1
- package/dist/ui/assets/{diff-CMJ2hGQW.js → diff-doJFF3fv.js} +1 -1
- package/dist/ui/assets/{django-Cq_XIhVZ.js → django-D3b-owa_.js} +1 -1
- package/dist/ui/assets/{dns-CJs3z6-E.js → dns-C42KYV-Z.js} +1 -1
- package/dist/ui/assets/{dockerfile-ehs0ogry.js → dockerfile-9KUINc2j.js} +1 -1
- package/dist/ui/assets/{dos-DXOYESf1.js → dos-CxnlJ6qp.js} +1 -1
- package/dist/ui/assets/{dsconfig-Cs2hs3Bl.js → dsconfig-6CMMCwmY.js} +1 -1
- package/dist/ui/assets/{dts-Dk8yoweb.js → dts-D78rdUIB.js} +1 -1
- package/dist/ui/assets/{dust-BMK9e-Ss.js → dust-Dv1uTfJU.js} +1 -1
- package/dist/ui/assets/{ebnf-DlyBI5m6.js → ebnf-BGbG1cFK.js} +1 -1
- package/dist/ui/assets/{ebnfDiagram-CCIWWBDH-DBp9JHEq.js → ebnfDiagram-CCIWWBDH-z2VgRSUV.js} +1 -1
- package/dist/ui/assets/{elixir-BThlsblT.js → elixir-ZgAQVY1J.js} +1 -1
- package/dist/ui/assets/{elm-DrmZwmcc.js → elm-CudiFuNu.js} +1 -1
- package/dist/ui/assets/{erDiagram-Q63AITRT-BhK4NKvx.js → erDiagram-Q63AITRT-X1TODuRv.js} +1 -1
- package/dist/ui/assets/{erb-BQM7j3K9.js → erb-Bz_NZh6W.js} +1 -1
- package/dist/ui/assets/{erlang-CuUaWEXv.js → erlang-DNuj1nb2.js} +1 -1
- package/dist/ui/assets/{erlang-repl-DB0uphao.js → erlang-repl-SP1Gan9W.js} +1 -1
- package/dist/ui/assets/{excel-DmsuWUss.js → excel-0K77uECF.js} +1 -1
- package/dist/ui/assets/{fix-D-Uzxpz_.js → fix-CalJq7JD.js} +1 -1
- package/dist/ui/assets/{flix-B_7EHWiA.js → flix-BlIs11_w.js} +1 -1
- package/dist/ui/assets/{flowDiagram-23GEKE2U-DtMG1G-h.js → flowDiagram-23GEKE2U-DA2dnmc0.js} +1 -1
- package/dist/ui/assets/{fortran-Djp5tH9W.js → fortran-ZCobXY2R.js} +1 -1
- package/dist/ui/assets/{fsharp-Pj_2ZEa4.js → fsharp-Be8rwUtc.js} +1 -1
- package/dist/ui/assets/{gams-B2i3v2ec.js → gams-DUat8frQ.js} +1 -1
- package/dist/ui/assets/{ganttDiagram-NO4QXBWP-C7M-JA0W.js → ganttDiagram-NO4QXBWP-DdFwaIGZ.js} +1 -1
- package/dist/ui/assets/{gauss-DaV8sHLU.js → gauss-BB4U88dy.js} +1 -1
- package/dist/ui/assets/{gcode-0Jvrh6HY.js → gcode-DzeUZuZg.js} +1 -1
- package/dist/ui/assets/{gherkin-DoOl28D6.js → gherkin-B_8vW_BO.js} +1 -1
- package/dist/ui/assets/{gitGraphDiagram-IHSO6WYX-D3HB5mow.js → gitGraphDiagram-IHSO6WYX-B-Dn8x6I.js} +1 -1
- package/dist/ui/assets/{glsl-DEbk7rH5.js → glsl-DGHGjPC1.js} +1 -1
- package/dist/ui/assets/{gml-CBcqXBNV.js → gml-BYEku8Yh.js} +1 -1
- package/dist/ui/assets/{go-DqesmqF8.js → go-D8aSgQMc.js} +1 -1
- package/dist/ui/assets/{golo-9U1oO0b5.js → golo-CDjCU_jh.js} +1 -1
- package/dist/ui/assets/{gradle-DZliBXTY.js → gradle-BeUw7tl_.js} +1 -1
- package/dist/ui/assets/{groovy-Dys3GQwv.js → groovy-5iCQOtR3.js} +1 -1
- package/dist/ui/assets/{haml-CrtAODl1.js → haml-BEdL8FJi.js} +1 -1
- package/dist/ui/assets/{handlebars-CueXuqSj.js → handlebars-BuYQNzoK.js} +1 -1
- package/dist/ui/assets/{haskell-CRungOQt.js → haskell-I4FCBcW0.js} +1 -1
- package/dist/ui/assets/{haxe-aMz7L4gD.js → haxe-yigyKfFr.js} +1 -1
- package/dist/ui/assets/{hsp-Cw75yqGb.js → hsp-ZUk4j7d1.js} +1 -1
- package/dist/ui/assets/{htmlbars-e_mpUZNH.js → htmlbars-QYP3lT3u.js} +1 -1
- package/dist/ui/assets/{http-Di7E_m1o.js → http-BJpD1O71.js} +1 -1
- package/dist/ui/assets/{hy-CwlvsNj6.js → hy-CIJ1bP6S.js} +1 -1
- package/dist/ui/assets/{index-BdSumlU0.js → index-BDXWttnT.js} +3 -3
- package/dist/ui/assets/index-C0fxlU9d.css +10 -0
- package/dist/ui/assets/{index-BVM6YOjH.js → index-COAgrx1J.js} +256 -256
- package/dist/ui/assets/{infoDiagram-FWYZ7A6U-_r-6eAzx.js → infoDiagram-FWYZ7A6U-fTg9eLNt.js} +1 -1
- package/dist/ui/assets/{inform7-dwg1imm1.js → inform7-DAsu-lC2.js} +1 -1
- package/dist/ui/assets/{ini-DEXL1rCA.js → ini-Bhz-zHCg.js} +1 -1
- package/dist/ui/assets/{irpf90-Ccs_8Sp-.js → irpf90-BunhbwBl.js} +1 -1
- package/dist/ui/assets/{isbl-B9d1nYmL.js → isbl-q9L6hOhP.js} +1 -1
- package/dist/ui/assets/{ishikawaDiagram-FXEZZL3T-lNCezpU4.js → ishikawaDiagram-FXEZZL3T-B8G0sdgd.js} +1 -1
- package/dist/ui/assets/{java-5fv2smM6.js → java-Iks5Pkau.js} +1 -1
- package/dist/ui/assets/{javascript-TAWm0NK8.js → javascript-C4vltXPw.js} +1 -1
- package/dist/ui/assets/{jboss-cli-dM1kcsbR.js → jboss-cli-BQBvd2X2.js} +1 -1
- package/dist/ui/assets/{journeyDiagram-5HDEW3XC-CBYHux8i.js → journeyDiagram-5HDEW3XC-Crbzgrum.js} +1 -1
- package/dist/ui/assets/{json-CtCzm6jF.js → json-DXK0_jUK.js} +1 -1
- package/dist/ui/assets/{julia-Co7H3kzk.js → julia-CCYoBiYK.js} +1 -1
- package/dist/ui/assets/{julia-repl-BT1ar5VS.js → julia-repl-y8v2Oorl.js} +1 -1
- package/dist/ui/assets/{kanban-definition-HUTT4EX6-B8x8eQyo.js → kanban-definition-HUTT4EX6-C8sCOsBX.js} +1 -1
- package/dist/ui/assets/{kotlin-W6mVKIj9.js → kotlin-Bnjk7_fw.js} +1 -1
- package/dist/ui/assets/{lasso-DJG4luGz.js → lasso-B-al6x63.js} +1 -1
- package/dist/ui/assets/{latex-DbBOxO7u.js → latex-BUmqlb9r.js} +1 -1
- package/dist/ui/assets/{ldif-CVS189JA.js → ldif-D42RWj6Q.js} +1 -1
- package/dist/ui/assets/{leaf-eYNiXTKP.js → leaf-CrH4BZ0m.js} +1 -1
- package/dist/ui/assets/{less-DxhvWM95.js → less-upmRlQQW.js} +1 -1
- package/dist/ui/assets/{lisp-SC7AwnXC.js → lisp-DHYS22SA.js} +1 -1
- package/dist/ui/assets/{livecodeserver-CR2eHihF.js → livecodeserver-CeQNmFP3.js} +1 -1
- package/dist/ui/assets/{livescript-DBZ-GaVK.js → livescript-PJWpY1JI.js} +1 -1
- package/dist/ui/assets/{llvm-BzURO4tt.js → llvm-BKtKWwCt.js} +1 -1
- package/dist/ui/assets/{lsl-DGoJxEUu.js → lsl-RWRLRjk7.js} +1 -1
- package/dist/ui/assets/{lua-qgG9gdiw.js → lua-BFUDiPGm.js} +1 -1
- package/dist/ui/assets/{makefile-D0kZ6SOe.js → makefile-CUDyOz5D.js} +1 -1
- package/dist/ui/assets/{markdown-DRQWgMxk.js → markdown-zZCLypc6.js} +1 -1
- package/dist/ui/assets/{mathematica-DIBvZyEZ.js → mathematica-BHbxKxnq.js} +1 -1
- package/dist/ui/assets/{matlab-BNg0BR0b.js → matlab-DlGtg--p.js} +1 -1
- package/dist/ui/assets/{maxima-Bpga3G1G.js → maxima-BBBeS3Ra.js} +1 -1
- package/dist/ui/assets/{mel-CMOJa9Mg.js → mel-nh8j7W_6.js} +1 -1
- package/dist/ui/assets/{mercury-uvrRzupw.js → mercury-DyyD-pqr.js} +1 -1
- package/dist/ui/assets/{mindmap-definition-LN4V7U3C-DK8j_8Ap.js → mindmap-definition-LN4V7U3C-CJlhDHqM.js} +1 -1
- package/dist/ui/assets/{mipsasm-p1gWpDuw.js → mipsasm-hiEhRRiq.js} +1 -1
- package/dist/ui/assets/{mizar-DV1ENOOU.js → mizar-BZa3iAAL.js} +1 -1
- package/dist/ui/assets/{mojolicious-tg5XQSro.js → mojolicious-BCIm2V_y.js} +1 -1
- package/dist/ui/assets/{monkey-D8mYa31Q.js → monkey-zmK-7N8b.js} +1 -1
- package/dist/ui/assets/{moonscript-1d_rtlyv.js → moonscript-BsS_Mn3D.js} +1 -1
- package/dist/ui/assets/{n1ql-C5srRxme.js → n1ql-D7xVgDP0.js} +1 -1
- package/dist/ui/assets/{nginx-xS1muaWm.js → nginx-ct2q4dtd.js} +1 -1
- package/dist/ui/assets/{nim-CGGiMQfp.js → nim-RO0UOmW3.js} +1 -1
- package/dist/ui/assets/{nix-C77HsR7m.js → nix-BcRJxPKH.js} +1 -1
- package/dist/ui/assets/{node-repl-CSeYusSM.js → node-repl-DgIefwxW.js} +1 -1
- package/dist/ui/assets/{nsis-BffC7mSW.js → nsis-DqHs9QhB.js} +1 -1
- package/dist/ui/assets/{objectivec-WpjnmlJB.js → objectivec-BBcWqc7Y.js} +1 -1
- package/dist/ui/assets/{ocaml-CHUkJkjB.js → ocaml-BExfw7D6.js} +1 -1
- package/dist/ui/assets/{openscad-BvImqFT0.js → openscad-CHPRELQb.js} +1 -1
- package/dist/ui/assets/{oxygene-BMBykbf5.js → oxygene-DpS9uMJW.js} +1 -1
- package/dist/ui/assets/{parser3-lRbuZW0M.js → parser3-CjJ_QdBp.js} +1 -1
- package/dist/ui/assets/{pegDiagram-2B236MQR-C4DWmrja.js → pegDiagram-2B236MQR-GM70woGy.js} +1 -1
- package/dist/ui/assets/{perl-B0DjfKoO.js → perl-BSNM2Kt8.js} +1 -1
- package/dist/ui/assets/{pf-Aor6NyYJ.js → pf-Z-hKf_88.js} +1 -1
- package/dist/ui/assets/{pgsql-CVKcjjNR.js → pgsql-DDgznxBg.js} +1 -1
- package/dist/ui/assets/{php-CZ7geHZt.js → php-BzAhxF-l.js} +1 -1
- package/dist/ui/assets/{php-template-DiFuW2dF.js → php-template-DkgcKHRc.js} +1 -1
- package/dist/ui/assets/{pieDiagram-ENE6RG2P-BO7AmF5j.js → pieDiagram-ENE6RG2P-Bst7mPyz.js} +1 -1
- package/dist/ui/assets/{plaintext-DcvmOuNc.js → plaintext-BYEppD0R.js} +1 -1
- package/dist/ui/assets/{pony-DGPeAcOc.js → pony-BT_kQd1K.js} +1 -1
- package/dist/ui/assets/{powershell-DsrPyJdK.js → powershell-BfRsuSsf.js} +1 -1
- package/dist/ui/assets/{processing-Co2VRXN1.js → processing-DpzWe5Iu.js} +1 -1
- package/dist/ui/assets/{profile-D4PjpLUf.js → profile-BCOhS5cM.js} +1 -1
- package/dist/ui/assets/{prolog-DEbkeg9r.js → prolog-OxaCCaW8.js} +1 -1
- package/dist/ui/assets/{properties-Cxqcuj1s.js → properties-DMFlA2Ca.js} +1 -1
- package/dist/ui/assets/{protobuf-C-zdlrww.js → protobuf-CRDFkXvZ.js} +1 -1
- package/dist/ui/assets/{puppet-BPX3SrOx.js → puppet-DnrVyLzx.js} +1 -1
- package/dist/ui/assets/{purebasic-BdQnNJS3.js → purebasic-Dht4Hniv.js} +1 -1
- package/dist/ui/assets/{python-D067_Gj8.js → python-B0aMirWu.js} +1 -1
- package/dist/ui/assets/{python-repl-DCqNVlc0.js → python-repl-BlYDBGa7.js} +1 -1
- package/dist/ui/assets/{q-kABXYW-8.js → q-DzrtW9kT.js} +1 -1
- package/dist/ui/assets/{qml-Iao-Whg7.js → qml-DnfQsR3i.js} +1 -1
- package/dist/ui/assets/{quadrantDiagram-ABIIQ3AL-DetQn-0l.js → quadrantDiagram-ABIIQ3AL-DNRYurBT.js} +1 -1
- package/dist/ui/assets/{r-BnwpapnO.js → r-DGI_ZuTD.js} +1 -1
- package/dist/ui/assets/{railroadDiagram-RFXS5EU6-DFaFKHAH.js → railroadDiagram-RFXS5EU6-CmbC3Vz4.js} +1 -1
- package/dist/ui/assets/{reasonml-Cn_Y03uT.js → reasonml-3SohMgh2.js} +1 -1
- package/dist/ui/assets/{requirementDiagram-TGXJPOKE-Dg1LrT-T.js → requirementDiagram-TGXJPOKE-8CxrXHco.js} +1 -1
- package/dist/ui/assets/{rib-ByAqQn0v.js → rib-DfRSd4Qa.js} +1 -1
- package/dist/ui/assets/{roboconf-BJPu6NC5.js → roboconf-CQczGdGW.js} +1 -1
- package/dist/ui/assets/{routeros-CL3Jm0Zq.js → routeros-DCka-T2i.js} +1 -1
- package/dist/ui/assets/{rsl-DaXy7KaD.js → rsl-Dr8MOwMo.js} +1 -1
- package/dist/ui/assets/{ruby-DI6awte_.js → ruby-C2zFSkh_.js} +1 -1
- package/dist/ui/assets/{ruleslanguage-DoTVEZE9.js → ruleslanguage-C97YsgQq.js} +1 -1
- package/dist/ui/assets/{rust-ULEd75wO.js → rust-H3h8kd9A.js} +1 -1
- package/dist/ui/assets/{sankeyDiagram-HTMAVEWB-DQtFl110.js → sankeyDiagram-HTMAVEWB-DBXLWjEq.js} +1 -1
- package/dist/ui/assets/{sas-f7ATFuJk.js → sas-04z0Xu8P.js} +1 -1
- package/dist/ui/assets/{scala-Dha1zro2.js → scala-DyB9Aoiv.js} +1 -1
- package/dist/ui/assets/{scheme-BcaFHKeF.js → scheme-DBj6nxUi.js} +1 -1
- package/dist/ui/assets/{scilab-CIiiyD4z.js → scilab-Btj7AD9s.js} +1 -1
- package/dist/ui/assets/{scss-CkBomL0n.js → scss-BXZJyXt7.js} +1 -1
- package/dist/ui/assets/{sequenceDiagram-DBY2YBRQ-DIbNQtCn.js → sequenceDiagram-DBY2YBRQ-DXIkBFKC.js} +1 -1
- package/dist/ui/assets/{shell-Cxu8Py1z.js → shell-BsreQR1Z.js} +1 -1
- package/dist/ui/assets/{sizeCapture-X5ZJPWSS-Cj7PglQv.js → sizeCapture-X5ZJPWSS-ocS9jxAQ.js} +1 -1
- package/dist/ui/assets/{smali-C4EYyWYz.js → smali-D9wQw9zm.js} +1 -1
- package/dist/ui/assets/{smalltalk-BlPTprP4.js → smalltalk-Dku6G_H3.js} +1 -1
- package/dist/ui/assets/{sml-DEPzhlr4.js → sml-BknyU6ya.js} +1 -1
- package/dist/ui/assets/{sqf-CRu3asu9.js → sqf-DRYMaOg8.js} +1 -1
- package/dist/ui/assets/{sql-DK-YfQqg.js → sql-Cw3Ax4KA.js} +1 -1
- package/dist/ui/assets/{sql_more-BuMEOcjj.js → sql_more-vWdslLE0.js} +1 -1
- package/dist/ui/assets/{stan-DMr13kyD.js → stan-8XH5bDS6.js} +1 -1
- package/dist/ui/assets/{stata-Bt6E2zQi.js → stata-4e77wgfe.js} +1 -1
- package/dist/ui/assets/{stateDiagram-2N3HPSRC-Bk-gF72D.js → stateDiagram-2N3HPSRC-RMmL9jMG.js} +1 -1
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-QvaEO5U6.js +1 -0
- package/dist/ui/assets/{step21-Bi954ur4.js → step21-ByIeDMY3.js} +1 -1
- package/dist/ui/assets/{stylus-CQwwMaLm.js → stylus-ZAhJyWsw.js} +1 -1
- package/dist/ui/assets/{subunit-BkixDEMH.js → subunit-pPW2UGkj.js} +1 -1
- package/dist/ui/assets/{swift-DS1DWNAE.js → swift-CX3BB5az.js} +1 -1
- package/dist/ui/assets/{swimlanes-5IMT3BWC-C-AZKO5z.js → swimlanes-5IMT3BWC-C2zAuJ56.js} +2 -2
- package/dist/ui/assets/swimlanesDiagram-G3AALYLV-DPgCOY0D.js +8 -0
- package/dist/ui/assets/{taggerscript-DZHi1hoc.js → taggerscript-BHcjbWIC.js} +1 -1
- package/dist/ui/assets/{tap-CXxSD8bM.js → tap-BOl1lBlS.js} +1 -1
- package/dist/ui/assets/{tcl-CdoAAMbn.js → tcl-DZjeOBDh.js} +1 -1
- package/dist/ui/assets/{thrift-DM086HVt.js → thrift-BxboWg4x.js} +1 -1
- package/dist/ui/assets/{timeline-definition-FHXFAJF6-DcrcjFwq.js → timeline-definition-FHXFAJF6-BOxsxyq_.js} +1 -1
- package/dist/ui/assets/{tp-Y-w3S3ES.js → tp-BNM6ql3J.js} +1 -1
- package/dist/ui/assets/{twig-C5c_nAus.js → twig-Dj9ZiXD4.js} +1 -1
- package/dist/ui/assets/{typescript-fc7SMhJu.js → typescript-7MEJlu_6.js} +1 -1
- package/dist/ui/assets/{vala-BV-GlwLI.js → vala-DNqOAgHJ.js} +1 -1
- package/dist/ui/assets/{vbnet-BIqQmnKr.js → vbnet-T0mNKVc_.js} +1 -1
- package/dist/ui/assets/{vbscript-h186Lnrz.js → vbscript-CeuwVMAI.js} +1 -1
- package/dist/ui/assets/{vbscript-html-DcuP7lTb.js → vbscript-html-BbJSt2w6.js} +1 -1
- package/dist/ui/assets/{vennDiagram-L72KCM5P-Dnh11y2e.js → vennDiagram-L72KCM5P-BX9mWeiT.js} +1 -1
- package/dist/ui/assets/{verilog-Cbgb_XnR.js → verilog-DYuhYfkX.js} +1 -1
- package/dist/ui/assets/{vhdl-COP7w5IC.js → vhdl-Cf9aT-t7.js} +1 -1
- package/dist/ui/assets/{vim-COGwKzgS.js → vim-DciP44K1.js} +1 -1
- package/dist/ui/assets/{wardleyDiagram-EHGQE667-BeiD8fPz.js → wardleyDiagram-EHGQE667-CDj2rOzu.js} +1 -1
- package/dist/ui/assets/{x86asm-BdBqPPf4.js → x86asm-E-AN_LXO.js} +1 -1
- package/dist/ui/assets/{xl-BmCQT7Vj.js → xl-CxYLJelN.js} +1 -1
- package/dist/ui/assets/{xml-DM0NxGiJ.js → xml-yz1SRLuU.js} +1 -1
- package/dist/ui/assets/{xquery-BUaYHDJM.js → xquery-BLzBF3tV.js} +1 -1
- package/dist/ui/assets/{xychartDiagram-FW5EYKEG-CnwvTrkm.js → xychartDiagram-FW5EYKEG-Czapk9-Z.js} +1 -1
- package/dist/ui/assets/{yaml-DMs8lGDt.js → yaml-Cv4Y7iN_.js} +1 -1
- package/dist/ui/assets/{zephir-BvjoPdmg.js → zephir-KRcdQfEX.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/dist/utils/__tests__/knowledge-store.test.js +86 -5
- package/dist/utils/__tests__/pi-browser-tools.test.d.ts +1 -0
- package/dist/utils/__tests__/pi-browser-tools.test.js +30 -0
- package/dist/utils/__tests__/pi-crawl-tools.test.d.ts +1 -0
- package/dist/utils/__tests__/pi-crawl-tools.test.js +315 -0
- package/dist/utils/__tests__/pi-dedup-reconcile.test.d.ts +1 -0
- package/dist/utils/__tests__/pi-dedup-reconcile.test.js +89 -0
- package/dist/utils/__tests__/pi-dedup.test.d.ts +1 -0
- package/dist/utils/__tests__/pi-dedup.test.js +106 -0
- package/dist/utils/__tests__/pi-learn-orchestrator.test.d.ts +1 -0
- package/dist/utils/__tests__/pi-learn-orchestrator.test.js +885 -0
- package/dist/utils/__tests__/pi-runtime-json.test.d.ts +1 -0
- package/dist/utils/__tests__/pi-runtime-json.test.js +11 -0
- package/dist/utils/__tests__/web-crawler.test.d.ts +1 -0
- package/dist/utils/__tests__/web-crawler.test.js +69 -0
- package/dist/utils/db.d.ts +1 -0
- package/dist/utils/db.js +18 -0
- package/dist/utils/knowledge-store.d.ts +9 -0
- package/dist/utils/knowledge-store.js +85 -11
- package/dist/utils/pi-browser-tools.d.ts +2 -0
- package/dist/utils/pi-browser-tools.js +9 -2
- package/dist/utils/pi-crawl-tools.d.ts +62 -0
- package/dist/utils/pi-crawl-tools.js +298 -0
- package/dist/utils/pi-dedup.d.ts +62 -0
- package/dist/utils/pi-dedup.js +218 -0
- package/dist/utils/pi-learn-orchestrator.d.ts +44 -0
- package/dist/utils/pi-learn-orchestrator.js +431 -0
- package/dist/utils/pi-runtime.d.ts +23 -1
- package/dist/utils/pi-runtime.js +255 -68
- package/dist/utils/request-writer.d.ts +1 -0
- package/dist/utils/request-writer.js +5 -4
- package/dist/utils/web-crawler.d.ts +13 -0
- package/dist/utils/web-crawler.js +64 -0
- package/package.json +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.CHyuB7c8.js +0 -1
- package/dist/ui/assets/channel-BdcV3Ykv.js +0 -1
- package/dist/ui/assets/classDiagram-OUVF2IWQ-CAZR5rAv.js +0 -1
- package/dist/ui/assets/classDiagram-v2-EOCWNBFH-CAZR5rAv.js +0 -1
- package/dist/ui/assets/index-WPLwx8h5.css +0 -10
- package/dist/ui/assets/stateDiagram-v2-6OUMAXLB-BFJCYsLY.js +0 -1
- 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
|
+
});
|
package/dist/utils/db.d.ts
CHANGED
|
@@ -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)
|
|
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
|
-
|
|
119
|
-
|
|
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
|
-
|
|
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
|
-
|
|
146
|
-
|
|
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
|
|
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 {};
|