blun-king-cli 9.0.0 → 9.1.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.
- package/LIESMICH.txt +32 -13
- package/README.md +39 -20
- package/bin/blun.js +248 -160
- package/bin/core-bootstrap.js +47 -0
- package/bin/king.js +277 -1
- package/bin/launcher-mode.js +15 -3
- package/bin/launcher-runtime.js +293 -0
- package/bin/plugin-bootstrap.js +11 -4
- package/bin/private-paths.js +1577 -10
- package/bin/update-lease.js +399 -0
- package/bin/update-notice.js +1245 -0
- package/blun.mjs +26606 -25239
- package/dist-web/assets/{CodeBlockNode-Bsvp6ZEy.js → CodeBlockNode-CXnTLMNr.js} +1 -1
- package/dist-web/assets/{CodeBlockShell.vue_vue_type_style_index_0_lang-ta7hLjia.js → CodeBlockShell.vue_vue_type_style_index_0_lang-CCF8Ntnq.js} +1 -1
- package/dist-web/assets/{DesignSystemView-BmDDe28A.js → DesignSystemView-BbMOu-XO.js} +1 -1
- package/dist-web/assets/{Tooltip-nEEfaYVY.js → Tooltip-CFQEzqC-.js} +1 -1
- package/dist-web/assets/abnfDiagram-N423BO3Z-CsByy-GW.js +1 -0
- package/dist-web/assets/abnfDiagram-N423BO3Z-Z1APZG5m.js +1 -0
- package/dist-web/assets/arc-C-LXCaja.js +1 -0
- package/dist-web/assets/arc-C4VyWloT.js +1 -0
- package/dist-web/assets/architectureDiagram-T3A2C74G-DZq4L18e.js +36 -0
- package/dist-web/assets/architectureDiagram-T3A2C74G-DpddbUcM.js +36 -0
- package/dist-web/assets/blockDiagram-VBNYF7ZC-BV4sIf98.js +132 -0
- package/dist-web/assets/blockDiagram-VBNYF7ZC-BqccOSMr.js +132 -0
- package/dist-web/assets/{c4Diagram-AAUBKEIU-DtzacMnD.js → c4Diagram-5PPSVZJV-0MRkZlgP.js} +1 -1
- package/dist-web/assets/{c4Diagram-AAUBKEIU-D1VdMx8d.js → c4Diagram-5PPSVZJV-OHAcJrTy.js} +1 -1
- package/dist-web/assets/channel-B2VOQOI-.js +1 -0
- package/dist-web/assets/channel-DKjwM05G.js +1 -0
- package/dist-web/assets/{chunk-ND2GUHAM-DJoY9wNJ.js → chunk-2GRJ4B5K-DqJHs8Fw.js} +1 -1
- package/dist-web/assets/{chunk-ND2GUHAM-C4-rwdcv.js → chunk-2GRJ4B5K-oO6nqeLA.js} +1 -1
- package/dist-web/assets/{chunk-QZHKN3VN-C7YGaShq.js → chunk-2Q5K7J3B-B1nCd91o.js} +1 -1
- package/dist-web/assets/{chunk-QZHKN3VN-_Rz9_NuS.js → chunk-2Q5K7J3B-BC0Hsfqy.js} +1 -1
- package/dist-web/assets/chunk-5RXB4S5H-BfZa4yDH.js +231 -0
- package/dist-web/assets/chunk-5RXB4S5H-neG70kZx.js +231 -0
- package/dist-web/assets/{chunk-FMBD7UC4-DlLNDUx6.js → chunk-5VM5RSS4-l7biGqeH.js} +1 -1
- package/dist-web/assets/{chunk-FMBD7UC4-B2zs_Y-d.js → chunk-5VM5RSS4-u00AcpiJ.js} +1 -1
- package/dist-web/assets/chunk-6Q2QTUOP-BO-F11Gs.js +88 -0
- package/dist-web/assets/chunk-6Q2QTUOP-RUVRPBzG.js +88 -0
- package/dist-web/assets/{chunk-727SXJPM-Dn5wkDO_.js → chunk-GF5L2VYU-Ba-86KTd.js} +5 -5
- package/dist-web/assets/{chunk-727SXJPM-Dk2Xa3bA.js → chunk-GF5L2VYU-BtC69fw0.js} +5 -5
- package/dist-web/assets/{chunk-4BX2VUAB-DxZViaHS.js → chunk-JWPE2WC7-DIOubEqr.js} +1 -1
- package/dist-web/assets/{chunk-4BX2VUAB-WqrE2gaw.js → chunk-JWPE2WC7-u8Pcfhwh.js} +1 -1
- package/dist-web/assets/{chunk-2J33WTMH-Dm_s0_4f.js → chunk-KBJHAD2P-DDUeH_Ba.js} +1 -1
- package/dist-web/assets/{chunk-2J33WTMH-w4sdiKFO.js → chunk-KBJHAD2P-DS3BL64y.js} +1 -1
- package/dist-web/assets/chunk-RYQCIY6F-B9gFMVbS.js +1 -0
- package/dist-web/assets/chunk-RYQCIY6F-xg3EO0le.js +1 -0
- package/dist-web/assets/{chunk-55IACEB6-B5dE1-Um.js → chunk-XXDRQBXY-B60H0rRC.js} +1 -1
- package/dist-web/assets/{chunk-55IACEB6-B12zGIFz.js → chunk-XXDRQBXY-Bn1Xz6TQ.js} +1 -1
- package/dist-web/assets/classDiagram-JCYQIIEL-BA1TjAxj.js +1 -0
- package/dist-web/assets/classDiagram-JCYQIIEL-BNU7Qn4k.js +1 -0
- package/dist-web/assets/classDiagram-v2-OCEON4UE-BA1TjAxj.js +1 -0
- package/dist-web/assets/classDiagram-v2-OCEON4UE-BNU7Qn4k.js +1 -0
- package/dist-web/assets/{cose-bilkent-S5V4N54A-Bi19n8m-.js → cose-bilkent-JH36ORCC-4Ybddg08.js} +1 -1
- package/dist-web/assets/{cose-bilkent-S5V4N54A-c8o8NFp5.js → cose-bilkent-JH36ORCC-DqigO3T4.js} +1 -1
- package/dist-web/assets/cynefin-VYW2F7L2-C-EfYT07.js +178 -0
- package/dist-web/assets/cynefin-VYW2F7L2-rpD93tQ-.js +178 -0
- package/dist-web/assets/cynefinDiagram-MW4NZA55-DWZPLJcD.js +62 -0
- package/dist-web/assets/cynefinDiagram-MW4NZA55-DbTqnkVJ.js +62 -0
- package/dist-web/assets/dagre-VZM6K2ZE-DcM8aEVY.js +4 -0
- package/dist-web/assets/dagre-VZM6K2ZE-M_HVNtqP.js +4 -0
- package/dist-web/assets/diagram-7IWD3JNH-DoNximNF.js +30 -0
- package/dist-web/assets/diagram-7IWD3JNH-UymgsBNa.js +30 -0
- package/dist-web/assets/{diagram-KO2AKTUF-CFQs13i5.js → diagram-B4RE2ZJO-BVA2EhnC.js} +3 -3
- package/dist-web/assets/{diagram-KO2AKTUF-agFIuPJW.js → diagram-B4RE2ZJO-BiYu5WPF.js} +3 -3
- package/dist-web/assets/{diagram-LMA3HP47-TMIXizxR.js → diagram-LBJQPF4R-BD3kkgOO.js} +2 -2
- package/dist-web/assets/{diagram-LMA3HP47-He5zlyMt.js → diagram-LBJQPF4R-m3a1Euj3.js} +2 -2
- package/dist-web/assets/diagram-Q27KOJAE-D1mYQ_cI.js +24 -0
- package/dist-web/assets/diagram-Q27KOJAE-hy_T73PK.js +24 -0
- package/dist-web/assets/diagram-UB23O5K3-BWkoQZ4A.js +41 -0
- package/dist-web/assets/diagram-UB23O5K3-BtX8u6HG.js +41 -0
- package/dist-web/assets/ebnfDiagram-BXEA7PRR-BKs9JUHW.js +1 -0
- package/dist-web/assets/ebnfDiagram-BXEA7PRR-CBAnFkRF.js +1 -0
- package/dist-web/assets/erDiagram-JOGREHBK-3vKcWsxm.js +85 -0
- package/dist-web/assets/erDiagram-JOGREHBK-BIpd6dTf.js +85 -0
- package/dist-web/assets/flowDiagram-UKHOOZJN-D9wBbHm2.js +156 -0
- package/dist-web/assets/flowDiagram-UKHOOZJN-Z83i2UWI.js +156 -0
- package/dist-web/assets/ganttDiagram-PKOTCBZU-Cd_dViF-.js +292 -0
- package/dist-web/assets/ganttDiagram-PKOTCBZU-DFrb_S1d.js +292 -0
- package/dist-web/assets/{gitGraphDiagram-PVQCEYII-BSDFfwdY.js → gitGraphDiagram-DS77QQ5N-BiEEtTo7.js} +3 -3
- package/dist-web/assets/{gitGraphDiagram-PVQCEYII-DMbTATyw.js → gitGraphDiagram-DS77QQ5N-Dp3Ar-hi.js} +3 -3
- package/dist-web/assets/{graph-BwjfAU3j.js → graph-CAUpWmoK.js} +1 -1
- package/dist-web/assets/{graph--OzhPTMs.js → graph-DOmOIIwC.js} +1 -1
- package/dist-web/assets/{index-W6VnSrkB.js → index-Ba1OvLjf.js} +2 -2
- package/dist-web/assets/{index-CkVgGDpx.js → index-CiPA8Kex.js} +4 -4
- package/dist-web/assets/{index-BzK4vJBu.js → index-DdEakFJM.js} +1 -1
- package/dist-web/assets/{index10-Czg_oF-W.js → index10-CNr4U-Nw.js} +1 -1
- package/dist-web/assets/{index11-BjzCZuCr.js → index11-Dto_yZNz.js} +1 -1
- package/dist-web/assets/{index5-DlVoNkCD.js → index5-B2PldaO2.js} +1 -1
- package/dist-web/assets/{index6-BxiXA2yo.js → index6-CBdZmmyx.js} +1 -1
- package/dist-web/assets/{index7-BPdza6d1.js → index7-Dz9oCsUF.js} +1 -1
- package/dist-web/assets/{index8-Q_XzGC1Z.js → index8-B6k25jtU.js} +2 -2
- package/dist-web/assets/{infoDiagram-5YYISTIA-2JF3XEdD.js → infoDiagram-6WML65LV-BSa2g04G.js} +1 -1
- package/dist-web/assets/{infoDiagram-5YYISTIA-UrQusrJq.js → infoDiagram-6WML65LV-D4ph2sIH.js} +1 -1
- package/dist-web/assets/{ishikawaDiagram-YF4QCWOH-7RVUL-vB.js → ishikawaDiagram-WSZJBQD7-DjKjbMm9.js} +5 -5
- package/dist-web/assets/{ishikawaDiagram-YF4QCWOH-C5OstRVV.js → ishikawaDiagram-WSZJBQD7-Hm36UOQe.js} +5 -5
- package/dist-web/assets/{journeyDiagram-JHISSGLW-B34fCMu9.js → journeyDiagram-NVQOT4AX-DttHDfPQ.js} +1 -1
- package/dist-web/assets/{journeyDiagram-JHISSGLW-yctdo4bX.js → journeyDiagram-NVQOT4AX-MvWWPNDV.js} +1 -1
- package/dist-web/assets/{kanban-definition-UN3LZRKU-BS4FBZsQ.js → kanban-definition-27J2QSJJ-C5gB-W0d.js} +7 -7
- package/dist-web/assets/{kanban-definition-UN3LZRKU-CxBCv27E.js → kanban-definition-27J2QSJJ-Cu-E_cXA.js} +5 -5
- package/dist-web/assets/layout-CvP6o9AK.js +1 -0
- package/dist-web/assets/layout-D-LzfAck.js +1 -0
- package/dist-web/assets/{linear-3mB6q2-g.js → linear-B3HWgQI2.js} +1 -1
- package/dist-web/assets/{linear-BKCnUo31.js → linear-BRGe4-d6.js} +1 -1
- package/dist-web/assets/map-CWKZqZjr.js +1 -0
- package/dist-web/assets/map-DxJ2ADlA.js +1 -0
- package/dist-web/assets/mermaid.core-D-9Sx1No.js +314 -0
- package/dist-web/assets/mermaidParser.worker-PTFfzpoB.js +318 -0
- package/dist-web/assets/{mindmap-definition-RKZ34NQL-BmJZpjh6.js → mindmap-definition-FAOFIHXS-C4vnms3i.js} +2 -2
- package/dist-web/assets/{mindmap-definition-RKZ34NQL-1mjWUcf6.js → mindmap-definition-FAOFIHXS-Cg_hoVIq.js} +1 -1
- package/dist-web/assets/pegDiagram-VL7TDLO6-B2fFEFUH.js +1 -0
- package/dist-web/assets/pegDiagram-VL7TDLO6-CSX9hitD.js +1 -0
- package/dist-web/assets/pieDiagram-7S7Q4E2Y-0L0mxahZ.js +39 -0
- package/dist-web/assets/pieDiagram-7S7Q4E2Y-C7T0Cmw1.js +39 -0
- package/dist-web/assets/{quadrantDiagram-W4KKPZXB-BmT_qM09.js → quadrantDiagram-CIZ2JOQS-BBy7w4kD.js} +3 -3
- package/dist-web/assets/{quadrantDiagram-W4KKPZXB-C0kPuyNP.js → quadrantDiagram-CIZ2JOQS-U483z0er.js} +3 -3
- package/dist-web/assets/railroadDiagram-AXF67PYL-D80a2_DJ.js +1 -0
- package/dist-web/assets/railroadDiagram-AXF67PYL-DX8y0MzW.js +1 -0
- package/dist-web/assets/{requirementDiagram-4Y6WPE33-C0YP_Amt.js → requirementDiagram-LRYGKXZP-CeyHfq8t.js} +3 -3
- package/dist-web/assets/{requirementDiagram-4Y6WPE33-CZrxH1Y2.js → requirementDiagram-LRYGKXZP-DGD5J_4k.js} +3 -3
- package/dist-web/assets/sankeyDiagram-W5VNT64P-CCISkkrR.js +40 -0
- package/dist-web/assets/sankeyDiagram-W5VNT64P-CT5PdZz2.js +40 -0
- package/dist-web/assets/sequenceDiagram-SI44F4Z6-BeMzHWXI.js +162 -0
- package/dist-web/assets/sequenceDiagram-SI44F4Z6-jQfm2XS7.js +162 -0
- package/dist-web/assets/sizeCapture-X5ZJPWSS-BQsTdtrv.js +1 -0
- package/dist-web/assets/sizeCapture-X5ZJPWSS-lRZsmCoS.js +1 -0
- package/dist-web/assets/stateDiagram-OKZ733FA-ClCgTdUm.js +1 -0
- package/dist-web/assets/stateDiagram-OKZ733FA-Cv59z5YT.js +1 -0
- package/dist-web/assets/stateDiagram-v2-UEYNNEHI-R8jTc--F.js +1 -0
- package/dist-web/assets/stateDiagram-v2-UEYNNEHI-fi_lrTAx.js +1 -0
- package/dist-web/assets/swimlanes-SLNWSIFB-BCdOUN05.js +2 -0
- package/dist-web/assets/swimlanes-SLNWSIFB-Cu5l7SuR.js +1 -0
- package/dist-web/assets/swimlanesDiagram-ULZ7WXOC-BUd_uYK3.js +8 -0
- package/dist-web/assets/swimlanesDiagram-ULZ7WXOC-CalrsgPK.js +8 -0
- package/dist-web/assets/{timeline-definition-PNZ67QCA-DsVZdrZa.js → timeline-definition-Z64GVDOM-CMjnh4bu.js} +4 -4
- package/dist-web/assets/{timeline-definition-PNZ67QCA-DnB6Usl0.js → timeline-definition-Z64GVDOM-DpWutSKa.js} +4 -4
- package/dist-web/assets/vennDiagram-T6HMQDX7-DKJW_8oU.js +34 -0
- package/dist-web/assets/vennDiagram-T6HMQDX7-DVC5JVsc.js +34 -0
- package/dist-web/assets/{vue.runtime.esm-bundler-pgHGheCW.js → vue.runtime.esm-bundler-BwwRtQwQ.js} +1 -1
- package/dist-web/assets/{wardleyDiagram-YWT4CUSO-oBauTCEw.js → wardleyDiagram-T6FBY63Y-BK2mrq7L.js} +3 -3
- package/dist-web/assets/{wardleyDiagram-YWT4CUSO-DCiyDQNB.js → wardleyDiagram-T6FBY63Y-oUvgepFn.js} +3 -3
- package/dist-web/assets/xychartDiagram-ELKLHX3M-DI6n79q0.js +7 -0
- package/dist-web/assets/xychartDiagram-ELKLHX3M-DUJu9F7-.js +7 -0
- package/dist-web/index.html +1 -1
- package/dist-web/vis/index.html.gz +0 -0
- package/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/package.json +9 -11
- package/skills/screenshot-lesen/SKILL.md +0 -1
- package/skills/web-lesen/SKILL.md +0 -1
- package/telegram-plugin/dist/bridge.mjs +7 -25
- package/telegram-plugin/dist/mcp-server.mjs +236 -71
- package/dist-web/assets/arc-4xPfymbf.js +0 -1
- package/dist-web/assets/arc-Doj0wRZ0.js +0 -1
- package/dist-web/assets/architectureDiagram-3BPJPVTR-BGih283a.js +0 -36
- package/dist-web/assets/architectureDiagram-3BPJPVTR-CQ09RrbH.js +0 -36
- package/dist-web/assets/blockDiagram-GPEHLZMM-3ShMf1gu.js +0 -132
- package/dist-web/assets/blockDiagram-GPEHLZMM-CAtDjkJt.js +0 -132
- package/dist-web/assets/channel-DNkUo9e6.js +0 -1
- package/dist-web/assets/channel-DcnUTIGB.js +0 -1
- package/dist-web/assets/chunk-AQP2D5EJ-FS8-f8lF.js +0 -231
- package/dist-web/assets/chunk-AQP2D5EJ-UKhb4V4r.js +0 -231
- package/dist-web/assets/classDiagram-4FO5ZUOK-B1ZO8EbE.js +0 -1
- package/dist-web/assets/classDiagram-4FO5ZUOK-xk6cM9Kq.js +0 -1
- package/dist-web/assets/classDiagram-v2-Q7XG4LA2-B1ZO8EbE.js +0 -1
- package/dist-web/assets/classDiagram-v2-Q7XG4LA2-xk6cM9Kq.js +0 -1
- package/dist-web/assets/dagre-BM42HDAG-CmUO9qKN.js +0 -4
- package/dist-web/assets/dagre-BM42HDAG-DLMfLCoV.js +0 -4
- package/dist-web/assets/diagram-2AECGRRQ-DQTst0OH.js +0 -43
- package/dist-web/assets/diagram-2AECGRRQ-L74iLMqd.js +0 -43
- package/dist-web/assets/diagram-5GNKFQAL-BiBm7CJR.js +0 -10
- package/dist-web/assets/diagram-5GNKFQAL-DoE6q7H1.js +0 -10
- package/dist-web/assets/diagram-OG6HWLK6-BHCt1E0n.js +0 -24
- package/dist-web/assets/diagram-OG6HWLK6-DRyxjFMa.js +0 -24
- package/dist-web/assets/erDiagram-TEJ5UH35-BoDczjGG.js +0 -85
- package/dist-web/assets/erDiagram-TEJ5UH35-yd6SOv_7.js +0 -85
- package/dist-web/assets/flowDiagram-I6XJVG4X-DHoceI7r.js +0 -162
- package/dist-web/assets/flowDiagram-I6XJVG4X-DkYNQv0R.js +0 -162
- package/dist-web/assets/ganttDiagram-6RSMTGT7-Cg1TQBc0.js +0 -292
- package/dist-web/assets/ganttDiagram-6RSMTGT7-Z6klo7KK.js +0 -292
- package/dist-web/assets/layout-C1ojF0zw.js +0 -1
- package/dist-web/assets/layout-SsrduOYp.js +0 -1
- package/dist-web/assets/mermaid.core-D_lKT0dR.js +0 -309
- package/dist-web/assets/mermaidParser.worker-Dx4jPi9z.js +0 -313
- package/dist-web/assets/pieDiagram-4H26LBE5-BU41t2A_.js +0 -30
- package/dist-web/assets/pieDiagram-4H26LBE5-BkwDAvbt.js +0 -30
- package/dist-web/assets/sankeyDiagram-5OEKKPKP-De_o7hDr.js +0 -40
- package/dist-web/assets/sankeyDiagram-5OEKKPKP-Dvuj6bMA.js +0 -40
- package/dist-web/assets/sequenceDiagram-3UESZ5HK-DuCrgPyA.js +0 -162
- package/dist-web/assets/sequenceDiagram-3UESZ5HK-VAxffBe7.js +0 -162
- package/dist-web/assets/stateDiagram-AJRCARHV-CYLupxM7.js +0 -1
- package/dist-web/assets/stateDiagram-AJRCARHV-nDExQydZ.js +0 -1
- package/dist-web/assets/stateDiagram-v2-BHNVJYJU-BhEc7Thx.js +0 -1
- package/dist-web/assets/stateDiagram-v2-BHNVJYJU-BzwD_BIl.js +0 -1
- package/dist-web/assets/vennDiagram-CIIHVFJN-BBHQmCFf.js +0 -34
- package/dist-web/assets/vennDiagram-CIIHVFJN-Cfj-K9NW.js +0 -34
- package/dist-web/assets/wardley-L42UT6IY-BJFn8eDD.js +0 -173
- package/dist-web/assets/wardley-L42UT6IY-BSu8-4hg.js +0 -173
- package/dist-web/assets/xychartDiagram-2RQKCTM6-C2iZpl9I.js +0 -7
- package/dist-web/assets/xychartDiagram-2RQKCTM6-Db_VoDBV.js +0 -7
- package/mnemo/access_routes.js +0 -692
- package/mnemo/agent_governance.js +0 -4242
- package/mnemo/agent_mail.js +0 -901
- package/mnemo/bootstrap_auto.js +0 -137
- package/mnemo/brief_coordination.js +0 -226
- package/mnemo/code_read_tools.js +0 -375
- package/mnemo/context_preview_tools.js +0 -603
- package/mnemo/embeddings.js +0 -66
- package/mnemo/external_repo_ops.js +0 -575
- package/mnemo/facts/example-project-rules.json +0 -90
- package/mnemo/facts/example.json +0 -34
- package/mnemo/identity_schema.sql +0 -139
- package/mnemo/journal_schema.js +0 -561
- package/mnemo/loop_doctor_tools.js +0 -661
- package/mnemo/mail_secret_refs.js +0 -150
- package/mnemo/mcp.js +0 -9309
- package/mnemo/memory_consolidation.js +0 -1914
- package/mnemo/memory_health_tools.js +0 -165
- package/mnemo/package.json +0 -79
- package/mnemo/protected_scope_gate.js +0 -627
- package/mnemo/resource_access_control.js +0 -684
- package/mnemo/runtime_governance.js +0 -1256
- package/mnemo/runtime_turn_gate.js +0 -862
- package/mnemo/sandbox.js +0 -143
- package/mnemo/schema.sql +0 -389
- package/mnemo/shared_utils.js +0 -763
- package/mnemo/skills/agent-auto-resume/SKILL.md +0 -56
- package/mnemo/skills/agent_hand/SKILL.md +0 -43
- package/mnemo/skills/agent_hand/run.js +0 -63
- package/mnemo/skills/book_flight/SKILL.md +0 -34
- package/mnemo/skills/external_repo_review/SKILL.md +0 -43
- package/mnemo/skills/external_repo_review/run.js +0 -73
- package/mnemo/skills/pay_invoice/SKILL.md +0 -34
- package/mnemo/team_quality_ops.js +0 -944
- package/mnemo/timeline_report_tools.js +0 -810
- package/mnemo/write_gate_risk.js +0 -80
- package/mnemo/writer_health.js +0 -152
- package/skills/doku-ingestion/SKILL.md +0 -48
- package/skills/doku-ingestion/ingest_docs.py +0 -133
package/mnemo/write_gate_risk.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const PRODUCTION_RE = /\b(production|prod|live|deploy|pm2|nginx|dns|ssl|cert|rollback)\b/;
|
|
4
|
-
const BILLING_RE = /\b(stripe|billing|invoice|pricing|checkout|refund|vat|vies|oss|subscription|plan)\b/;
|
|
5
|
-
const AUTH_RE = /\b(auth|login|signup|signin|sign-in|sso|session|cookie|oauth|password|reset|forgot|verify|onboarding|account)\b/;
|
|
6
|
-
const WRITE_RE = /\b(edit|change|fix|implement|update|deploy|restart|migrate|patch|write|remove|delete|rename|refactor|create|build|rollout)\b/;
|
|
7
|
-
|
|
8
|
-
const RISK_TERMS =
|
|
9
|
-
"(?:production|prod|live|deploy|deployment|pm2|nginx|dns|ssl|cert|rollback|" +
|
|
10
|
-
"auth|login|signup|signin|sign-in|sso|session|cookie|oauth|password|reset|forgot|verify|onboarding|account|" +
|
|
11
|
-
"stripe|billing|invoice|pricing|checkout|refund|vat|vies|oss|subscription|plan|" +
|
|
12
|
-
"server|servers|env|secret|secrets|source|app|apps)";
|
|
13
|
-
|
|
14
|
-
const NEGATED_LIST_RE = new RegExp(
|
|
15
|
-
"\\b(?:no|without|never|keine|kein|keinen|ohne)\\s+" +
|
|
16
|
-
"(?:" + RISK_TERMS + "(?:\\s*(?:/|,|;|\\+|&|\\band\\b|\\bor\\b|\\bund\\b|\\boder\\b|\\s)\\s*)?){1,16}" +
|
|
17
|
-
"(?:\\s+(?:work|edits?|writes?|changes?|scope|paths?|files?|activity|actions?))?",
|
|
18
|
-
"gi"
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
const DO_NOT_TOUCH_RE = new RegExp(
|
|
22
|
-
"\\b(?:do\\s+not|don't|dont|never|nicht)\\s+" +
|
|
23
|
-
"(?:touch|edit|change|write|deploy|modify|manage|alter)\\s+" +
|
|
24
|
-
"[^.;\\n]{0,100}\\b" + RISK_TERMS + "\\b[^.;\\n]{0,80}",
|
|
25
|
-
"gi"
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
const ORPHAN_NEGATED_TAIL_RE = new RegExp(
|
|
29
|
-
"\\b(?:or|and|oder|und)\\s+" + RISK_TERMS +
|
|
30
|
-
"(?:\\s+(?:work|edits?|writes?|changes?|scope|paths?|files?|activity|actions?))?",
|
|
31
|
-
"gi"
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
function riskScanText(text) {
|
|
35
|
-
let removedNegatedRisk = false;
|
|
36
|
-
let out = String(text || "")
|
|
37
|
-
.replace(NEGATED_LIST_RE, () => {
|
|
38
|
-
removedNegatedRisk = true;
|
|
39
|
-
return " ";
|
|
40
|
-
})
|
|
41
|
-
.replace(DO_NOT_TOUCH_RE, () => {
|
|
42
|
-
removedNegatedRisk = true;
|
|
43
|
-
return " ";
|
|
44
|
-
});
|
|
45
|
-
if (removedNegatedRisk) out = out.replace(ORPHAN_NEGATED_TAIL_RE, " ");
|
|
46
|
-
return out;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function classifyActionRisk(input = {}) {
|
|
50
|
-
const text = [
|
|
51
|
-
input.project,
|
|
52
|
-
input.task,
|
|
53
|
-
input.summary,
|
|
54
|
-
input.action_type,
|
|
55
|
-
Array.isArray(input.topics) ? input.topics.join(" ") : "",
|
|
56
|
-
Array.isArray(input.files) ? input.files.join(" ") : "",
|
|
57
|
-
Array.isArray(input.system_names) ? input.system_names.join(" ") : ""
|
|
58
|
-
].filter(Boolean).join(" ");
|
|
59
|
-
const normalized = riskScanText(text).toLowerCase();
|
|
60
|
-
const rawActionType = String(input.action_type || "").toLowerCase();
|
|
61
|
-
const touchesProduction = PRODUCTION_RE.test(normalized) || /\bdeploy\b/.test(rawActionType);
|
|
62
|
-
const touchesBilling = BILLING_RE.test(normalized);
|
|
63
|
-
const touchesAuth = AUTH_RE.test(normalized);
|
|
64
|
-
const writeIntent = WRITE_RE.test(normalized) || WRITE_RE.test(rawActionType);
|
|
65
|
-
const environment = input.environment || (touchesProduction ? "production" : "staging");
|
|
66
|
-
return {
|
|
67
|
-
text,
|
|
68
|
-
scan_text: normalized,
|
|
69
|
-
write_intent: writeIntent,
|
|
70
|
-
touches_production: touchesProduction,
|
|
71
|
-
touches_billing: touchesBilling,
|
|
72
|
-
touches_auth: touchesAuth,
|
|
73
|
-
environment,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
module.exports = {
|
|
78
|
-
classifyActionRisk,
|
|
79
|
-
riskScanText,
|
|
80
|
-
};
|
package/mnemo/writer_health.js
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const DEFAULT_REQUIRED_FRESH_WRITERS = [];
|
|
4
|
-
const DEFAULT_STALE_MS = 2 * 60 * 60 * 1000;
|
|
5
|
-
const DEFAULT_DEAD_MS = 24 * 60 * 60 * 1000;
|
|
6
|
-
|
|
7
|
-
const HEALTHY_STATUSES = new Set([
|
|
8
|
-
"alive",
|
|
9
|
-
"alive_no_new",
|
|
10
|
-
"ok",
|
|
11
|
-
"healthy",
|
|
12
|
-
"success",
|
|
13
|
-
"idle",
|
|
14
|
-
]);
|
|
15
|
-
|
|
16
|
-
function normalizeStatus(status) {
|
|
17
|
-
return String(status || "").trim().toLowerCase();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function parseList(value, fallback) {
|
|
21
|
-
const raw = value == null || value === "" ? fallback : value;
|
|
22
|
-
const list = Array.isArray(raw) ? raw : String(raw || "").split(",");
|
|
23
|
-
return list.map((item) => String(item || "").trim()).filter(Boolean);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function requiredFreshWriterSet(options = {}) {
|
|
27
|
-
return new Set(parseList(
|
|
28
|
-
options.requiredFreshWriters ||
|
|
29
|
-
process.env.MNEMO_WRITER_HEALTH_REQUIRED ||
|
|
30
|
-
process.env.MNEMO_HOOK_WATCHDOG_CRITICAL_WRITERS,
|
|
31
|
-
DEFAULT_REQUIRED_FRESH_WRITERS
|
|
32
|
-
));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function writerStatusClass(status) {
|
|
36
|
-
const s = normalizeStatus(status);
|
|
37
|
-
if (!s) return "unknown";
|
|
38
|
-
if (s === "stale") return "stale";
|
|
39
|
-
if (s === "dead") return "dead";
|
|
40
|
-
if (s.startsWith("disabled")) return "disabled";
|
|
41
|
-
if (s.startsWith("error") || s.includes("database is locked") || s.includes("sqlite_corrupt")) return "error";
|
|
42
|
-
if (s.startsWith("blocked")) return "blocked";
|
|
43
|
-
if (s.startsWith("partial")) return "degraded";
|
|
44
|
-
if (HEALTHY_STATUSES.has(s)) return "healthy";
|
|
45
|
-
return "unknown";
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function ageMs(iso, nowMs) {
|
|
49
|
-
const t = iso ? Date.parse(iso) : 0;
|
|
50
|
-
if (!t) return null;
|
|
51
|
-
return Math.max(0, nowMs - t);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function freshnessFromAge(age, staleMs, deadMs, required) {
|
|
55
|
-
if (age == null) return required ? "missing" : "not_required";
|
|
56
|
-
if (age > deadMs) return required ? "critical" : "idle";
|
|
57
|
-
if (age > staleMs) return required ? "stale" : "idle";
|
|
58
|
-
return "fresh";
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function assessWriterHealth(row = {}, options = {}) {
|
|
62
|
-
const writer = String(row.writer || "");
|
|
63
|
-
const status = normalizeStatus(row.status);
|
|
64
|
-
const statusClass = writerStatusClass(status);
|
|
65
|
-
const nowMs = options.nowMs || Date.now();
|
|
66
|
-
const staleMs = Number(options.staleMs || DEFAULT_STALE_MS);
|
|
67
|
-
const deadMs = Number(options.deadMs || DEFAULT_DEAD_MS);
|
|
68
|
-
const lastWriteAgeMs = ageMs(row.last_write_at, nowMs);
|
|
69
|
-
const lastCheckAgeMs = ageMs(row.last_check_at, nowMs);
|
|
70
|
-
const freshnessRequired = requiredFreshWriterSet(options).has(writer);
|
|
71
|
-
const freshness = freshnessFromAge(lastWriteAgeMs, staleMs, deadMs, freshnessRequired);
|
|
72
|
-
|
|
73
|
-
let healthy = true;
|
|
74
|
-
let reason = "writer is informational or event-driven";
|
|
75
|
-
let nextStatus = status || "idle";
|
|
76
|
-
let drift = false;
|
|
77
|
-
let driftSeverity = "M";
|
|
78
|
-
|
|
79
|
-
if (statusClass === "disabled") {
|
|
80
|
-
reason = `writer disabled (${status})`;
|
|
81
|
-
nextStatus = status;
|
|
82
|
-
} else if (["error", "blocked", "degraded"].includes(statusClass)) {
|
|
83
|
-
healthy = false;
|
|
84
|
-
drift = true;
|
|
85
|
-
driftSeverity = statusClass === "degraded" ? "M" : "H";
|
|
86
|
-
reason = `writer status is ${status}`;
|
|
87
|
-
nextStatus = status;
|
|
88
|
-
} else if (freshnessRequired) {
|
|
89
|
-
if (lastWriteAgeMs == null) {
|
|
90
|
-
healthy = false;
|
|
91
|
-
drift = true;
|
|
92
|
-
driftSeverity = "H";
|
|
93
|
-
reason = "required writer has never written";
|
|
94
|
-
nextStatus = "missing";
|
|
95
|
-
} else if (lastWriteAgeMs > deadMs) {
|
|
96
|
-
healthy = false;
|
|
97
|
-
drift = true;
|
|
98
|
-
driftSeverity = "H";
|
|
99
|
-
reason = "required writer has not written within dead threshold";
|
|
100
|
-
nextStatus = "dead";
|
|
101
|
-
} else if (lastWriteAgeMs > staleMs) {
|
|
102
|
-
healthy = false;
|
|
103
|
-
drift = true;
|
|
104
|
-
driftSeverity = "M";
|
|
105
|
-
reason = "required writer has not written within stale threshold";
|
|
106
|
-
nextStatus = "stale";
|
|
107
|
-
} else {
|
|
108
|
-
reason = "required writer is fresh";
|
|
109
|
-
nextStatus = "alive";
|
|
110
|
-
}
|
|
111
|
-
} else if (lastWriteAgeMs != null && lastWriteAgeMs <= staleMs && statusClass !== "unknown") {
|
|
112
|
-
reason = "writer wrote recently";
|
|
113
|
-
nextStatus = HEALTHY_STATUSES.has(status) ? status : "alive";
|
|
114
|
-
} else {
|
|
115
|
-
reason = "writer is not freshness-gated";
|
|
116
|
-
nextStatus = statusClass === "stale" || statusClass === "dead" || !status ? "idle" : status;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
writer,
|
|
121
|
-
status,
|
|
122
|
-
status_class: statusClass,
|
|
123
|
-
freshness_required: freshnessRequired,
|
|
124
|
-
freshness,
|
|
125
|
-
healthy,
|
|
126
|
-
drift,
|
|
127
|
-
drift_severity: driftSeverity,
|
|
128
|
-
health_reason: reason,
|
|
129
|
-
next_status: nextStatus,
|
|
130
|
-
last_write_age_ms: lastWriteAgeMs,
|
|
131
|
-
last_write_age_min: lastWriteAgeMs == null ? null : Math.round(lastWriteAgeMs / 60000),
|
|
132
|
-
last_check_age_ms: lastCheckAgeMs,
|
|
133
|
-
last_check_age_min: lastCheckAgeMs == null ? null : Math.round(lastCheckAgeMs / 60000),
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function enrichWriterHealth(row, options = {}) {
|
|
138
|
-
return Object.assign({}, row, assessWriterHealth(row, options));
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function enrichWriterHealthRows(rows, options = {}) {
|
|
142
|
-
return (rows || []).map((row) => enrichWriterHealth(row, options));
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
module.exports = {
|
|
146
|
-
DEFAULT_REQUIRED_FRESH_WRITERS,
|
|
147
|
-
assessWriterHealth,
|
|
148
|
-
enrichWriterHealth,
|
|
149
|
-
enrichWriterHealthRows,
|
|
150
|
-
requiredFreshWriterSet,
|
|
151
|
-
writerStatusClass,
|
|
152
|
-
};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: doku-ingestion
|
|
3
|
-
description: "Eine API-/Software-Dokumentation dauerhaft ins eigene Gedaechtnis aufnehmen: crawlen, in sinnvolle Abschnitte zerlegen und in Mnemo speichern, damit Endpunkte, Parameter und Code-Beispiele spaeter zuverlaessig zitierbar sind. Mandatory triggers: 'lern die API-Doku von X', 'nimm die Doku auf', 'merk dir die Dokumentation', 'ingest docs', 'speichere die Doku dauerhaft', eine Doku-URL mit der Bitte, sie zu behalten. Fuer einmaliges Lesen ohne Speichern reicht der web-lesen-Skill."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Doku-Ingestion
|
|
7
|
-
|
|
8
|
-
Der Unterschied zu web-lesen: hier wird die Doku nicht nur EINMAL gelesen,
|
|
9
|
-
sondern DAUERHAFT ins Gedaechtnis aufgenommen — in zitierbaren Abschnitten,
|
|
10
|
-
sodass du spaeter „welche Parameter hat Endpunkt X?" beantworten kannst, ohne
|
|
11
|
-
die Seite erneut zu laden.
|
|
12
|
-
|
|
13
|
-
## Ablauf
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
python ingest_docs.py "<DOKU-URL>" --source <kurzname>
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Das Skript (liegt neben dieser Datei):
|
|
20
|
-
1. Crawlt die Seite mit Crawl4AI zu sauberem Markdown.
|
|
21
|
-
2. Zerlegt sie an Ueberschriften in Abschnitte (grosse weiter an Absaetzen,
|
|
22
|
-
~1800 Zeichen pro Stueck — ein Endpunkt/Thema pro Abschnitt).
|
|
23
|
-
3. Speichert jeden Abschnitt als Capture in deine Mnemo-Lane, mit URL, Quelle
|
|
24
|
-
und Abschnittsnummer in den Metadaten.
|
|
25
|
-
|
|
26
|
-
Voraussetzungen (Umgebung setzt der Starter):
|
|
27
|
-
`BLUN_MNEMO_MCP` (Pfad mcp.js), `BLUN_MNEMO_AGENT`, ggf. `BLUN_MNEMO_NODE`.
|
|
28
|
-
Crawl4AI einmalig: `pip install crawl4ai && crawl4ai-setup`.
|
|
29
|
-
|
|
30
|
-
## Spaeter abrufen
|
|
31
|
-
|
|
32
|
-
Nach dem Ingest findest du Doku-Wissen ueber die normale Erinnerung:
|
|
33
|
-
`mem_recall` mit der Frage (z.B. „glm chat completions parameter"). Die
|
|
34
|
-
Abschnitte kommen mit Quelle+URL zurueck — zitiere sie mit Herkunft.
|
|
35
|
-
|
|
36
|
-
## Mehrseitige Dokus
|
|
37
|
-
|
|
38
|
-
Erst die Uebersichtsseite lesen (web-lesen), die Unterseiten-Links sammeln,
|
|
39
|
-
dann pro relevanter Unterseite `ingest_docs.py` aufrufen. Nicht die ganze
|
|
40
|
-
Domain blind crawlen — nur die fuer die Aufgabe noetigen Seiten.
|
|
41
|
-
|
|
42
|
-
## Regeln
|
|
43
|
-
|
|
44
|
-
- Nur oeffentliche/offizielle Dokus. Keine bezahlten/geschuetzten Inhalte
|
|
45
|
-
ohne Auftrag.
|
|
46
|
-
- Bei bekannten Libraries zuerst den Context7-MCP versuchen (immer aktuell,
|
|
47
|
-
kein Crawlen). Crawl4AI fuer alles ohne Context7-Eintrag.
|
|
48
|
-
- Immer sagen, WAS du aufgenommen hast (Quelle + wie viele Abschnitte).
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
"""BLUN Doku-Ingestion: eine (API-)Doku crawlen -> in Abschnitte zerlegen ->
|
|
3
|
-
in die eigene Mnemo-Lane speichern, damit sie spaeter zitierbar wiederfindbar
|
|
4
|
-
ist. Kein Cloud-Dienst, alles lokal.
|
|
5
|
-
|
|
6
|
-
Nutzung:
|
|
7
|
-
python ingest_docs.py <URL> [--source doku-name] [--max-chunks N]
|
|
8
|
-
|
|
9
|
-
Voraussetzung: crawl4ai (pip install crawl4ai) und ein laufender Mnemo-MCP
|
|
10
|
-
(mcp.js) — Pfad via BLUN_MNEMO_MCP, Agent via BLUN_MNEMO_AGENT.
|
|
11
|
-
"""
|
|
12
|
-
import asyncio
|
|
13
|
-
import json
|
|
14
|
-
import os
|
|
15
|
-
import re
|
|
16
|
-
import subprocess
|
|
17
|
-
import sys
|
|
18
|
-
|
|
19
|
-
MCP = os.environ.get("BLUN_MNEMO_MCP")
|
|
20
|
-
NODE = os.environ.get("BLUN_MNEMO_NODE") or "node"
|
|
21
|
-
AGENT = os.environ.get("BLUN_MNEMO_AGENT", "agent")
|
|
22
|
-
CHUNK_CHARS = 1800 # ~ ein sinnvoller Doku-Abschnitt
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def chunk_markdown(md: str):
|
|
26
|
-
"""Zerteilt Markdown an Ueberschriften; grosse Bloecke weiter an Absaetzen."""
|
|
27
|
-
parts = re.split(r"(?=^#{1,4}\s)", md, flags=re.MULTILINE)
|
|
28
|
-
chunks = []
|
|
29
|
-
for part in parts:
|
|
30
|
-
part = part.strip()
|
|
31
|
-
if not part:
|
|
32
|
-
continue
|
|
33
|
-
if len(part) <= CHUNK_CHARS:
|
|
34
|
-
chunks.append(part)
|
|
35
|
-
else:
|
|
36
|
-
buf = ""
|
|
37
|
-
for para in part.split("\n\n"):
|
|
38
|
-
if len(buf) + len(para) + 2 > CHUNK_CHARS and buf:
|
|
39
|
-
chunks.append(buf.strip())
|
|
40
|
-
buf = ""
|
|
41
|
-
buf += para + "\n\n"
|
|
42
|
-
if buf.strip():
|
|
43
|
-
chunks.append(buf.strip())
|
|
44
|
-
return [c for c in chunks if len(c) > 40]
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
async def crawl(url: str) -> str:
|
|
48
|
-
from crawl4ai import AsyncWebCrawler
|
|
49
|
-
async with AsyncWebCrawler() as c:
|
|
50
|
-
res = await c.arun(url=url)
|
|
51
|
-
return res.markdown or ""
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def ingest(items):
|
|
55
|
-
"""Spricht mcp.js per JSON-RPC/stdio, capture-batch in Chunks."""
|
|
56
|
-
if not MCP or not os.path.exists(MCP):
|
|
57
|
-
print("WARN: BLUN_MNEMO_MCP nicht gesetzt/gefunden — speichere nicht, gebe nur aus.")
|
|
58
|
-
for it in items[:3]:
|
|
59
|
-
print(" -", it["content"][:80].replace("\n", " "))
|
|
60
|
-
print(f" ... {len(items)} Abschnitte insgesamt (nicht gespeichert).")
|
|
61
|
-
return
|
|
62
|
-
proc = subprocess.Popen(
|
|
63
|
-
[NODE, MCP], stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
|
64
|
-
stderr=subprocess.DEVNULL, text=True, env={**os.environ, "MNEMO_AGENT": AGENT},
|
|
65
|
-
)
|
|
66
|
-
nid = 0
|
|
67
|
-
|
|
68
|
-
def rpc(method, params):
|
|
69
|
-
nonlocal nid
|
|
70
|
-
nid += 1
|
|
71
|
-
proc.stdin.write(json.dumps({"jsonrpc": "2.0", "id": nid, "method": method, "params": params}) + "\n")
|
|
72
|
-
proc.stdin.flush()
|
|
73
|
-
for line in proc.stdout:
|
|
74
|
-
line = line.strip()
|
|
75
|
-
if not line:
|
|
76
|
-
continue
|
|
77
|
-
try:
|
|
78
|
-
msg = json.loads(line)
|
|
79
|
-
except Exception:
|
|
80
|
-
continue
|
|
81
|
-
if msg.get("id") == nid:
|
|
82
|
-
return msg
|
|
83
|
-
return None
|
|
84
|
-
|
|
85
|
-
rpc("initialize", {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "doku-ingest", "version": "1"}})
|
|
86
|
-
proc.stdin.write(json.dumps({"jsonrpc": "2.0", "method": "notifications/initialized"}) + "\n")
|
|
87
|
-
proc.stdin.flush()
|
|
88
|
-
captured = 0
|
|
89
|
-
for i in range(0, len(items), 20):
|
|
90
|
-
batch = items[i:i + 20]
|
|
91
|
-
res = rpc("tools/call", {"name": "mem_capture_ingest_batch", "arguments": {"items": batch}})
|
|
92
|
-
text = ((res or {}).get("result", {}).get("content") or [{}])[0].get("text", "{}")
|
|
93
|
-
try:
|
|
94
|
-
captured += json.loads(text).get("captured", 0)
|
|
95
|
-
except Exception:
|
|
96
|
-
pass
|
|
97
|
-
proc.terminate()
|
|
98
|
-
print(f"Gespeichert: {captured}/{len(items)} Doku-Abschnitte in Mnemo (Agent {AGENT}).")
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def main():
|
|
102
|
-
if len(sys.argv) < 2:
|
|
103
|
-
print("Nutzung: python ingest_docs.py <URL> [--source name] [--max-chunks N]")
|
|
104
|
-
sys.exit(1)
|
|
105
|
-
url = sys.argv[1]
|
|
106
|
-
source = "doku"
|
|
107
|
-
max_chunks = 200
|
|
108
|
-
if "--source" in sys.argv:
|
|
109
|
-
source = sys.argv[sys.argv.index("--source") + 1]
|
|
110
|
-
if "--max-chunks" in sys.argv:
|
|
111
|
-
max_chunks = int(sys.argv[sys.argv.index("--max-chunks") + 1])
|
|
112
|
-
|
|
113
|
-
md = asyncio.run(crawl(url))
|
|
114
|
-
if not md.strip():
|
|
115
|
-
print("Keine Inhalte gecrawlt — URL erreichbar?")
|
|
116
|
-
sys.exit(1)
|
|
117
|
-
chunks = chunk_markdown(md)[:max_chunks]
|
|
118
|
-
thread = f"doku-{re.sub(r'[^a-z0-9]+', '-', source.lower()).strip('-') or 'x'}"
|
|
119
|
-
items = [{
|
|
120
|
-
"source": "doku", "channel": "doku-ingest", "direction": "inbound",
|
|
121
|
-
"actor": AGENT, "event_kind": "doc_chunk",
|
|
122
|
-
"occurred_at": "1970-01-01T00:00:00Z", # Aufrufer/Hub stempelt real
|
|
123
|
-
"ref_id": f"doku-{source}-{n}",
|
|
124
|
-
"content": f"[{source}] {url}\n\n{c}"[:4000],
|
|
125
|
-
"meta": {"for_agent": AGENT, "doc_url": url, "doc_source": source, "chunk": n},
|
|
126
|
-
"thread_id": thread,
|
|
127
|
-
} for n, c in enumerate(chunks)]
|
|
128
|
-
print(f"Gecrawlt: {len(md)} Zeichen -> {len(items)} Abschnitte aus {url}")
|
|
129
|
-
ingest(items)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if __name__ == "__main__":
|
|
133
|
-
main()
|