@openhands/agent-canvas 1.12.0 → 1.13.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/README.md +1 -1
- package/README.windows.md +2 -2
- package/build/assets/{acp-providers-BkL3HWa3.js → acp-providers-D1PORKc0.js} +1 -1
- package/build/assets/active-backend-context-IqOjobNK.js +2 -0
- package/build/assets/{agent-context-settings-CzWS1DgR.js → agent-context-settings-DMrObcIS.js} +1 -1
- package/build/assets/agent-profiles-settings-DororXN5.js +1 -0
- package/build/assets/agent-server-conversation-service.api-DWBe0rbX.js +86 -0
- package/build/assets/{agent-settings-D2J1dKVd.js → agent-settings-BJVk92PU.js} +1 -1
- package/build/assets/agent-settings-COfJsQ1d.js +1 -0
- package/build/assets/{alert-banner-lrK-2_0Y.js → alert-banner-CzZsm7ms.js} +1 -1
- package/build/assets/{api-key-entry-screen-D70oJj2c.js → api-key-entry-screen-D8Fade_-.js} +1 -1
- package/build/assets/{app-settings-D0OKHB3M.js → app-settings-CpyGB3AT.js} +1 -1
- package/build/assets/{automation-detail-C0SxWTnQ.js → automation-detail-B-jQ39Mm.js} +1 -1
- package/build/assets/{automation-export-BjQa_fT6.js → automation-export-B1dywoqk.js} +1 -1
- package/build/assets/{automation-setup-route-BzCNpljP.js → automation-setup-route-C-bWUZBi.js} +1 -1
- package/build/assets/{automation-templates-D9gs6ihu.js → automation-templates-DgpCGOJV.js} +1 -1
- package/build/assets/{automations-list-dZg8zOCl.js → automations-list-DnMxlxsL.js} +1 -1
- package/build/assets/{back-nav-button-B3pYwmUJ.js → back-nav-button-HHEneWMw.js} +1 -1
- package/build/assets/{backend-form-modal-HwclKrUS.js → backend-form-modal-DiVrD4Cm.js} +1 -1
- package/build/assets/{backend-synced-settings-badge-YI3k09Wr.js → backend-synced-settings-badge-7MIjpr8M.js} +1 -1
- package/build/assets/{badge-Dpn3-LTV.js → badge-CpYmcVZV.js} +1 -1
- package/build/assets/{base-modal-3NmIOKDm.js → base-modal-Fnh6Uln9.js} +1 -1
- package/build/assets/bot-BQZx8e2i.js +1 -0
- package/build/assets/{brand-button-CJcwjnfb.js → brand-button-swT1RyO0.js} +1 -1
- package/build/assets/browser-B9AbV6kG.js +7 -0
- package/build/assets/{browser-tab-4CPdj3J3.js → browser-tab-zAY12m_i.js} +1 -1
- package/build/assets/{chat-send-button-B8n6-DQA.js → chat-send-button-DsJtivmL.js} +1 -1
- package/build/assets/check-WAFXrrs_.js +1 -0
- package/build/assets/chevron-down-CifNWzme.js +1 -0
- package/build/assets/circle-check-CtnimJa8.js +1 -0
- package/build/assets/{circle-plus-check-toggle-BVzv5EkZ.js → circle-plus-check-toggle-Cuzx55bo.js} +1 -1
- package/build/assets/{cloud-funnel-analytics-CcSez21r.js → cloud-funnel-analytics-86CwNdSh.js} +1 -1
- package/build/assets/{combobox-caret-BlmRwiM8.js → combobox-caret-D0fRotFi.js} +1 -1
- package/build/assets/{command-menu-BKOLj-TC.js → command-menu-BXy03FBl.js} +1 -1
- package/build/assets/{condenser-settings-DLQogFnB.js → condenser-settings-BmZa0ui_.js} +1 -1
- package/build/assets/{confirmation-modal-DAH0XtOp.js → confirmation-modal-BgoN6lbN.js} +1 -1
- package/build/assets/{context-menu-list-item-BQhmFVEK.js → context-menu-list-item-Bq02tc-P.js} +1 -1
- package/build/assets/conversation-BPo8SvLN.js +1 -0
- package/build/assets/conversation-CPCVsCUY.js +90 -0
- package/build/assets/conversation-panel-BPo8SvLN.js +1 -0
- package/build/assets/{conversation-state-store-CtgILxWF.js → conversation-state-store-C5YpjMNy.js} +1 -1
- package/build/assets/conversation-store-Blc5xysY.js +6 -0
- package/build/assets/{conversation-tab-empty-state-C9sfDOlt.js → conversation-tab-empty-state-CMqo_0Bd.js} +1 -1
- package/build/assets/{copy-to-clipboard-button-DatoElj8.js → copy-to-clipboard-button-Cg1pF0xn.js} +1 -1
- package/build/assets/{device-verify-BIjXeW9N.js → device-verify-BfQLgNyq.js} +1 -1
- package/build/assets/{dropdown-classes-zFW7qPSK.js → dropdown-classes-BIqQr5mx.js} +1 -1
- package/build/assets/{entry.client-EBn3ZtNP.js → entry.client-CxFjRYqH.js} +2 -2
- package/build/assets/{enum-filter-dropdown-CctILg5t.js → enum-filter-dropdown-C_yV4_bo.js} +1 -1
- package/build/assets/{environment-switch-overlay-Cvmo6clk.js → environment-switch-overlay-Bi4qbh2g.js} +1 -1
- package/build/assets/{extensions-hub-BZ3HYztk.js → extensions-hub-BqUINAhp.js} +1 -1
- package/build/assets/{extensions-navigation-Bnx32WAb.js → extensions-navigation-lraj88Wk.js} +1 -1
- package/build/assets/external-link-CgtpA_a1.js +1 -0
- package/build/assets/{file-text-RecuaId_.js → file-text-DEK4LSVw.js} +1 -1
- package/build/assets/files-tab-DV0L-lFE.js +1 -0
- package/build/assets/{form-control-classes-DLN3Qgub.js → form-control-classes-7yFSQJq_.js} +1 -1
- package/build/assets/{format-relative-time-BerVamGl.js → format-relative-time-DSErAuVr.js} +1 -1
- package/build/assets/git-provider-icon-BvlLAche.js +1 -0
- package/build/assets/{git-repo-dropdown-B5VnMftu.js → git-repo-dropdown-ByMzpNko.js} +1 -1
- package/build/assets/git-repo-dropdown-C6R7hgM8.js +1 -0
- package/build/assets/{highlighted-source-view-CgJfD5VT.js → highlighted-source-view-C_sfncLZ.js} +1 -1
- package/build/assets/{home-Y0aDou-a.js → home-BOrlwLqG.js} +1 -1
- package/build/assets/home-BvMNC6E-.js +1 -0
- package/build/assets/{home-store-Cubdq0uP.js → home-store-CxqsY9Fi.js} +1 -1
- package/build/assets/index-home-BvMNC6E-.js +1 -0
- package/build/assets/info-BRVcJAUg.js +1 -0
- package/build/assets/{install-server-modal-DW6dSyGr.js → install-server-modal-Bl4G1zF4.js} +1 -1
- package/build/assets/{kebab-menu-item-content-CKydZrbH.js → kebab-menu-item-content-BGoGFEAg.js} +1 -1
- package/build/assets/{launch-c4GEP8oo.js → launch-CkqiSCqi.js} +1 -1
- package/build/assets/{list-todo-CheUtB7F.js → list-todo-DNWlzfaM.js} +1 -1
- package/build/assets/llm-not-configured-banner-DLw_tu-G.js +27 -0
- package/build/assets/llm-settings-B-pkVCrt.js +1 -0
- package/build/assets/llm-settings-DSC0-IQ7.js +1 -0
- package/build/assets/llm-subscription-service-BAdOl5Xx.js +1 -0
- package/build/assets/loader-circle-B47W9XqT.js +1 -0
- package/build/assets/{loading-spinner-CN3riY7k.js → loading-spinner-xhnrGP4Y.js} +1 -1
- package/build/assets/{manage-backends-modal-DTCME_Pu.js → manage-backends-modal-DhGk5mJt.js} +1 -1
- package/build/assets/manifest-653b89aa.js +1 -0
- package/build/assets/{manifest-subpage-layout-Ds7G5GZ8.js → manifest-subpage-layout-CKWvL2ig.js} +1 -1
- package/build/assets/{map-provider-7Bp2aih5.js → map-provider-Mx8mZuE-.js} +1 -1
- package/build/assets/markdown-renderer-DUmk7pFc.js +8 -0
- package/build/assets/{mcp-Da7wFU7A.js → mcp-DCkvl6K0.js} +2 -2
- package/build/assets/mcp-marketplace-utils-DEbMXlQr.js +1 -0
- package/build/assets/messages-DSXvyc21.js +40 -0
- package/build/assets/{modal-body-duRaxj_K.js → modal-body-gIe21fDv.js} +1 -1
- package/build/assets/{modal-classes-CLEXO6dj.js → modal-classes-D66dlgZ7.js} +1 -1
- package/build/assets/{modal-close-button-D0aT02hs.js → modal-close-button-B6iOGYpI.js} +1 -1
- package/build/assets/{mouse-pointer-click-Px-dXWcS.js → mouse-pointer-click-BYX1Pw5W.js} +1 -1
- package/build/assets/{npm-Cswluf6-.js → npm-DLckoeJc.js} +1 -1
- package/build/assets/{onboarding-BKbTYlW1.js → onboarding-D7WDG66N.js} +1 -1
- package/build/assets/{onboarding-modal-DrrGlEQq.js → onboarding-modal-C_xVrFNv.js} +1 -1
- package/build/assets/{organization-service.api-DK8csGvK.js → organization-service.api-D-s9z18a.js} +1 -1
- package/build/assets/pencil-BGOCPRyu.js +1 -0
- package/build/assets/{planner-tab-D-mZ1I7n.js → planner-tab-AKaXIIfg.js} +1 -1
- package/build/assets/{plugins-management-service-CywqyfLK.js → plugins-management-service-wtmY4QQw.js} +1 -1
- package/build/assets/plus-zNEL8rcX.js +1 -0
- package/build/assets/{profiles-service.api-vcE_jJCe.js → profiles-service.api-DCMYxHMi.js} +1 -1
- package/build/assets/{providers-CdrPPm0z.js → providers-BjrtjX4L.js} +1 -1
- package/build/assets/{proxy-b4aqL4SX.js → proxy-9Z_WZggZ.js} +1 -1
- package/build/assets/{puzzle-B3v361yY.js → puzzle-BWLmN8z4.js} +1 -1
- package/build/assets/recommended-automations-launcher-CFlzhu1o.js +1 -0
- package/build/assets/refresh-cw-CXtFWpwv.js +1 -0
- package/build/assets/root-CanxKlNV.css +1 -0
- package/build/assets/{root-CBBi6IAe.js → root-DkfG_UWR.js} +2 -2
- package/build/assets/root-layout-D75LHYhh.js +2 -0
- package/build/assets/{schema-field-Z-rMg9ti.js → schema-field-OnM5Uob_.js} +1 -1
- package/build/assets/{sdk-section-page-m_cjygxR.js → sdk-section-page-m5WQm2sy.js} +1 -1
- package/build/assets/search-CycosyjN.js +1 -0
- package/build/assets/{secrets-service-BHF4fxML.js → secrets-service-B26R61C1.js} +1 -1
- package/build/assets/{secrets-settings-aBGXtQhX.js → secrets-settings-CbLYCKOX.js} +1 -1
- package/build/assets/{segmented-toggle-SmvsR3jW.js → segmented-toggle-DCspm2U5.js} +1 -1
- package/build/assets/{settings-CZPGNens.js → settings-BJQI_iBM.js} +1 -1
- package/build/assets/{settings-dropdown-input-TWIeiG02.js → settings-dropdown-input-BI8V_Nov.js} +1 -1
- package/build/assets/{settings-index-Dtlegd6s.js → settings-index-BiTqJoH7.js} +1 -1
- package/build/assets/{settings-input-D61Vzp9e.js → settings-input-Cz62hWVW.js} +1 -1
- package/build/assets/{settings-list-classes-sE0ASr1s.js → settings-list-classes-z_3FW5H3.js} +1 -1
- package/build/assets/{settings-modal-CalzJP2l.js → settings-modal-BIrIVn97.js} +1 -1
- package/build/assets/{settings-service.api-DfPYaxZJ.js → settings-service.api--rJmnuLa.js} +1 -1
- package/build/assets/{settings-switch-Drt-rF5s.js → settings-switch-BRsSI8Vs.js} +1 -1
- package/build/assets/{settings-utils-gw2ppAvw.js → settings-utils-Ba7vel6T.js} +1 -1
- package/build/assets/shared-conversation-CQK_PqHx.js +1 -0
- package/build/assets/shield-check-T3JsDJiM.js +1 -0
- package/build/assets/{sidebar-layout-Dxg6zc2K.js → sidebar-layout-Bhi3hVcu.js} +1 -1
- package/build/assets/{sidebar-mobile-menu-toggle-C6HpQ55l.js → sidebar-mobile-menu-toggle-YWJNRN4p.js} +1 -1
- package/build/assets/{sidebar-nav-link-CxLoG-dG.js → sidebar-nav-link-BSUlY5Ml.js} +1 -1
- package/build/assets/{sidebar-store-BJeYY-E9.js → sidebar-store-Cl1cUv_F.js} +1 -1
- package/build/assets/{skill-card-pill-row-B_BYBONu.js → skill-card-pill-row-BXz8L8Rn.js} +1 -1
- package/build/assets/{skill-icon-badge-CN41Hy9l.js → skill-icon-badge-QgfKv31M.js} +1 -1
- package/build/assets/{skill-scope-Dt1V5X2p.js → skill-scope-Dc3JPW-8.js} +1 -1
- package/build/assets/{skills-plugins-B-H0cCOP.js → skills-plugins-CpTV27n3.js} +1 -1
- package/build/assets/{skills-settings-DthdIDUb.js → skills-settings-CSW__IW4.js} +1 -1
- package/build/assets/{sparkles-g7y3r-Ut.js → sparkles-TJ0mdECe.js} +1 -1
- package/build/assets/{styled-tooltip-C5C07RQC.js → styled-tooltip-BUMSbgrF.js} +1 -1
- package/build/assets/{task-list-tab-BTde81Iu.js → task-list-tab-mAHMOkUz.js} +1 -1
- package/build/assets/{terminal-DRrJo-cR.js → terminal-BzxBaHx2.js} +1 -1
- package/build/assets/{toggle-switch-CIioisto.js → toggle-switch-O5v1FgxW.js} +1 -1
- package/build/assets/trash-2-C0xNVp9c.js +1 -0
- package/build/assets/{typography-D9tiHct7.js → typography-NOKSk9_R.js} +1 -1
- package/build/assets/usage-tab-tEmVN0KD.js +1 -0
- package/build/assets/{use-acp-credential-form-DGyo0QvL.js → use-acp-credential-form-BPNi0Zbm.js} +1 -1
- package/build/assets/{use-activate-agent-profile-DrPzIKJF.js → use-activate-agent-profile-D9YRQPTF.js} +1 -1
- package/build/assets/{use-agent-profiles-B37XWDLq.js → use-agent-profiles-Cb2zUW3l.js} +1 -1
- package/build/assets/{use-can-manage-org-profiles-BzE28H3x.js → use-can-manage-org-profiles-Dxzq2AEd.js} +1 -1
- package/build/assets/{use-cloud-current-user-id-U6HPjy50.js → use-cloud-current-user-id-Co2eJk2A.js} +1 -1
- package/build/assets/{use-config-DapX3pjC.js → use-config-DKAMiI5R.js} +1 -1
- package/build/assets/use-create-conversation-CoHTiCbI.js +1 -0
- package/build/assets/{use-create-secret-DcpT3RPw.js → use-create-secret-2zBlCDsF.js} +1 -1
- package/build/assets/use-is-authed-C52-ivnB.js +1 -0
- package/build/assets/{use-is-creating-conversation-CVefC9Ns.js → use-is-creating-conversation-DdaAE6jV.js} +1 -1
- package/build/assets/{use-launch-skill-in-chat-BcKNjxxd.js → use-launch-skill-in-chat-COnDpxCQ.js} +1 -1
- package/build/assets/use-llm-profiles-C_BHue65.js +1 -0
- package/build/assets/{use-manifest-capabilities-zihHDbMW.js → use-manifest-capabilities-DPrQsaPP.js} +1 -1
- package/build/assets/{use-onboarding-completion-6kWOW3ul.js → use-onboarding-completion-CCE8OQgV.js} +1 -1
- package/build/assets/{use-plugins-marketplace-CqkR8kLE.js → use-plugins-marketplace-CEiak69h.js} +1 -1
- package/build/assets/use-save-agent-profile-DK9idD6a.js +1 -0
- package/build/assets/{use-save-settings-DIEurJ3D.js → use-save-settings-DNmnbG6f.js} +1 -1
- package/build/assets/{use-settings-nav-items-DV9qgeu7.js → use-settings-nav-items-BlFL7YhM.js} +1 -1
- package/build/assets/{use-settings-BmLzQjnC.js → use-settings-wCwPaSIv.js} +1 -1
- package/build/assets/{use-tracking-salbPJxT.js → use-tracking-CVwPmhlX.js} +1 -1
- package/build/assets/{use-user-conversation-Dt-W6uNw.js → use-user-conversation-DVtfg0B_.js} +1 -1
- package/build/assets/{useInfiniteQuery-DbCv0Jzd.js → useInfiniteQuery-p1xq35r2.js} +1 -1
- package/build/assets/{useMutation-ChpkYxI5.js → useMutation-BFDQmgk9.js} +1 -1
- package/build/assets/{useQueries-Cjv3E8_1.js → useQueries-DF1NAAeC.js} +1 -1
- package/build/assets/{useQuery-BCnzy4LX.js → useQuery-DRv--6bK.js} +1 -1
- package/build/assets/utils-zxEjKE70.js +1 -0
- package/build/assets/{vendor~browser-DJ1pl_wn.js → vendor~browser-B-fae1JU.js} +14 -14
- package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~kv3pap4j-oGvLV0dO.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~kv3pap4j-B8i84bh4.js} +3 -3
- package/build/assets/{vendor~files-tab-C87pjSpi.js → vendor~files-tab-D9wR9yM2.js} +1 -1
- package/build/assets/vendor~index-home~home~conversation-panel~conversation-Ipoe6hvY.js +13 -0
- package/build/assets/vendor~root-layout-C-IgVx6e.js +1 -0
- package/build/assets/{vendor~root-layout~conversation-panel~conversation-DEzjR4K7.js → vendor~root-layout~conversation-panel~conversation-Dhd_I4H4.js} +1 -1
- package/build/assets/{vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-U-xdsAEx.js → vendor~root-layout~conversation-panel~conversation~skills-settings~automations-list~shared-~bovqqk8e-Cc0f9kPP.js} +1 -1
- package/build/assets/{vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-CQR5Sa0H.js → vendor~root-layout~index-home~home~conversation-panel~conversation~shared-conversation-d7svw-BB.js} +1 -1
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gxu4j2ea-Cwhh3zLe.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~gxu4j2ea-D5DWZVc7.js} +1 -1
- package/build/assets/{vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hjcjabwg-CuQhkiS7.js → vendor~root~root-layout~index-home~home~conversation-panel~conversation~launch~extensions-h~hjcjabwg-4WsUP-tz.js} +2 -2
- package/build/assets/{verification-settings-oi54wEc1.js → verification-settings-B8UMQ7MG.js} +1 -1
- package/build/assets/{wrench-B1_H-tL1.js → wrench-DIka3hCq.js} +1 -1
- package/build/assets/x-BWKA2Ver.js +1 -0
- package/build/assets/zap-DHddTPc0.js +1 -0
- package/build/index.html +4 -4
- package/build/locales/ar/openhands.json +28 -1
- package/build/locales/ca/openhands.json +28 -1
- package/build/locales/de/openhands.json +28 -1
- package/build/locales/en/openhands.json +28 -1
- package/build/locales/es/openhands.json +28 -1
- package/build/locales/fr/openhands.json +28 -1
- package/build/locales/it/openhands.json +28 -1
- package/build/locales/ja/openhands.json +28 -1
- package/build/locales/ko-KR/openhands.json +28 -1
- package/build/locales/no/openhands.json +28 -1
- package/build/locales/pt/openhands.json +28 -1
- package/build/locales/tr/openhands.json +28 -1
- package/build/locales/uk/openhands.json +28 -1
- package/build/locales/zh-CN/openhands.json +28 -1
- package/build/locales/zh-TW/openhands.json +28 -1
- package/config/defaults.json +3 -3
- package/dist/api/agent-server-compatibility.cjs +1 -1
- package/dist/api/agent-server-compatibility.cjs.map +1 -1
- package/dist/api/agent-server-compatibility.js +1 -1
- package/dist/api/agent-server-compatibility.js.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.cjs.map +1 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.d.ts +24 -1
- package/dist/api/conversation-service/agent-server-conversation-service.api.js +116 -97
- package/dist/api/conversation-service/agent-server-conversation-service.api.js.map +1 -1
- package/dist/api/llm-balance-service.cjs +2 -0
- package/dist/api/llm-balance-service.cjs.map +1 -0
- package/dist/api/llm-balance-service.d.ts +33 -0
- package/dist/api/llm-balance-service.js +53 -0
- package/dist/api/llm-balance-service.js.map +1 -0
- package/dist/api/llm-subscription-service.cjs +1 -1
- package/dist/api/llm-subscription-service.cjs.map +1 -1
- package/dist/api/llm-subscription-service.js +42 -34
- package/dist/api/llm-subscription-service.js.map +1 -1
- package/dist/components/conversation/index.cjs +1 -1
- package/dist/components/conversation/index.d.ts +0 -1
- package/dist/components/conversation/index.js +0 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js +1 -1
- package/dist/components/conversation-events/chat/event-content-helpers/get-event-content.js.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.cjs +1 -1
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.cjs.map +1 -1
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.js +24 -23
- package/dist/components/conversation-events/chat/event-message-components/generic-event-message-wrapper.js.map +1 -1
- package/dist/components/conversation-events/chat/group-events.cjs +1 -1
- package/dist/components/conversation-events/chat/group-events.cjs.map +1 -1
- package/dist/components/conversation-events/chat/group-events.d.ts +3 -3
- package/dist/components/conversation-events/chat/group-events.js +27 -26
- package/dist/components/conversation-events/chat/group-events.js.map +1 -1
- package/dist/components/features/automations/recommended-automations-section.d.ts +7 -0
- package/dist/components/features/chat/components/chat-input-actions.cjs +1 -1
- package/dist/components/features/chat/components/chat-input-actions.cjs.map +1 -1
- package/dist/components/features/chat/components/chat-input-actions.js +123 -118
- package/dist/components/features/chat/components/chat-input-actions.js.map +1 -1
- package/dist/components/features/chat/components/chat-input-grip.cjs +1 -1
- package/dist/components/features/chat/components/chat-input-grip.cjs.map +1 -1
- package/dist/components/features/chat/components/chat-input-grip.d.ts +2 -1
- package/dist/components/features/chat/components/chat-input-grip.js +7 -7
- package/dist/components/features/chat/components/chat-input-grip.js.map +1 -1
- package/dist/components/features/chat/components/context-window-meter.cjs +2 -0
- package/dist/components/features/chat/components/context-window-meter.cjs.map +1 -0
- package/dist/components/features/chat/components/context-window-meter.d.ts +2 -0
- package/dist/components/features/chat/components/context-window-meter.js +131 -0
- package/dist/components/features/chat/components/context-window-meter.js.map +1 -0
- package/dist/components/features/chat/components/context-window-ring.cjs +2 -0
- package/dist/components/features/chat/components/context-window-ring.cjs.map +1 -0
- package/dist/components/features/chat/components/context-window-ring.d.ts +26 -0
- package/dist/components/features/chat/components/context-window-ring.js +45 -0
- package/dist/components/features/chat/components/context-window-ring.js.map +1 -0
- package/dist/components/features/chat/custom-chat-input.cjs +1 -1
- package/dist/components/features/chat/custom-chat-input.cjs.map +1 -1
- package/dist/components/features/chat/custom-chat-input.js +68 -67
- package/dist/components/features/chat/custom-chat-input.js.map +1 -1
- package/dist/components/features/chat/path-component.cjs +1 -1
- package/dist/components/features/chat/path-component.cjs.map +1 -1
- package/dist/components/features/chat/path-component.js +9 -6
- package/dist/components/features/chat/path-component.js.map +1 -1
- package/dist/components/features/chat/plan-preview.cjs +1 -1
- package/dist/components/features/chat/plan-preview.js +4 -4
- package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.cjs +1 -1
- package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.cjs.map +1 -1
- package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.d.ts +0 -8
- package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.js +92 -50
- package/dist/components/features/chat/tool-visualizers/file-editor/file-editor.js.map +1 -1
- package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.cjs +1 -1
- package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.cjs.map +1 -1
- package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.d.ts +7 -2
- package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.js +15 -9
- package/dist/components/features/chat/tool-visualizers/primitives/file-path-chip.js.map +1 -1
- package/dist/components/features/chat/tool-visualizers/primitives/markdown-file-preview.cjs +2 -0
- package/dist/components/features/chat/tool-visualizers/primitives/markdown-file-preview.cjs.map +1 -0
- package/dist/components/features/chat/tool-visualizers/primitives/markdown-file-preview.d.ts +20 -0
- package/dist/components/features/chat/tool-visualizers/primitives/markdown-file-preview.js +76 -0
- package/dist/components/features/chat/tool-visualizers/primitives/markdown-file-preview.js.map +1 -0
- package/dist/components/features/controls/server-status-context-menu.cjs +1 -1
- package/dist/components/features/controls/server-status-context-menu.cjs.map +1 -1
- package/dist/components/features/controls/server-status-context-menu.d.ts +5 -3
- package/dist/components/features/controls/server-status-context-menu.js +8 -8
- package/dist/components/features/controls/server-status-context-menu.js.map +1 -1
- package/dist/components/features/conversation/conversation-name-context-menu.cjs +1 -1
- package/dist/components/features/conversation/conversation-name-context-menu.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-name-context-menu.js +58 -61
- package/dist/components/features/conversation/conversation-name-context-menu.js.map +1 -1
- package/dist/components/features/conversation/conversation-name-with-status.cjs +1 -1
- package/dist/components/features/conversation/conversation-name-with-status.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-name-with-status.js +74 -46
- package/dist/components/features/conversation/conversation-name-with-status.js.map +1 -1
- package/dist/components/features/conversation/conversation-name.cjs +1 -1
- package/dist/components/features/conversation/conversation-name.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-name.js +69 -71
- package/dist/components/features/conversation/conversation-name.js.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.cjs +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.js +7 -6
- package/dist/components/features/conversation/conversation-tabs/conversation-tab-content/conversation-tab-content.js.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js +92 -86
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs-context-menu.js.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.cjs.map +1 -1
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js +81 -71
- package/dist/components/features/conversation/conversation-tabs/conversation-tabs.js.map +1 -1
- package/dist/components/features/conversation/metrics-modal/cost-section.cjs +1 -1
- package/dist/components/features/conversation/metrics-modal/cost-section.cjs.map +1 -1
- package/dist/components/features/conversation/metrics-modal/cost-section.js +6 -6
- package/dist/components/features/conversation/metrics-modal/cost-section.js.map +1 -1
- package/dist/components/features/conversation/metrics-modal/metric-row.cjs +1 -1
- package/dist/components/features/conversation/metrics-modal/metric-row.cjs.map +1 -1
- package/dist/components/features/conversation/metrics-modal/metric-row.d.ts +2 -1
- package/dist/components/features/conversation/metrics-modal/metric-row.js +10 -9
- package/dist/components/features/conversation/metrics-modal/metric-row.js.map +1 -1
- package/dist/components/features/conversation/metrics-modal/usage-section.cjs +1 -1
- package/dist/components/features/conversation/metrics-modal/usage-section.cjs.map +1 -1
- package/dist/components/features/conversation/metrics-modal/usage-section.js +2 -1
- package/dist/components/features/conversation/metrics-modal/usage-section.js.map +1 -1
- package/dist/components/features/conversation/usage-panel/compact-context-button.cjs +2 -0
- package/dist/components/features/conversation/usage-panel/compact-context-button.cjs.map +1 -0
- package/dist/components/features/conversation/usage-panel/compact-context-button.d.ts +16 -0
- package/dist/components/features/conversation/usage-panel/compact-context-button.js +59 -0
- package/dist/components/features/conversation/usage-panel/compact-context-button.js.map +1 -0
- package/dist/components/features/conversation/usage-panel/context-meter.cjs +2 -0
- package/dist/components/features/conversation/usage-panel/context-meter.cjs.map +1 -0
- package/dist/components/features/conversation/usage-panel/context-meter.d.ts +19 -0
- package/dist/components/features/conversation/usage-panel/context-meter.js +46 -0
- package/dist/components/features/conversation/usage-panel/context-meter.js.map +1 -0
- package/dist/components/features/conversation/usage-panel/provider-balance-card.cjs +2 -0
- package/dist/components/features/conversation/usage-panel/provider-balance-card.cjs.map +1 -0
- package/dist/components/features/conversation/usage-panel/provider-balance-card.d.ts +7 -0
- package/dist/components/features/conversation/usage-panel/provider-balance-card.js +57 -0
- package/dist/components/features/conversation/usage-panel/provider-balance-card.js.map +1 -0
- package/dist/components/features/conversation/usage-panel/usage-panel.cjs +2 -0
- package/dist/components/features/conversation/usage-panel/usage-panel.cjs.map +1 -0
- package/dist/components/features/conversation/usage-panel/usage-panel.d.ts +9 -0
- package/dist/components/features/conversation/usage-panel/usage-panel.js +68 -0
- package/dist/components/features/conversation/usage-panel/usage-panel.js.map +1 -0
- package/dist/components/features/conversation-panel/budget-display.cjs +1 -1
- package/dist/components/features/conversation-panel/budget-display.cjs.map +1 -1
- package/dist/components/features/conversation-panel/budget-display.js +10 -13
- package/dist/components/features/conversation-panel/budget-display.js.map +1 -1
- package/dist/components/features/conversation-panel/budget-progress-bar.cjs +1 -1
- package/dist/components/features/conversation-panel/budget-progress-bar.cjs.map +1 -1
- package/dist/components/features/conversation-panel/budget-progress-bar.js +2 -2
- package/dist/components/features/conversation-panel/budget-progress-bar.js.map +1 -1
- package/dist/components/features/conversation-panel/confirm-archive-modal.cjs +2 -0
- package/dist/components/features/conversation-panel/confirm-archive-modal.cjs.map +1 -0
- package/dist/components/features/conversation-panel/confirm-archive-modal.d.ts +8 -0
- package/dist/components/features/conversation-panel/confirm-archive-modal.js +48 -0
- package/dist/components/features/conversation-panel/confirm-archive-modal.js.map +1 -0
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.d.ts +3 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.js +39 -34
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-actions.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.d.ts +3 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js +104 -80
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-context-menu.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.d.ts +7 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js +25 -17
- package/dist/components/features/conversation-panel/conversation-card/conversation-card-footer.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.d.ts +9 -1
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.js +94 -84
- package/dist/components/features/conversation-panel/conversation-card/conversation-card.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-group-folder-list.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-group-folder-list.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-group-folder-list.d.ts +2 -1
- package/dist/components/features/conversation-panel/conversation-group-folder-list.js +32 -31
- package/dist/components/features/conversation-panel/conversation-group-folder-list.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-group-folder-row.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-group-folder-row.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-group-folder-row.d.ts +2 -1
- package/dist/components/features/conversation-panel/conversation-group-folder-row.js +27 -26
- package/dist/components/features/conversation-panel/conversation-group-folder-row.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.d.ts +3 -1
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js +116 -106
- package/dist/components/features/conversation-panel/conversation-panel-filter-menu.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.d.ts +27 -0
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js +69 -46
- package/dist/components/features/conversation-panel/conversation-panel-list-helpers.js.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.cjs +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.cjs.map +1 -1
- package/dist/components/features/conversation-panel/conversation-panel.js +230 -165
- package/dist/components/features/conversation-panel/conversation-panel.js.map +1 -1
- package/dist/components/features/files-tab/file-content-viewer.cjs +1 -1
- package/dist/components/features/files-tab/file-content-viewer.cjs.map +1 -1
- package/dist/components/features/files-tab/file-content-viewer.js +22 -25
- package/dist/components/features/files-tab/file-content-viewer.js.map +1 -1
- package/dist/components/features/markdown/markdown-table-scroll.cjs +1 -1
- package/dist/components/features/markdown/markdown-table-scroll.cjs.map +1 -1
- package/dist/components/features/markdown/markdown-table-scroll.js +2 -2
- package/dist/components/features/markdown/markdown-table-scroll.js.map +1 -1
- package/dist/components/shared/buttons/conversation-confirmation-buttons.cjs +1 -1
- package/dist/components/shared/buttons/conversation-confirmation-buttons.cjs.map +1 -1
- package/dist/components/shared/buttons/conversation-confirmation-buttons.js +2 -2
- package/dist/components/shared/buttons/conversation-confirmation-buttons.js.map +1 -1
- package/dist/components/shared/modals/confirmation-modals/base-modal.cjs +1 -1
- package/dist/components/shared/modals/confirmation-modals/base-modal.cjs.map +1 -1
- package/dist/components/shared/modals/confirmation-modals/base-modal.js +1 -1
- package/dist/components/shared/modals/confirmation-modals/base-modal.js.map +1 -1
- package/dist/config/defaults.cjs +1 -1
- package/dist/config/defaults.cjs.map +1 -1
- package/dist/config/defaults.js +3 -3
- package/dist/config/defaults.js.map +1 -1
- package/dist/constants/llm-balance.cjs +2 -0
- package/dist/constants/llm-balance.cjs.map +1 -0
- package/dist/constants/llm-balance.d.ts +13 -0
- package/dist/constants/llm-balance.js +6 -0
- package/dist/constants/llm-balance.js.map +1 -0
- package/dist/contexts/conversation-websocket-context.cjs +2 -2
- package/dist/contexts/conversation-websocket-context.cjs.map +1 -1
- package/dist/contexts/conversation-websocket-context.js +217 -209
- package/dist/contexts/conversation-websocket-context.js.map +1 -1
- package/dist/hooks/chat/use-grip-resize.cjs +1 -1
- package/dist/hooks/chat/use-grip-resize.cjs.map +1 -1
- package/dist/hooks/chat/use-grip-resize.d.ts +1 -0
- package/dist/hooks/chat/use-grip-resize.js +39 -30
- package/dist/hooks/chat/use-grip-resize.js.map +1 -1
- package/dist/hooks/mutation/use-condense-conversation.cjs +2 -0
- package/dist/hooks/mutation/use-condense-conversation.cjs.map +1 -0
- package/dist/hooks/mutation/use-condense-conversation.d.ts +12 -0
- package/dist/hooks/mutation/use-condense-conversation.js +17 -0
- package/dist/hooks/mutation/use-condense-conversation.js.map +1 -0
- package/dist/hooks/mutation/use-create-conversation.cjs +1 -1
- package/dist/hooks/mutation/use-create-conversation.cjs.map +1 -1
- package/dist/hooks/mutation/use-create-conversation.js +30 -21
- package/dist/hooks/mutation/use-create-conversation.js.map +1 -1
- package/dist/hooks/mutation/use-new-conversation-command.cjs +1 -1
- package/dist/hooks/mutation/use-new-conversation-command.cjs.map +1 -1
- package/dist/hooks/mutation/use-new-conversation-command.js +1 -1
- package/dist/hooks/mutation/use-new-conversation-command.js.map +1 -1
- package/dist/hooks/query/use-conversation-metrics.cjs +1 -1
- package/dist/hooks/query/use-conversation-metrics.cjs.map +1 -1
- package/dist/hooks/query/use-conversation-metrics.js +1 -1
- package/dist/hooks/query/use-conversation-metrics.js.map +1 -1
- package/dist/hooks/query/use-llm-balance.cjs +2 -0
- package/dist/hooks/query/use-llm-balance.cjs.map +1 -0
- package/dist/hooks/query/use-llm-balance.d.ts +10 -0
- package/dist/hooks/query/use-llm-balance.js +24 -0
- package/dist/hooks/query/use-llm-balance.js.map +1 -0
- package/dist/hooks/query/use-search-providers.cjs +1 -1
- package/dist/hooks/query/use-search-providers.cjs.map +1 -1
- package/dist/hooks/query/use-search-providers.js +1 -1
- package/dist/hooks/query/use-search-providers.js.map +1 -1
- package/dist/hooks/use-await-context-compaction.cjs +2 -0
- package/dist/hooks/use-await-context-compaction.cjs.map +1 -0
- package/dist/hooks/use-await-context-compaction.d.ts +38 -0
- package/dist/hooks/use-await-context-compaction.js +61 -0
- package/dist/hooks/use-await-context-compaction.js.map +1 -0
- package/dist/hooks/use-compact-context-action.cjs +2 -0
- package/dist/hooks/use-compact-context-action.cjs.map +1 -0
- package/dist/hooks/use-compact-context-action.d.ts +10 -0
- package/dist/hooks/use-compact-context-action.js +61 -0
- package/dist/hooks/use-compact-context-action.js.map +1 -0
- package/dist/hooks/use-context-window-usage.cjs +2 -0
- package/dist/hooks/use-context-window-usage.cjs.map +1 -0
- package/dist/hooks/use-context-window-usage.d.ts +5 -0
- package/dist/hooks/use-context-window-usage.js +20 -0
- package/dist/hooks/use-context-window-usage.js.map +1 -0
- package/dist/hooks/use-conversation-name-context-menu.cjs +1 -1
- package/dist/hooks/use-conversation-name-context-menu.cjs.map +1 -1
- package/dist/hooks/use-conversation-name-context-menu.d.ts +0 -3
- package/dist/hooks/use-conversation-name-context-menu.js +54 -57
- package/dist/hooks/use-conversation-name-context-menu.js.map +1 -1
- package/dist/hooks/use-drag-resize.cjs +1 -1
- package/dist/hooks/use-drag-resize.cjs.map +1 -1
- package/dist/hooks/use-drag-resize.d.ts +8 -0
- package/dist/hooks/use-drag-resize.js +21 -18
- package/dist/hooks/use-drag-resize.js.map +1 -1
- package/dist/hooks/use-live-conversation-metrics.cjs +2 -0
- package/dist/hooks/use-live-conversation-metrics.cjs.map +1 -0
- package/dist/hooks/use-live-conversation-metrics.d.ts +18 -0
- package/dist/hooks/use-live-conversation-metrics.js +37 -0
- package/dist/hooks/use-live-conversation-metrics.js.map +1 -0
- package/dist/hooks/use-select-conversation-tab.cjs +1 -1
- package/dist/hooks/use-select-conversation-tab.cjs.map +1 -1
- package/dist/hooks/use-select-conversation-tab.js +2 -2
- package/dist/hooks/use-select-conversation-tab.js.map +1 -1
- package/dist/i18n/declaration.cjs +1 -1
- package/dist/i18n/declaration.cjs.map +1 -1
- package/dist/i18n/declaration.d.ts +27 -0
- package/dist/i18n/declaration.js +1 -1
- package/dist/i18n/declaration.js.map +1 -1
- package/dist/i18n/translation.cjs +2 -2
- package/dist/i18n/translation.cjs.map +1 -1
- package/dist/i18n/translation.js +474 -15
- package/dist/i18n/translation.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +28 -29
- package/dist/lib/index.cjs +1 -1
- package/dist/lib/index.js +0 -1
- package/dist/locales/ar/openhands.json +28 -1
- package/dist/locales/ca/openhands.json +28 -1
- package/dist/locales/de/openhands.json +28 -1
- package/dist/locales/en/openhands.json +28 -1
- package/dist/locales/es/openhands.json +28 -1
- package/dist/locales/fr/openhands.json +28 -1
- package/dist/locales/it/openhands.json +28 -1
- package/dist/locales/ja/openhands.json +28 -1
- package/dist/locales/ko-KR/openhands.json +28 -1
- package/dist/locales/no/openhands.json +28 -1
- package/dist/locales/pt/openhands.json +28 -1
- package/dist/locales/tr/openhands.json +28 -1
- package/dist/locales/uk/openhands.json +28 -1
- package/dist/locales/zh-CN/openhands.json +28 -1
- package/dist/locales/zh-TW/openhands.json +28 -1
- package/dist/node_modules/@microlink/react-json-view/dist/main.cjs +5 -5
- package/dist/node_modules/@microlink/react-json-view/dist/main.cjs.map +1 -1
- package/dist/node_modules/@microlink/react-json-view/dist/main.js +5194 -5187
- package/dist/node_modules/@microlink/react-json-view/dist/main.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.cjs +2 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.cjs.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.js +21 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/desktop-client.js.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.cjs +2 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.cjs.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.js +22 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/hooks-client.js.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.cjs +2 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.cjs.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.js +33 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/meta-profiles-client.js.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.js +56 -22
- package/dist/node_modules/@openhands/typescript-client/dist/client/openhands-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/profiles-client.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/profiles-client.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/profiles-client.js +3 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/profiles-client.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.cjs +2 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.cjs.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.js +31 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/shared-client.js.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.cjs +2 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.cjs.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.js +21 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/sub-agents-client.js.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.cjs +2 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.cjs.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.js +21 -1
- package/dist/node_modules/@openhands/typescript-client/dist/client/tool-client.js.map +1 -0
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/local-conversation.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/conversation/local-conversation.js.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.cjs.map +1 -1
- package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js +9 -5
- package/dist/node_modules/@openhands/typescript-client/dist/models/acp-providers.js.map +1 -1
- package/dist/node_modules/i18next-http-backend/esm/index.cjs +1 -1
- package/dist/node_modules/i18next-http-backend/esm/index.cjs.map +1 -1
- package/dist/node_modules/i18next-http-backend/esm/index.js +2 -2
- package/dist/node_modules/i18next-http-backend/esm/index.js.map +1 -1
- package/dist/node_modules/lucide-react/dist/esm/icons/archive-restore.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/archive-restore.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/archive-restore.js +31 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/archive-restore.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/archive.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/archive.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/archive.js +23 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/archive.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/gauge.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/gauge.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/gauge.js +12 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/gauge.js.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/minimize.cjs +2 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/minimize.cjs.map +1 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/minimize.js +23 -0
- package/dist/node_modules/lucide-react/dist/esm/icons/minimize.js.map +1 -0
- package/dist/node_modules/zustand/esm/middleware.cjs +3 -3
- package/dist/node_modules/zustand/esm/middleware.cjs.map +1 -1
- package/dist/node_modules/zustand/esm/middleware.js +33 -31
- package/dist/node_modules/zustand/esm/middleware.js.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.cjs.map +1 -1
- package/dist/package.js +17 -16
- package/dist/package.js.map +1 -1
- package/dist/routes/usage-tab.cjs +2 -0
- package/dist/routes/usage-tab.cjs.map +1 -0
- package/dist/routes/usage-tab.d.ts +2 -0
- package/dist/routes/usage-tab.js +10 -0
- package/dist/routes/usage-tab.js.map +1 -0
- package/dist/services/child-conversation-launch.cjs +1 -1
- package/dist/services/child-conversation-launch.cjs.map +1 -1
- package/dist/services/child-conversation-launch.js +11 -5
- package/dist/services/child-conversation-launch.js.map +1 -1
- package/dist/stores/archived-conversations-store.cjs +2 -0
- package/dist/stores/archived-conversations-store.cjs.map +1 -0
- package/dist/stores/archived-conversations-store.d.ts +24 -0
- package/dist/stores/archived-conversations-store.js +33 -0
- package/dist/stores/archived-conversations-store.js.map +1 -0
- package/dist/stores/conversation-panel-preferences-store.cjs +1 -1
- package/dist/stores/conversation-panel-preferences-store.cjs.map +1 -1
- package/dist/stores/conversation-panel-preferences-store.d.ts +3 -0
- package/dist/stores/conversation-panel-preferences-store.js +4 -0
- package/dist/stores/conversation-panel-preferences-store.js.map +1 -1
- package/dist/stores/conversation-store.cjs.map +1 -1
- package/dist/stores/conversation-store.d.ts +1 -1
- package/dist/stores/conversation-store.js.map +1 -1
- package/dist/stores/metrics-store.cjs +1 -1
- package/dist/stores/metrics-store.cjs.map +1 -1
- package/dist/stores/metrics-store.d.ts +1 -0
- package/dist/stores/metrics-store.js +7 -4
- package/dist/stores/metrics-store.js.map +1 -1
- package/dist/types/agent-server/core/events/condensation-event.d.ts +3 -0
- package/dist/types/agent-server/core/events/conversation-state-event.d.ts +4 -6
- package/dist/types/agent-server/type-guards.cjs +1 -1
- package/dist/types/agent-server/type-guards.cjs.map +1 -1
- package/dist/types/agent-server/type-guards.d.ts +5 -0
- package/dist/types/agent-server/type-guards.js +3 -3
- package/dist/types/agent-server/type-guards.js.map +1 -1
- package/dist/utils/conversation-local-storage.cjs +1 -1
- package/dist/utils/conversation-local-storage.cjs.map +1 -1
- package/dist/utils/conversation-local-storage.js +2 -1
- package/dist/utils/conversation-local-storage.js.map +1 -1
- package/dist/utils/format-token-count.cjs +2 -0
- package/dist/utils/format-token-count.cjs.map +1 -0
- package/dist/utils/format-token-count.d.ts +3 -0
- package/dist/utils/format-token-count.js +19 -0
- package/dist/utils/format-token-count.js.map +1 -0
- package/dist/utils/hover-reveal-classes.cjs +2 -0
- package/dist/utils/hover-reveal-classes.cjs.map +1 -0
- package/dist/utils/hover-reveal-classes.d.ts +34 -0
- package/dist/utils/hover-reveal-classes.js +41 -0
- package/dist/utils/hover-reveal-classes.js.map +1 -0
- package/dist/utils/is-markdown-file-path.cjs +2 -0
- package/dist/utils/is-markdown-file-path.cjs.map +1 -0
- package/dist/utils/is-markdown-file-path.d.ts +4 -0
- package/dist/utils/is-markdown-file-path.js +14 -0
- package/dist/utils/is-markdown-file-path.js.map +1 -0
- package/dist/utils/mcp-marketplace-utils.cjs +1 -1
- package/dist/utils/mcp-marketplace-utils.cjs.map +1 -1
- package/dist/utils/mcp-marketplace-utils.d.ts +7 -0
- package/dist/utils/mcp-marketplace-utils.js +19 -16
- package/dist/utils/mcp-marketplace-utils.js.map +1 -1
- package/dist/utils/transcript-export/index.cjs +3 -3
- package/dist/utils/transcript-export/index.cjs.map +1 -1
- package/dist/utils/transcript-export/index.js +12 -12
- package/dist/utils/transcript-export/index.js.map +1 -1
- package/dist/utils/transcript-export/load-complete-events.cjs +1 -1
- package/dist/utils/transcript-export/load-complete-events.cjs.map +1 -1
- package/dist/utils/transcript-export/load-complete-events.js +4 -4
- package/dist/utils/transcript-export/load-complete-events.js.map +1 -1
- package/dist/utils/workspace-relative-path.cjs +2 -0
- package/dist/utils/workspace-relative-path.cjs.map +1 -0
- package/dist/utils/workspace-relative-path.d.ts +10 -0
- package/dist/utils/workspace-relative-path.js +22 -0
- package/dist/utils/workspace-relative-path.js.map +1 -0
- package/package.json +17 -16
- package/scripts/check-sdk-version-sync.mjs +6 -6
- package/scripts/dev-process-utils.mjs +6 -1
- package/scripts/dev-safe.mjs +57 -2
- package/build/assets/active-backend-context-B_bg5h9O.js +0 -2
- package/build/assets/agent-profiles-settings-hd2cAIZM.js +0 -1
- package/build/assets/agent-server-conversation-service.api-BheU4HX3.js +0 -86
- package/build/assets/agent-settings-D_SVrWhI.js +0 -1
- package/build/assets/bot-DuN83i3p.js +0 -1
- package/build/assets/browser--eoQOo4M.js +0 -6
- package/build/assets/check-DLOKoFU9.js +0 -1
- package/build/assets/chevron-down-CnIbtM6i.js +0 -1
- package/build/assets/circle-check-CxCYJrpZ.js +0 -1
- package/build/assets/conversation-Cmyw9bFh.js +0 -90
- package/build/assets/conversation-CvoGZ5vC.js +0 -1
- package/build/assets/conversation-panel-CvoGZ5vC.js +0 -1
- package/build/assets/conversation-store-B8Eahyeg.js +0 -6
- package/build/assets/external-link-zWbg5KXS.js +0 -1
- package/build/assets/files-tab-D5zuU5TY.js +0 -1
- package/build/assets/git-provider-icon-zuKz2cwo.js +0 -1
- package/build/assets/git-repo-dropdown-Bo7ciSNX.js +0 -1
- package/build/assets/home-DqyeeFA_.js +0 -1
- package/build/assets/index-home-DqyeeFA_.js +0 -1
- package/build/assets/info-C9lpK5pw.js +0 -1
- package/build/assets/llm-not-configured-banner-DCE_0B4I.js +0 -27
- package/build/assets/llm-settings-8eWBF3Ij.js +0 -1
- package/build/assets/llm-settings-D9ko42Pi.js +0 -1
- package/build/assets/llm-subscription-service-B3K-97lP.js +0 -1
- package/build/assets/loader-circle-C5AnEN8r.js +0 -1
- package/build/assets/manifest-e1c3bc3b.js +0 -1
- package/build/assets/markdown-renderer-DzvgdZey.js +0 -8
- package/build/assets/mcp-marketplace-utils-DSLou4n7.js +0 -1
- package/build/assets/messages-B2l0qLVk.js +0 -40
- package/build/assets/pencil-Bl3GWhgq.js +0 -1
- package/build/assets/plus-CtzlyAoF.js +0 -1
- package/build/assets/recommended-automations-launcher-DIYgUdMm.js +0 -1
- package/build/assets/refresh-cw-B9GhC3QC.js +0 -1
- package/build/assets/root-CRK9fOFd.css +0 -1
- package/build/assets/root-layout-BFN2rCOy.js +0 -2
- package/build/assets/search-CYaiKHRp.js +0 -1
- package/build/assets/shared-conversation-BIAcuORk.js +0 -1
- package/build/assets/shield-check-D2cpEpv3.js +0 -1
- package/build/assets/trash-2-CzDVN-Iw.js +0 -1
- package/build/assets/use-create-conversation-CRf1dCm5.js +0 -1
- package/build/assets/use-is-authed-Bka89Xmm.js +0 -1
- package/build/assets/use-llm-profiles-CHxqoHiN.js +0 -1
- package/build/assets/use-save-agent-profile-CH9_EXQG.js +0 -1
- package/build/assets/utils-DPQfkd-7.js +0 -1
- package/build/assets/vendor~index-home~home~conversation-panel~conversation-DiXf0dkj.js +0 -13
- package/build/assets/x-RYDBg-e2.js +0 -1
- package/build/assets/zap-tbKDzCe3.js +0 -1
- package/dist/components/features/conversation/metrics-modal/context-window-section.cjs +0 -2
- package/dist/components/features/conversation/metrics-modal/context-window-section.cjs.map +0 -1
- package/dist/components/features/conversation/metrics-modal/context-window-section.d.ts +0 -6
- package/dist/components/features/conversation/metrics-modal/context-window-section.js +0 -46
- package/dist/components/features/conversation/metrics-modal/context-window-section.js.map +0 -1
- package/dist/components/features/conversation/metrics-modal/empty-state.cjs +0 -2
- package/dist/components/features/conversation/metrics-modal/empty-state.cjs.map +0 -1
- package/dist/components/features/conversation/metrics-modal/empty-state.d.ts +0 -1
- package/dist/components/features/conversation/metrics-modal/empty-state.js +0 -18
- package/dist/components/features/conversation/metrics-modal/empty-state.js.map +0 -1
- package/dist/components/features/conversation/metrics-modal/metrics-modal-header.cjs +0 -2
- package/dist/components/features/conversation/metrics-modal/metrics-modal-header.cjs.map +0 -1
- package/dist/components/features/conversation/metrics-modal/metrics-modal-header.d.ts +0 -5
- package/dist/components/features/conversation/metrics-modal/metrics-modal-header.js +0 -20
- package/dist/components/features/conversation/metrics-modal/metrics-modal-header.js.map +0 -1
- package/dist/components/features/conversation/metrics-modal/metrics-modal.cjs +0 -2
- package/dist/components/features/conversation/metrics-modal/metrics-modal.cjs.map +0 -1
- package/dist/components/features/conversation/metrics-modal/metrics-modal.d.ts +0 -6
- package/dist/components/features/conversation/metrics-modal/metrics-modal.js +0 -57
- package/dist/components/features/conversation/metrics-modal/metrics-modal.js.map +0 -1
- package/dist/icons/u-credit-card.cjs +0 -2
- package/dist/icons/u-credit-card.cjs.map +0 -1
- package/dist/icons/u-credit-card.js +0 -21
- package/dist/icons/u-credit-card.js.map +0 -1
- /package/build/assets/{vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~cy4jtuc2-rfV8mQ9m.js → vendor~entry.client~root~root-layout~index-home~home~conversation-panel~conversation~launch~dh9v73sa-rfV8mQ9m.js} +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/utils/format-token-count.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
if (e >= 1e6) {
|
|
4
|
+
let t = e / 1e6;
|
|
5
|
+
return t >= 10 && Number.isInteger(t) ? `${t.toFixed(0)}M` : `${t.toFixed(1)}M`;
|
|
6
|
+
}
|
|
7
|
+
if (e >= 1e3) {
|
|
8
|
+
let t = e / 1e3;
|
|
9
|
+
return Number.isInteger(t) ? `${t.toFixed(0)}k` : `${t.toFixed(1)}k`;
|
|
10
|
+
}
|
|
11
|
+
return e.toLocaleString();
|
|
12
|
+
}
|
|
13
|
+
function t(e, t) {
|
|
14
|
+
return t <= 0 ? 0 : Math.min(100, e / t * 100);
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { e as formatCompactTokenCount, t as getContextWindowUsagePercentage };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=format-token-count.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-token-count.js","names":[],"sources":["../../src/utils/format-token-count.ts"],"sourcesContent":["/** Compact token counts for context-window UI (e.g. 198.5k, 1.0M). */\nexport function formatCompactTokenCount(value: number): string {\n if (value >= 1_000_000) {\n const millions = value / 1_000_000;\n if (millions >= 10 && Number.isInteger(millions)) {\n return `${millions.toFixed(0)}M`;\n }\n return `${millions.toFixed(1)}M`;\n }\n\n if (value >= 1_000) {\n const thousands = value / 1_000;\n if (Number.isInteger(thousands)) {\n return `${thousands.toFixed(0)}k`;\n }\n return `${thousands.toFixed(1)}k`;\n }\n\n return value.toLocaleString();\n}\n\nexport function getContextWindowUsagePercentage(\n perTurnToken: number,\n contextWindow: number,\n): number {\n if (contextWindow <= 0) {\n return 0;\n }\n\n return Math.min(100, (perTurnToken / contextWindow) * 100);\n}\n"],"mappings":";AACA,SAAgB,EAAwB,GAAuB;CAC7D,IAAI,KAAS,KAAW;EACtB,IAAM,IAAW,IAAQ;EAIzB,OAHI,KAAY,MAAM,OAAO,UAAU,CAAQ,IACtC,GAAG,EAAS,QAAQ,CAAC,EAAE,KAEzB,GAAG,EAAS,QAAQ,CAAC,EAAE;CAChC;CAEA,IAAI,KAAS,KAAO;EAClB,IAAM,IAAY,IAAQ;EAI1B,OAHI,OAAO,UAAU,CAAS,IACrB,GAAG,EAAU,QAAQ,CAAC,EAAE,KAE1B,GAAG,EAAU,QAAQ,CAAC,EAAE;CACjC;CAEA,OAAO,EAAM,eAAe;AAC9B;AAEA,SAAgB,EACd,GACA,GACQ;CAKR,OAJI,KAAiB,IACZ,IAGF,KAAK,IAAI,KAAM,IAAe,IAAiB,GAAG;AAC3D"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");const e=require("./utils.cjs");var t=[`[@media(hover:hover)_and_(pointer:fine)]:pointer-events-none`,`[@media(hover:hover)_and_(pointer:fine)]:invisible`,`[@media(hover:hover)_and_(pointer:fine)]:opacity-0`,`[@media(hover:hover)_and_(pointer:fine)]:group-hover:pointer-events-auto`,`[@media(hover:hover)_and_(pointer:fine)]:group-hover:visible`,`[@media(hover:hover)_and_(pointer:fine)]:group-hover:opacity-100`,`[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:pointer-events-auto`,`[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:visible`,`[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:opacity-100`],n=[`[@media(hover:hover)_and_(pointer:fine)]:opacity-100`,`[@media(hover:hover)_and_(pointer:fine)]:group-hover:opacity-0`,`[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:opacity-0`],r=[`[@media(hover:hover)_and_(pointer:fine)]:min-w-0`,`[@media(hover:hover)_and_(pointer:fine)]:group-hover:min-w-[3.75rem]`,`[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:min-w-[3.75rem]`],i=[`[@media(hover:hover)_and_(pointer:fine)]:flex`,`[@media(hover:hover)_and_(pointer:fine)]:group-hover:hidden`,`[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:hidden`];function a(n=!1){return n?`pointer-events-auto visible opacity-100`:e.cn(`pointer-events-auto visible opacity-100`,...t)}function o(t=!1){return t?`opacity-0`:e.cn(`opacity-0`,...n)}function s(t=!1){return t?`min-w-[3.75rem]`:e.cn(`min-w-[3.75rem]`,...r)}function c(t=!1){return t?`hidden`:e.cn(`hidden`,...i)}exports.hoverRevealActionClassName=a,exports.hoverRevealPinnedTimestampClassName=c,exports.hoverRevealReserveClassName=s,exports.hoverRevealYieldClassName=o;
|
|
2
|
+
//# sourceMappingURL=hover-reveal-classes.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hover-reveal-classes.cjs","names":[],"sources":["../../src/utils/hover-reveal-classes.ts"],"sourcesContent":["import { cn } from \"#/utils/utils\";\n\n/**\n * Full Tailwind candidates for fine-hover media — devices where CSS `:hover`\n * is a reliable primary interaction (mouse/trackpad). Coarse-pointer /\n * touch-primary devices match the inverse and keep overflow actions always\n * visible + clickable. Kept as complete string literals so the production CSS\n * scanner can emit the arbitrary-variant rules (dynamic prefix concatenation\n * is not discoverable).\n */\nexport const FINE_HOVER_ACTION_CLASSES = [\n \"[@media(hover:hover)_and_(pointer:fine)]:pointer-events-none\",\n \"[@media(hover:hover)_and_(pointer:fine)]:invisible\",\n \"[@media(hover:hover)_and_(pointer:fine)]:opacity-0\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:pointer-events-auto\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:visible\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:opacity-100\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:pointer-events-auto\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:visible\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:opacity-100\",\n] as const;\n\nexport const FINE_HOVER_YIELD_CLASSES = [\n \"[@media(hover:hover)_and_(pointer:fine)]:opacity-100\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:opacity-0\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:opacity-0\",\n] as const;\n\nexport const FINE_HOVER_RESERVE_CLASSES = [\n \"[@media(hover:hover)_and_(pointer:fine)]:min-w-0\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:min-w-[3.75rem]\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:min-w-[3.75rem]\",\n] as const;\n\nexport const FINE_HOVER_PINNED_TIMESTAMP_CLASSES = [\n \"[@media(hover:hover)_and_(pointer:fine)]:flex\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:hidden\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:hidden\",\n] as const;\n\n/**\n * Overlay action chrome (ellipsis, pin, etc.): always interactable on touch;\n * hover/focus-reveal only on fine-pointer hover devices.\n */\nexport function hoverRevealActionClassName(forceVisible = false): string {\n if (forceVisible) {\n return \"pointer-events-auto visible opacity-100\";\n }\n\n return cn(\n \"pointer-events-auto visible opacity-100\",\n ...FINE_HOVER_ACTION_CLASSES,\n );\n}\n\n/**\n * Companion for timestamps that yield space to hover-reveal actions:\n * hidden on touch (actions stay visible); on fine-pointer devices, visible\n * until the row is hovered / focused / menu-open.\n */\nexport function hoverRevealYieldClassName(forceHidden = false): string {\n if (forceHidden) {\n return \"opacity-0\";\n }\n\n return cn(\"opacity-0\", ...FINE_HOVER_YIELD_CLASSES);\n}\n\n/**\n * Reserve trailing space for hover-reveal actions. Always reserved on touch;\n * on fine-pointer devices, reserved on hover / focus / open.\n */\nexport function hoverRevealReserveClassName(forceReserved = false): string {\n if (forceReserved) {\n return \"min-w-[3.75rem]\";\n }\n\n return cn(\"min-w-[3.75rem]\", ...FINE_HOVER_RESERVE_CLASSES);\n}\n\n/**\n * Absolute-positioned timestamp that sits under a pinned-card ellipsis slot:\n * shown at rest on fine-pointer devices, hidden when the row reveals actions\n * (or when the menu is open / on touch where the ellipsis stays visible).\n */\nexport function hoverRevealPinnedTimestampClassName(\n forceHidden = false,\n): string {\n if (forceHidden) {\n return \"hidden\";\n }\n\n return cn(\"hidden\", ...FINE_HOVER_PINNED_TIMESTAMP_CLASSES);\n}\n"],"mappings":"4EAUA,IAAa,EAA4B,CACvC,+DACA,qDACA,qDACA,2EACA,+DACA,mEACA,kFACA,sEACA,yEACF,EAEa,EAA2B,CACtC,uDACA,iEACA,uEACF,EAEa,EAA6B,CACxC,mDACA,uEACA,6EACF,EAEa,EAAsC,CACjD,gDACA,8DACA,oEACF,EAMA,SAAgB,EAA2B,EAAe,GAAe,CAKvE,OAJI,EACK,0CAGF,EAAA,GACL,0CACA,GAAG,CACL,CACF,CAOA,SAAgB,EAA0B,EAAc,GAAe,CAKrE,OAJI,EACK,YAGF,EAAA,GAAG,YAAa,GAAG,CAAwB,CACpD,CAMA,SAAgB,EAA4B,EAAgB,GAAe,CAKzE,OAJI,EACK,kBAGF,EAAA,GAAG,kBAAmB,GAAG,CAA0B,CAC5D,CAOA,SAAgB,EACd,EAAc,GACN,CAKR,OAJI,EACK,SAGF,EAAA,GAAG,SAAU,GAAG,CAAmC,CAC5D"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Full Tailwind candidates for fine-hover media — devices where CSS `:hover`
|
|
3
|
+
* is a reliable primary interaction (mouse/trackpad). Coarse-pointer /
|
|
4
|
+
* touch-primary devices match the inverse and keep overflow actions always
|
|
5
|
+
* visible + clickable. Kept as complete string literals so the production CSS
|
|
6
|
+
* scanner can emit the arbitrary-variant rules (dynamic prefix concatenation
|
|
7
|
+
* is not discoverable).
|
|
8
|
+
*/
|
|
9
|
+
export declare const FINE_HOVER_ACTION_CLASSES: readonly ["[@media(hover:hover)_and_(pointer:fine)]:pointer-events-none", "[@media(hover:hover)_and_(pointer:fine)]:invisible", "[@media(hover:hover)_and_(pointer:fine)]:opacity-0", "[@media(hover:hover)_and_(pointer:fine)]:group-hover:pointer-events-auto", "[@media(hover:hover)_and_(pointer:fine)]:group-hover:visible", "[@media(hover:hover)_and_(pointer:fine)]:group-hover:opacity-100", "[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:pointer-events-auto", "[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:visible", "[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:opacity-100"];
|
|
10
|
+
export declare const FINE_HOVER_YIELD_CLASSES: readonly ["[@media(hover:hover)_and_(pointer:fine)]:opacity-100", "[@media(hover:hover)_and_(pointer:fine)]:group-hover:opacity-0", "[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:opacity-0"];
|
|
11
|
+
export declare const FINE_HOVER_RESERVE_CLASSES: readonly ["[@media(hover:hover)_and_(pointer:fine)]:min-w-0", "[@media(hover:hover)_and_(pointer:fine)]:group-hover:min-w-[3.75rem]", "[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:min-w-[3.75rem]"];
|
|
12
|
+
export declare const FINE_HOVER_PINNED_TIMESTAMP_CLASSES: readonly ["[@media(hover:hover)_and_(pointer:fine)]:flex", "[@media(hover:hover)_and_(pointer:fine)]:group-hover:hidden", "[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:hidden"];
|
|
13
|
+
/**
|
|
14
|
+
* Overlay action chrome (ellipsis, pin, etc.): always interactable on touch;
|
|
15
|
+
* hover/focus-reveal only on fine-pointer hover devices.
|
|
16
|
+
*/
|
|
17
|
+
export declare function hoverRevealActionClassName(forceVisible?: boolean): string;
|
|
18
|
+
/**
|
|
19
|
+
* Companion for timestamps that yield space to hover-reveal actions:
|
|
20
|
+
* hidden on touch (actions stay visible); on fine-pointer devices, visible
|
|
21
|
+
* until the row is hovered / focused / menu-open.
|
|
22
|
+
*/
|
|
23
|
+
export declare function hoverRevealYieldClassName(forceHidden?: boolean): string;
|
|
24
|
+
/**
|
|
25
|
+
* Reserve trailing space for hover-reveal actions. Always reserved on touch;
|
|
26
|
+
* on fine-pointer devices, reserved on hover / focus / open.
|
|
27
|
+
*/
|
|
28
|
+
export declare function hoverRevealReserveClassName(forceReserved?: boolean): string;
|
|
29
|
+
/**
|
|
30
|
+
* Absolute-positioned timestamp that sits under a pinned-card ellipsis slot:
|
|
31
|
+
* shown at rest on fine-pointer devices, hidden when the row reveals actions
|
|
32
|
+
* (or when the menu is open / on touch where the ellipsis stays visible).
|
|
33
|
+
*/
|
|
34
|
+
export declare function hoverRevealPinnedTimestampClassName(forceHidden?: boolean): string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { cn as e } from "./utils.js";
|
|
2
|
+
//#region src/utils/hover-reveal-classes.ts
|
|
3
|
+
var t = [
|
|
4
|
+
"[@media(hover:hover)_and_(pointer:fine)]:pointer-events-none",
|
|
5
|
+
"[@media(hover:hover)_and_(pointer:fine)]:invisible",
|
|
6
|
+
"[@media(hover:hover)_and_(pointer:fine)]:opacity-0",
|
|
7
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-hover:pointer-events-auto",
|
|
8
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-hover:visible",
|
|
9
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-hover:opacity-100",
|
|
10
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:pointer-events-auto",
|
|
11
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:visible",
|
|
12
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:opacity-100"
|
|
13
|
+
], n = [
|
|
14
|
+
"[@media(hover:hover)_and_(pointer:fine)]:opacity-100",
|
|
15
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-hover:opacity-0",
|
|
16
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:opacity-0"
|
|
17
|
+
], r = [
|
|
18
|
+
"[@media(hover:hover)_and_(pointer:fine)]:min-w-0",
|
|
19
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-hover:min-w-[3.75rem]",
|
|
20
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:min-w-[3.75rem]"
|
|
21
|
+
], i = [
|
|
22
|
+
"[@media(hover:hover)_and_(pointer:fine)]:flex",
|
|
23
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-hover:hidden",
|
|
24
|
+
"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:hidden"
|
|
25
|
+
];
|
|
26
|
+
function a(n = !1) {
|
|
27
|
+
return n ? "pointer-events-auto visible opacity-100" : e("pointer-events-auto visible opacity-100", ...t);
|
|
28
|
+
}
|
|
29
|
+
function o(t = !1) {
|
|
30
|
+
return t ? "opacity-0" : e("opacity-0", ...n);
|
|
31
|
+
}
|
|
32
|
+
function s(t = !1) {
|
|
33
|
+
return t ? "min-w-[3.75rem]" : e("min-w-[3.75rem]", ...r);
|
|
34
|
+
}
|
|
35
|
+
function c(t = !1) {
|
|
36
|
+
return t ? "hidden" : e("hidden", ...i);
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
export { a as hoverRevealActionClassName, c as hoverRevealPinnedTimestampClassName, s as hoverRevealReserveClassName, o as hoverRevealYieldClassName };
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=hover-reveal-classes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hover-reveal-classes.js","names":[],"sources":["../../src/utils/hover-reveal-classes.ts"],"sourcesContent":["import { cn } from \"#/utils/utils\";\n\n/**\n * Full Tailwind candidates for fine-hover media — devices where CSS `:hover`\n * is a reliable primary interaction (mouse/trackpad). Coarse-pointer /\n * touch-primary devices match the inverse and keep overflow actions always\n * visible + clickable. Kept as complete string literals so the production CSS\n * scanner can emit the arbitrary-variant rules (dynamic prefix concatenation\n * is not discoverable).\n */\nexport const FINE_HOVER_ACTION_CLASSES = [\n \"[@media(hover:hover)_and_(pointer:fine)]:pointer-events-none\",\n \"[@media(hover:hover)_and_(pointer:fine)]:invisible\",\n \"[@media(hover:hover)_and_(pointer:fine)]:opacity-0\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:pointer-events-auto\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:visible\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:opacity-100\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:pointer-events-auto\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:visible\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:opacity-100\",\n] as const;\n\nexport const FINE_HOVER_YIELD_CLASSES = [\n \"[@media(hover:hover)_and_(pointer:fine)]:opacity-100\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:opacity-0\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:opacity-0\",\n] as const;\n\nexport const FINE_HOVER_RESERVE_CLASSES = [\n \"[@media(hover:hover)_and_(pointer:fine)]:min-w-0\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:min-w-[3.75rem]\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:min-w-[3.75rem]\",\n] as const;\n\nexport const FINE_HOVER_PINNED_TIMESTAMP_CLASSES = [\n \"[@media(hover:hover)_and_(pointer:fine)]:flex\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-hover:hidden\",\n \"[@media(hover:hover)_and_(pointer:fine)]:group-focus-within:hidden\",\n] as const;\n\n/**\n * Overlay action chrome (ellipsis, pin, etc.): always interactable on touch;\n * hover/focus-reveal only on fine-pointer hover devices.\n */\nexport function hoverRevealActionClassName(forceVisible = false): string {\n if (forceVisible) {\n return \"pointer-events-auto visible opacity-100\";\n }\n\n return cn(\n \"pointer-events-auto visible opacity-100\",\n ...FINE_HOVER_ACTION_CLASSES,\n );\n}\n\n/**\n * Companion for timestamps that yield space to hover-reveal actions:\n * hidden on touch (actions stay visible); on fine-pointer devices, visible\n * until the row is hovered / focused / menu-open.\n */\nexport function hoverRevealYieldClassName(forceHidden = false): string {\n if (forceHidden) {\n return \"opacity-0\";\n }\n\n return cn(\"opacity-0\", ...FINE_HOVER_YIELD_CLASSES);\n}\n\n/**\n * Reserve trailing space for hover-reveal actions. Always reserved on touch;\n * on fine-pointer devices, reserved on hover / focus / open.\n */\nexport function hoverRevealReserveClassName(forceReserved = false): string {\n if (forceReserved) {\n return \"min-w-[3.75rem]\";\n }\n\n return cn(\"min-w-[3.75rem]\", ...FINE_HOVER_RESERVE_CLASSES);\n}\n\n/**\n * Absolute-positioned timestamp that sits under a pinned-card ellipsis slot:\n * shown at rest on fine-pointer devices, hidden when the row reveals actions\n * (or when the menu is open / on touch where the ellipsis stays visible).\n */\nexport function hoverRevealPinnedTimestampClassName(\n forceHidden = false,\n): string {\n if (forceHidden) {\n return \"hidden\";\n }\n\n return cn(\"hidden\", ...FINE_HOVER_PINNED_TIMESTAMP_CLASSES);\n}\n"],"mappings":";;AAUA,IAAa,IAA4B;CACvC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GAEa,IAA2B;CACtC;CACA;CACA;AACF,GAEa,IAA6B;CACxC;CACA;CACA;AACF,GAEa,IAAsC;CACjD;CACA;CACA;AACF;AAMA,SAAgB,EAA2B,IAAe,IAAe;CAKvE,OAJI,IACK,4CAGF,EACL,2CACA,GAAG,CACL;AACF;AAOA,SAAgB,EAA0B,IAAc,IAAe;CAKrE,OAJI,IACK,cAGF,EAAG,aAAa,GAAG,CAAwB;AACpD;AAMA,SAAgB,EAA4B,IAAgB,IAAe;CAKzE,OAJI,IACK,oBAGF,EAAG,mBAAmB,GAAG,CAA0B;AAC5D;AAOA,SAAgB,EACd,IAAc,IACN;CAKR,OAJI,IACK,WAGF,EAAG,UAAU,GAAG,CAAmC;AAC5D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-markdown-file-path.cjs","names":[],"sources":["../../src/utils/is-markdown-file-path.ts"],"sourcesContent":["/** Extensions treated as Markdown for rich preview rendering. */\nconst MARKDOWN_EXTS = new Set([\"md\", \"markdown\", \"mdx\"]);\n\n/**\n * True when `path` ends with a Markdown extension (`.md`, `.markdown`, `.mdx`).\n */\nexport function isMarkdownFilePath(path: string): boolean {\n const idx = path.lastIndexOf(\".\");\n if (idx === -1) return false;\n return MARKDOWN_EXTS.has(path.slice(idx + 1).toLowerCase());\n}\n"],"mappings":"6CACA,IAAM,EAAgB,IAAI,IAAI,CAAC,KAAM,WAAY,KAAK,CAAC,EAKvD,SAAgB,EAAmB,EAAuB,CACxD,IAAM,EAAM,EAAK,YAAY,GAAG,EAEhC,OADI,IAAQ,GAAW,GAChB,EAAc,IAAI,EAAK,MAAM,EAAM,CAAC,EAAE,YAAY,CAAC,CAC5D"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/utils/is-markdown-file-path.ts
|
|
2
|
+
var e = new Set([
|
|
3
|
+
"md",
|
|
4
|
+
"markdown",
|
|
5
|
+
"mdx"
|
|
6
|
+
]);
|
|
7
|
+
function t(t) {
|
|
8
|
+
let n = t.lastIndexOf(".");
|
|
9
|
+
return n === -1 ? !1 : e.has(t.slice(n + 1).toLowerCase());
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { t as isMarkdownFilePath };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=is-markdown-file-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-markdown-file-path.js","names":[],"sources":["../../src/utils/is-markdown-file-path.ts"],"sourcesContent":["/** Extensions treated as Markdown for rich preview rendering. */\nconst MARKDOWN_EXTS = new Set([\"md\", \"markdown\", \"mdx\"]);\n\n/**\n * True when `path` ends with a Markdown extension (`.md`, `.markdown`, `.mdx`).\n */\nexport function isMarkdownFilePath(path: string): boolean {\n const idx = path.lastIndexOf(\".\");\n if (idx === -1) return false;\n return MARKDOWN_EXTS.has(path.slice(idx + 1).toLowerCase());\n}\n"],"mappings":";AACA,IAAM,IAAgB,IAAI,IAAI;CAAC;CAAM;CAAY;AAAK,CAAC;AAKvD,SAAgB,EAAmB,GAAuB;CACxD,IAAM,IAAM,EAAK,YAAY,GAAG;CAEhC,OADI,MAAQ,KAAW,KAChB,EAAc,IAAI,EAAK,MAAM,IAAM,CAAC,EAAE,YAAY,CAAC;AAC5D"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");function e(e){return e.connectionOptions.filter(e=>e.provider===`mcp`&&!!e.transport)}function t(t){return e(t)[0]}function n(e){if(e.auth.strategy!==`oauth2`)return!0;let t=e.auth.oauth;return t?!t.authorizationUrl&&!t.tokenUrl&&!t.registrationUrl&&!t.additionalAuthorizationParams&&!t.additionalTokenParams:!1}function r(t){return e(t).find(n)}function i(e){return t(e)?.transport}function a(e){switch(e){case`none`:return`none`;case`body`:return`client_secret_post`;case`basic`:return`client_secret_basic`;default:return}}function o(e){if(e.auth.strategy!==`oauth2`)return;let t={type:`oauth`},n=a(e.auth.oauth?.clientAuthentication);return n&&(t.client_auth_method=n),e.auth.oauth?.scopes?.length&&(t.scopes=e.auth.oauth.scopes),Object.keys(t).length>1?t:void 0}function s(e){return e.filter(e
|
|
1
|
+
require("../_virtual/_rolldown/runtime.cjs");function e(e){return e.connectionOptions.filter(e=>e.provider===`mcp`&&!!e.transport)}function t(t){return e(t)[0]}function n(e){if(e.auth.strategy!==`oauth2`)return!0;let t=e.auth.oauth;return t?!t.authorizationUrl&&!t.tokenUrl&&!t.registrationUrl&&!t.additionalAuthorizationParams&&!t.additionalTokenParams:!1}function r(t){return e(t).find(n)}function i(e){return t(e)?.transport}function a(e){switch(e){case`none`:return`none`;case`body`:return`client_secret_post`;case`basic`:return`client_secret_basic`;default:return}}function o(e){if(e.auth.strategy!==`oauth2`)return;let t={type:`oauth`},n=a(e.auth.oauth?.clientAuthentication);return n&&(t.client_auth_method=n),e.auth.oauth?.scopes?.length&&(t.scopes=e.auth.oauth.scopes),Object.keys(t).length>1?t:void 0}function s(e){return e.filter(c)}function c(e){return!!t(e)}var l=e=>{try{return new URL(e)}catch{return null}};function u(e,t){let n=typeof e==`string`?e:``,r=typeof t==`string`?t:``;if(!n||!r)return!1;let i=l(n),a=l(r);return!i||!a?n.replace(/\/+$/,``)===r.replace(/\/+$/,``):i.protocol===a.protocol&&i.host===a.host&&i.pathname.replace(/\/+$/,``)===a.pathname.replace(/\/+$/,``)}function d(e,t){if(e.kind===`shttp`){let n=e.url;return t.type===`shttp`&&!!t.url&&u(t.url,n)}if(e.kind===`sse`){let n=e.url;return t.type===`sse`&&!!t.url&&u(t.url,n)}return t.type===`stdio`&&t.name===e.serverName}function f(e){return e.trim().toLowerCase()}function p(e){return e.map((e,t)=>({entry:e,index:t})).sort((e,t)=>(t.entry.popularityRank??0)-(e.entry.popularityRank??0)||e.index-t.index).map(({entry:e})=>e)}function m(e,t){let n=f(t);return n?[e.name,e.description,e.id,...e.keywords??[]].join(` `).toLowerCase().includes(n):!0}function h(e,t,n){let r=f(n);return r?[e.type,`name`in e?e.name:void 0,`command`in e?e.command:void 0,`args`in e?e.args?.join(` `):void 0,`url`in e?e.url:void 0,t?.name,t?.description,t?.id,...t?.keywords??[]].filter(Boolean).join(` `).toLowerCase().includes(r):!0}function g(t,n){return n.find(n=>e(n).some(e=>d(e.transport,t)))}exports.findCatalogEntryForServer=g,exports.getDefaultMcpTransport=i,exports.getInstallableMcpConnectionOption=r,exports.getMarketplaceEntriesByPopularity=p,exports.getMcpMarketplaceCatalog=s,exports.getMcpOAuthAuthenticationConfig=o,exports.installedServerMatchesQuery=h,exports.marketplaceEntryMatchesQuery=m;
|
|
2
2
|
//# sourceMappingURL=mcp-marketplace-utils.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-marketplace-utils.cjs","names":[],"sources":["../../src/utils/mcp-marketplace-utils.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport type {\n MCPAuthenticationConfig,\n MCPOAuthClientAuthMethod,\n} from \"#/types/mcp-auth\";\nimport type {\n IntegrationAuthConfig,\n IntegrationCatalogEntry as MarketplaceEntry,\n IntegrationConnectionOption,\n IntegrationOAuthConfig,\n IntegrationTransport,\n} from \"@openhands/extensions/integrations\";\n\nexport type { MarketplaceEntry };\n\ntype McpIntegrationAuthConfig = IntegrationAuthConfig & {\n credentialSecretName?: string;\n saveCredentialAsSecretByDefault?: boolean;\n};\n\nexport type McpMarketplaceConnectionOption = Omit<\n IntegrationConnectionOption,\n \"auth\" | \"provider\" | \"transport\"\n> & {\n provider: \"mcp\";\n transport: IntegrationTransport;\n auth: McpIntegrationAuthConfig;\n};\n\nexport function getMcpConnectionOptions(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption[] {\n return entry.connectionOptions.filter(\n (option): option is McpMarketplaceConnectionOption =>\n option.provider === \"mcp\" && !!option.transport,\n );\n}\n\nexport function getDefaultMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry)[0];\n}\n\nfunction isLocallyInstallableMcpOption(\n option: McpMarketplaceConnectionOption,\n): boolean {\n if (option.auth.strategy !== \"oauth2\") return true;\n\n const oauth = option.auth.oauth;\n if (!oauth) return false;\n\n // Local agent-server installs only support OAuth flows initiated by the MCP\n // server itself through fastmcp. Catalog entries that specify provider OAuth\n // endpoints still need the hosted integration-auth flow and should not be\n // exposed as locally installable static MCP configs.\n return (\n !oauth.authorizationUrl &&\n !oauth.tokenUrl &&\n !oauth.registrationUrl &&\n !oauth.additionalAuthorizationParams &&\n !oauth.additionalTokenParams\n );\n}\n\nexport function getInstallableMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry).find(isLocallyInstallableMcpOption);\n}\n\nexport function getDefaultMcpTransport(\n entry: MarketplaceEntry,\n): IntegrationTransport | undefined {\n return getDefaultMcpConnectionOption(entry)?.transport;\n}\n\nfunction toMcpOAuthClientAuthMethod(\n value: IntegrationOAuthConfig[\"clientAuthentication\"] | undefined,\n): MCPOAuthClientAuthMethod | undefined {\n switch (value) {\n case \"none\":\n return \"none\";\n case \"body\":\n return \"client_secret_post\";\n case \"basic\":\n return \"client_secret_basic\";\n default:\n return undefined;\n }\n}\n\nexport function getMcpOAuthAuthenticationConfig(\n option: McpMarketplaceConnectionOption,\n): MCPAuthenticationConfig | undefined {\n if (option.auth.strategy !== \"oauth2\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n const clientAuthMethod = toMcpOAuthClientAuthMethod(\n option.auth.oauth?.clientAuthentication,\n );\n if (clientAuthMethod) {\n authentication.client_auth_method = clientAuthMethod;\n }\n if (option.auth.oauth?.scopes?.length) {\n authentication.scopes = option.auth.oauth.scopes;\n }\n return Object.keys(authentication).length > 1 ? authentication : undefined;\n}\n\nexport function getMcpMarketplaceCatalog(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog.filter((entry) => !!getDefaultMcpConnectionOption(entry));\n}\n\nconst tryUrl = (raw: string): URL | null => {\n try {\n return new URL(raw);\n } catch {\n return null;\n }\n};\n\n/**\n * Loose URL match that ignores query strings, trailing slashes, and\n * default ports. We want clicking \"Linear\" to flag the entry as\n * installed even if the user pasted the URL with extra trailing slash\n * or a different port-equivalent variant.\n *\n * Defensive against runtime data that doesn't match the static type:\n * if either input is not a string (e.g. parsed from an older settings\n * blob), we fall through the URL parsing path and the safe trim\n * fallback below, never calling `.replace` on undefined.\n */\nexport function urlsMatch(a: unknown, b: unknown): boolean {\n const aStr = typeof a === \"string\" ? a : \"\";\n const bStr = typeof b === \"string\" ? b : \"\";\n if (!aStr || !bStr) return false;\n const left = tryUrl(aStr);\n const right = tryUrl(bStr);\n if (!left || !right) {\n return aStr.replace(/\\/+$/, \"\") === bStr.replace(/\\/+$/, \"\");\n }\n return (\n left.protocol === right.protocol &&\n left.host === right.host &&\n left.pathname.replace(/\\/+$/, \"\") === right.pathname.replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Decide whether a marketplace template is already represented by one\n * of the installed MCP servers. Used to render an \"Installed\" badge on\n * the marketplace tile. Returns the first matching server, or null.\n */\nexport function findInstalledMatch(\n transport: IntegrationTransport,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n return (\n servers.find((server) => transportMatchesServer(transport, server)) ?? null\n );\n}\n\nexport function findInstalledEntryMatch(\n entry: MarketplaceEntry,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n for (const option of getMcpConnectionOptions(entry)) {\n const match = findInstalledMatch(option.transport, servers);\n if (match) return match;\n }\n return null;\n}\n\nfunction transportMatchesServer(\n transport: IntegrationTransport,\n server: MCPServerConfig,\n): boolean {\n if (transport.kind === \"shttp\") {\n const tplUrl = transport.url;\n return (\n server.type === \"shttp\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n if (transport.kind === \"sse\") {\n const tplUrl = transport.url;\n return (\n server.type === \"sse\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n // stdio: match on the registered server name.\n return server.type === \"stdio\" && server.name === transport.serverName;\n}\n\nfunction normalize(query: string): string {\n return query.trim().toLowerCase();\n}\n\n/**\n * Case-insensitive substring match against the catalog entry's\n * user-visible identity (name, description, id, keywords). Empty\n * queries always match.\n */\nexport function getMarketplaceEntriesByPopularity(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.entry.popularityRank ?? 0) - (a.entry.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ entry }) => entry);\n}\n\nexport function getMarketplaceEntryById(\n id: string,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => entry.id === id);\n}\n\nexport function marketplaceEntryMatchesQuery(\n entry: MarketplaceEntry,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n entry.name,\n entry.description,\n entry.id,\n ...(entry.keywords ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Search match for an installed (already-configured) server. We\n * search the server's own identifying fields and — if it's a catalog\n * entry — its catalog name/keywords too, so typing \"Slack\" matches\n * the installed Slack tile even though the persisted server is just\n * `{ type: \"stdio\", name: \"slack\", ... }`.\n */\nexport function installedServerMatchesQuery(\n server: MCPServerConfig,\n catalogEntry: MarketplaceEntry | undefined,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n server.type,\n \"name\" in server ? server.name : undefined,\n \"command\" in server ? server.command : undefined,\n \"args\" in server ? server.args?.join(\" \") : undefined,\n \"url\" in server ? server.url : undefined,\n catalogEntry?.name,\n catalogEntry?.description,\n catalogEntry?.id,\n ...(catalogEntry?.keywords ?? []),\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Look up the catalog entry that best matches an installed server.\n * Mirrors the lookup used in `installed-server-card.tsx` for\n * rendering the friendly icon.\n */\nexport function findCatalogEntryForServer(\n server: MCPServerConfig,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => {\n // Check every MCP option rather than only the default. Some unified\n // integration entries default to OAuth-hosted MCP while still exposing\n // an API/stdio option; existing installed servers should match either.\n return getMcpConnectionOptions(entry).some((option) =>\n transportMatchesServer(option.transport, server),\n );\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mcp-marketplace-utils.cjs","names":[],"sources":["../../src/utils/mcp-marketplace-utils.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport type {\n MCPAuthenticationConfig,\n MCPOAuthClientAuthMethod,\n} from \"#/types/mcp-auth\";\nimport type {\n IntegrationAuthConfig,\n IntegrationCatalogEntry as MarketplaceEntry,\n IntegrationConnectionOption,\n IntegrationOAuthConfig,\n IntegrationTransport,\n} from \"@openhands/extensions/integrations\";\n\nexport type { MarketplaceEntry };\n\ntype McpIntegrationAuthConfig = IntegrationAuthConfig & {\n credentialSecretName?: string;\n saveCredentialAsSecretByDefault?: boolean;\n};\n\nexport type McpMarketplaceConnectionOption = Omit<\n IntegrationConnectionOption,\n \"auth\" | \"provider\" | \"transport\"\n> & {\n provider: \"mcp\";\n transport: IntegrationTransport;\n auth: McpIntegrationAuthConfig;\n};\n\nexport function getMcpConnectionOptions(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption[] {\n return entry.connectionOptions.filter(\n (option): option is McpMarketplaceConnectionOption =>\n option.provider === \"mcp\" && !!option.transport,\n );\n}\n\nexport function getDefaultMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry)[0];\n}\n\nfunction isLocallyInstallableMcpOption(\n option: McpMarketplaceConnectionOption,\n): boolean {\n if (option.auth.strategy !== \"oauth2\") return true;\n\n const oauth = option.auth.oauth;\n if (!oauth) return false;\n\n // Local agent-server installs only support OAuth flows initiated by the MCP\n // server itself through fastmcp. Catalog entries that specify provider OAuth\n // endpoints still need the hosted integration-auth flow and should not be\n // exposed as locally installable static MCP configs.\n return (\n !oauth.authorizationUrl &&\n !oauth.tokenUrl &&\n !oauth.registrationUrl &&\n !oauth.additionalAuthorizationParams &&\n !oauth.additionalTokenParams\n );\n}\n\nexport function getInstallableMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry).find(isLocallyInstallableMcpOption);\n}\n\nexport function getDefaultMcpTransport(\n entry: MarketplaceEntry,\n): IntegrationTransport | undefined {\n return getDefaultMcpConnectionOption(entry)?.transport;\n}\n\nfunction toMcpOAuthClientAuthMethod(\n value: IntegrationOAuthConfig[\"clientAuthentication\"] | undefined,\n): MCPOAuthClientAuthMethod | undefined {\n switch (value) {\n case \"none\":\n return \"none\";\n case \"body\":\n return \"client_secret_post\";\n case \"basic\":\n return \"client_secret_basic\";\n default:\n return undefined;\n }\n}\n\nexport function getMcpOAuthAuthenticationConfig(\n option: McpMarketplaceConnectionOption,\n): MCPAuthenticationConfig | undefined {\n if (option.auth.strategy !== \"oauth2\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n const clientAuthMethod = toMcpOAuthClientAuthMethod(\n option.auth.oauth?.clientAuthentication,\n );\n if (clientAuthMethod) {\n authentication.client_auth_method = clientAuthMethod;\n }\n if (option.auth.oauth?.scopes?.length) {\n authentication.scopes = option.auth.oauth.scopes;\n }\n return Object.keys(authentication).length > 1 ? authentication : undefined;\n}\n\nexport function getMcpMarketplaceCatalog(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog.filter(isMcpInstallableEntry);\n}\n\n/**\n * Whether this backend can install/configure the entry as an MCP server.\n * Entries whose only connection options use another provider or transport\n * (e.g. Jira's HTTP/OpenAPI option) exist in the catalog but cannot go\n * through the local MCP install flow.\n */\nexport function isMcpInstallableEntry(entry: MarketplaceEntry): boolean {\n return !!getDefaultMcpConnectionOption(entry);\n}\n\nconst tryUrl = (raw: string): URL | null => {\n try {\n return new URL(raw);\n } catch {\n return null;\n }\n};\n\n/**\n * Loose URL match that ignores query strings, trailing slashes, and\n * default ports. We want clicking \"Linear\" to flag the entry as\n * installed even if the user pasted the URL with extra trailing slash\n * or a different port-equivalent variant.\n *\n * Defensive against runtime data that doesn't match the static type:\n * if either input is not a string (e.g. parsed from an older settings\n * blob), we fall through the URL parsing path and the safe trim\n * fallback below, never calling `.replace` on undefined.\n */\nexport function urlsMatch(a: unknown, b: unknown): boolean {\n const aStr = typeof a === \"string\" ? a : \"\";\n const bStr = typeof b === \"string\" ? b : \"\";\n if (!aStr || !bStr) return false;\n const left = tryUrl(aStr);\n const right = tryUrl(bStr);\n if (!left || !right) {\n return aStr.replace(/\\/+$/, \"\") === bStr.replace(/\\/+$/, \"\");\n }\n return (\n left.protocol === right.protocol &&\n left.host === right.host &&\n left.pathname.replace(/\\/+$/, \"\") === right.pathname.replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Decide whether a marketplace template is already represented by one\n * of the installed MCP servers. Used to render an \"Installed\" badge on\n * the marketplace tile. Returns the first matching server, or null.\n */\nexport function findInstalledMatch(\n transport: IntegrationTransport,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n return (\n servers.find((server) => transportMatchesServer(transport, server)) ?? null\n );\n}\n\nexport function findInstalledEntryMatch(\n entry: MarketplaceEntry,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n for (const option of getMcpConnectionOptions(entry)) {\n const match = findInstalledMatch(option.transport, servers);\n if (match) return match;\n }\n return null;\n}\n\nfunction transportMatchesServer(\n transport: IntegrationTransport,\n server: MCPServerConfig,\n): boolean {\n if (transport.kind === \"shttp\") {\n const tplUrl = transport.url;\n return (\n server.type === \"shttp\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n if (transport.kind === \"sse\") {\n const tplUrl = transport.url;\n return (\n server.type === \"sse\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n // stdio: match on the registered server name.\n return server.type === \"stdio\" && server.name === transport.serverName;\n}\n\nfunction normalize(query: string): string {\n return query.trim().toLowerCase();\n}\n\n/**\n * Case-insensitive substring match against the catalog entry's\n * user-visible identity (name, description, id, keywords). Empty\n * queries always match.\n */\nexport function getMarketplaceEntriesByPopularity(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.entry.popularityRank ?? 0) - (a.entry.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ entry }) => entry);\n}\n\nexport function getMarketplaceEntryById(\n id: string,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => entry.id === id);\n}\n\nexport function marketplaceEntryMatchesQuery(\n entry: MarketplaceEntry,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n entry.name,\n entry.description,\n entry.id,\n ...(entry.keywords ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Search match for an installed (already-configured) server. We\n * search the server's own identifying fields and — if it's a catalog\n * entry — its catalog name/keywords too, so typing \"Slack\" matches\n * the installed Slack tile even though the persisted server is just\n * `{ type: \"stdio\", name: \"slack\", ... }`.\n */\nexport function installedServerMatchesQuery(\n server: MCPServerConfig,\n catalogEntry: MarketplaceEntry | undefined,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n server.type,\n \"name\" in server ? server.name : undefined,\n \"command\" in server ? server.command : undefined,\n \"args\" in server ? server.args?.join(\" \") : undefined,\n \"url\" in server ? server.url : undefined,\n catalogEntry?.name,\n catalogEntry?.description,\n catalogEntry?.id,\n ...(catalogEntry?.keywords ?? []),\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Look up the catalog entry that best matches an installed server.\n * Mirrors the lookup used in `installed-server-card.tsx` for\n * rendering the friendly icon.\n */\nexport function findCatalogEntryForServer(\n server: MCPServerConfig,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => {\n // Check every MCP option rather than only the default. Some unified\n // integration entries default to OAuth-hosted MCP while still exposing\n // an API/stdio option; existing installed servers should match either.\n return getMcpConnectionOptions(entry).some((option) =>\n transportMatchesServer(option.transport, server),\n );\n });\n}\n"],"mappings":"6CA6BA,SAAgB,EACd,EACkC,CAClC,OAAO,EAAM,kBAAkB,OAC5B,GACC,EAAO,WAAa,OAAS,CAAC,CAAC,EAAO,SAC1C,CACF,CAEA,SAAgB,EACd,EAC4C,CAC5C,OAAO,EAAwB,CAAK,EAAE,EACxC,CAEA,SAAS,EACP,EACS,CACT,GAAI,EAAO,KAAK,WAAa,SAAU,MAAO,GAE9C,IAAM,EAAQ,EAAO,KAAK,MAO1B,OANK,EAOH,CAAC,EAAM,kBACP,CAAC,EAAM,UACP,CAAC,EAAM,iBACP,CAAC,EAAM,+BACP,CAAC,EAAM,sBAXU,EAarB,CAEA,SAAgB,EACd,EAC4C,CAC5C,OAAO,EAAwB,CAAK,EAAE,KAAK,CAA6B,CAC1E,CAEA,SAAgB,EACd,EACkC,CAClC,OAAO,EAA8B,CAAK,GAAG,SAC/C,CAEA,SAAS,EACP,EACsC,CACtC,OAAQ,EAAR,CACE,IAAK,OACH,MAAO,OACT,IAAK,OACH,MAAO,qBACT,IAAK,QACH,MAAO,sBACT,QACE,MACJ,CACF,CAEA,SAAgB,EACd,EACqC,CACrC,GAAI,EAAO,KAAK,WAAa,SAAU,OACvC,IAAM,EAA0C,CAAE,KAAM,OAAQ,EAC1D,EAAmB,EACvB,EAAO,KAAK,OAAO,oBACrB,EAOA,OANI,IACF,EAAe,mBAAqB,GAElC,EAAO,KAAK,OAAO,QAAQ,SAC7B,EAAe,OAAS,EAAO,KAAK,MAAM,QAErC,OAAO,KAAK,CAAc,EAAE,OAAS,EAAI,EAAiB,IAAA,EACnE,CAEA,SAAgB,EACd,EACoB,CACpB,OAAO,EAAQ,OAAO,CAAqB,CAC7C,CAQA,SAAgB,EAAsB,EAAkC,CACtE,MAAO,CAAC,CAAC,EAA8B,CAAK,CAC9C,CAEA,IAAM,EAAU,GAA4B,CAC1C,GAAI,CACF,OAAO,IAAI,IAAI,CAAG,CACpB,MAAQ,CACN,OAAO,IACT,CACF,EAaA,SAAgB,EAAU,EAAY,EAAqB,CACzD,IAAM,EAAO,OAAO,GAAM,SAAW,EAAI,GACnC,EAAO,OAAO,GAAM,SAAW,EAAI,GACzC,GAAI,CAAC,GAAQ,CAAC,EAAM,MAAO,GAC3B,IAAM,EAAO,EAAO,CAAI,EAClB,EAAQ,EAAO,CAAI,EAIzB,MAHI,CAAC,GAAQ,CAAC,EACL,EAAK,QAAQ,OAAQ,EAAE,IAAM,EAAK,QAAQ,OAAQ,EAAE,EAG3D,EAAK,WAAa,EAAM,UACxB,EAAK,OAAS,EAAM,MACpB,EAAK,SAAS,QAAQ,OAAQ,EAAE,IAAM,EAAM,SAAS,QAAQ,OAAQ,EAAE,CAE3E,CA2BA,SAAS,EACP,EACA,EACS,CACT,GAAI,EAAU,OAAS,QAAS,CAC9B,IAAM,EAAS,EAAU,IACzB,OACE,EAAO,OAAS,SAAW,CAAC,CAAC,EAAO,KAAO,EAAU,EAAO,IAAK,CAAM,CAE3E,CAEA,GAAI,EAAU,OAAS,MAAO,CAC5B,IAAM,EAAS,EAAU,IACzB,OACE,EAAO,OAAS,OAAS,CAAC,CAAC,EAAO,KAAO,EAAU,EAAO,IAAK,CAAM,CAEzE,CAGA,OAAO,EAAO,OAAS,SAAW,EAAO,OAAS,EAAU,UAC9D,CAEA,SAAS,EAAU,EAAuB,CACxC,OAAO,EAAM,KAAK,EAAE,YAAY,CAClC,CAOA,SAAgB,EACd,EACoB,CACpB,OAAO,EACJ,KAAK,EAAO,KAAW,CAAE,QAAO,OAAM,EAAE,EACxC,MAAM,EAAG,KAEL,EAAE,MAAM,gBAAkB,IAAM,EAAE,MAAM,gBAAkB,IACtC,EAAE,MAAQ,EAAE,KACpC,EACA,KAAK,CAAE,WAAY,CAAK,CAC7B,CASA,SAAgB,EACd,EACA,EACS,CACT,IAAM,EAAI,EAAU,CAAQ,EAU5B,OATK,EACY,CACf,EAAM,KACN,EAAM,YACN,EAAM,GACN,GAAI,EAAM,UAAY,CAAC,CACzB,EACG,KAAK,GAAG,EACR,YACI,EAAS,SAAS,CAAC,EATX,EAUjB,CASA,SAAgB,EACd,EACA,EACA,EACS,CACT,IAAM,EAAI,EAAU,CAAQ,EAgB5B,OAfK,EACY,CACf,EAAO,KACP,SAAU,EAAS,EAAO,KAAO,IAAA,GACjC,YAAa,EAAS,EAAO,QAAU,IAAA,GACvC,SAAU,EAAS,EAAO,MAAM,KAAK,GAAG,EAAI,IAAA,GAC5C,QAAS,EAAS,EAAO,IAAM,IAAA,GAC/B,GAAc,KACd,GAAc,YACd,GAAc,GACd,GAAI,GAAc,UAAY,CAAC,CACjC,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EACR,YACI,EAAS,SAAS,CAAC,EAfX,EAgBjB,CAOA,SAAgB,EACd,EACA,EAC8B,CAC9B,OAAO,EAAQ,KAAM,GAIZ,EAAwB,CAAK,EAAE,KAAM,GAC1C,EAAuB,EAAO,UAAW,CAAM,CACjD,CACD,CACH"}
|
|
@@ -17,6 +17,13 @@ export declare function getInstallableMcpConnectionOption(entry: MarketplaceEntr
|
|
|
17
17
|
export declare function getDefaultMcpTransport(entry: MarketplaceEntry): IntegrationTransport | undefined;
|
|
18
18
|
export declare function getMcpOAuthAuthenticationConfig(option: McpMarketplaceConnectionOption): MCPAuthenticationConfig | undefined;
|
|
19
19
|
export declare function getMcpMarketplaceCatalog(catalog: MarketplaceEntry[]): MarketplaceEntry[];
|
|
20
|
+
/**
|
|
21
|
+
* Whether this backend can install/configure the entry as an MCP server.
|
|
22
|
+
* Entries whose only connection options use another provider or transport
|
|
23
|
+
* (e.g. Jira's HTTP/OpenAPI option) exist in the catalog but cannot go
|
|
24
|
+
* through the local MCP install flow.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isMcpInstallableEntry(entry: MarketplaceEntry): boolean;
|
|
20
27
|
/**
|
|
21
28
|
* Loose URL match that ignores query strings, trailing slashes, and
|
|
22
29
|
* default ports. We want clicking "Linear" to flag the entry as
|
|
@@ -30,43 +30,46 @@ function o(e) {
|
|
|
30
30
|
return n && (t.client_auth_method = n), e.auth.oauth?.scopes?.length && (t.scopes = e.auth.oauth.scopes), Object.keys(t).length > 1 ? t : void 0;
|
|
31
31
|
}
|
|
32
32
|
function s(e) {
|
|
33
|
-
return e.filter(
|
|
33
|
+
return e.filter(c);
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
function c(e) {
|
|
36
|
+
return !!t(e);
|
|
37
|
+
}
|
|
38
|
+
var l = (e) => {
|
|
36
39
|
try {
|
|
37
40
|
return new URL(e);
|
|
38
41
|
} catch {
|
|
39
42
|
return null;
|
|
40
43
|
}
|
|
41
44
|
};
|
|
42
|
-
function
|
|
45
|
+
function u(e, t) {
|
|
43
46
|
let n = typeof e == "string" ? e : "", r = typeof t == "string" ? t : "";
|
|
44
47
|
if (!n || !r) return !1;
|
|
45
|
-
let i =
|
|
48
|
+
let i = l(n), a = l(r);
|
|
46
49
|
return !i || !a ? n.replace(/\/+$/, "") === r.replace(/\/+$/, "") : i.protocol === a.protocol && i.host === a.host && i.pathname.replace(/\/+$/, "") === a.pathname.replace(/\/+$/, "");
|
|
47
50
|
}
|
|
48
|
-
function
|
|
51
|
+
function d(e, t) {
|
|
49
52
|
if (e.kind === "shttp") {
|
|
50
53
|
let n = e.url;
|
|
51
|
-
return t.type === "shttp" && !!t.url &&
|
|
54
|
+
return t.type === "shttp" && !!t.url && u(t.url, n);
|
|
52
55
|
}
|
|
53
56
|
if (e.kind === "sse") {
|
|
54
57
|
let n = e.url;
|
|
55
|
-
return t.type === "sse" && !!t.url &&
|
|
58
|
+
return t.type === "sse" && !!t.url && u(t.url, n);
|
|
56
59
|
}
|
|
57
60
|
return t.type === "stdio" && t.name === e.serverName;
|
|
58
61
|
}
|
|
59
|
-
function
|
|
62
|
+
function f(e) {
|
|
60
63
|
return e.trim().toLowerCase();
|
|
61
64
|
}
|
|
62
|
-
function
|
|
65
|
+
function p(e) {
|
|
63
66
|
return e.map((e, t) => ({
|
|
64
67
|
entry: e,
|
|
65
68
|
index: t
|
|
66
69
|
})).sort((e, t) => (t.entry.popularityRank ?? 0) - (e.entry.popularityRank ?? 0) || e.index - t.index).map(({ entry: e }) => e);
|
|
67
70
|
}
|
|
68
|
-
function
|
|
69
|
-
let n =
|
|
71
|
+
function m(e, t) {
|
|
72
|
+
let n = f(t);
|
|
70
73
|
return n ? [
|
|
71
74
|
e.name,
|
|
72
75
|
e.description,
|
|
@@ -74,8 +77,8 @@ function p(e, t) {
|
|
|
74
77
|
...e.keywords ?? []
|
|
75
78
|
].join(" ").toLowerCase().includes(n) : !0;
|
|
76
79
|
}
|
|
77
|
-
function
|
|
78
|
-
let r =
|
|
80
|
+
function h(e, t, n) {
|
|
81
|
+
let r = f(n);
|
|
79
82
|
return r ? [
|
|
80
83
|
e.type,
|
|
81
84
|
"name" in e ? e.name : void 0,
|
|
@@ -88,10 +91,10 @@ function m(e, t, n) {
|
|
|
88
91
|
...t?.keywords ?? []
|
|
89
92
|
].filter(Boolean).join(" ").toLowerCase().includes(r) : !0;
|
|
90
93
|
}
|
|
91
|
-
function
|
|
92
|
-
return n.find((n) => e(n).some((e) =>
|
|
94
|
+
function g(t, n) {
|
|
95
|
+
return n.find((n) => e(n).some((e) => d(e.transport, t)));
|
|
93
96
|
}
|
|
94
97
|
//#endregion
|
|
95
|
-
export {
|
|
98
|
+
export { g as findCatalogEntryForServer, i as getDefaultMcpTransport, r as getInstallableMcpConnectionOption, p as getMarketplaceEntriesByPopularity, s as getMcpMarketplaceCatalog, o as getMcpOAuthAuthenticationConfig, h as installedServerMatchesQuery, m as marketplaceEntryMatchesQuery };
|
|
96
99
|
|
|
97
100
|
//# sourceMappingURL=mcp-marketplace-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-marketplace-utils.js","names":[],"sources":["../../src/utils/mcp-marketplace-utils.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport type {\n MCPAuthenticationConfig,\n MCPOAuthClientAuthMethod,\n} from \"#/types/mcp-auth\";\nimport type {\n IntegrationAuthConfig,\n IntegrationCatalogEntry as MarketplaceEntry,\n IntegrationConnectionOption,\n IntegrationOAuthConfig,\n IntegrationTransport,\n} from \"@openhands/extensions/integrations\";\n\nexport type { MarketplaceEntry };\n\ntype McpIntegrationAuthConfig = IntegrationAuthConfig & {\n credentialSecretName?: string;\n saveCredentialAsSecretByDefault?: boolean;\n};\n\nexport type McpMarketplaceConnectionOption = Omit<\n IntegrationConnectionOption,\n \"auth\" | \"provider\" | \"transport\"\n> & {\n provider: \"mcp\";\n transport: IntegrationTransport;\n auth: McpIntegrationAuthConfig;\n};\n\nexport function getMcpConnectionOptions(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption[] {\n return entry.connectionOptions.filter(\n (option): option is McpMarketplaceConnectionOption =>\n option.provider === \"mcp\" && !!option.transport,\n );\n}\n\nexport function getDefaultMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry)[0];\n}\n\nfunction isLocallyInstallableMcpOption(\n option: McpMarketplaceConnectionOption,\n): boolean {\n if (option.auth.strategy !== \"oauth2\") return true;\n\n const oauth = option.auth.oauth;\n if (!oauth) return false;\n\n // Local agent-server installs only support OAuth flows initiated by the MCP\n // server itself through fastmcp. Catalog entries that specify provider OAuth\n // endpoints still need the hosted integration-auth flow and should not be\n // exposed as locally installable static MCP configs.\n return (\n !oauth.authorizationUrl &&\n !oauth.tokenUrl &&\n !oauth.registrationUrl &&\n !oauth.additionalAuthorizationParams &&\n !oauth.additionalTokenParams\n );\n}\n\nexport function getInstallableMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry).find(isLocallyInstallableMcpOption);\n}\n\nexport function getDefaultMcpTransport(\n entry: MarketplaceEntry,\n): IntegrationTransport | undefined {\n return getDefaultMcpConnectionOption(entry)?.transport;\n}\n\nfunction toMcpOAuthClientAuthMethod(\n value: IntegrationOAuthConfig[\"clientAuthentication\"] | undefined,\n): MCPOAuthClientAuthMethod | undefined {\n switch (value) {\n case \"none\":\n return \"none\";\n case \"body\":\n return \"client_secret_post\";\n case \"basic\":\n return \"client_secret_basic\";\n default:\n return undefined;\n }\n}\n\nexport function getMcpOAuthAuthenticationConfig(\n option: McpMarketplaceConnectionOption,\n): MCPAuthenticationConfig | undefined {\n if (option.auth.strategy !== \"oauth2\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n const clientAuthMethod = toMcpOAuthClientAuthMethod(\n option.auth.oauth?.clientAuthentication,\n );\n if (clientAuthMethod) {\n authentication.client_auth_method = clientAuthMethod;\n }\n if (option.auth.oauth?.scopes?.length) {\n authentication.scopes = option.auth.oauth.scopes;\n }\n return Object.keys(authentication).length > 1 ? authentication : undefined;\n}\n\nexport function getMcpMarketplaceCatalog(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog.filter((entry) => !!getDefaultMcpConnectionOption(entry));\n}\n\nconst tryUrl = (raw: string): URL | null => {\n try {\n return new URL(raw);\n } catch {\n return null;\n }\n};\n\n/**\n * Loose URL match that ignores query strings, trailing slashes, and\n * default ports. We want clicking \"Linear\" to flag the entry as\n * installed even if the user pasted the URL with extra trailing slash\n * or a different port-equivalent variant.\n *\n * Defensive against runtime data that doesn't match the static type:\n * if either input is not a string (e.g. parsed from an older settings\n * blob), we fall through the URL parsing path and the safe trim\n * fallback below, never calling `.replace` on undefined.\n */\nexport function urlsMatch(a: unknown, b: unknown): boolean {\n const aStr = typeof a === \"string\" ? a : \"\";\n const bStr = typeof b === \"string\" ? b : \"\";\n if (!aStr || !bStr) return false;\n const left = tryUrl(aStr);\n const right = tryUrl(bStr);\n if (!left || !right) {\n return aStr.replace(/\\/+$/, \"\") === bStr.replace(/\\/+$/, \"\");\n }\n return (\n left.protocol === right.protocol &&\n left.host === right.host &&\n left.pathname.replace(/\\/+$/, \"\") === right.pathname.replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Decide whether a marketplace template is already represented by one\n * of the installed MCP servers. Used to render an \"Installed\" badge on\n * the marketplace tile. Returns the first matching server, or null.\n */\nexport function findInstalledMatch(\n transport: IntegrationTransport,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n return (\n servers.find((server) => transportMatchesServer(transport, server)) ?? null\n );\n}\n\nexport function findInstalledEntryMatch(\n entry: MarketplaceEntry,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n for (const option of getMcpConnectionOptions(entry)) {\n const match = findInstalledMatch(option.transport, servers);\n if (match) return match;\n }\n return null;\n}\n\nfunction transportMatchesServer(\n transport: IntegrationTransport,\n server: MCPServerConfig,\n): boolean {\n if (transport.kind === \"shttp\") {\n const tplUrl = transport.url;\n return (\n server.type === \"shttp\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n if (transport.kind === \"sse\") {\n const tplUrl = transport.url;\n return (\n server.type === \"sse\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n // stdio: match on the registered server name.\n return server.type === \"stdio\" && server.name === transport.serverName;\n}\n\nfunction normalize(query: string): string {\n return query.trim().toLowerCase();\n}\n\n/**\n * Case-insensitive substring match against the catalog entry's\n * user-visible identity (name, description, id, keywords). Empty\n * queries always match.\n */\nexport function getMarketplaceEntriesByPopularity(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.entry.popularityRank ?? 0) - (a.entry.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ entry }) => entry);\n}\n\nexport function getMarketplaceEntryById(\n id: string,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => entry.id === id);\n}\n\nexport function marketplaceEntryMatchesQuery(\n entry: MarketplaceEntry,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n entry.name,\n entry.description,\n entry.id,\n ...(entry.keywords ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Search match for an installed (already-configured) server. We\n * search the server's own identifying fields and — if it's a catalog\n * entry — its catalog name/keywords too, so typing \"Slack\" matches\n * the installed Slack tile even though the persisted server is just\n * `{ type: \"stdio\", name: \"slack\", ... }`.\n */\nexport function installedServerMatchesQuery(\n server: MCPServerConfig,\n catalogEntry: MarketplaceEntry | undefined,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n server.type,\n \"name\" in server ? server.name : undefined,\n \"command\" in server ? server.command : undefined,\n \"args\" in server ? server.args?.join(\" \") : undefined,\n \"url\" in server ? server.url : undefined,\n catalogEntry?.name,\n catalogEntry?.description,\n catalogEntry?.id,\n ...(catalogEntry?.keywords ?? []),\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Look up the catalog entry that best matches an installed server.\n * Mirrors the lookup used in `installed-server-card.tsx` for\n * rendering the friendly icon.\n */\nexport function findCatalogEntryForServer(\n server: MCPServerConfig,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => {\n // Check every MCP option rather than only the default. Some unified\n // integration entries default to OAuth-hosted MCP while still exposing\n // an API/stdio option; existing installed servers should match either.\n return getMcpConnectionOptions(entry).some((option) =>\n transportMatchesServer(option.transport, server),\n );\n });\n}\n"],"mappings":";AA6BA,SAAgB,EACd,GACkC;CAClC,OAAO,EAAM,kBAAkB,QAC5B,MACC,EAAO,aAAa,SAAS,CAAC,CAAC,EAAO,SAC1C;AACF;AAEA,SAAgB,EACd,GAC4C;CAC5C,OAAO,EAAwB,CAAK,EAAE;AACxC;AAEA,SAAS,EACP,GACS;CACT,IAAI,EAAO,KAAK,aAAa,UAAU,OAAO;CAE9C,IAAM,IAAQ,EAAO,KAAK;CAO1B,OANK,IAOH,CAAC,EAAM,oBACP,CAAC,EAAM,YACP,CAAC,EAAM,mBACP,CAAC,EAAM,iCACP,CAAC,EAAM,wBAXU;AAarB;AAEA,SAAgB,EACd,GAC4C;CAC5C,OAAO,EAAwB,CAAK,EAAE,KAAK,CAA6B;AAC1E;AAEA,SAAgB,EACd,GACkC;CAClC,OAAO,EAA8B,CAAK,GAAG;AAC/C;AAEA,SAAS,EACP,GACsC;CACtC,QAAQ,GAAR;EACE,KAAK,QACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,SACE;CACJ;AACF;AAEA,SAAgB,EACd,GACqC;CACrC,IAAI,EAAO,KAAK,aAAa,UAAU;CACvC,IAAM,IAA0C,EAAE,MAAM,QAAQ,GAC1D,IAAmB,EACvB,EAAO,KAAK,OAAO,oBACrB;CAOA,OANI,MACF,EAAe,qBAAqB,IAElC,EAAO,KAAK,OAAO,QAAQ,WAC7B,EAAe,SAAS,EAAO,KAAK,MAAM,SAErC,OAAO,KAAK,CAAc,EAAE,SAAS,IAAI,IAAiB,KAAA;AACnE;AAEA,SAAgB,EACd,GACoB;CACpB,OAAO,EAAQ,QAAQ,MAAU,CAAC,CAAC,EAA8B,CAAK,CAAC;AACzE;AAEA,IAAM,KAAU,MAA4B;CAC1C,IAAI;EACF,OAAO,IAAI,IAAI,CAAG;CACpB,QAAQ;EACN,OAAO;CACT;AACF;AAaA,SAAgB,EAAU,GAAY,GAAqB;CACzD,IAAM,IAAO,OAAO,KAAM,WAAW,IAAI,IACnC,IAAO,OAAO,KAAM,WAAW,IAAI;CACzC,IAAI,CAAC,KAAQ,CAAC,GAAM,OAAO;CAC3B,IAAM,IAAO,EAAO,CAAI,GAClB,IAAQ,EAAO,CAAI;CAIzB,OAHI,CAAC,KAAQ,CAAC,IACL,EAAK,QAAQ,QAAQ,EAAE,MAAM,EAAK,QAAQ,QAAQ,EAAE,IAG3D,EAAK,aAAa,EAAM,YACxB,EAAK,SAAS,EAAM,QACpB,EAAK,SAAS,QAAQ,QAAQ,EAAE,MAAM,EAAM,SAAS,QAAQ,QAAQ,EAAE;AAE3E;AA2BA,SAAS,EACP,GACA,GACS;CACT,IAAI,EAAU,SAAS,SAAS;EAC9B,IAAM,IAAS,EAAU;EACzB,OACE,EAAO,SAAS,WAAW,CAAC,CAAC,EAAO,OAAO,EAAU,EAAO,KAAK,CAAM;CAE3E;CAEA,IAAI,EAAU,SAAS,OAAO;EAC5B,IAAM,IAAS,EAAU;EACzB,OACE,EAAO,SAAS,SAAS,CAAC,CAAC,EAAO,OAAO,EAAU,EAAO,KAAK,CAAM;CAEzE;CAGA,OAAO,EAAO,SAAS,WAAW,EAAO,SAAS,EAAU;AAC9D;AAEA,SAAS,EAAU,GAAuB;CACxC,OAAO,EAAM,KAAK,EAAE,YAAY;AAClC;AAOA,SAAgB,EACd,GACoB;CACpB,OAAO,EACJ,KAAK,GAAO,OAAW;EAAE;EAAO;CAAM,EAAE,EACxC,MAAM,GAAG,OAEL,EAAE,MAAM,kBAAkB,MAAM,EAAE,MAAM,kBAAkB,MACtC,EAAE,QAAQ,EAAE,KACpC,EACA,KAAK,EAAE,eAAY,CAAK;AAC7B;AASA,SAAgB,EACd,GACA,GACS;CACT,IAAM,IAAI,EAAU,CAAQ;CAU5B,OATK,IACY;EACf,EAAM;EACN,EAAM;EACN,EAAM;EACN,GAAI,EAAM,YAAY,CAAC;CACzB,EACG,KAAK,GAAG,EACR,YACI,EAAS,SAAS,CAAC,IATX;AAUjB;AASA,SAAgB,EACd,GACA,GACA,GACS;CACT,IAAM,IAAI,EAAU,CAAQ;CAgB5B,OAfK,IACY;EACf,EAAO;EACP,UAAU,IAAS,EAAO,OAAO,KAAA;EACjC,aAAa,IAAS,EAAO,UAAU,KAAA;EACvC,UAAU,IAAS,EAAO,MAAM,KAAK,GAAG,IAAI,KAAA;EAC5C,SAAS,IAAS,EAAO,MAAM,KAAA;EAC/B,GAAc;EACd,GAAc;EACd,GAAc;EACd,GAAI,GAAc,YAAY,CAAC;CACjC,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EACR,YACI,EAAS,SAAS,CAAC,IAfX;AAgBjB;AAOA,SAAgB,EACd,GACA,GAC8B;CAC9B,OAAO,EAAQ,MAAM,MAIZ,EAAwB,CAAK,EAAE,MAAM,MAC1C,EAAuB,EAAO,WAAW,CAAM,CACjD,CACD;AACH"}
|
|
1
|
+
{"version":3,"file":"mcp-marketplace-utils.js","names":[],"sources":["../../src/utils/mcp-marketplace-utils.ts"],"sourcesContent":["import { MCPServerConfig } from \"#/types/mcp-server\";\nimport type {\n MCPAuthenticationConfig,\n MCPOAuthClientAuthMethod,\n} from \"#/types/mcp-auth\";\nimport type {\n IntegrationAuthConfig,\n IntegrationCatalogEntry as MarketplaceEntry,\n IntegrationConnectionOption,\n IntegrationOAuthConfig,\n IntegrationTransport,\n} from \"@openhands/extensions/integrations\";\n\nexport type { MarketplaceEntry };\n\ntype McpIntegrationAuthConfig = IntegrationAuthConfig & {\n credentialSecretName?: string;\n saveCredentialAsSecretByDefault?: boolean;\n};\n\nexport type McpMarketplaceConnectionOption = Omit<\n IntegrationConnectionOption,\n \"auth\" | \"provider\" | \"transport\"\n> & {\n provider: \"mcp\";\n transport: IntegrationTransport;\n auth: McpIntegrationAuthConfig;\n};\n\nexport function getMcpConnectionOptions(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption[] {\n return entry.connectionOptions.filter(\n (option): option is McpMarketplaceConnectionOption =>\n option.provider === \"mcp\" && !!option.transport,\n );\n}\n\nexport function getDefaultMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry)[0];\n}\n\nfunction isLocallyInstallableMcpOption(\n option: McpMarketplaceConnectionOption,\n): boolean {\n if (option.auth.strategy !== \"oauth2\") return true;\n\n const oauth = option.auth.oauth;\n if (!oauth) return false;\n\n // Local agent-server installs only support OAuth flows initiated by the MCP\n // server itself through fastmcp. Catalog entries that specify provider OAuth\n // endpoints still need the hosted integration-auth flow and should not be\n // exposed as locally installable static MCP configs.\n return (\n !oauth.authorizationUrl &&\n !oauth.tokenUrl &&\n !oauth.registrationUrl &&\n !oauth.additionalAuthorizationParams &&\n !oauth.additionalTokenParams\n );\n}\n\nexport function getInstallableMcpConnectionOption(\n entry: MarketplaceEntry,\n): McpMarketplaceConnectionOption | undefined {\n return getMcpConnectionOptions(entry).find(isLocallyInstallableMcpOption);\n}\n\nexport function getDefaultMcpTransport(\n entry: MarketplaceEntry,\n): IntegrationTransport | undefined {\n return getDefaultMcpConnectionOption(entry)?.transport;\n}\n\nfunction toMcpOAuthClientAuthMethod(\n value: IntegrationOAuthConfig[\"clientAuthentication\"] | undefined,\n): MCPOAuthClientAuthMethod | undefined {\n switch (value) {\n case \"none\":\n return \"none\";\n case \"body\":\n return \"client_secret_post\";\n case \"basic\":\n return \"client_secret_basic\";\n default:\n return undefined;\n }\n}\n\nexport function getMcpOAuthAuthenticationConfig(\n option: McpMarketplaceConnectionOption,\n): MCPAuthenticationConfig | undefined {\n if (option.auth.strategy !== \"oauth2\") return undefined;\n const authentication: MCPAuthenticationConfig = { type: \"oauth\" };\n const clientAuthMethod = toMcpOAuthClientAuthMethod(\n option.auth.oauth?.clientAuthentication,\n );\n if (clientAuthMethod) {\n authentication.client_auth_method = clientAuthMethod;\n }\n if (option.auth.oauth?.scopes?.length) {\n authentication.scopes = option.auth.oauth.scopes;\n }\n return Object.keys(authentication).length > 1 ? authentication : undefined;\n}\n\nexport function getMcpMarketplaceCatalog(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog.filter(isMcpInstallableEntry);\n}\n\n/**\n * Whether this backend can install/configure the entry as an MCP server.\n * Entries whose only connection options use another provider or transport\n * (e.g. Jira's HTTP/OpenAPI option) exist in the catalog but cannot go\n * through the local MCP install flow.\n */\nexport function isMcpInstallableEntry(entry: MarketplaceEntry): boolean {\n return !!getDefaultMcpConnectionOption(entry);\n}\n\nconst tryUrl = (raw: string): URL | null => {\n try {\n return new URL(raw);\n } catch {\n return null;\n }\n};\n\n/**\n * Loose URL match that ignores query strings, trailing slashes, and\n * default ports. We want clicking \"Linear\" to flag the entry as\n * installed even if the user pasted the URL with extra trailing slash\n * or a different port-equivalent variant.\n *\n * Defensive against runtime data that doesn't match the static type:\n * if either input is not a string (e.g. parsed from an older settings\n * blob), we fall through the URL parsing path and the safe trim\n * fallback below, never calling `.replace` on undefined.\n */\nexport function urlsMatch(a: unknown, b: unknown): boolean {\n const aStr = typeof a === \"string\" ? a : \"\";\n const bStr = typeof b === \"string\" ? b : \"\";\n if (!aStr || !bStr) return false;\n const left = tryUrl(aStr);\n const right = tryUrl(bStr);\n if (!left || !right) {\n return aStr.replace(/\\/+$/, \"\") === bStr.replace(/\\/+$/, \"\");\n }\n return (\n left.protocol === right.protocol &&\n left.host === right.host &&\n left.pathname.replace(/\\/+$/, \"\") === right.pathname.replace(/\\/+$/, \"\")\n );\n}\n\n/**\n * Decide whether a marketplace template is already represented by one\n * of the installed MCP servers. Used to render an \"Installed\" badge on\n * the marketplace tile. Returns the first matching server, or null.\n */\nexport function findInstalledMatch(\n transport: IntegrationTransport,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n return (\n servers.find((server) => transportMatchesServer(transport, server)) ?? null\n );\n}\n\nexport function findInstalledEntryMatch(\n entry: MarketplaceEntry,\n servers: MCPServerConfig[],\n): MCPServerConfig | null {\n for (const option of getMcpConnectionOptions(entry)) {\n const match = findInstalledMatch(option.transport, servers);\n if (match) return match;\n }\n return null;\n}\n\nfunction transportMatchesServer(\n transport: IntegrationTransport,\n server: MCPServerConfig,\n): boolean {\n if (transport.kind === \"shttp\") {\n const tplUrl = transport.url;\n return (\n server.type === \"shttp\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n if (transport.kind === \"sse\") {\n const tplUrl = transport.url;\n return (\n server.type === \"sse\" && !!server.url && urlsMatch(server.url, tplUrl)\n );\n }\n\n // stdio: match on the registered server name.\n return server.type === \"stdio\" && server.name === transport.serverName;\n}\n\nfunction normalize(query: string): string {\n return query.trim().toLowerCase();\n}\n\n/**\n * Case-insensitive substring match against the catalog entry's\n * user-visible identity (name, description, id, keywords). Empty\n * queries always match.\n */\nexport function getMarketplaceEntriesByPopularity(\n catalog: MarketplaceEntry[],\n): MarketplaceEntry[] {\n return catalog\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => {\n const byPopularity =\n (b.entry.popularityRank ?? 0) - (a.entry.popularityRank ?? 0);\n return byPopularity || a.index - b.index;\n })\n .map(({ entry }) => entry);\n}\n\nexport function getMarketplaceEntryById(\n id: string,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => entry.id === id);\n}\n\nexport function marketplaceEntryMatchesQuery(\n entry: MarketplaceEntry,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n entry.name,\n entry.description,\n entry.id,\n ...(entry.keywords ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Search match for an installed (already-configured) server. We\n * search the server's own identifying fields and — if it's a catalog\n * entry — its catalog name/keywords too, so typing \"Slack\" matches\n * the installed Slack tile even though the persisted server is just\n * `{ type: \"stdio\", name: \"slack\", ... }`.\n */\nexport function installedServerMatchesQuery(\n server: MCPServerConfig,\n catalogEntry: MarketplaceEntry | undefined,\n rawQuery: string,\n): boolean {\n const q = normalize(rawQuery);\n if (!q) return true;\n const haystack = [\n server.type,\n \"name\" in server ? server.name : undefined,\n \"command\" in server ? server.command : undefined,\n \"args\" in server ? server.args?.join(\" \") : undefined,\n \"url\" in server ? server.url : undefined,\n catalogEntry?.name,\n catalogEntry?.description,\n catalogEntry?.id,\n ...(catalogEntry?.keywords ?? []),\n ]\n .filter(Boolean)\n .join(\" \")\n .toLowerCase();\n return haystack.includes(q);\n}\n\n/**\n * Look up the catalog entry that best matches an installed server.\n * Mirrors the lookup used in `installed-server-card.tsx` for\n * rendering the friendly icon.\n */\nexport function findCatalogEntryForServer(\n server: MCPServerConfig,\n catalog: MarketplaceEntry[],\n): MarketplaceEntry | undefined {\n return catalog.find((entry) => {\n // Check every MCP option rather than only the default. Some unified\n // integration entries default to OAuth-hosted MCP while still exposing\n // an API/stdio option; existing installed servers should match either.\n return getMcpConnectionOptions(entry).some((option) =>\n transportMatchesServer(option.transport, server),\n );\n });\n}\n"],"mappings":"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"}
|
|
@@ -8,11 +8,11 @@ require("../../_virtual/_rolldown/runtime.cjs");const e=require("../../i18n/decl
|
|
|
8
8
|
`):``,A=e=>[r.getReasoningContent(e),r.getActionThoughtText(e)].map(e=>e.trim()).filter(Boolean).join(`
|
|
9
9
|
|
|
10
10
|
`),j=e=>![`FinishAction`,`SwitchLLMAction`,`ThinkAction`].includes(e.action.kind),M=(c,l)=>{let d=c.reduce((e,t)=>{try{return i.handleEventForUI(t,e)}catch{return e}},[]),f=new Map(c.filter(n.isActionEvent).map(e=>[e.id,e])),h=[],g=new Set,_=u.groupEvents(d.filter(e=>n.isSwitchLLMObservationEvent(e)&&!e.observation.is_error||a.shouldRenderEvent(e)),2**53-1,c),v=e=>{if(g.has(e.id)||!j(e))return;g.add(e.id);let t=A(e);t&&h.push({kind:`message`,author:`assistant`,content:t,timestamp:e.timestamp})};for(let i of _){if(i.kind===`group`)continue;if(i.kind===`thought`){v(i.action);continue}let{event:a}=i;try{let i=n.isActionEvent(a)?a:n.isObservationEvent(a)?f.get(a.action_id):void 0;if(i&&v(i),n.isSwitchLLMObservationEvent(a)&&!a.observation.is_error){h.push({kind:`note`,summary:y(e.I18nKey.MODEL$SWITCHED_TO_PROFILE,{name:a.observation.profile_name}),content:[a.observation.active_model?`${t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$MODEL)}: ${a.observation.active_model}`:``,a.observation.reason?`${t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$REASON)}: ${a.observation.reason}`:``].filter(Boolean).join(`
|
|
11
|
-
`),timestamp:a.timestamp});continue}if(n.isMessageEvent(a)){let e=s.parseMessageFromEvent(a).trim();if(a.source===`agent`){let{reasoning:t,message:n}=r.splitInlineThink(e);[t,n].filter(Boolean).forEach(e=>{h.push({kind:`message`,author:`assistant`,content:e,timestamp:a.timestamp})})}else e&&h.push({kind:`message`,author:`user`,content:e,timestamp:a.timestamp});continue}if(n.isStreamingDeltaEvent(a)){let{reasoning:e,message:t}=r.splitInlineThink(a.content??``,{streaming:!0}),n=[a.reasoning_content?.trim()||``,e].filter(Boolean).join(`
|
|
11
|
+
`),timestamp:a.timestamp??``});continue}if(n.isMessageEvent(a)){let e=s.parseMessageFromEvent(a).trim();if(a.source===`agent`){let{reasoning:t,message:n}=r.splitInlineThink(e);[t,n].filter(Boolean).forEach(e=>{h.push({kind:`message`,author:`assistant`,content:e,timestamp:a.timestamp??``})})}else e&&h.push({kind:`message`,author:`user`,content:e,timestamp:a.timestamp??``});continue}if(n.isStreamingDeltaEvent(a)){let{reasoning:e,message:t}=r.splitInlineThink(a.content??``,{streaming:!0}),n=[a.reasoning_content?.trim()||``,e].filter(Boolean).join(`
|
|
12
12
|
|
|
13
|
-
`);n&&h.push({kind:`message`,author:`assistant`,content:n,timestamp:a.timestamp}),t.trim()&&h.push({kind:`message`,author:`assistant`,content:t.trim(),timestamp:a.timestamp});continue}if(n.isAgentErrorEvent(a)){h.push({kind:`error`,content:a.error,timestamp:a.timestamp});continue}if(n.isActionEvent(a)){if(a.action.kind===`FinishAction`){let e=a.action.message.trim();e&&h.push({kind:`message`,author:`assistant`,content:e,timestamp:a.timestamp})}else h.push({kind:`tool`,summary:S(a),details:l?D(a):``,timestamp:a.timestamp});continue}if(n.isObservationEvent(a)){let e=f.get(a.action_id);h.push({kind:`tool`,summary:C(a,e),details:l?O(a,e):``,timestamp:a.timestamp});continue}if(n.isACPToolCallEvent(a)){h.push({kind:`tool`,summary:o.stripRedundantTitlePrefix(a)||t.default.t(e.I18nKey.ACTION_MESSAGE$ACP_TOOL),details:l?o.getACPToolCallContent(a):``,timestamp:a.timestamp});continue}if(n.isHookExecutionEvent(a)){h.push({kind:`tool`,summary:t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$HOOK,{command:m(p(a.hook_command),100)}),details:l?k(a):``,timestamp:a.timestamp});continue}n.isConversationStateUpdateEvent(a)&&n.isGoalConversationStateUpdateEvent(a)&&h.push({kind:`note`,summary:`${t.default.t(e.I18nKey.GOAL$PREFIX)} ${t.default.t({running:e.I18nKey.GOAL$STATUS_RUNNING,complete:e.I18nKey.GOAL$STATUS_COMPLETE,capped:e.I18nKey.GOAL$STATUS_CAPPED,interrupted:e.I18nKey.GOAL$STATUS_INTERRUPTED}[a.value.status])}`,content:[a.value.objective,a.value.verdict?.missing||``].filter(Boolean).join(`
|
|
13
|
+
`);n&&h.push({kind:`message`,author:`assistant`,content:n,timestamp:a.timestamp??``}),t.trim()&&h.push({kind:`message`,author:`assistant`,content:t.trim(),timestamp:a.timestamp??``});continue}if(n.isAgentErrorEvent(a)){h.push({kind:`error`,content:a.error,timestamp:a.timestamp??``});continue}if(n.isActionEvent(a)){if(a.action.kind===`FinishAction`){let e=a.action.message.trim();e&&h.push({kind:`message`,author:`assistant`,content:e,timestamp:a.timestamp??``})}else h.push({kind:`tool`,summary:S(a),details:l?D(a):``,timestamp:a.timestamp??``});continue}if(n.isObservationEvent(a)){let e=f.get(a.action_id);h.push({kind:`tool`,summary:C(a,e),details:l?O(a,e):``,timestamp:a.timestamp??``});continue}if(n.isACPToolCallEvent(a)){h.push({kind:`tool`,summary:o.stripRedundantTitlePrefix(a)||t.default.t(e.I18nKey.ACTION_MESSAGE$ACP_TOOL),details:l?o.getACPToolCallContent(a):``,timestamp:a.timestamp??``});continue}if(n.isHookExecutionEvent(a)){h.push({kind:`tool`,summary:t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$HOOK,{command:m(p(a.hook_command),100)}),details:l?k(a):``,timestamp:a.timestamp??``});continue}n.isConversationStateUpdateEvent(a)&&n.isGoalConversationStateUpdateEvent(a)&&h.push({kind:`note`,summary:`${t.default.t(e.I18nKey.GOAL$PREFIX)} ${t.default.t({running:e.I18nKey.GOAL$STATUS_RUNNING,complete:e.I18nKey.GOAL$STATUS_COMPLETE,capped:e.I18nKey.GOAL$STATUS_CAPPED,interrupted:e.I18nKey.GOAL$STATUS_INTERRUPTED}[a.value.status])}`,content:[a.value.objective,a.value.verdict?.missing||``].filter(Boolean).join(`
|
|
14
14
|
|
|
15
|
-
`),timestamp:a.timestamp})}catch{}}return h},N=(e,t)=>t.includeTimestamps?`<sub>${g(h(e.timestamp))}</sub>\n\n`:``,P=e=>{let t=Math.max(0,...Array.from(e.matchAll(/`+/g),e=>e[0].length)),n="`".repeat(Math.max(3,t+1));return`${n}text\n${e}\n${n}`},F=(n,r)=>{let i=[`# ${_(v(r.title))}`,``];r.model&&i.push(`**${t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$MODEL)}:** ${_(p(r.model))}`,``);for(let a of M(n,r.includeToolDetails)){let n=N(a,r);if(a.kind===`message`){let r=a.author===`user`?t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$USER):t.default.t(e.I18nKey.CHAT_INTERFACE$ASSISTANT);i.push(`## ${r}`,``,n+_(a.content),``)}else if(a.kind===`error`){let r=a.content.split(`
|
|
15
|
+
`),timestamp:a.timestamp??``})}catch{}}return h},N=(e,t)=>t.includeTimestamps?`<sub>${g(h(e.timestamp))}</sub>\n\n`:``,P=e=>{let t=Math.max(0,...Array.from(e.matchAll(/`+/g),e=>e[0].length)),n="`".repeat(Math.max(3,t+1));return`${n}text\n${e}\n${n}`},F=(n,r)=>{let i=[`# ${_(v(r.title))}`,``];r.model&&i.push(`**${t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$MODEL)}:** ${_(p(r.model))}`,``);for(let a of M(n,r.includeToolDetails)){let n=N(a,r);if(a.kind===`message`){let r=a.author===`user`?t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$USER):t.default.t(e.I18nKey.CHAT_INTERFACE$ASSISTANT);i.push(`## ${r}`,``,n+_(a.content),``)}else if(a.kind===`error`){let r=a.content.split(`
|
|
16
16
|
`).map(e=>`> ${_(e)}`).join(`
|
|
17
17
|
`);i.push(`## ${t.default.t(e.I18nKey.COMMON$ERROR)}`,``,n+r,``)}else if(a.kind===`note`)i.push(`> **${g(a.summary)}**`,``,n+_(a.content),``);else if(r.includeToolDetails&&a.details)i.push(`<details>`,`<summary><strong>${g(t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$TOOL))}:</strong> ${g(a.summary)}</summary>`,``,n+P(a.details),``,`</details>`,``);else{let r=n?`<br>${n.trimEnd()}`:``;i.push(`<p><strong>${g(t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$TOOL))}:</strong> ${g(a.summary)}${r}</p>`,``)}}return`${i.join(`
|
|
18
18
|
`).trim()}\n`},I=(e,t)=>{if(!t.includeTimestamps)return``;let n=h(e.timestamp);return`<time datetime="${g(n)}">${g(n)}</time>`},L=(n,r)=>{let i=v(r.title),a=M(n,r.includeToolDetails).map(n=>{let i=I(n,r);if(n.kind===`message`){let r=n.author===`user`?t.default.t(e.I18nKey.TRANSCRIPT_EXPORT$USER):t.default.t(e.I18nKey.CHAT_INTERFACE$ASSISTANT);return`<section class="message ${n.author.toLowerCase()}">
|