reasonix 0.49.0 → 0.50.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/dashboard/dist/app.css +1 -0
- package/dashboard/dist/app.js +28 -30531
- package/dashboard/dist/app.js.map +1 -1
- package/dashboard/dist/assets/KaTeX_AMS-Regular.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_AMS-Regular.woff +0 -0
- package/dashboard/dist/assets/KaTeX_AMS-Regular.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Caligraphic-Bold.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Caligraphic-Regular.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Fraktur-Bold.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Fraktur-Bold.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Fraktur-Regular.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Fraktur-Regular.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Main-Bold.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Main-Bold.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Main-Bold.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Main-BoldItalic.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Main-BoldItalic.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Main-Italic.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Main-Italic.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Main-Italic.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Main-Regular.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Main-Regular.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Main-Regular.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Math-BoldItalic.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Math-BoldItalic.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Math-Italic.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Math-Italic.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Math-Italic.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_SansSerif-Bold.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_SansSerif-Bold.woff +0 -0
- package/dashboard/dist/assets/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_SansSerif-Italic.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_SansSerif-Italic.woff +0 -0
- package/dashboard/dist/assets/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_SansSerif-Regular.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_SansSerif-Regular.woff +0 -0
- package/dashboard/dist/assets/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Script-Regular.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Script-Regular.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Script-Regular.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Size1-Regular.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Size1-Regular.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Size1-Regular.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Size2-Regular.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Size2-Regular.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Size2-Regular.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Size3-Regular.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Size3-Regular.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Size4-Regular.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Size4-Regular.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Size4-Regular.woff2 +0 -0
- package/dashboard/dist/assets/KaTeX_Typewriter-Regular.ttf +0 -0
- package/dashboard/dist/assets/KaTeX_Typewriter-Regular.woff +0 -0
- package/dashboard/dist/assets/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/dashboard/dist/assets/geist-cyrillic-400-normal.woff +0 -0
- package/dashboard/dist/assets/geist-cyrillic-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-cyrillic-500-normal.woff +0 -0
- package/dashboard/dist/assets/geist-cyrillic-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-cyrillic-600-normal.woff +0 -0
- package/dashboard/dist/assets/geist-cyrillic-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-cyrillic-700-normal.woff +0 -0
- package/dashboard/dist/assets/geist-cyrillic-700-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-cyrillic-ext-500-normal.woff +0 -0
- package/dashboard/dist/assets/geist-cyrillic-ext-600-normal.woff +0 -0
- package/dashboard/dist/assets/geist-cyrillic-ext-700-normal.woff +0 -0
- package/dashboard/dist/assets/geist-latin-400-normal.woff +0 -0
- package/dashboard/dist/assets/geist-latin-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-latin-500-normal.woff +0 -0
- package/dashboard/dist/assets/geist-latin-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-latin-600-normal.woff +0 -0
- package/dashboard/dist/assets/geist-latin-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-latin-700-normal.woff +0 -0
- package/dashboard/dist/assets/geist-latin-700-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-latin-ext-400-normal.woff +0 -0
- package/dashboard/dist/assets/geist-latin-ext-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-latin-ext-500-normal.woff +0 -0
- package/dashboard/dist/assets/geist-latin-ext-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-latin-ext-600-normal.woff +0 -0
- package/dashboard/dist/assets/geist-latin-ext-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-latin-ext-700-normal.woff +0 -0
- package/dashboard/dist/assets/geist-latin-ext-700-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-mono-cyrillic-400-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-cyrillic-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-mono-cyrillic-500-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-cyrillic-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-mono-cyrillic-600-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-cyrillic-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-mono-latin-400-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-latin-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-mono-latin-500-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-latin-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-mono-latin-600-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-latin-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-mono-latin-ext-400-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-latin-ext-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-mono-latin-ext-500-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-latin-ext-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-mono-latin-ext-600-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-latin-ext-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-mono-symbols2-400-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-symbols2-500-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-symbols2-600-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-vietnamese-400-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-vietnamese-500-normal.woff +0 -0
- package/dashboard/dist/assets/geist-mono-vietnamese-600-normal.woff +0 -0
- package/dashboard/dist/assets/geist-vietnamese-400-normal.woff +0 -0
- package/dashboard/dist/assets/geist-vietnamese-500-normal.woff +0 -0
- package/dashboard/dist/assets/geist-vietnamese-600-normal.woff +0 -0
- package/dashboard/dist/assets/geist-vietnamese-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/geist-vietnamese-700-normal.woff +0 -0
- package/dashboard/dist/assets/inter-cyrillic-400-normal.woff +0 -0
- package/dashboard/dist/assets/inter-cyrillic-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-cyrillic-500-normal.woff +0 -0
- package/dashboard/dist/assets/inter-cyrillic-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-cyrillic-600-normal.woff +0 -0
- package/dashboard/dist/assets/inter-cyrillic-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-cyrillic-700-normal.woff +0 -0
- package/dashboard/dist/assets/inter-cyrillic-700-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-cyrillic-ext-400-normal.woff +0 -0
- package/dashboard/dist/assets/inter-cyrillic-ext-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-cyrillic-ext-500-normal.woff +0 -0
- package/dashboard/dist/assets/inter-cyrillic-ext-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-cyrillic-ext-600-normal.woff +0 -0
- package/dashboard/dist/assets/inter-cyrillic-ext-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-cyrillic-ext-700-normal.woff +0 -0
- package/dashboard/dist/assets/inter-cyrillic-ext-700-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-greek-400-normal.woff +0 -0
- package/dashboard/dist/assets/inter-greek-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-greek-500-normal.woff +0 -0
- package/dashboard/dist/assets/inter-greek-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-greek-600-normal.woff +0 -0
- package/dashboard/dist/assets/inter-greek-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-greek-700-normal.woff +0 -0
- package/dashboard/dist/assets/inter-greek-700-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-greek-ext-400-normal.woff +0 -0
- package/dashboard/dist/assets/inter-greek-ext-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-greek-ext-500-normal.woff +0 -0
- package/dashboard/dist/assets/inter-greek-ext-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-greek-ext-600-normal.woff +0 -0
- package/dashboard/dist/assets/inter-greek-ext-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-greek-ext-700-normal.woff +0 -0
- package/dashboard/dist/assets/inter-greek-ext-700-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-latin-400-normal.woff +0 -0
- package/dashboard/dist/assets/inter-latin-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-latin-500-normal.woff +0 -0
- package/dashboard/dist/assets/inter-latin-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-latin-600-normal.woff +0 -0
- package/dashboard/dist/assets/inter-latin-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-latin-700-normal.woff +0 -0
- package/dashboard/dist/assets/inter-latin-700-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-latin-ext-400-normal.woff +0 -0
- package/dashboard/dist/assets/inter-latin-ext-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-latin-ext-500-normal.woff +0 -0
- package/dashboard/dist/assets/inter-latin-ext-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-latin-ext-600-normal.woff +0 -0
- package/dashboard/dist/assets/inter-latin-ext-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-latin-ext-700-normal.woff +0 -0
- package/dashboard/dist/assets/inter-latin-ext-700-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-vietnamese-400-normal.woff +0 -0
- package/dashboard/dist/assets/inter-vietnamese-400-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-vietnamese-500-normal.woff +0 -0
- package/dashboard/dist/assets/inter-vietnamese-500-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-vietnamese-600-normal.woff +0 -0
- package/dashboard/dist/assets/inter-vietnamese-600-normal.woff2 +0 -0
- package/dashboard/dist/assets/inter-vietnamese-700-normal.woff +0 -0
- package/dashboard/dist/assets/inter-vietnamese-700-normal.woff2 +0 -0
- package/dashboard/dist/vendor-icons.js +102 -0
- package/dashboard/dist/vendor-icons.js.map +1 -0
- package/dashboard/dist/vendor-katex.css +1 -0
- package/dashboard/dist/vendor-katex.js +258 -0
- package/dashboard/dist/vendor-katex.js.map +1 -0
- package/dashboard/dist/vendor-markdown.js +36 -0
- package/dashboard/dist/vendor-markdown.js.map +1 -0
- package/dashboard/dist/vendor-prism.js +15 -0
- package/dashboard/dist/vendor-prism.js.map +1 -0
- package/dashboard/dist/vendor-react.js +50 -0
- package/dashboard/dist/vendor-react.js.map +1 -0
- package/dashboard/index.html +4 -3
- package/dist/cli/{acp-WFQIC6SO.js → acp-6B25WIFF.js} +48 -49
- package/dist/cli/acp-6B25WIFF.js.map +1 -0
- package/dist/cli/chat-7WASPB4O.js +50 -0
- package/dist/cli/{chunk-QF32ROX2.js → chunk-3KRRTLC5.js} +955 -788
- package/dist/cli/chunk-3KRRTLC5.js.map +1 -0
- package/dist/cli/{chunk-TEDWJKEI.js → chunk-3RNFYDDM.js} +11 -27
- package/dist/cli/chunk-3RNFYDDM.js.map +1 -0
- package/dist/cli/{chunk-ZWHSHFDP.js → chunk-6IUMTRFP.js} +35 -7
- package/dist/cli/chunk-6IUMTRFP.js.map +1 -0
- package/dist/cli/{chunk-GNS7BAT2.js → chunk-7WITYWKN.js} +2 -2
- package/dist/cli/{chunk-HIYTRCSW.js → chunk-7YPMTE3U.js} +65 -28
- package/dist/cli/chunk-7YPMTE3U.js.map +1 -0
- package/dist/cli/{chunk-DFX5ZH5L.js → chunk-AAHB2PFX.js} +2 -2
- package/dist/cli/{chunk-PB3MAFEI.js → chunk-AJIZ5KFK.js} +3 -3
- package/dist/cli/{chunk-U5XQDCK7.js → chunk-ALCOQP6R.js} +10 -9
- package/dist/cli/chunk-ALCOQP6R.js.map +1 -0
- package/dist/cli/{chunk-6OWJV3YW.js → chunk-CAGKEGNE.js} +1 -2
- package/dist/cli/{chunk-JNTMOX7G.js → chunk-ENFBF6HI.js} +15 -3
- package/dist/cli/chunk-ENFBF6HI.js.map +1 -0
- package/dist/cli/{chunk-J2IHQGPQ.js → chunk-EZ57UEZQ.js} +2 -2
- package/dist/cli/{chunk-QX5TWXRZ.js → chunk-FQSQFCBI.js} +41 -2
- package/dist/cli/chunk-FQSQFCBI.js.map +1 -0
- package/dist/cli/{chunk-ZAEJWKXB.js → chunk-GMSAB2TC.js} +2 -2
- package/dist/cli/{chunk-MQWO32ZD.js → chunk-GPUH2BNM.js} +123 -286
- package/dist/cli/chunk-GPUH2BNM.js.map +1 -0
- package/dist/cli/{chunk-7AST3QQ3.js → chunk-I4Q3QT4W.js} +2 -2
- package/dist/cli/{chunk-O5LIHAMP.js → chunk-I6FBSTTR.js} +3 -3
- package/dist/cli/{chunk-AWEULQG6.js → chunk-IBRTU5WO.js} +25 -15
- package/dist/cli/{chunk-AWEULQG6.js.map → chunk-IBRTU5WO.js.map} +1 -1
- package/dist/cli/{chunk-RRXUIPWG.js → chunk-IK6WWRIX.js} +1 -1
- package/dist/cli/chunk-IK6WWRIX.js.map +1 -0
- package/dist/cli/{chunk-WMTMMSXU.js → chunk-MXWPAPZW.js} +315 -233
- package/dist/cli/chunk-MXWPAPZW.js.map +1 -0
- package/dist/cli/{chunk-7JTKBJ2G.js → chunk-NLRC3DWQ.js} +3 -3
- package/dist/cli/{chunk-PXBQ6IZ7.js → chunk-OPGWCKKU.js} +2 -2
- package/dist/cli/{chunk-23ZPCIPR.js → chunk-OWA42BKS.js} +21 -20
- package/dist/cli/chunk-OWA42BKS.js.map +1 -0
- package/dist/cli/{chunk-YEF7C4XI.js → chunk-PYIZZAVQ.js} +102 -94
- package/dist/cli/chunk-PYIZZAVQ.js.map +1 -0
- package/dist/cli/{chunk-EQATK2L2.js → chunk-SVD4UPRQ.js} +4 -3
- package/dist/cli/chunk-SVD4UPRQ.js.map +1 -0
- package/dist/cli/{chunk-PEMG6CUB.js → chunk-TX652NBA.js} +2 -2
- package/dist/cli/{chunk-W46ZMNKO.js → chunk-VVMY4M7J.js} +21 -2
- package/dist/cli/chunk-VVMY4M7J.js.map +1 -0
- package/dist/cli/{chunk-TAIKVL35.js → chunk-WSBFVOCO.js} +2 -2
- package/dist/cli/{chunk-ASOLXV67.js → chunk-X2BQZQEE.js} +3 -3
- package/dist/cli/{chunk-E5WCLUIU.js → chunk-XJZWMU5P.js} +2 -2
- package/dist/cli/{chunk-MGTBP7GG.js → chunk-XWPZHWC2.js} +20 -7
- package/dist/cli/chunk-XWPZHWC2.js.map +1 -0
- package/dist/cli/{chunk-JGTX4RRQ.js → chunk-ZAXMJANP.js} +2 -2
- package/dist/cli/{code-R4IHI7SR.js → code-TBK2TASK.js} +49 -57
- package/dist/cli/code-TBK2TASK.js.map +1 -0
- package/dist/cli/{commands-DRHFCYMO.js → commands-NXTKSQTN.js} +4 -4
- package/dist/cli/{commit-AG5KB4YP.js → commit-IR5SPP7A.js} +7 -8
- package/dist/cli/commit-IR5SPP7A.js.map +1 -0
- package/dist/cli/config-XK5WQGTS.js +194 -0
- package/dist/cli/{desktop-JGL6GORA.js → desktop-5NTQBADL.js} +200 -113
- package/dist/cli/desktop-5NTQBADL.js.map +1 -0
- package/dist/cli/{diff-4Z7ETWZO.js → diff-JNYX5BSZ.js} +8 -8
- package/dist/cli/{doctor-VA3RHQLB.js → doctor-IKYLUFXX.js} +11 -11
- package/dist/cli/{events-VRYXOSKI.js → events-HSC57ONU.js} +12 -8
- package/dist/cli/{events-VRYXOSKI.js.map → events-HSC57ONU.js.map} +1 -1
- package/dist/cli/index.js +87 -84
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-LZO4HXFA.js → mcp-BDJJWOCD.js} +3 -3
- package/dist/cli/{mcp-browse-C3GXVMYZ.js → mcp-browse-NJRZDI6V.js} +8 -8
- package/dist/cli/{mcp-inspect-ZMYUNFDS.js → mcp-inspect-Y62NWZQL.js} +7 -6
- package/dist/cli/mcp-inspect-Y62NWZQL.js.map +1 -0
- package/dist/cli/{prompt-MC3U5KRP.js → prompt-UTOIFUQC.js} +5 -5
- package/dist/cli/{prune-sessions-OEPFH4N6.js → prune-sessions-UCUD4XAP.js} +4 -4
- package/dist/cli/{replay-4TP7ZUMZ.js → replay-VVIN64MN.js} +10 -19
- package/dist/cli/replay-VVIN64MN.js.map +1 -0
- package/dist/cli/{run-6MXQYBOE.js → run-76OBDZFB.js} +28 -25
- package/dist/cli/run-76OBDZFB.js.map +1 -0
- package/dist/cli/{server-Z3IMJNNI.js → server-SZZDKTH2.js} +404 -163
- package/dist/cli/server-SZZDKTH2.js.map +1 -0
- package/dist/cli/{sessions-NXQ5SAV7.js → sessions-FZTGRCM5.js} +18 -18
- package/dist/cli/{setup-LHZELI6I.js → setup-4UNENGOE.js} +14 -40
- package/dist/cli/setup-4UNENGOE.js.map +1 -0
- package/dist/cli/{stats-SUIJ3QWY.js → stats-F4NDOD7D.js} +6 -6
- package/dist/cli/stats-F4NDOD7D.js.map +1 -0
- package/dist/cli/version-LUVTWHLL.js +33 -0
- package/dist/index.d.ts +325 -299
- package/dist/index.js +438 -528
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
- package/dist/cli/acp-WFQIC6SO.js.map +0 -1
- package/dist/cli/chat-D32JGNVH.js +0 -51
- package/dist/cli/chunk-23ZPCIPR.js.map +0 -1
- package/dist/cli/chunk-EQATK2L2.js.map +0 -1
- package/dist/cli/chunk-HIYTRCSW.js.map +0 -1
- package/dist/cli/chunk-JNTMOX7G.js.map +0 -1
- package/dist/cli/chunk-LGEKVMMV.js +0 -59
- package/dist/cli/chunk-LGEKVMMV.js.map +0 -1
- package/dist/cli/chunk-MGTBP7GG.js.map +0 -1
- package/dist/cli/chunk-MQWO32ZD.js.map +0 -1
- package/dist/cli/chunk-QF32ROX2.js.map +0 -1
- package/dist/cli/chunk-QX5TWXRZ.js.map +0 -1
- package/dist/cli/chunk-RRXUIPWG.js.map +0 -1
- package/dist/cli/chunk-TEDWJKEI.js.map +0 -1
- package/dist/cli/chunk-U5XQDCK7.js.map +0 -1
- package/dist/cli/chunk-W46ZMNKO.js.map +0 -1
- package/dist/cli/chunk-WMTMMSXU.js.map +0 -1
- package/dist/cli/chunk-YEF7C4XI.js.map +0 -1
- package/dist/cli/chunk-ZWHSHFDP.js.map +0 -1
- package/dist/cli/code-R4IHI7SR.js.map +0 -1
- package/dist/cli/commit-AG5KB4YP.js.map +0 -1
- package/dist/cli/desktop-JGL6GORA.js.map +0 -1
- package/dist/cli/mcp-inspect-ZMYUNFDS.js.map +0 -1
- package/dist/cli/replay-4TP7ZUMZ.js.map +0 -1
- package/dist/cli/run-6MXQYBOE.js.map +0 -1
- package/dist/cli/server-Z3IMJNNI.js.map +0 -1
- package/dist/cli/setup-LHZELI6I.js.map +0 -1
- package/dist/cli/version-BIFONEUB.js +0 -33
- /package/dist/cli/{chat-D32JGNVH.js.map → chat-7WASPB4O.js.map} +0 -0
- /package/dist/cli/{chunk-GNS7BAT2.js.map → chunk-7WITYWKN.js.map} +0 -0
- /package/dist/cli/{chunk-DFX5ZH5L.js.map → chunk-AAHB2PFX.js.map} +0 -0
- /package/dist/cli/{chunk-PB3MAFEI.js.map → chunk-AJIZ5KFK.js.map} +0 -0
- /package/dist/cli/{chunk-6OWJV3YW.js.map → chunk-CAGKEGNE.js.map} +0 -0
- /package/dist/cli/{chunk-J2IHQGPQ.js.map → chunk-EZ57UEZQ.js.map} +0 -0
- /package/dist/cli/{chunk-ZAEJWKXB.js.map → chunk-GMSAB2TC.js.map} +0 -0
- /package/dist/cli/{chunk-7AST3QQ3.js.map → chunk-I4Q3QT4W.js.map} +0 -0
- /package/dist/cli/{chunk-O5LIHAMP.js.map → chunk-I6FBSTTR.js.map} +0 -0
- /package/dist/cli/{chunk-7JTKBJ2G.js.map → chunk-NLRC3DWQ.js.map} +0 -0
- /package/dist/cli/{chunk-PXBQ6IZ7.js.map → chunk-OPGWCKKU.js.map} +0 -0
- /package/dist/cli/{chunk-PEMG6CUB.js.map → chunk-TX652NBA.js.map} +0 -0
- /package/dist/cli/{chunk-TAIKVL35.js.map → chunk-WSBFVOCO.js.map} +0 -0
- /package/dist/cli/{chunk-ASOLXV67.js.map → chunk-X2BQZQEE.js.map} +0 -0
- /package/dist/cli/{chunk-E5WCLUIU.js.map → chunk-XJZWMU5P.js.map} +0 -0
- /package/dist/cli/{chunk-JGTX4RRQ.js.map → chunk-ZAXMJANP.js.map} +0 -0
- /package/dist/cli/{commands-DRHFCYMO.js.map → commands-NXTKSQTN.js.map} +0 -0
- /package/dist/cli/{doctor-VA3RHQLB.js.map → config-XK5WQGTS.js.map} +0 -0
- /package/dist/cli/{diff-4Z7ETWZO.js.map → diff-JNYX5BSZ.js.map} +0 -0
- /package/dist/cli/{prompt-MC3U5KRP.js.map → doctor-IKYLUFXX.js.map} +0 -0
- /package/dist/cli/{mcp-LZO4HXFA.js.map → mcp-BDJJWOCD.js.map} +0 -0
- /package/dist/cli/{mcp-browse-C3GXVMYZ.js.map → mcp-browse-NJRZDI6V.js.map} +0 -0
- /package/dist/cli/{stats-SUIJ3QWY.js.map → prompt-UTOIFUQC.js.map} +0 -0
- /package/dist/cli/{prune-sessions-OEPFH4N6.js.map → prune-sessions-UCUD4XAP.js.map} +0 -0
- /package/dist/cli/{sessions-NXQ5SAV7.js.map → sessions-FZTGRCM5.js.map} +0 -0
- /package/dist/cli/{version-BIFONEUB.js.map → version-LUVTWHLL.js.map} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
|
|
3
3
|
import {
|
|
4
4
|
t
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-PYIZZAVQ.js";
|
|
6
6
|
|
|
7
7
|
// src/cli/ui/mcp-lifecycle.ts
|
|
8
8
|
var STATE = {
|
|
@@ -47,4 +47,4 @@ export {
|
|
|
47
47
|
formatMcpLifecycleEvent,
|
|
48
48
|
formatMcpSlowToast
|
|
49
49
|
};
|
|
50
|
-
//# sourceMappingURL=chunk-
|
|
50
|
+
//# sourceMappingURL=chunk-7WITYWKN.js.map
|
|
@@ -7,6 +7,10 @@ import {
|
|
|
7
7
|
VERSION
|
|
8
8
|
} from "./chunk-XXC2BYTV.js";
|
|
9
9
|
|
|
10
|
+
// src/mcp/client.ts
|
|
11
|
+
import { basename, resolve } from "path";
|
|
12
|
+
import { pathToFileURL } from "url";
|
|
13
|
+
|
|
10
14
|
// src/mcp/types.ts
|
|
11
15
|
var MCP_PROTOCOL_VERSION = "2024-11-05";
|
|
12
16
|
function isJsonRpcError(msg) {
|
|
@@ -17,6 +21,8 @@ function isJsonRpcError(msg) {
|
|
|
17
21
|
var McpClient = class {
|
|
18
22
|
transport;
|
|
19
23
|
clientInfo;
|
|
24
|
+
workspaceDir;
|
|
25
|
+
workspaceRoot;
|
|
20
26
|
requestTimeoutMs;
|
|
21
27
|
pending = /* @__PURE__ */ new Map();
|
|
22
28
|
nextId = 1;
|
|
@@ -36,6 +42,14 @@ var McpClient = class {
|
|
|
36
42
|
constructor(opts) {
|
|
37
43
|
this.transport = opts.transport;
|
|
38
44
|
this.clientInfo = opts.clientInfo ?? { name: "reasonix", version: VERSION };
|
|
45
|
+
const workspaceDir = opts.workspaceDir?.trim();
|
|
46
|
+
if (workspaceDir) {
|
|
47
|
+
this.workspaceDir = resolve(workspaceDir);
|
|
48
|
+
this.workspaceRoot = {
|
|
49
|
+
uri: pathToFileURL(this.workspaceDir).href,
|
|
50
|
+
name: basename(this.workspaceDir) || this.workspaceDir
|
|
51
|
+
};
|
|
52
|
+
}
|
|
39
53
|
this.requestTimeoutMs = opts.requestTimeoutMs ?? 6e4;
|
|
40
54
|
}
|
|
41
55
|
/** Server's advertised capabilities, available after initialize(). */
|
|
@@ -54,24 +68,29 @@ var McpClient = class {
|
|
|
54
68
|
get serverInstructions() {
|
|
55
69
|
return this._instructions;
|
|
56
70
|
}
|
|
71
|
+
get workspaceRootDir() {
|
|
72
|
+
return this.workspaceDir;
|
|
73
|
+
}
|
|
57
74
|
/** Compliant servers reject other methods until this completes. */
|
|
58
75
|
async initialize(opts = {}) {
|
|
59
76
|
if (this.initialized) throw new Error("MCP client already initialized");
|
|
60
77
|
this.startReaderIfNeeded();
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
{
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
const capabilities = {
|
|
79
|
+
tools: {},
|
|
80
|
+
resources: {},
|
|
81
|
+
prompts: {},
|
|
82
|
+
...this.workspaceRoot ? { roots: {} } : {}
|
|
83
|
+
};
|
|
84
|
+
const params = {
|
|
85
|
+
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
86
|
+
capabilities,
|
|
87
|
+
clientInfo: this.clientInfo,
|
|
88
|
+
...this.workspaceRoot ? {
|
|
89
|
+
rootUri: this.workspaceRoot.uri,
|
|
90
|
+
workspaceFolders: [this.workspaceRoot]
|
|
91
|
+
} : {}
|
|
92
|
+
};
|
|
93
|
+
const result = await this.request("initialize", params, opts.signal);
|
|
75
94
|
this._serverCapabilities = result.capabilities ?? {};
|
|
76
95
|
this._serverInfo = result.serverInfo ?? { name: "", version: "" };
|
|
77
96
|
this._protocolVersion = result.protocolVersion ?? "";
|
|
@@ -148,7 +167,7 @@ var McpClient = class {
|
|
|
148
167
|
const id = this.nextId++;
|
|
149
168
|
const frame = { jsonrpc: "2.0", id, method, params };
|
|
150
169
|
let abortHandler = null;
|
|
151
|
-
const promise = new Promise((
|
|
170
|
+
const promise = new Promise((resolve2, reject) => {
|
|
152
171
|
const timeout = setTimeout(() => {
|
|
153
172
|
this.pending.delete(id);
|
|
154
173
|
if (abortHandler && signal) signal.removeEventListener("abort", abortHandler);
|
|
@@ -157,7 +176,7 @@ var McpClient = class {
|
|
|
157
176
|
);
|
|
158
177
|
}, this.requestTimeoutMs);
|
|
159
178
|
this.pending.set(id, {
|
|
160
|
-
resolve,
|
|
179
|
+
resolve: resolve2,
|
|
161
180
|
reject,
|
|
162
181
|
timeout
|
|
163
182
|
});
|
|
@@ -231,7 +250,10 @@ var McpClient = class {
|
|
|
231
250
|
}
|
|
232
251
|
return;
|
|
233
252
|
}
|
|
234
|
-
if (!("result" in msg) && !("error" in msg))
|
|
253
|
+
if (!("result" in msg) && !("error" in msg)) {
|
|
254
|
+
this.handleServerRequest(msg);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
235
257
|
const pending = this.pending.get(msg.id);
|
|
236
258
|
if (!pending) return;
|
|
237
259
|
this.pending.delete(msg.id);
|
|
@@ -243,6 +265,21 @@ var McpClient = class {
|
|
|
243
265
|
pending.resolve(resp.result);
|
|
244
266
|
}
|
|
245
267
|
}
|
|
268
|
+
handleServerRequest(req) {
|
|
269
|
+
if (req.method === "roots/list" && this.workspaceRoot) {
|
|
270
|
+
void this.transport.send({
|
|
271
|
+
jsonrpc: "2.0",
|
|
272
|
+
id: req.id,
|
|
273
|
+
result: { roots: [this.workspaceRoot] }
|
|
274
|
+
}).catch(() => void 0);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
void this.transport.send({
|
|
278
|
+
jsonrpc: "2.0",
|
|
279
|
+
id: req.id,
|
|
280
|
+
error: { code: -32601, message: `method not found: ${req.method}` }
|
|
281
|
+
}).catch(() => void 0);
|
|
282
|
+
}
|
|
246
283
|
};
|
|
247
284
|
|
|
248
285
|
// src/mcp/inspect.ts
|
|
@@ -321,12 +358,12 @@ var StdioTransport = class {
|
|
|
321
358
|
}
|
|
322
359
|
async send(message) {
|
|
323
360
|
if (this.closed) throw new Error("MCP transport is closed");
|
|
324
|
-
return new Promise((
|
|
361
|
+
return new Promise((resolve2, reject) => {
|
|
325
362
|
const line = `${JSON.stringify(message)}
|
|
326
363
|
`;
|
|
327
364
|
this.child.stdin.write(line, "utf8", (err) => {
|
|
328
365
|
if (err) reject(err);
|
|
329
|
-
else
|
|
366
|
+
else resolve2();
|
|
330
367
|
});
|
|
331
368
|
});
|
|
332
369
|
}
|
|
@@ -337,8 +374,8 @@ var StdioTransport = class {
|
|
|
337
374
|
continue;
|
|
338
375
|
}
|
|
339
376
|
if (this.closed) return;
|
|
340
|
-
const next = await new Promise((
|
|
341
|
-
this.waiters.push(
|
|
377
|
+
const next = await new Promise((resolve2) => {
|
|
378
|
+
this.waiters.push(resolve2);
|
|
342
379
|
});
|
|
343
380
|
if (next === null) return;
|
|
344
381
|
yield next;
|
|
@@ -417,8 +454,8 @@ var SseTransport = class {
|
|
|
417
454
|
constructor(opts) {
|
|
418
455
|
this.url = opts.url;
|
|
419
456
|
this.headers = opts.headers ?? {};
|
|
420
|
-
this.endpointReady = new Promise((
|
|
421
|
-
this.resolveEndpoint =
|
|
457
|
+
this.endpointReady = new Promise((resolve2, reject) => {
|
|
458
|
+
this.resolveEndpoint = resolve2;
|
|
422
459
|
this.rejectEndpoint = reject;
|
|
423
460
|
});
|
|
424
461
|
this.endpointReady.catch(() => void 0);
|
|
@@ -445,8 +482,8 @@ var SseTransport = class {
|
|
|
445
482
|
continue;
|
|
446
483
|
}
|
|
447
484
|
if (this.closed) return;
|
|
448
|
-
const next = await new Promise((
|
|
449
|
-
this.waiters.push(
|
|
485
|
+
const next = await new Promise((resolve2) => {
|
|
486
|
+
this.waiters.push(resolve2);
|
|
450
487
|
});
|
|
451
488
|
if (next === null) return;
|
|
452
489
|
yield next;
|
|
@@ -631,8 +668,8 @@ var StreamableHttpTransport = class {
|
|
|
631
668
|
continue;
|
|
632
669
|
}
|
|
633
670
|
if (this.closed) return;
|
|
634
|
-
const next = await new Promise((
|
|
635
|
-
this.waiters.push(
|
|
671
|
+
const next = await new Promise((resolve2) => {
|
|
672
|
+
this.waiters.push(resolve2);
|
|
636
673
|
});
|
|
637
674
|
if (next === null) return;
|
|
638
675
|
yield next;
|
|
@@ -697,4 +734,4 @@ export {
|
|
|
697
734
|
StreamableHttpTransport,
|
|
698
735
|
inspectMcpServer
|
|
699
736
|
};
|
|
700
|
-
//# sourceMappingURL=chunk-
|
|
737
|
+
//# sourceMappingURL=chunk-7YPMTE3U.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/mcp/client.ts","../../src/mcp/types.ts","../../src/mcp/inspect.ts","../../src/mcp/stdio.ts","../../src/mcp/sse.ts","../../src/mcp/streamable-http.ts"],"sourcesContent":["import { basename, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { VERSION } from \"../version.js\";\nimport type { McpTransport } from \"./stdio.js\";\nimport {\n type CallToolParams,\n type CallToolResult,\n type GetPromptParams,\n type GetPromptResult,\n type InitializeParams,\n type InitializeResult,\n type JsonRpcId,\n type JsonRpcMessage,\n type JsonRpcRequest,\n type JsonRpcResponse,\n type ListPromptsParams,\n type ListPromptsResult,\n type ListResourcesParams,\n type ListResourcesResult,\n type ListToolsResult,\n MCP_PROTOCOL_VERSION,\n type McpClientInfo,\n type McpProgressHandler,\n type McpRoot,\n type ProgressNotificationParams,\n type ReadResourceParams,\n type ReadResourceResult,\n isJsonRpcError,\n} from \"./types.js\";\n\nexport interface McpClientOptions {\n transport: McpTransport;\n clientInfo?: McpClientInfo;\n workspaceDir?: string;\n /** Per-request timeout. Default 60s. */\n requestTimeoutMs?: number;\n}\n\ninterface PendingRequest {\n resolve: (value: unknown) => void;\n reject: (err: Error) => void;\n timeout: NodeJS.Timeout;\n}\n\nexport class McpClient {\n private readonly transport: McpTransport;\n private readonly clientInfo: McpClientInfo;\n private readonly workspaceDir: string | undefined;\n private readonly workspaceRoot: McpRoot | undefined;\n private readonly requestTimeoutMs: number;\n private readonly pending = new Map<JsonRpcId, PendingRequest>();\n private nextId = 1;\n private readerStarted = false;\n private initialized = false;\n private _serverCapabilities: InitializeResult[\"capabilities\"] = {};\n private _serverInfo: InitializeResult[\"serverInfo\"] = { name: \"\", version: \"\" };\n private _protocolVersion = \"\";\n private _instructions: string | undefined;\n // Progress-token → handler for notifications/progress routing. Tokens\n // are minted per call when the caller supplies an onProgress\n // callback; cleared when the final response lands (or the pending\n // request rejects). No leaks — the `try/finally` in callTool\n // guarantees cleanup even on timeout.\n private readonly progressHandlers = new Map<string | number, McpProgressHandler>();\n private nextProgressToken = 1;\n\n constructor(opts: McpClientOptions) {\n this.transport = opts.transport;\n this.clientInfo = opts.clientInfo ?? { name: \"reasonix\", version: VERSION };\n const workspaceDir = opts.workspaceDir?.trim();\n if (workspaceDir) {\n this.workspaceDir = resolve(workspaceDir);\n this.workspaceRoot = {\n uri: pathToFileURL(this.workspaceDir).href,\n name: basename(this.workspaceDir) || this.workspaceDir,\n };\n }\n this.requestTimeoutMs = opts.requestTimeoutMs ?? 60_000;\n }\n\n /** Server's advertised capabilities, available after initialize(). */\n get serverCapabilities(): InitializeResult[\"capabilities\"] {\n return this._serverCapabilities;\n }\n\n /** Server's self-reported name + version, available after initialize(). */\n get serverInfo(): InitializeResult[\"serverInfo\"] {\n return this._serverInfo;\n }\n\n /** Protocol version the server agreed to during the handshake. */\n get protocolVersion(): string {\n return this._protocolVersion;\n }\n\n /** Optional free-form instructions the server provides at handshake. */\n get serverInstructions(): string | undefined {\n return this._instructions;\n }\n\n get workspaceRootDir(): string | undefined {\n return this.workspaceDir;\n }\n\n /** Compliant servers reject other methods until this completes. */\n async initialize(opts: { signal?: AbortSignal } = {}): Promise<InitializeResult> {\n if (this.initialized) throw new Error(\"MCP client already initialized\");\n this.startReaderIfNeeded();\n const capabilities: InitializeParams[\"capabilities\"] = {\n tools: {},\n resources: {},\n prompts: {},\n ...(this.workspaceRoot ? { roots: {} } : {}),\n };\n const params: InitializeParams = {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities,\n clientInfo: this.clientInfo,\n ...(this.workspaceRoot\n ? {\n rootUri: this.workspaceRoot.uri,\n workspaceFolders: [this.workspaceRoot],\n }\n : {}),\n };\n const result = await this.request<InitializeResult>(\"initialize\", params, opts.signal);\n this._serverCapabilities = result.capabilities ?? {};\n this._serverInfo = result.serverInfo ?? { name: \"\", version: \"\" };\n this._protocolVersion = result.protocolVersion ?? \"\";\n this._instructions = result.instructions;\n // Per spec: client sends notifications/initialized after receiving the\n // initialize response. Only then is the connection live for other\n // methods.\n await this.transport.send({\n jsonrpc: \"2.0\",\n method: \"notifications/initialized\",\n });\n this.initialized = true;\n return result;\n }\n\n /** List tools the server exposes. */\n async listTools(): Promise<ListToolsResult> {\n this.assertInitialized();\n return this.request<ListToolsResult>(\"tools/list\", {});\n }\n\n /** Abort sends `notifications/cancelled` and rejects immediately; late server responses are dropped. */\n async callTool(\n name: string,\n args?: Record<string, unknown>,\n opts: { onProgress?: McpProgressHandler; signal?: AbortSignal } = {},\n ): Promise<CallToolResult> {\n this.assertInitialized();\n const params: CallToolParams = { name, arguments: args ?? {} };\n let token: number | undefined;\n if (opts.onProgress) {\n token = this.nextProgressToken++;\n this.progressHandlers.set(token, opts.onProgress);\n params._meta = { progressToken: token };\n }\n try {\n return await this.request<CallToolResult>(\"tools/call\", params, opts.signal);\n } finally {\n if (token !== undefined) this.progressHandlers.delete(token);\n }\n }\n\n /** Throws on method-not-found; callers should gate on `serverCapabilities.resources` first. */\n async listResources(cursor?: string): Promise<ListResourcesResult> {\n this.assertInitialized();\n return this.request<ListResourcesResult>(\"resources/list\", {\n ...(cursor ? { cursor } : {}),\n } satisfies ListResourcesParams);\n }\n\n /** Read the contents of a resource by URI. */\n async readResource(uri: string): Promise<ReadResourceResult> {\n this.assertInitialized();\n return this.request<ReadResourceResult>(\"resources/read\", {\n uri,\n } satisfies ReadResourceParams);\n }\n\n /** List prompt templates the server exposes. */\n async listPrompts(cursor?: string): Promise<ListPromptsResult> {\n this.assertInitialized();\n return this.request<ListPromptsResult>(\"prompts/list\", {\n ...(cursor ? { cursor } : {}),\n } satisfies ListPromptsParams);\n }\n\n async getPrompt(name: string, args?: Record<string, string>): Promise<GetPromptResult> {\n this.assertInitialized();\n return this.request<GetPromptResult>(\"prompts/get\", {\n name,\n ...(args ? { arguments: args } : {}),\n } satisfies GetPromptParams);\n }\n\n /** Close the transport and reject any outstanding requests. */\n async close(): Promise<void> {\n for (const [, pending] of this.pending) {\n clearTimeout(pending.timeout);\n pending.reject(new Error(\"MCP client closed\"));\n }\n this.pending.clear();\n await this.transport.close();\n }\n\n private assertInitialized(): void {\n if (!this.initialized) throw new Error(\"MCP client not initialized — call initialize() first\");\n }\n\n private async request<R>(method: string, params: unknown, signal?: AbortSignal): Promise<R> {\n const id = this.nextId++;\n const frame: JsonRpcRequest = { jsonrpc: \"2.0\", id, method, params };\n let abortHandler: (() => void) | null = null;\n const promise = new Promise<R>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pending.delete(id);\n if (abortHandler && signal) signal.removeEventListener(\"abort\", abortHandler);\n reject(\n new Error(`MCP request ${method} (id=${id}) timed out after ${this.requestTimeoutMs}ms`),\n );\n }, this.requestTimeoutMs);\n this.pending.set(id, {\n resolve: resolve as (value: unknown) => void,\n reject,\n timeout,\n });\n // Wire up cancellation: when signal fires, send an MCP cancellation\n // notification to the server (so it can stop whatever it was doing)\n // and reject the caller immediately — no need to wait for the\n // subprocess to finish its in-flight work. Late responses from the\n // server are dropped by `dispatch` because the id is gone from\n // `pending`.\n if (signal) {\n if (signal.aborted) {\n this.pending.delete(id);\n clearTimeout(timeout);\n reject(new Error(`MCP request ${method} (id=${id}) aborted before send`));\n return;\n }\n abortHandler = () => {\n this.pending.delete(id);\n clearTimeout(timeout);\n void this.transport\n .send({\n jsonrpc: \"2.0\",\n method: \"notifications/cancelled\",\n params: { requestId: id, reason: \"aborted by user\" },\n })\n .catch(() => {\n // Transport may already be closing — swallow; we still\n // reject the caller below so they unblock.\n });\n reject(new Error(`MCP request ${method} (id=${id}) aborted by user`));\n };\n signal.addEventListener(\"abort\", abortHandler, { once: true });\n }\n });\n promise.catch(() => undefined);\n // Swallow rejection on the race-leg derivative too — if `send` wins the race,\n // a late-rejecting `promise.then(...)` would otherwise be orphaned (#742).\n const promiseSettled = promise.then(\n () => undefined,\n () => undefined,\n );\n try {\n await Promise.race([this.transport.send(frame), promiseSettled]);\n } catch (err) {\n const pending = this.pending.get(id);\n if (pending) clearTimeout(pending.timeout);\n this.pending.delete(id);\n if (abortHandler && signal) signal.removeEventListener(\"abort\", abortHandler);\n throw err;\n }\n try {\n return await promise;\n } finally {\n if (abortHandler && signal) signal.removeEventListener(\"abort\", abortHandler);\n }\n }\n\n private startReaderIfNeeded(): void {\n if (this.readerStarted) return;\n this.readerStarted = true;\n // Fire-and-forget: the reader runs for the lifetime of the client.\n void this.readLoop();\n }\n\n private async readLoop(): Promise<void> {\n try {\n for await (const msg of this.transport.messages()) {\n this.dispatch(msg);\n }\n } catch (err) {\n // Surface as rejections on all pending requests so nobody hangs.\n for (const [, pending] of this.pending) {\n clearTimeout(pending.timeout);\n pending.reject(err as Error);\n }\n this.pending.clear();\n }\n }\n\n private dispatch(msg: JsonRpcMessage): void {\n // Notifications (no `id`): route by method. Progress notifications\n // go to the per-call handler if one was registered; everything\n // else is dropped silently (we don't yet handle tools/list_changed\n // or resources/list_changed).\n if (!(\"id\" in msg) || msg.id === null || msg.id === undefined) {\n if (\"method\" in msg && msg.method === \"notifications/progress\") {\n const p = msg.params as ProgressNotificationParams | undefined;\n if (!p || p.progressToken === undefined) return;\n const handler = this.progressHandlers.get(p.progressToken);\n if (!handler) return; // late notification after the call resolved\n handler({ progress: p.progress, total: p.total, message: p.message });\n }\n return;\n }\n if (!(\"result\" in msg) && !(\"error\" in msg)) {\n this.handleServerRequest(msg as JsonRpcRequest);\n return;\n }\n const pending = this.pending.get(msg.id);\n if (!pending) return; // late response after timeout; drop\n this.pending.delete(msg.id);\n clearTimeout(pending.timeout);\n const resp = msg as JsonRpcResponse;\n if (isJsonRpcError(resp)) {\n pending.reject(new Error(`MCP ${resp.error.code}: ${resp.error.message}`));\n } else {\n pending.resolve(resp.result);\n }\n }\n\n private handleServerRequest(req: JsonRpcRequest): void {\n if (req.method === \"roots/list\" && this.workspaceRoot) {\n void this.transport\n .send({\n jsonrpc: \"2.0\",\n id: req.id,\n result: { roots: [this.workspaceRoot] },\n })\n .catch(() => undefined);\n return;\n }\n void this.transport\n .send({\n jsonrpc: \"2.0\",\n id: req.id,\n error: { code: -32601, message: `method not found: ${req.method}` },\n })\n .catch(() => undefined);\n }\n}\n","/** MCP types (spec 2024-11-05). Stdio wire format is NDJSON — one JSON-RPC message per line, no Content-Length framing. */\n\nexport type JsonRpcId = string | number;\n\nexport interface JsonRpcRequest<P = unknown> {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n method: string;\n params?: P;\n}\n\nexport interface JsonRpcNotification<P = unknown> {\n jsonrpc: \"2.0\";\n method: string;\n params?: P;\n}\n\nexport interface JsonRpcSuccess<R = unknown> {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n result: R;\n}\n\nexport interface JsonRpcError {\n jsonrpc: \"2.0\";\n id: JsonRpcId | null;\n error: {\n /** JSON-RPC standard codes: -32700 parse, -32600 invalid request, -32601 method not found, -32602 invalid params, -32603 internal. MCP also defines its own range. */\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\nexport type JsonRpcResponse<R = unknown> = JsonRpcSuccess<R> | JsonRpcError;\n\nexport type JsonRpcMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcSuccess | JsonRpcError;\n\nexport interface McpClientInfo {\n name: string;\n version: string;\n}\n\nexport interface McpClientCapabilities {\n /** Empty object advertises support without any optional sub-features. */\n tools?: Record<string, never>;\n /** Advertised when the client can consume `resources/list` + `resources/read`. */\n resources?: Record<string, never>;\n /** Advertised when the client can consume `prompts/list` + `prompts/get`. */\n prompts?: Record<string, never>;\n /** Advertised when the client can answer `roots/list`. */\n roots?: { listChanged?: boolean };\n // sampling would go here — deferred.\n}\n\nexport interface McpRoot {\n uri: string;\n name?: string;\n}\n\nexport interface InitializeParams {\n protocolVersion: string;\n capabilities: McpClientCapabilities;\n clientInfo: McpClientInfo;\n rootUri?: string;\n workspaceFolders?: McpRoot[];\n}\n\nexport interface InitializeResult {\n protocolVersion: string;\n serverInfo: { name: string; version: string };\n capabilities: {\n tools?: { listChanged?: boolean };\n resources?: unknown;\n prompts?: unknown;\n };\n instructions?: string;\n}\n\nexport interface McpToolSchema {\n /** JSON Schema — compatible with Reasonix's tools.ts JSONSchema shape. */\n type?: string;\n properties?: Record<string, unknown>;\n required?: string[];\n [extra: string]: unknown;\n}\n\nexport interface McpTool {\n name: string;\n description?: string;\n /** MCP calls this `inputSchema`. Reasonix's `parameters` field is the same concept. */\n inputSchema: McpToolSchema;\n}\n\nexport interface ListToolsResult {\n tools: McpTool[];\n nextCursor?: string;\n}\n\nexport interface CallToolParams {\n name: string;\n arguments?: Record<string, unknown>;\n _meta?: { progressToken?: string | number };\n}\n\nexport interface ProgressNotificationParams {\n progressToken: string | number;\n progress: number;\n total?: number;\n message?: string;\n}\n\n/** Values a `ProgressHandler` receives — `progressToken` is already matched away. */\nexport interface McpProgressInfo {\n progress: number;\n total?: number;\n message?: string;\n}\n\nexport type McpProgressHandler = (info: McpProgressInfo) => void;\n\nexport interface McpContentBlockText {\n type: \"text\";\n text: string;\n}\n\nexport interface McpContentBlockImage {\n type: \"image\";\n data: string;\n mimeType: string;\n}\n\n/** MCP result content is an array of typed blocks. Reasonix consumes only text for now — image blocks get stringified with a placeholder. */\nexport type McpContentBlock = McpContentBlockText | McpContentBlockImage;\n\nexport interface CallToolResult {\n content: McpContentBlock[];\n /** True = tool raised an error; the content describes it. */\n isError?: boolean;\n}\n\nexport interface McpResource {\n uri: string;\n name: string;\n description?: string;\n /** Hint for the content type (e.g. \"text/markdown\"). Purely informational. */\n mimeType?: string;\n}\n\nexport interface ListResourcesParams {\n /** Pagination cursor from a previous listResources response. */\n cursor?: string;\n}\n\nexport interface ListResourcesResult {\n resources: McpResource[];\n nextCursor?: string;\n}\n\nexport interface ReadResourceParams {\n uri: string;\n}\n\n/** Server populates exactly one of `text` (UTF-8) or `blob` (base64) per entry. */\nexport interface McpResourceContentsText {\n uri: string;\n mimeType?: string;\n text: string;\n}\n\nexport interface McpResourceContentsBlob {\n uri: string;\n mimeType?: string;\n blob: string;\n}\n\nexport type McpResourceContents = McpResourceContentsText | McpResourceContentsBlob;\n\nexport interface ReadResourceResult {\n contents: McpResourceContents[];\n}\n\nexport interface McpPromptArgument {\n name: string;\n description?: string;\n required?: boolean;\n}\n\nexport interface McpPrompt {\n name: string;\n description?: string;\n arguments?: McpPromptArgument[];\n}\n\nexport interface ListPromptsParams {\n cursor?: string;\n}\n\nexport interface ListPromptsResult {\n prompts: McpPrompt[];\n nextCursor?: string;\n}\n\nexport interface GetPromptParams {\n name: string;\n arguments?: Record<string, string>;\n}\n\nexport interface McpPromptMessage {\n role: \"user\" | \"assistant\";\n content: McpContentBlock | McpPromptResourceBlock;\n}\n\nexport interface McpPromptResourceBlock {\n type: \"resource\";\n resource: McpResourceContents;\n}\n\nexport interface GetPromptResult {\n description?: string;\n messages: McpPromptMessage[];\n}\n\n/** Current MCP protocol version Reasonix is coded against. */\nexport const MCP_PROTOCOL_VERSION = \"2024-11-05\";\n\n/** Type guard — success vs error response. */\nexport function isJsonRpcError(msg: JsonRpcResponse): msg is JsonRpcError {\n return \"error\" in msg;\n}\n","/** Unsupported list methods surface as `{supported:false}` instead of throwing — minimal servers still get a clean report. */\n\nimport type { McpClient } from \"./client.js\";\nimport type { McpPrompt, McpResource, McpTool } from \"./types.js\";\n\nexport interface InspectionReport {\n protocolVersion: string;\n serverInfo: { name: string; version: string };\n capabilities: Record<string, unknown>;\n instructions?: string;\n tools: SectionResult<McpTool>;\n resources: SectionResult<McpResource>;\n prompts: SectionResult<McpPrompt>;\n /** Wall-clock for the three list calls combined; surfaced as the server's \"p95-ish\" latency in the browser. */\n elapsedMs: number;\n}\n\nexport type SectionResult<T> =\n | { supported: true; items: T[] }\n | { supported: false; reason: string };\n\n/** Caller owns initialize() / close() — keeps this pure so tests can feed a FakeMcpTransport. */\nexport async function inspectMcpServer(client: McpClient): Promise<InspectionReport> {\n const t0 = Date.now();\n // Always try all three listings — some servers omit capability flags but still serve the methods.\n const tools = await trySection<McpTool>(() => client.listTools().then((r) => r.tools));\n const resources = await trySection<McpResource>(() =>\n client.listResources().then((r) => r.resources),\n );\n const prompts = await trySection<McpPrompt>(() => client.listPrompts().then((r) => r.prompts));\n\n return {\n protocolVersion: client.protocolVersion || \"(unknown)\",\n serverInfo: client.serverInfo,\n capabilities: client.serverCapabilities ?? {},\n instructions: client.serverInstructions,\n tools,\n resources,\n prompts,\n elapsedMs: Date.now() - t0,\n };\n}\n\nasync function trySection<T>(load: () => Promise<T[]>): Promise<SectionResult<T>> {\n try {\n const items = await load();\n return { supported: true, items };\n } catch (err) {\n const msg = (err as Error).message ?? String(err);\n // -32601 is JSON-RPC \"method not found\" — the canonical response\n // from a server that doesn't implement this family. Treat it as\n // \"not supported\" rather than a hard error, so the CLI can render\n // a clean summary instead of aborting on the first missing method.\n if (/-32601/.test(msg) || /method not found/i.test(msg)) {\n return { supported: false, reason: \"method not found (-32601)\" };\n }\n return { supported: false, reason: msg };\n }\n}\n","/** MCP stdio = newline-delimited JSON-RPC; transport iface lets tests fake it without spawning. */\n\nimport { type ChildProcess, spawn } from \"node:child_process\";\nimport type { JsonRpcMessage } from \"./types.js\";\n\nexport interface McpTransport {\n /** Send one JSON-RPC message. Resolves when the bytes are accepted. */\n send(message: JsonRpcMessage): Promise<void>;\n /** Async iterator over incoming messages. Ends when the connection closes. */\n messages(): AsyncIterableIterator<JsonRpcMessage>;\n /** Close the underlying resource (kill child process, close streams). */\n close(): Promise<void>;\n}\n\nexport interface StdioTransportOptions {\n /** Argv to spawn. First element is the command. */\n command: string;\n args?: string[];\n /** Env overlay — merged over process.env unless replaceEnv=true. */\n env?: Record<string, string>;\n /** When true, only the env above is visible to the child. Default false. */\n replaceEnv?: boolean;\n /** CWD for the child. Default: process.cwd(). */\n cwd?: string;\n /** Default true on win32 to resolve `.cmd`/`.bat` wrappers (npx.cmd etc.). */\n shell?: boolean;\n}\n\nexport class StdioTransport implements McpTransport {\n private readonly child: ChildProcess;\n private readonly queue: JsonRpcMessage[] = [];\n private readonly waiters: Array<(m: JsonRpcMessage | null) => void> = [];\n private closed = false;\n private stdoutBuffer = \"\";\n\n constructor(opts: StdioTransportOptions) {\n const env = opts.replaceEnv ? { ...(opts.env ?? {}) } : { ...process.env, ...(opts.env ?? {}) };\n // Windows wraps binaries as .cmd/.bat shims (npx.cmd, pnpm.cmd, …).\n // child_process.spawn without shell:true can't resolve them, which\n // breaks `--mcp \"npx -y some-server\"` — the most common MCP setup.\n // Default shell:true on win32 and leave POSIX alone.\n const shell = opts.shell ?? process.platform === \"win32\";\n\n if (shell) {\n // Node's shell:true + args[] triggers DEP0190 because it concatenates\n // with spaces and doesn't quote args — unsafe if an arg contains\n // shell metacharacters. We build a single command line ourselves,\n // quoting ONLY the args (command stays bare so the shell's PATH /\n // PATHEXT lookup finds `npx` → `npx.cmd` on Windows).\n const line = [\n opts.command,\n ...(opts.args ?? []).map((a) => quoteArg(a, process.platform === \"win32\")),\n ].join(\" \");\n this.child = spawn(line, [], {\n env,\n cwd: opts.cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n shell: true,\n });\n } else {\n this.child = spawn(opts.command, opts.args ?? [], {\n env,\n cwd: opts.cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n }\n this.child.stdout!.setEncoding(\"utf8\");\n this.child.stdout!.on(\"data\", (chunk: string) => this.onStdout(chunk));\n this.child.stderr!.setEncoding(\"utf8\");\n this.child.stderr!.on(\"data\", (chunk: string) => this.onStderr(chunk));\n this.child.on(\"close\", () => this.onClose());\n this.child.on(\"error\", (err) => {\n // Surface spawn errors as a synthetic JsonRpcError so callers don't\n // hang on a stream that never emits anything.\n this.push({\n jsonrpc: \"2.0\",\n id: null,\n error: { code: -32000, message: `transport error: ${err.message}` },\n });\n });\n }\n\n async send(message: JsonRpcMessage): Promise<void> {\n if (this.closed) throw new Error(\"MCP transport is closed\");\n return new Promise((resolve, reject) => {\n const line = `${JSON.stringify(message)}\\n`;\n this.child.stdin!.write(line, \"utf8\", (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n }\n\n async *messages(): AsyncIterableIterator<JsonRpcMessage> {\n while (true) {\n if (this.queue.length > 0) {\n yield this.queue.shift()!;\n continue;\n }\n if (this.closed) return;\n const next = await new Promise<JsonRpcMessage | null>((resolve) => {\n this.waiters.push(resolve);\n });\n if (next === null) return; // closed while we were waiting\n yield next;\n }\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n // Signal any pending waiters.\n while (this.waiters.length > 0) this.waiters.shift()!(null);\n try {\n this.child.stdin!.end();\n } catch {\n /* already ended */\n }\n if (this.child.exitCode === null && !this.child.killed) {\n // child.kill(\"SIGTERM\") throws EINVAL on Windows; plain kill()\n // can also throw on failed spawns. Swallow both.\n try {\n this.child.kill(process.platform === \"win32\" ? undefined : \"SIGTERM\");\n } catch {\n /* already exited or unsignallable */\n }\n }\n }\n\n /** Parse incoming stdout chunks into NDJSON messages. */\n private onStdout(chunk: string): void {\n this.stdoutBuffer += chunk;\n let newlineIdx: number;\n // biome-ignore lint/suspicious/noAssignInExpressions: idiomatic loop shape\n while ((newlineIdx = this.stdoutBuffer.indexOf(\"\\n\")) !== -1) {\n const line = this.stdoutBuffer.slice(0, newlineIdx).trim();\n this.stdoutBuffer = this.stdoutBuffer.slice(newlineIdx + 1);\n if (!line) continue;\n try {\n const msg = JSON.parse(line) as JsonRpcMessage;\n this.push(msg);\n } catch {\n // Malformed stdout lines are dropped — some servers emit startup\n // banners before the JSON-RPC loop begins. Surface only under\n // REASONIX_DEBUG_MCP=1; otherwise the noise corrupts the TUI render.\n if (process.env.REASONIX_DEBUG_MCP === \"1\") {\n process.stderr.write(`[mcp-stdio] dropped malformed line: ${line}\\n`);\n }\n }\n }\n }\n\n // Python MCP SDK writes info logs (`server.py:534 ListPromptsRequest`)\n // to stderr — letting those through would corrupt the TUI render.\n private onStderr(chunk: string): void {\n if (process.env.REASONIX_DEBUG_MCP === \"1\") {\n process.stderr.write(chunk);\n }\n }\n\n private onClose(): void {\n this.closed = true;\n while (this.waiters.length > 0) this.waiters.shift()!(null);\n }\n\n private push(msg: JsonRpcMessage): void {\n const waiter = this.waiters.shift();\n if (waiter) waiter(msg);\n else this.queue.push(msg);\n }\n}\n\nfunction quoteArg(s: string, windows: boolean): string {\n if (!windows) {\n // POSIX: single-quote, escape single quotes.\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n }\n // cmd.exe: double-quote, escape internal quotes by doubling.\n return `\"${s.replace(/\"/g, '\"\"')}\"`;\n}\n","/** MCP HTTP+SSE transport (spec 2024-11-05) — POST endpoint URL arrives as the first `event: endpoint` SSE frame. */\n\nimport { createParser } from \"eventsource-parser\";\nimport type { McpTransport } from \"./stdio.js\";\nimport type { JsonRpcMessage } from \"./types.js\";\n\nexport interface SseTransportOptions {\n /** SSE endpoint URL, e.g. `https://mcp.example.com/sse`. */\n url: string;\n /** Extra headers sent on both the SSE GET and the JSON-RPC POSTs (e.g. `Authorization`). */\n headers?: Record<string, string>;\n}\n\nexport class SseTransport implements McpTransport {\n private readonly url: string;\n private readonly headers: Record<string, string>;\n private readonly queue: JsonRpcMessage[] = [];\n private readonly waiters: Array<(m: JsonRpcMessage | null) => void> = [];\n private readonly controller = new AbortController();\n private closed = false;\n private postUrl: string | null = null;\n private readonly endpointReady: Promise<string>;\n private resolveEndpoint!: (url: string) => void;\n private rejectEndpoint!: (err: Error) => void;\n\n constructor(opts: SseTransportOptions) {\n this.url = opts.url;\n this.headers = opts.headers ?? {};\n this.endpointReady = new Promise<string>((resolve, reject) => {\n this.resolveEndpoint = resolve;\n this.rejectEndpoint = reject;\n });\n // Swallow unhandled-rejection noise if nobody ever calls send().\n this.endpointReady.catch(() => undefined);\n void this.runStream();\n }\n\n async send(message: JsonRpcMessage): Promise<void> {\n if (this.closed) throw new Error(\"MCP SSE transport is closed\");\n const postUrl = await this.endpointReady;\n const res = await fetch(postUrl, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", ...this.headers },\n body: JSON.stringify(message),\n signal: this.controller.signal,\n });\n // Drain body so the socket returns to the pool even if the server\n // elected to write one. We explicitly don't parse it — responses\n // arrive on the SSE channel.\n await res.arrayBuffer().catch(() => undefined);\n if (!res.ok) {\n throw new Error(`MCP SSE POST ${postUrl} failed: ${res.status} ${res.statusText}`);\n }\n }\n\n async *messages(): AsyncIterableIterator<JsonRpcMessage> {\n while (true) {\n if (this.queue.length > 0) {\n yield this.queue.shift()!;\n continue;\n }\n if (this.closed) return;\n const next = await new Promise<JsonRpcMessage | null>((resolve) => {\n this.waiters.push(resolve);\n });\n if (next === null) return;\n yield next;\n }\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n while (this.waiters.length > 0) this.waiters.shift()!(null);\n // Reject any still-pending send() that was waiting for the endpoint.\n this.rejectEndpoint(new Error(\"MCP SSE transport closed before endpoint was ready\"));\n try {\n this.controller.abort();\n } catch {\n /* already aborted */\n }\n }\n\n private async runStream(): Promise<void> {\n let res: Response;\n try {\n res = await fetch(this.url, {\n method: \"GET\",\n headers: { accept: \"text/event-stream\", ...this.headers },\n signal: this.controller.signal,\n });\n } catch (err) {\n this.failHandshake(`SSE connect to ${this.url} failed: ${(err as Error).message}`);\n return;\n }\n if (!res.ok || !res.body) {\n // Drain body to free the socket before giving up.\n await res.body?.cancel().catch(() => undefined);\n this.failHandshake(`SSE handshake ${this.url} → ${res.status} ${res.statusText}`);\n return;\n }\n\n const parser = createParser({\n onEvent: (ev) => this.handleEvent(ev.event ?? \"message\", ev.data),\n });\n const decoder = new TextDecoder();\n try {\n for await (const chunk of res.body as AsyncIterable<Uint8Array>) {\n parser.feed(decoder.decode(chunk, { stream: true }));\n }\n } catch (err) {\n if (!this.closed) {\n this.pushError(`SSE stream error: ${(err as Error).message}`);\n }\n } finally {\n this.markClosed();\n }\n }\n\n private handleEvent(type: string, data: string): void {\n if (type === \"endpoint\") {\n if (this.postUrl) return; // ignore repeat announcements\n try {\n this.postUrl = new URL(data, this.url).toString();\n this.resolveEndpoint(this.postUrl);\n } catch (err) {\n this.failHandshake(`SSE endpoint event had bad URL \"${data}\": ${(err as Error).message}`);\n }\n return;\n }\n if (type === \"message\") {\n try {\n const parsed = JSON.parse(data) as JsonRpcMessage;\n this.pushMessage(parsed);\n } catch {\n // Malformed JSON-RPC on an SSE frame — drop it, same as stdio.\n }\n return;\n }\n // Unknown event types (server pings, custom extensions) — ignore.\n }\n\n private failHandshake(reason: string): void {\n this.rejectEndpoint(new Error(reason));\n this.pushError(reason);\n this.markClosed();\n }\n\n private pushMessage(msg: JsonRpcMessage): void {\n const waiter = this.waiters.shift();\n if (waiter) waiter(msg);\n else this.queue.push(msg);\n }\n\n private pushError(message: string): void {\n this.pushMessage({\n jsonrpc: \"2.0\",\n id: null,\n error: { code: -32000, message },\n });\n }\n\n private markClosed(): void {\n if (this.closed) return;\n this.closed = true;\n while (this.waiters.length > 0) this.waiters.shift()!(null);\n }\n}\n","/** MCP Streamable HTTP transport (2025-03-26) — POST-only; no long-lived GET stream, no Last-Event-ID resume. */\n\nimport { createParser } from \"eventsource-parser\";\nimport type { McpTransport } from \"./stdio.js\";\nimport type { JsonRpcMessage } from \"./types.js\";\n\nexport interface StreamableHttpTransportOptions {\n /** Streamable HTTP endpoint URL, e.g. `https://mcp.example.com/mcp`. */\n url: string;\n /** Extra headers sent on every request (e.g. `Authorization`). */\n headers?: Record<string, string>;\n}\n\nconst SESSION_HEADER = \"mcp-session-id\";\n\nexport class StreamableHttpTransport implements McpTransport {\n private readonly url: string;\n private readonly extraHeaders: Record<string, string>;\n private readonly queue: JsonRpcMessage[] = [];\n private readonly waiters: Array<(m: JsonRpcMessage | null) => void> = [];\n private readonly controller = new AbortController();\n /** Session id minted by server on (typically) the initialize response. */\n private sessionId: string | null = null;\n private closed = false;\n /** Background SSE read-loops kicked off by send(); awaited on close(). */\n private readonly streams = new Set<Promise<void>>();\n\n constructor(opts: StreamableHttpTransportOptions) {\n this.url = opts.url;\n this.extraHeaders = opts.headers ?? {};\n }\n\n async send(message: JsonRpcMessage): Promise<void> {\n if (this.closed) throw new Error(\"MCP Streamable HTTP transport is closed\");\n const headers: Record<string, string> = {\n \"content-type\": \"application/json\",\n // Both accepted — server picks. application/json first signals a\n // mild preference for the simpler shape when the response is a\n // single message.\n accept: \"application/json, text/event-stream\",\n ...this.extraHeaders,\n };\n if (this.sessionId !== null) headers[\"mcp-session-id\"] = this.sessionId;\n\n let res: Response;\n try {\n res = await fetch(this.url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(message),\n signal: this.controller.signal,\n });\n } catch (err) {\n throw new Error(`MCP Streamable HTTP POST ${this.url} failed: ${(err as Error).message}`);\n }\n\n // Capture session id the first time the server hands one out.\n const serverSessionId = res.headers.get(SESSION_HEADER);\n if (serverSessionId && this.sessionId === null) {\n this.sessionId = serverSessionId;\n }\n\n if (res.status === 404 && this.sessionId !== null) {\n // Session expired / unknown to the server. Surface as an error so\n // McpClient can recreate; drain the body so the socket goes back\n // to the pool.\n await res.body?.cancel().catch(() => undefined);\n throw new Error(\n `MCP Streamable HTTP session expired (server returned 404 with Mcp-Session-Id \"${this.sessionId}\"). Reinitialize the client.`,\n );\n }\n\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(\n `MCP Streamable HTTP POST ${this.url} → ${res.status} ${res.statusText}${body ? `: ${body}` : \"\"}`,\n );\n }\n\n // 202 Accepted: request was a notification or pure ack — no body.\n if (res.status === 202) {\n await res.body?.cancel().catch(() => undefined);\n return;\n }\n\n const ct = (res.headers.get(\"content-type\") ?? \"\").toLowerCase();\n if (ct.includes(\"application/json\")) {\n let parsed: unknown;\n try {\n parsed = await res.json();\n } catch (err) {\n throw new Error(`MCP Streamable HTTP body wasn't valid JSON: ${(err as Error).message}`);\n }\n if (Array.isArray(parsed)) {\n for (const item of parsed) this.pushMessage(item as JsonRpcMessage);\n } else {\n this.pushMessage(parsed as JsonRpcMessage);\n }\n return;\n }\n\n if (ct.includes(\"text/event-stream\")) {\n // Stream may carry multiple events (progress notifications +\n // the eventual response). Read it concurrently with subsequent\n // sends — return as soon as the stream is wired so callers can\n // pipeline more requests.\n if (!res.body) {\n throw new Error(\"MCP Streamable HTTP SSE response had no body\");\n }\n const stream = this.consumeStream(res.body as AsyncIterable<Uint8Array>);\n this.streams.add(stream);\n stream.finally(() => this.streams.delete(stream));\n return;\n }\n\n // Unknown content type — drain and treat as a no-op rather than\n // hanging. Servers that want to extend the protocol should not\n // wedge older clients with an unexpected MIME.\n await res.body?.cancel().catch(() => undefined);\n }\n\n async *messages(): AsyncIterableIterator<JsonRpcMessage> {\n while (true) {\n if (this.queue.length > 0) {\n yield this.queue.shift()!;\n continue;\n }\n if (this.closed) return;\n const next = await new Promise<JsonRpcMessage | null>((resolve) => {\n this.waiters.push(resolve);\n });\n if (next === null) return;\n yield next;\n }\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n while (this.waiters.length > 0) this.waiters.shift()!(null);\n try {\n this.controller.abort();\n } catch {\n /* already aborted */\n }\n // Wait for any in-flight SSE streams to wind down so a subsequent\n // process.exit() doesn't trip on a hanging socket. Cap at \"done\";\n // controller.abort() above unblocks them.\n await Promise.allSettled(Array.from(this.streams));\n }\n\n /** Visible for tests — confirm session header round-trip. */\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n private async consumeStream(body: AsyncIterable<Uint8Array>): Promise<void> {\n const parser = createParser({\n onEvent: (ev) => {\n // Per spec, server-side events use the `message` event type\n // (default if `event:` line is missing). Other event types\n // (server pings, custom extensions) we silently ignore.\n const type = ev.event ?? \"message\";\n if (type !== \"message\") return;\n try {\n const parsed = JSON.parse(ev.data) as JsonRpcMessage;\n this.pushMessage(parsed);\n } catch {\n /* malformed JSON — drop, mirror SSE behavior */\n }\n },\n });\n const decoder = new TextDecoder();\n try {\n for await (const chunk of body) {\n if (this.closed) break;\n parser.feed(decoder.decode(chunk, { stream: true }));\n }\n } catch (err) {\n if (!this.closed) {\n this.pushMessage({\n jsonrpc: \"2.0\",\n id: null,\n error: {\n code: -32000,\n message: `Streamable HTTP stream error: ${(err as Error).message}`,\n },\n });\n }\n }\n }\n\n private pushMessage(msg: JsonRpcMessage): void {\n const waiter = this.waiters.shift();\n if (waiter) waiter(msg);\n else this.queue.push(msg);\n }\n}\n"],"mappings":"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","names":["resolve","resolve","resolve","resolve"]}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
compileFilters,
|
|
9
9
|
defaultIndexConfig,
|
|
10
10
|
resolveSemanticEmbeddingConfig
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MXWPAPZW.js";
|
|
12
12
|
|
|
13
13
|
// src/index/semantic/builder.ts
|
|
14
14
|
import { promises as fs3 } from "fs";
|
|
@@ -882,4 +882,4 @@ export {
|
|
|
882
882
|
indexExists,
|
|
883
883
|
indexCompatible
|
|
884
884
|
};
|
|
885
|
-
//# sourceMappingURL=chunk-
|
|
885
|
+
//# sourceMappingURL=chunk-AAHB2PFX.js.map
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
|
|
3
3
|
import {
|
|
4
4
|
t
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-PYIZZAVQ.js";
|
|
6
6
|
import {
|
|
7
7
|
projectHooksTrusted
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MXWPAPZW.js";
|
|
9
9
|
|
|
10
10
|
// src/hooks.ts
|
|
11
11
|
import { spawn } from "child_process";
|
|
@@ -209,4 +209,4 @@ export {
|
|
|
209
209
|
formatHookOutcomeMessage,
|
|
210
210
|
runHooks
|
|
211
211
|
};
|
|
212
|
-
//# sourceMappingURL=chunk-
|
|
212
|
+
//# sourceMappingURL=chunk-AJIZ5KFK.js.map
|
|
@@ -3,18 +3,18 @@ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.requi
|
|
|
3
3
|
import {
|
|
4
4
|
formatMcpLifecycleEvent,
|
|
5
5
|
formatMcpSlowToast
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-7WITYWKN.js";
|
|
7
7
|
import {
|
|
8
8
|
buildTransportFromSpec,
|
|
9
9
|
preflightStdioSpec
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-SVD4UPRQ.js";
|
|
11
11
|
import {
|
|
12
12
|
bridgeMcpTools
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-GPUH2BNM.js";
|
|
14
14
|
import {
|
|
15
15
|
McpClient,
|
|
16
16
|
inspectMcpServer
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-7YPMTE3U.js";
|
|
18
18
|
import {
|
|
19
19
|
wrapper_default
|
|
20
20
|
} from "./chunk-FEZK652I.js";
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
} from "./chunk-2UQP6H6T.js";
|
|
24
24
|
import {
|
|
25
25
|
t
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-PYIZZAVQ.js";
|
|
27
27
|
import {
|
|
28
28
|
decideQQAccess,
|
|
29
29
|
describeQQAccess,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
readConfig,
|
|
37
37
|
redactQQOpenId,
|
|
38
38
|
specToRaw
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-MXWPAPZW.js";
|
|
40
40
|
|
|
41
41
|
// src/qq/channel.ts
|
|
42
42
|
import { mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
|
|
@@ -635,8 +635,9 @@ function createMcpRuntime(ctx) {
|
|
|
635
635
|
const t0 = Date.now();
|
|
636
636
|
const namePrefix = spec.name ? `${spec.name}_` : ctx.getRequestedCount() === 1 && ctx.getMcpPrefix() ? ctx.getMcpPrefix() : "";
|
|
637
637
|
if (spec.transport === "stdio") preflightStdioSpec(spec);
|
|
638
|
-
const
|
|
639
|
-
|
|
638
|
+
const workspaceDir = ctx.getWorkspaceDir?.();
|
|
639
|
+
const transport = buildTransportFromSpec(spec, { cwd: workspaceDir });
|
|
640
|
+
mcp = new McpClient({ transport, workspaceDir });
|
|
640
641
|
await mcp.initialize({ signal });
|
|
641
642
|
const host = { client: mcp };
|
|
642
643
|
const bridge = await bridgeMcpTools(mcp, {
|
|
@@ -828,4 +829,4 @@ export {
|
|
|
828
829
|
QQChannel,
|
|
829
830
|
createMcpRuntime
|
|
830
831
|
};
|
|
831
|
-
//# sourceMappingURL=chunk-
|
|
832
|
+
//# sourceMappingURL=chunk-ALCOQP6R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/qq/channel.ts","../../src/qq/bot.ts","../../src/qq/strings.ts","../../src/mcp/summary.ts","../../src/cli/commands/mcp-runtime.ts"],"sourcesContent":["import { mkdirSync, readFileSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { loadQQConfig } from \"../config.js\";\nimport { loadDotenv } from \"../env.js\";\nimport { t } from \"../i18n/index.js\";\nimport { decideQQAccess, describeQQAccess, redactQQOpenId } from \"./access.js\";\nimport { type C2CMessage, QQBot } from \"./bot.js\";\nimport { formatQQAccessSummary } from \"./strings.js\";\n\nconst QQ_LOCK_FILE = join(homedir(), \".reasonix\", \"qq-channel.pid\");\nconst QQ_MAX_CHUNK_BYTES = 1500;\nconst NATURAL_SPLIT_MIN_FRACTION = 0.6;\n\nfunction fitUtf8Slice(text: string, maxBytes: number): string {\n let end = 0;\n let bytes = 0;\n for (const char of text) {\n const nextBytes = Buffer.byteLength(char, \"utf8\");\n if (bytes > 0 && bytes + nextBytes > maxBytes) break;\n end += char.length;\n bytes += nextBytes;\n }\n return end > 0 ? text.slice(0, end) : text.slice(0, 1);\n}\n\nfunction pickNaturalSplit(candidate: string): number {\n const minSplit = Math.floor(candidate.length * NATURAL_SPLIT_MIN_FRACTION);\n const splitters = [\"\\n\\n\", \"\\n\", \" \"];\n for (const splitter of splitters) {\n const at = candidate.lastIndexOf(splitter);\n if (at >= minSplit) return at + splitter.length;\n }\n return candidate.length;\n}\n\nexport function splitQQMessage(text: string, maxBytes = QQ_MAX_CHUNK_BYTES): string[] {\n const chunks: string[] = [];\n let remaining = text;\n while (remaining.length > 0) {\n if (Buffer.byteLength(remaining, \"utf8\") <= maxBytes) {\n chunks.push(remaining);\n break;\n }\n\n const candidate = fitUtf8Slice(remaining, maxBytes);\n const splitAt = pickNaturalSplit(candidate);\n chunks.push(candidate.slice(0, splitAt));\n remaining = remaining.slice(splitAt).trimStart();\n }\n return chunks;\n}\n\nexport class QQChannel {\n private bot: QQBot | null = null;\n private qqUserId: string | null = null;\n private qqMessageId: string | null = null;\n private ownerOpenId: string | undefined;\n private allowlist: string[] | undefined;\n private runtimeBoundOpenId: string | null = null;\n private processedMsgIds = new Set<string>();\n private processedMsgIdQueue: string[] = [];\n private lockAcquired = false;\n private nextOutboundMsgSeq = 1;\n\n constructor(\n private callbacks: {\n onSubmitMessage: (text: string) => void;\n onError?: (msg: string) => void;\n },\n ) {}\n\n private rememberMessage(id: string): boolean {\n if (this.processedMsgIds.has(id)) return false;\n this.processedMsgIds.add(id);\n this.processedMsgIdQueue.push(id);\n if (this.processedMsgIdQueue.length > 200) {\n const oldest = this.processedMsgIdQueue.shift();\n if (oldest) this.processedMsgIds.delete(oldest);\n }\n return true;\n }\n\n private acquireLock(): void {\n try {\n const existing = Number(readFileSync(QQ_LOCK_FILE, \"utf8\").trim());\n if (Number.isInteger(existing) && existing > 0 && existing !== process.pid) {\n try {\n process.kill(existing, 0);\n throw new Error(t(\"handlers.qq.lockAlreadyRunning\", { pid: existing }));\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code !== \"ESRCH\") throw err;\n }\n }\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code !== \"ENOENT\") throw err;\n }\n\n mkdirSync(dirname(QQ_LOCK_FILE), { recursive: true });\n writeFileSync(QQ_LOCK_FILE, String(process.pid), \"utf8\");\n this.lockAcquired = true;\n }\n\n private releaseLock(): void {\n if (!this.lockAcquired) return;\n try {\n const existing = Number(readFileSync(QQ_LOCK_FILE, \"utf8\").trim());\n if (existing === process.pid) unlinkSync(QQ_LOCK_FILE);\n } catch {}\n this.lockAcquired = false;\n }\n\n private applyAccessConfig(config: ReturnType<typeof loadQQConfig>): void {\n this.ownerOpenId = config.ownerOpenId;\n this.allowlist = config.allowlist;\n if (this.ownerOpenId || (this.allowlist?.length ?? 0) > 0) {\n this.runtimeBoundOpenId = null;\n }\n }\n\n private handlePrivateMessage(msg: C2CMessage): void {\n const text = msg.content?.trim();\n if (!text) return;\n if (!this.rememberMessage(msg.id)) return;\n\n const openid = msg.author.user_openid;\n const verdict = decideQQAccess(\n {\n ownerOpenId: this.ownerOpenId,\n allowlist: this.allowlist,\n runtimeBoundOpenId: this.runtimeBoundOpenId,\n },\n openid,\n );\n if (!verdict.accept) {\n this.callbacks.onError?.(\n t(\"handlers.qq.unauthorizedMessage\", {\n openid: redactQQOpenId(openid),\n access: formatQQAccessSummary({\n ownerOpenId: this.ownerOpenId,\n allowlist: this.allowlist,\n runtimeBoundOpenId: this.runtimeBoundOpenId,\n }),\n }),\n );\n return;\n }\n if (verdict.bindRuntime) {\n this.runtimeBoundOpenId = openid;\n this.callbacks.onError?.(\n t(\"handlers.qq.runtimeBound\", {\n openid: redactQQOpenId(openid),\n }),\n );\n }\n\n this.qqUserId = openid;\n this.qqMessageId = msg.id;\n this.callbacks.onSubmitMessage(`[QQ] ${text}`);\n }\n\n refreshAccessConfig(): void {\n this.applyAccessConfig(loadQQConfig());\n }\n\n describeAccess(): string {\n return describeQQAccess({\n ownerOpenId: this.ownerOpenId,\n allowlist: this.allowlist,\n runtimeBoundOpenId: this.runtimeBoundOpenId,\n });\n }\n\n getRuntimeBoundOpenId(): string | null {\n return this.runtimeBoundOpenId;\n }\n\n async start(): Promise<void> {\n loadDotenv();\n this.acquireLock();\n\n const config = loadQQConfig();\n if (!config.appId) {\n this.releaseLock();\n throw new Error(t(\"handlers.qq.missingAppId\"));\n }\n if (!config.appSecret) {\n this.releaseLock();\n throw new Error(t(\"handlers.qq.missingAppSecret\"));\n }\n this.applyAccessConfig(config);\n\n const bot = new QQBot({\n appid: config.appId,\n secret: config.appSecret,\n sandbox: config.sandbox ?? false,\n });\n\n bot.on(\"online\", () => {\n process.stderr.write(\"QQ bot is online!\\n\");\n });\n\n bot.on(\"bot_error\", (msg: string) => {\n this.callbacks.onError?.(msg);\n });\n\n bot.on(\"message.private\", (msg: C2CMessage) => {\n this.handlePrivateMessage(msg);\n });\n\n this.bot = bot;\n\n try {\n await bot.start();\n\n const readyOrError = await Promise.race([\n new Promise<\"ready\">((resolve) => bot.once(\"online\", () => resolve(\"ready\"))),\n new Promise<\"error\">((resolve) => bot.once(\"bot_error\", () => resolve(\"error\"))),\n new Promise<\"timeout\">((resolve) => setTimeout(() => resolve(\"timeout\"), 15_000)),\n ]);\n\n if (readyOrError === \"error\") {\n throw new Error(t(\"handlers.qq.authFailed\"));\n }\n if (readyOrError === \"timeout\") {\n throw new Error(t(\"handlers.qq.readyTimeout\"));\n }\n } catch (err) {\n this.releaseLock();\n throw err;\n }\n }\n\n async sendResponse(text: string): Promise<void> {\n if (!this.bot || !this.qqUserId) return;\n const chunks = splitQQMessage(text);\n for (let index = 0; index < chunks.length; index++) {\n const chunk = chunks[index];\n if (!chunk) continue;\n try {\n await this.bot.sendPrivateMessage(\n this.qqUserId,\n chunk,\n this.qqMessageId ?? undefined,\n this.nextOutboundMsgSeq++,\n );\n } catch (err) {\n const msg = `QQ sendResponse chunk ${index + 1}/${chunks.length} failed: ${(err as Error).message}`;\n this.callbacks.onError?.(msg);\n break;\n }\n }\n }\n\n async stop(): Promise<void> {\n await this.bot?.stop();\n this.releaseLock();\n }\n}\n","import { EventEmitter } from \"node:events\";\nimport WebSocket from \"ws\";\n\nconst TOKEN_URL = \"https://bots.qq.com/app/getAppAccessToken\";\nconst BASE_URL = \"https://api.sgroup.qq.com\";\nconst SANDBOX_URL = \"https://sandbox.api.sgroup.qq.com\";\nconst INTENT_C2C_GROUP = 1 << 25;\nconst MIN_HEARTBEAT_INTERVAL_MS = 5_000;\nconst MAX_HEARTBEAT_INTERVAL_MS = 60_000;\nconst ALLOWED_GATEWAY_HOSTS = [\"api.sgroup.qq.com\", \"sandbox.api.sgroup.qq.com\", \"qq.com\"];\n\ninterface QQBotConfig {\n appid: string;\n secret: string;\n sandbox?: boolean;\n}\n\nexport interface C2CMessage {\n author: { user_openid: string };\n content: string;\n id: string;\n timestamp: string;\n}\n\nexport class QQBot extends EventEmitter {\n private config: QQBotConfig;\n private token = \"\";\n private tokenExpiresAt = 0;\n private ws: WebSocket | null = null;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private seq = 0;\n private sessionId = \"\";\n private closed = false;\n private readyReceived = false;\n\n constructor(config: QQBotConfig) {\n super();\n this.config = config;\n }\n\n private get baseUrl(): string {\n return this.config.sandbox ? SANDBOX_URL : BASE_URL;\n }\n\n private sanitizeHeartbeatInterval(interval: unknown): number | null {\n if (typeof interval !== \"number\" || !Number.isFinite(interval)) {\n return null;\n }\n if (interval < MIN_HEARTBEAT_INTERVAL_MS) {\n return MIN_HEARTBEAT_INTERVAL_MS;\n }\n if (interval > MAX_HEARTBEAT_INTERVAL_MS) {\n return MAX_HEARTBEAT_INTERVAL_MS;\n }\n return Math.trunc(interval);\n }\n\n private validateGatewayUrl(rawUrl: string): string {\n const url = new URL(rawUrl);\n const trustedHost = ALLOWED_GATEWAY_HOSTS.some(\n (host) => url.hostname === host || url.hostname.endsWith(`.${host}`),\n );\n if (\n url.protocol !== \"wss:\" ||\n !trustedHost ||\n url.username ||\n url.password ||\n url.search ||\n url.hash\n ) {\n throw new Error(`Unexpected QQ gateway URL: ${rawUrl}`);\n }\n return url.toString();\n }\n\n private async ensureToken(): Promise<string> {\n if (this.token && Date.now() < this.tokenExpiresAt - 60_000) {\n return this.token;\n }\n const res = await fetch(TOKEN_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n appId: this.config.appid,\n clientSecret: this.config.secret,\n }),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Failed to get access token (${res.status}): ${text}`);\n }\n const data = (await res.json()) as {\n access_token: string;\n expires_in: number;\n };\n this.token = data.access_token;\n this.tokenExpiresAt = Date.now() + data.expires_in * 1000;\n return this.token;\n }\n\n private async getGateway(): Promise<string> {\n const token = await this.ensureToken();\n const res = await fetch(`${this.baseUrl}/gateway`, {\n headers: { Authorization: `QQBot ${token}` },\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Failed to get gateway (${res.status}): ${text}`);\n }\n const data = (await res.json()) as { url: string };\n return this.validateGatewayUrl(data.url);\n }\n\n private sendOp(op: number, data?: unknown) {\n if (!this.ws) return;\n this.ws.send(JSON.stringify({ op, d: data ?? {} }));\n }\n\n private async handlePayload(payload: {\n op: number;\n d?: Record<string, unknown>;\n s?: number;\n t?: string;\n }) {\n switch (payload.op) {\n case 10: {\n const d = payload.d as { heartbeat_interval: number } | undefined;\n this.sendOp(2, {\n token: `QQBot ${await this.ensureToken()}`,\n intents: INTENT_C2C_GROUP,\n shard: [0, 1],\n });\n const heartbeatInterval = this.sanitizeHeartbeatInterval(d?.heartbeat_interval);\n if (heartbeatInterval) {\n this.heartbeatTimer = setInterval(() => {\n this.sendOp(1, this.seq || null);\n }, heartbeatInterval);\n }\n break;\n }\n case 0: {\n if (payload.s) this.seq = payload.s;\n if (payload.t === \"READY\") {\n const d = payload.d as { session_id: string; user?: { id: string } };\n this.sessionId = d.session_id;\n this.readyReceived = true;\n this.emit(\"online\");\n } else if (payload.t === \"C2C_MESSAGE_CREATE\") {\n this.emit(\"message.private\", payload.d as unknown as C2CMessage);\n } else if (payload.t === \"GROUP_AT_MESSAGE_CREATE\") {\n this.emit(\"message.group\", payload.d);\n }\n break;\n }\n case 7: {\n this.reconnect();\n break;\n }\n case 9: {\n this.sessionId = \"\";\n this.sendOp(2, {\n token: `QQBot ${await this.ensureToken()}`,\n intents: INTENT_C2C_GROUP,\n shard: [0, 1],\n });\n break;\n }\n }\n }\n\n private async reconnect() {\n this.cleanup();\n await this.connect();\n }\n\n private cleanup() {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n if (this.ws) {\n this.ws.removeAllListeners();\n this.ws.close();\n this.ws = null;\n }\n }\n\n private async connect() {\n const gatewayUrl = await this.getGateway();\n const token = await this.ensureToken();\n this.ws = new WebSocket(gatewayUrl, {\n headers: {\n Authorization: `QQBot ${token}`,\n \"X-Union-Appid\": this.config.appid,\n },\n });\n\n this.ws.on(\"open\", () => {\n if (this.sessionId) {\n this.sendOp(6, {\n token: `QQBot ${this.token}`,\n session_id: this.sessionId,\n seq: this.seq,\n });\n }\n });\n\n this.ws.on(\"message\", (raw: WebSocket.RawData) => {\n try {\n const payload = JSON.parse(raw.toString());\n this.handlePayload(payload).catch(() => {});\n } catch {\n // ignore parse errors\n }\n });\n\n this.ws.on(\"close\", () => {\n if (!this.closed) {\n if (this.readyReceived) {\n // Was online — transient disconnect, reconnect.\n console.error(\"QQ WebSocket reconnecting...\");\n this.cleanup();\n setTimeout(() => this.reconnect(), 3000);\n } else {\n // Never received READY — authentication or network failure.\n const msg =\n \"QQ WebSocket closed before authentication completed — check your appId and appSecret\";\n this.emit(\"bot_error\", msg);\n this.closed = true; // prevent further reconnect attempts\n }\n }\n });\n\n this.ws.on(\"error\", (err: Error) => {\n const msg = `QQ WebSocket error: ${err.message}`;\n console.error(msg);\n this.emit(\"bot_error\", msg);\n });\n }\n\n async start(): Promise<void> {\n this.closed = false;\n this.readyReceived = false;\n await this.connect();\n }\n\n async stop(): Promise<void> {\n this.closed = true;\n this.cleanup();\n }\n\n async sendPrivateMessage(\n openid: string,\n content: string,\n msgId?: string,\n msgSeq?: number,\n ): Promise<void> {\n const token = await this.ensureToken();\n const body: Record<string, unknown> = {\n content,\n msg_type: 0,\n };\n if (msgId) body.msg_id = msgId;\n if (typeof msgSeq === \"number\" && Number.isFinite(msgSeq)) body.msg_seq = Math.trunc(msgSeq);\n const res = await fetch(`${this.baseUrl}/v2/users/${encodeURIComponent(openid)}/messages`, {\n method: \"POST\",\n headers: {\n Authorization: `QQBot ${token}`,\n \"Content-Type\": \"application/json\",\n \"X-Union-Appid\": this.config.appid,\n },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const text = await res.text();\n const msg = `QQ sendPrivateMessage failed (${res.status}): ${text}`;\n throw new Error(msg);\n }\n }\n}\n","import { t } from \"../i18n/index.js\";\nimport {\n type QQAccessConfig,\n normalizeQQAllowlist,\n normalizeQQOpenId,\n redactQQOpenId,\n} from \"./access.js\";\n\nexport type QQSetupStep = \"appId\" | \"appSecret\";\n\nexport function formatQQModeLabel(codeMode: boolean): string {\n return t(codeMode ? \"handlers.qq.modeCode\" : \"handlers.qq.modeChat\");\n}\n\nexport function formatQQAccessSummary(config: QQAccessConfig): string {\n const ownerOpenId = normalizeQQOpenId(config.ownerOpenId);\n const allowlist = normalizeQQAllowlist(config.allowlist) ?? [];\n const runtimeBoundOpenId = normalizeQQOpenId(config.runtimeBoundOpenId);\n\n if (ownerOpenId) {\n if (allowlist.length > 0) {\n return t(\"handlers.qq.accessOwnerWithAllowlist\", {\n owner: redactQQOpenId(ownerOpenId),\n count: allowlist.length,\n });\n }\n return t(\"handlers.qq.accessOwner\", {\n owner: redactQQOpenId(ownerOpenId),\n });\n }\n if (allowlist.length > 0) {\n return t(\"handlers.qq.accessAllowlist\", { count: allowlist.length });\n }\n if (runtimeBoundOpenId) {\n return t(\"handlers.qq.accessRuntime\", {\n owner: redactQQOpenId(runtimeBoundOpenId),\n });\n }\n return t(\"handlers.qq.accessOpen\");\n}\n\nexport function formatQQSetupPrompt(step: QQSetupStep): string {\n return t(step === \"appId\" ? \"handlers.qq.promptAppId\" : \"handlers.qq.promptAppSecret\");\n}\n\nexport function formatQQSetupWaiting(step: QQSetupStep): string {\n return t(\n step === \"appId\" ? \"handlers.qq.setupWaitingAppId\" : \"handlers.qq.setupWaitingAppSecret\",\n );\n}\n","import type { InspectionReport } from \"./inspect.js\";\nimport type { BridgeEnv, McpClientHost } from \"./registry.js\";\nimport type { GetPromptResult, ReadResourceResult } from \"./types.js\";\n\nexport interface McpServerSummary {\n label: string;\n spec: string;\n toolCount: number;\n report: InspectionReport;\n host: McpClientHost;\n bridgeEnv: BridgeEnv;\n readResource(uri: string): Promise<ReadResourceResult>;\n getPrompt(name: string, args?: Record<string, string>): Promise<GetPromptResult>;\n}\n\nexport function buildMcpServerSummary(opts: {\n label: string;\n spec: string;\n toolCount: number;\n report: InspectionReport;\n host: McpClientHost;\n bridgeEnv: BridgeEnv;\n}): McpServerSummary {\n return {\n label: opts.label,\n spec: opts.spec,\n toolCount: opts.toolCount,\n report: opts.report,\n host: opts.host,\n bridgeEnv: opts.bridgeEnv,\n readResource(uri) {\n return opts.host.client.readResource(uri);\n },\n getPrompt(name, args) {\n return args !== undefined\n ? opts.host.client.getPrompt(name, args)\n : opts.host.client.getPrompt(name);\n },\n };\n}\n","import { normalizeMcpConfig, readConfig } from \"../../config.js\";\nimport { t } from \"../../i18n/index.js\";\nimport type { CacheFirstLoop } from \"../../loop.js\";\nimport { McpClient } from \"../../mcp/client.js\";\nimport { type InspectionReport, inspectMcpServer } from \"../../mcp/inspect.js\";\nimport { preflightStdioSpec } from \"../../mcp/preflight.js\";\nimport { type McpClientHost, bridgeMcpTools } from \"../../mcp/registry.js\";\nimport { overlayMatchedSpec, parseMcpSpec, specToRaw } from \"../../mcp/spec.js\";\nimport { buildMcpServerSummary } from \"../../mcp/summary.js\";\nimport { buildTransportFromSpec } from \"../../mcp/transport-from-spec.js\";\nimport type { ToolRegistry } from \"../../tools.js\";\nimport type { ToolSpec } from \"../../types.js\";\nimport { type McpLifecycleEvent, formatMcpLifecycleEvent } from \"../ui/mcp-lifecycle.js\";\nimport { formatMcpSlowToast } from \"../ui/mcp-toast.js\";\nimport type { McpServerSummary } from \"../ui/slash.js\";\n\nexport interface ProgressInfo {\n toolName: string;\n progress: number;\n total?: number;\n message?: string;\n}\n\ninterface SpecRecord {\n spec: string;\n client: McpClient;\n summary: McpServerSummary;\n /** Names of bridged tools — used for hot-unbridge. */\n registeredNames: string[];\n /** ToolSpec snapshots captured AFTER bridge — handed to loop.prefix.addTool on hot-add. */\n registeredSpecs: ToolSpec[];\n}\n\nexport interface RuntimeContext {\n getTools: () => ToolRegistry | undefined;\n getMcpPrefix: () => string | undefined;\n getRequestedCount: () => number;\n getWorkspaceDir?: () => string | undefined;\n progressSink: { current: ((info: ProgressInfo) => void) | null };\n}\n\nexport type McpLifecycleNotice =\n | { kind: \"handshake\"; name: string }\n | {\n kind: \"connected\";\n name: string;\n tools: number;\n resources: number;\n prompts: number;\n ms: number;\n }\n | { kind: \"disabled\"; name: string }\n | { kind: \"failed\"; name: string; reason: string }\n | { kind: \"slow\"; serverName: string; p95Ms: number; sampleSize: number }\n | { kind: \"tools-ready\"; name: string; tools: number; ms: number }\n | { kind: \"warn\"; name: string; reason: string };\n\nexport type McpLifecycleSink = (notice: McpLifecycleNotice) => void;\n\nexport const stderrLifecycleSink: McpLifecycleSink = (n) => {\n if (n.kind === \"slow\") {\n process.stderr.write(\n `${formatMcpSlowToast({ name: n.serverName, p95Ms: n.p95Ms, sampleSize: n.sampleSize })}\\n`,\n );\n return;\n }\n if (n.kind === \"failed\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: \"failed\", name: n.name, reason: n.reason })}\\n → ${t(\"mcpLifecycle.failedSetupHint\")}\\n`,\n );\n return;\n }\n if (n.kind === \"connected\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({\n state: \"connected\",\n name: n.name,\n tools: n.tools,\n resources: n.resources,\n prompts: n.prompts,\n ms: n.ms,\n })}\\n`,\n );\n return;\n }\n if (n.kind === \"tools-ready\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: \"tools-ready\", name: n.name, tools: n.tools, ms: n.ms })}\\n`,\n );\n return;\n }\n if (n.kind === \"warn\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: \"warn\", name: n.name, reason: n.reason })}\\n`,\n );\n return;\n }\n // handshake / disabled — no extra fields needed\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: n.kind as \"handshake\" | \"disabled\", name: n.name })}\\n`,\n );\n};\n\nexport interface McpFailure {\n spec: string;\n name: string;\n reason: string;\n at: number;\n}\n\nexport interface McpRuntime {\n size(): number;\n specs(): string[];\n summaries(): McpServerSummary[];\n /** Last bridge failure per spec — drives the \"未桥接\" reason shown in the dashboard. */\n failures(): McpFailure[];\n addSpec(\n raw: string,\n loop?: CacheFirstLoop,\n signal?: AbortSignal,\n ): Promise<{ ok: true; summary: McpServerSummary } | { ok: false; reason: string }>;\n removeSpec(raw: string, loop?: CacheFirstLoop): Promise<boolean>;\n reloadFromConfig(loop?: CacheFirstLoop): Promise<{\n added: string[];\n removed: string[];\n failed: Array<{ spec: string; reason: string }>;\n summaries: McpServerSummary[];\n }>;\n closeAll(): Promise<void>;\n /** Replace the sink that lifecycle events flow through — App.tsx swaps this in on mount so toasts land in the alt-screen UI instead of corrupting it via stderr. */\n setLifecycleSink(sink: McpLifecycleSink): void;\n}\n\nexport function createMcpRuntime(ctx: RuntimeContext): McpRuntime {\n const records = new Map<string, SpecRecord>();\n const insertionOrder: string[] = [];\n const failureMap = new Map<string, McpFailure>();\n let sink: McpLifecycleSink = stderrLifecycleSink;\n\n async function addSpec(\n raw: string,\n loop?: CacheFirstLoop,\n signal?: AbortSignal,\n ): Promise<{ ok: true; summary: McpServerSummary } | { ok: false; reason: string }> {\n if (records.has(raw)) {\n return { ok: true, summary: records.get(raw)!.summary };\n }\n failureMap.delete(raw);\n const tools = ctx.getTools();\n if (!tools) return { ok: false, reason: \"no tool registry available\" };\n const cfg = readConfig();\n const normalized = normalizeMcpConfig(cfg);\n let label = \"anon\";\n let mcp: McpClient | undefined;\n // Per-server readiness gate — tool dispatches via the bridge await\n // this before calling into `live.callTool`. Resolved on `connected`,\n // rejected on `failed`, so a tool invoked mid-handshake waits\n // (capped by `bridgeMcpTools`'s `readyTimeoutMs`) instead of\n // surfacing a transport error.\n let resolveReady!: () => void;\n let rejectReady!: (err: Error) => void;\n const ready = new Promise<void>((resolve, reject) => {\n resolveReady = resolve;\n rejectReady = reject;\n });\n // Avoid unhandledRejection if no consumer awaits `ready` yet.\n ready.catch(() => undefined);\n try {\n const parsed = parseMcpSpec(raw);\n label = parsed.name ?? \"anon\";\n const matched = parsed.name ? normalized.find((s) => s.name === parsed.name) : undefined;\n const spec = overlayMatchedSpec(parsed, matched);\n if (spec.disabled) {\n sink({ kind: \"disabled\", name: label });\n rejectReady(new Error(`MCP server \"${label}\" is disabled`));\n failureMap.set(raw, { spec: raw, name: label, reason: \"disabled by user\", at: Date.now() });\n return { ok: false, reason: \"disabled by user\" };\n }\n sink({ kind: \"handshake\", name: label });\n const t0 = Date.now();\n const namePrefix = spec.name\n ? `${spec.name}_`\n : ctx.getRequestedCount() === 1 && ctx.getMcpPrefix()\n ? (ctx.getMcpPrefix() as string)\n : \"\";\n if (spec.transport === \"stdio\") preflightStdioSpec(spec);\n const workspaceDir = ctx.getWorkspaceDir?.();\n const transport = buildTransportFromSpec(spec, { cwd: workspaceDir });\n mcp = new McpClient({ transport, workspaceDir });\n await mcp.initialize({ signal });\n const host: McpClientHost = { client: mcp };\n const bridge = await bridgeMcpTools(mcp, {\n registry: tools,\n namePrefix,\n serverName: label,\n host,\n ready,\n onProgress: (info) => ctx.progressSink.current?.(info),\n onSlow: (info) =>\n sink({\n kind: \"slow\",\n serverName: info.serverName,\n p95Ms: info.p95Ms,\n sampleSize: info.sampleSize,\n }),\n });\n // Tools are registered — record the bridge NOW so the UI shows\n // \"bridged\" even if later non-critical steps (inspect, hot-add) fail.\n const ms = Date.now() - t0;\n const allSpecs = tools.specs();\n const registeredSpecs = allSpecs.filter((s) =>\n bridge.registeredNames.includes(s.function.name),\n );\n // Create a provisional record immediately (tools already usable).\n records.set(raw, {\n spec: raw,\n client: mcp,\n summary: buildMcpServerSummary({\n label,\n spec: raw,\n toolCount: bridge.registeredNames.length,\n report: {\n protocolVersion: mcp.protocolVersion,\n serverInfo: mcp.serverInfo,\n capabilities: mcp.serverCapabilities ?? {},\n tools: { supported: true, items: [] },\n resources: { supported: false, reason: \"still inspecting\" },\n prompts: { supported: false, reason: \"still inspecting\" },\n elapsedMs: ms,\n },\n host,\n bridgeEnv: bridge.env,\n }),\n registeredNames: bridge.registeredNames,\n registeredSpecs,\n });\n insertionOrder.push(raw);\n resolveReady();\n sink({\n kind: \"tools-ready\",\n name: label,\n tools: bridge.registeredNames.length,\n ms,\n });\n\n // Non-critical: inspect + hot-add. Failures here don't un-bridge.\n let report: InspectionReport;\n try {\n report = await inspectMcpServer(mcp);\n } catch {\n report = {\n protocolVersion: mcp.protocolVersion,\n serverInfo: mcp.serverInfo,\n capabilities: mcp.serverCapabilities ?? {},\n tools: { supported: true, items: [] },\n resources: { supported: false, reason: \"inspect failed\" },\n prompts: { supported: false, reason: \"inspect failed\" },\n elapsedMs: 0,\n };\n }\n const resourceCount = report.resources.supported ? report.resources.items.length : 0;\n const promptCount = report.prompts.supported ? report.prompts.items.length : 0;\n // Re-emit with full inspection data (the provisional event reported 0).\n sink({\n kind: \"connected\",\n name: label,\n tools: bridge.registeredNames.length,\n resources: resourceCount,\n prompts: promptCount,\n ms,\n });\n const summary = buildMcpServerSummary({\n label,\n spec: raw,\n toolCount: bridge.registeredNames.length,\n report,\n host,\n bridgeEnv: bridge.env,\n });\n // Replace the provisional record with the fully-inspected summary.\n records.set(raw, {\n spec: raw,\n client: mcp,\n summary,\n registeredNames: bridge.registeredNames,\n registeredSpecs,\n });\n // Hot-add: shift the prefix so the live loop sees the new tools\n // on the very next turn. Each addTool is one cache-miss turn.\n if (loop)\n for (const s of registeredSpecs)\n try {\n loop.prefix.addTool(s);\n } catch (err) {\n sink({\n kind: \"warn\",\n name: label,\n reason: `addTool failed for ${s.function.name}: ${(err as Error).message}`,\n });\n }\n return { ok: true, summary };\n } catch (err) {\n // If we got far enough to create a provisional record, keep it —\n // tools are already registered and usable even after a late failure.\n const reason = (err as Error).message;\n if (!records.has(raw)) {\n await mcp?.close().catch(() => undefined);\n rejectReady(new Error(`MCP server \"${label}\" failed to start: ${reason}`));\n sink({ kind: \"failed\", name: label, reason });\n failureMap.set(raw, { spec: raw, name: label, reason, at: Date.now() });\n return { ok: false, reason };\n }\n sink({ kind: \"warn\", name: label, reason });\n return { ok: true, summary: records.get(raw)!.summary };\n }\n }\n\n async function removeSpec(raw: string, loop?: CacheFirstLoop): Promise<boolean> {\n failureMap.delete(raw);\n const record = records.get(raw);\n if (!record) return false;\n await record.client.close().catch(() => undefined);\n const tools = ctx.getTools();\n for (const name of record.registeredNames) {\n tools?.unregister(name);\n loop?.prefix.removeTool(name);\n }\n records.delete(raw);\n const idx = insertionOrder.indexOf(raw);\n if (idx >= 0) insertionOrder.splice(idx, 1);\n return true;\n }\n\n async function reloadFromConfig(loop?: CacheFirstLoop): Promise<{\n added: string[];\n removed: string[];\n failed: Array<{ spec: string; reason: string }>;\n summaries: McpServerSummary[];\n }> {\n const normalized = normalizeMcpConfig(readConfig());\n const desired = normalized.map(specToRaw);\n const desiredSet = new Set(desired);\n const currentSet = new Set(records.keys());\n const added: string[] = [];\n const removed: string[] = [];\n const failed: Array<{ spec: string; reason: string }> = [];\n\n for (const spec of [...currentSet]) {\n if (!desiredSet.has(spec)) {\n await removeSpec(spec, loop);\n removed.push(spec);\n }\n }\n for (const spec of desired) {\n if (currentSet.has(spec)) continue;\n const result = await addSpec(spec, loop);\n if (result.ok) added.push(spec);\n else failed.push({ spec, reason: result.reason });\n }\n return { added, removed, failed, summaries: summaries() };\n }\n\n function specs(): string[] {\n return [...insertionOrder];\n }\n function summaries(): McpServerSummary[] {\n return insertionOrder\n .map((s) => records.get(s)?.summary)\n .filter((s): s is McpServerSummary => Boolean(s));\n }\n async function closeAll(): Promise<void> {\n for (const r of records.values()) await r.client.close().catch(() => undefined);\n records.clear();\n insertionOrder.length = 0;\n failureMap.clear();\n }\n function failures(): McpFailure[] {\n return [...failureMap.values()];\n }\n function setLifecycleSink(s: McpLifecycleSink): void {\n sink = s;\n }\n return {\n size: () => records.size,\n specs,\n summaries,\n failures,\n addSpec,\n removeSpec,\n reloadFromConfig,\n closeAll,\n setLifecycleSink,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
|
|
3
3
|
import {
|
|
4
4
|
t
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-PYIZZAVQ.js";
|
|
6
6
|
|
|
7
7
|
// src/memory/project.ts
|
|
8
8
|
import { existsSync, readFileSync, statSync } from "fs";
|
|
@@ -191,11 +191,15 @@ function parseAllowedTools(raw) {
|
|
|
191
191
|
const names = raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
192
192
|
return names.length > 0 ? Object.freeze(names) : void 0;
|
|
193
193
|
}
|
|
194
|
+
function subagentModelForPreset(preset) {
|
|
195
|
+
return preset === "pro" ? "deepseek-v4-pro" : "deepseek-v4-flash";
|
|
196
|
+
}
|
|
194
197
|
var SkillStore = class {
|
|
195
198
|
homeDir;
|
|
196
199
|
projectRoot;
|
|
197
200
|
customSkillPaths;
|
|
198
201
|
disableBuiltins;
|
|
202
|
+
subagentModels;
|
|
199
203
|
constructor(opts = {}) {
|
|
200
204
|
this.homeDir = opts.homeDir ?? homedir();
|
|
201
205
|
this.projectRoot = opts.projectRoot ? resolve(opts.projectRoot) : void 0;
|
|
@@ -204,6 +208,7 @@ var SkillStore = class {
|
|
|
204
208
|
opts.customSkillPaths?.map((p) => resolveCustomSkillPath(p, baseDir, this.homeDir)) ?? []
|
|
205
209
|
);
|
|
206
210
|
this.disableBuiltins = opts.disableBuiltins === true;
|
|
211
|
+
this.subagentModels = opts.subagentModels ?? {};
|
|
207
212
|
}
|
|
208
213
|
/** True iff this store was configured with a project root. */
|
|
209
214
|
hasProjectScope() {
|
|
@@ -257,7 +262,14 @@ var SkillStore = class {
|
|
|
257
262
|
if (!byName.has(skill.name)) byName.set(skill.name, skill);
|
|
258
263
|
}
|
|
259
264
|
}
|
|
260
|
-
return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
265
|
+
return [...byName.values()].map((s) => this.applyModelOverride(s)).sort((a, b) => a.name.localeCompare(b.name));
|
|
266
|
+
}
|
|
267
|
+
/** Apply `subagentModels` config override on top of frontmatter `model:`. Inline skills are unaffected. */
|
|
268
|
+
applyModelOverride(skill) {
|
|
269
|
+
if (skill.runAs !== "subagent") return skill;
|
|
270
|
+
const override = this.subagentModels[skill.name];
|
|
271
|
+
if (!override) return skill;
|
|
272
|
+
return { ...skill, model: subagentModelForPreset(override) };
|
|
261
273
|
}
|
|
262
274
|
/** Scaffold a new skill stub at the chosen scope. Refuses to overwrite. */
|
|
263
275
|
create(name, scope) {
|
|
@@ -642,4 +654,4 @@ export {
|
|
|
642
654
|
SkillStore,
|
|
643
655
|
applySkillsIndex
|
|
644
656
|
};
|
|
645
|
-
//# sourceMappingURL=chunk-
|
|
657
|
+
//# sourceMappingURL=chunk-ENFBF6HI.js.map
|