dsh-agent-plugins-market 0.4.5 → 0.4.6
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 +4 -4
- package/README.zh.md +4 -4
- package/client/client.js +697 -63
- package/client/client.js.map +1 -1
- package/lib/discovery.js +30 -28
- package/lib/index.js +4 -0
- package/lib/manager.js +11 -0
- package/lib/mcp-status.js +147 -0
- package/lib/routes.js +3 -0
- package/lib/types/discovery.d.ts +7 -4
- package/lib/types/manager.d.ts +6 -0
- package/lib/types/mcp-status.d.ts +51 -0
- package/package.json +1 -1
package/client/client.js
CHANGED
|
@@ -2,7 +2,7 @@ window.__ModuleLoader__.load({ id: "dsh-agent-plugins-market", factory: (require
|
|
|
2
2
|
|
|
3
3
|
var module = { exports: {} };
|
|
4
4
|
var exports = module.exports;
|
|
5
|
-
(function(){if(typeof document!=="undefined"){var s=document.createElement("style");s.setAttribute("data-dsh-client","dsh-agent-plugins-market");s.textContent=".qMtKNa_market {\n min-width: 0;\n height: 100%;\n min-height: 0;\n color: var(--dsw-alias-label-primary, #1f2328);\n flex-direction: column;\n gap: 14px;\n display: flex;\n}\n\n.qMtKNa_header {\n flex-direction: column;\n flex-shrink: 0;\n gap: 8px;\n display: flex;\n}\n\n.qMtKNa_titleRow {\n align-items: center;\n gap: 12px;\n display: flex;\n}\n\n.qMtKNa_title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n line-height: 24px;\n}\n\n.qMtKNa_sub {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n align-items: center;\n gap: 8px;\n min-width: 0;\n margin: 0;\n font-size: 13px;\n line-height: 20px;\n display: flex;\n overflow: hidden;\n}\n\n.qMtKNa_spacer {\n flex: 1;\n}\n\n.qMtKNa_tabGap {\n flex-shrink: 0;\n width: 16px;\n}\n\n.qMtKNa_searchGroup {\n align-items: center;\n gap: 2px;\n display: flex;\n}\n\n.qMtKNa_searchWrap, .qMtKNa_searchInput {\n align-items: center;\n display: flex;\n}\n\n.qMtKNa_searchInput input {\n width: 240px;\n font-size: 12px;\n line-height: 20px;\n}\n\n.qMtKNa_tabRow {\n border-bottom: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n justify-content: flex-end;\n align-items: flex-end;\n gap: 2px;\n display: flex;\n}\n\n.qMtKNa_tab, .qMtKNa_tabOn {\n font: inherit;\n color: var(--dsw-alias-label-secondary, #6b7280);\n cursor: pointer;\n white-space: nowrap;\n background: none;\n border: none;\n border-bottom: 2px solid #0000;\n padding: 7px 12px;\n font-size: 13px;\n}\n\n.qMtKNa_tabOn {\n color: var(--dsw-alias-brand-primary, #4f6ef7);\n border-bottom-color: var(--dsw-alias-brand-primary, #4f6ef7);\n font-weight: 600;\n}\n\n.qMtKNa_viewSwitch {\n font: inherit;\n color: var(--dsw-alias-label-tertiary, #9ca3af);\n cursor: pointer;\n white-space: nowrap;\n background: none;\n border: none;\n border-bottom: 2px solid #0000;\n padding: 7px 12px;\n font-size: 13px;\n}\n\n.qMtKNa_viewSwitch:hover {\n color: var(--dsw-alias-label-primary, #1f2328);\n}\n\n.qMtKNa_body {\n flex: 1;\n align-items: flex-start;\n gap: 20px;\n min-height: 0;\n display: flex;\n}\n\n.qMtKNa_sourceTabsRow {\n padding: 0;\n display: block;\n}\n\n.qMtKNa_sourceTabsScroll {\n grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));\n gap: 6px;\n display: grid;\n}\n\n.qMtKNa_srcTabEdit {\n font: inherit;\n color: var(--dsw-alias-label-tertiary, #9ca3af);\n cursor: pointer;\n background: none;\n border: none;\n flex-shrink: 0;\n padding: 2px;\n font-size: 12px;\n line-height: 18px;\n}\n\n.qMtKNa_srcTabEdit:hover {\n color: var(--dsw-alias-label-primary, #1f2328);\n}\n\n.qMtKNa_srcTabOn .qMtKNa_srcTabEdit {\n color: #ffffffd9;\n}\n\n.qMtKNa_srcTabOn .qMtKNa_srcTabEdit:hover {\n color: #fff;\n}\n\n.qMtKNa_srcTab, .qMtKNa_srcTabOn {\n border: 1px solid var(--dsw-alias-border-l3, #d9dde3);\n background: var(--dsw-alias-bg-layer-1, #fff);\n border-radius: 999px;\n justify-content: center;\n align-items: center;\n width: 100%;\n height: 24px;\n display: inline-flex;\n overflow: hidden;\n}\n\n.qMtKNa_srcTabMain {\n font: inherit;\n color: var(--dsw-alias-label-primary, #1f2328);\n cursor: pointer;\n white-space: nowrap;\n text-overflow: ellipsis;\n background: none;\n border: none;\n flex: 1;\n min-width: 0;\n padding: 2px 2px 2px 10px;\n font-size: 12px;\n line-height: 18px;\n overflow: hidden;\n}\n\n.qMtKNa_srcTabMain:hover {\n color: var(--dsw-alias-brand-primary, #4f6ef7);\n}\n\n.qMtKNa_srcTabOn {\n background: var(--dsw-alias-brand-primary, #4f6ef7);\n border-color: var(--dsw-alias-brand-primary, #4f6ef7);\n}\n\n.qMtKNa_srcTabOn .qMtKNa_srcTabMain {\n color: #fff;\n font-weight: 600;\n}\n\n.qMtKNa_srcTabDel {\n font: inherit;\n color: var(--dsw-alias-label-tertiary, #9ca3af);\n cursor: pointer;\n background: none;\n border: none;\n flex-shrink: 0;\n padding: 2px 8px 2px 2px;\n font-size: 12px;\n line-height: 18px;\n}\n\n.qMtKNa_srcTabDel:hover {\n color: var(--dsw-alias-state-error-primary, #dc2626);\n}\n\n.qMtKNa_srcTabOn .qMtKNa_srcTabDel {\n color: #ffffffd9;\n}\n\n.qMtKNa_srcTabOn .qMtKNa_srcTabDel:hover {\n color: #fff;\n}\n\n.qMtKNa_grid {\n scrollbar-gutter: stable;\n flex: 1;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n align-content: start;\n gap: 12px;\n min-width: 0;\n min-height: 0;\n padding-right: 4px;\n display: grid;\n overflow-y: auto;\n}\n\n.qMtKNa_list {\n scrollbar-gutter: stable;\n flex-direction: column;\n flex: 1;\n gap: 8px;\n min-width: 0;\n min-height: 0;\n padding-right: 4px;\n display: flex;\n overflow-y: auto;\n}\n\n.qMtKNa_list .qMtKNa_card {\n flex-flow: wrap;\n align-items: center;\n gap: 8px 14px;\n}\n\n.qMtKNa_list .qMtKNa_cardTop {\n flex: none;\n}\n\n.qMtKNa_list .qMtKNa_cardDesc {\n -webkit-line-clamp: 1;\n flex: 1;\n min-width: 200px;\n min-height: 0;\n}\n\n.qMtKNa_list .qMtKNa_cardActions {\n flex: none;\n}\n\n.qMtKNa_list .qMtKNa_meta {\n flex-basis: 100%;\n}\n\n.qMtKNa_empty {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n text-align: center;\n grid-column: 1 / -1;\n padding: 48px 0;\n font-size: 13px;\n}\n\n.qMtKNa_card {\n background: var(--dsw-alias-bg-layer-1, #fff);\n border: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n border-radius: 12px;\n flex-direction: column;\n gap: 8px;\n min-width: 0;\n padding: 12px 14px;\n display: flex;\n}\n\n.qMtKNa_cardTop {\n align-items: center;\n gap: 8px;\n display: flex;\n}\n\n.qMtKNa_cardTitle {\n flex: 1;\n align-items: center;\n gap: 8px;\n min-width: 0;\n display: flex;\n}\n\n.qMtKNa_cardName {\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n font-weight: 600;\n line-height: 22px;\n overflow: hidden;\n}\n\n.qMtKNa_version {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n font-variant-numeric: tabular-nums;\n flex-shrink: 0;\n font-size: 12px;\n line-height: 20px;\n}\n\n.qMtKNa_cardActions {\n flex-shrink: 0;\n align-items: center;\n gap: 4px;\n display: flex;\n}\n\n.qMtKNa_switchOn, .qMtKNa_switchOff {\n cursor: pointer;\n border: none;\n border-radius: 999px;\n flex-shrink: 0;\n width: 38px;\n height: 22px;\n padding: 0;\n transition: background-color .15s;\n position: relative;\n}\n\n.qMtKNa_switchOn {\n background: var(--dsw-alias-state-success-primary, #22c55e);\n}\n\n.qMtKNa_switchOff {\n background: var(--dsw-alias-state-neutral, #d1d5db);\n}\n\n.qMtKNa_switchOn:disabled, .qMtKNa_switchOff:disabled {\n opacity: .6;\n cursor: default;\n}\n\n.qMtKNa_switchThumb {\n pointer-events: none;\n background: #fff;\n border-radius: 50%;\n width: 16px;\n height: 16px;\n transition: left .15s;\n position: absolute;\n top: 3px;\n left: 3px;\n box-shadow: 0 1px 2px #0003;\n}\n\n.qMtKNa_switchOn .qMtKNa_switchThumb {\n left: 19px;\n}\n\n.qMtKNa_desc {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n min-height: 36px;\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n display: -webkit-box;\n overflow: hidden;\n}\n\n.qMtKNa_meta {\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n display: flex;\n}\n\n.qMtKNa_src {\n color: var(--dsw-alias-label-secondary, #9ca3af);\n font-size: 12px;\n text-decoration: none;\n}\n\n.qMtKNa_tag {\n border: 1px solid var(--dsw-alias-border-l3, #d9dde3);\n color: var(--dsw-alias-label-secondary, #6b7280);\n border-radius: 4px;\n flex-shrink: 0;\n padding: 1px 6px;\n font-size: 12px;\n line-height: 18px;\n}\n\n.qMtKNa_okState {\n color: var(--dsw-alias-state-success-primary, #16a34a);\n white-space: nowrap;\n font-size: 12px;\n font-weight: 600;\n}\n\n.qMtKNa_warnLine {\n color: var(--dsw-alias-state-warn-primary, #b45309);\n cursor: help;\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n}\n\n.qMtKNa_modalFooter {\n justify-content: flex-end;\n gap: 8px;\n width: 100%;\n display: flex;\n}\n\n.qMtKNa_modalFooterLeft {\n gap: 8px;\n margin-right: auto;\n display: flex;\n}\n\n.qMtKNa_editorDialog {\n width: min(500px, 92vw);\n}\n\n.qMtKNa_editorForm {\n flex-direction: column;\n gap: 14px;\n min-width: 0;\n display: flex;\n}\n\n.qMtKNa_modeRow {\n border: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n background: var(--dsw-alias-bg-layer-2, #f3f4f6);\n border-radius: 10px;\n align-self: flex-start;\n gap: 6px;\n padding: 3px;\n display: flex;\n}\n\n.qMtKNa_seg, .qMtKNa_segOn {\n font: inherit;\n color: var(--dsw-alias-label-secondary, #6b7280);\n cursor: pointer;\n background: none;\n border: none;\n border-radius: 8px;\n padding: 5px 14px;\n font-size: 13px;\n line-height: 20px;\n}\n\n.qMtKNa_segOn {\n background: var(--dsw-alias-bg-layer-1, #fff);\n color: var(--dsw-alias-label-primary, #1f2328);\n font-weight: 600;\n box-shadow: 0 1px 2px #00000014;\n}\n\n.qMtKNa_fieldGroup {\n flex-direction: column;\n gap: 5px;\n display: flex;\n}\n\n.qMtKNa_fieldLabel {\n color: var(--dsw-alias-label-secondary, #6b7280);\n font-size: 12px;\n font-weight: 600;\n}\n\n.qMtKNa_fieldHint {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n font-size: 12px;\n line-height: 16px;\n}\n\n.qMtKNa_staticId {\n border: 1px dashed var(--dsw-alias-border-l3, #d9dde3);\n background: var(--dsw-alias-bg-layer-2, #f3f4f6);\n border-radius: 8px;\n align-items: center;\n gap: 8px;\n padding: 7px 10px;\n display: flex;\n}\n\n.qMtKNa_staticIdValue {\n color: var(--dsw-alias-label-primary, #1f2328);\n font-size: 13px;\n font-weight: 600;\n}\n\n.qMtKNa_detailDialog {\n width: min(800px, 94vw);\n}\n\n.qMtKNa_detailBody {\n flex-direction: column;\n gap: 14px;\n max-height: 78vh;\n display: flex;\n overflow-y: auto;\n}\n\n.qMtKNa_detailSections {\n flex-direction: column;\n gap: 14px;\n display: flex;\n}\n\n.qMtKNa_detailSection {\n flex-direction: column;\n gap: 6px;\n display: flex;\n}\n\n.qMtKNa_detailHead {\n color: var(--dsw-alias-label-secondary, #6b7280);\n border-bottom: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n margin: 0;\n padding-bottom: 4px;\n font-size: 13px;\n font-weight: 600;\n}\n\n.qMtKNa_detailGrid {\n grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\n gap: 6px 14px;\n display: grid;\n}\n\n.qMtKNa_detailCell {\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n display: flex;\n}\n\n.qMtKNa_detailKey {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n font-size: 12px;\n}\n\n.qMtKNa_detailValue {\n color: var(--dsw-alias-label-primary, #1f2328);\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n overflow: hidden;\n}\n\n.qMtKNa_detailDesc {\n color: var(--dsw-alias-label-secondary, #6b7280);\n margin: 4px 0 0;\n font-size: 13px;\n line-height: 20px;\n}\n\n.qMtKNa_mono {\n word-break: break-all;\n white-space: pre-wrap;\n color: var(--dsw-alias-label-primary, #1f2328);\n margin: 0;\n font-family: ui-monospace, Menlo, Consolas, monospace;\n font-size: 12px;\n line-height: 18px;\n}\n\n.qMtKNa_detailItem {\n border: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n border-radius: 8px;\n flex-direction: column;\n display: flex;\n overflow: hidden;\n}\n\n.qMtKNa_detailItemRow, .qMtKNa_detailItemOpen {\n width: 100%;\n font: inherit;\n text-align: left;\n cursor: pointer;\n color: var(--dsw-alias-label-primary, #1f2328);\n background: none;\n border: none;\n align-items: center;\n gap: 8px;\n padding: 7px 10px;\n display: flex;\n}\n\n.qMtKNa_detailItemRow:hover {\n background: var(--dsw-alias-bg-hover, #0000000d);\n}\n\n.qMtKNa_detailItemOpen {\n background: var(--dsw-alias-bg-selected, #4f6ef714);\n}\n\n.qMtKNa_detailItemName {\n flex-shrink: 0;\n font-size: 13px;\n font-weight: 600;\n}\n\n.qMtKNa_detailItemDesc {\n min-width: 0;\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n font-size: 12px;\n overflow: hidden;\n}\n\n.qMtKNa_detailChevron {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n flex-shrink: 0;\n}\n\n.qMtKNa_skillContent {\n border-top: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n max-height: 320px;\n color: var(--dsw-alias-label-primary, #1f2328);\n padding: 10px 12px;\n font-size: 13px;\n line-height: 20px;\n overflow-y: auto;\n}\n\n.qMtKNa_progress, .qMtKNa_progressError {\n border: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n background: var(--dsw-alias-bg-layer-2, #7f7f7f0f);\n color: var(--dsw-alias-label-primary, #1f2328);\n border-radius: 8px;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n font-size: 13px;\n line-height: 20px;\n display: flex;\n}\n\n.qMtKNa_progressError {\n border-color: var(--dsw-alias-danger, #e5484d);\n color: var(--dsw-alias-danger, #e5484d);\n}\n\n.qMtKNa_progressSpin {\n border: 2px solid var(--dsw-alias-border-l2, #e5e7eb);\n border-top-color: var(--dsw-alias-brand-primary, #4f6ef7);\n border-radius: 50%;\n flex-shrink: 0;\n width: 14px;\n height: 14px;\n animation: .8s linear infinite qMtKNa_dshApmSpin;\n}\n\n@keyframes qMtKNa_dshApmSpin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.qMtKNa_progressFail {\n flex-shrink: 0;\n font-size: 13px;\n}\n\n.qMtKNa_progressText {\n overflow-wrap: anywhere;\n min-width: 0;\n}\n";document.head.appendChild(s);}})();
|
|
5
|
+
(function(){if(typeof document!=="undefined"){var s=document.createElement("style");s.setAttribute("data-dsh-client","dsh-agent-plugins-market");s.textContent=".qMtKNa_market {\n min-width: 0;\n height: 100%;\n min-height: 0;\n color: var(--dsw-alias-label-primary, #1f2328);\n flex-direction: column;\n gap: 24px;\n display: flex;\n}\n\n.qMtKNa_pageMode {\n width: 100%;\n min-width: 0;\n}\n\n.qMtKNa_marketControls {\n flex-direction: column;\n gap: 8px;\n min-height: 0;\n display: flex;\n}\n\n.qMtKNa_mcpSurface {\n flex: 1;\n min-height: 0;\n display: flex;\n}\n\n.qMtKNa_surfaceSwitch {\n border: 1px solid var(--dsw-alias-border-l2, #d4dce8);\n background: var(--dsw-alias-bg-layer-1, #fff);\n height: 26px;\n color: var(--dsw-alias-brand-primary, #4966f5);\n cursor: pointer;\n border-radius: 7px;\n flex: none;\n align-self: center;\n padding: 0 10px;\n font-size: 11px;\n}\n\n.qMtKNa_surfaceSwitch:hover {\n background: var(--dsw-alias-bg-selected, #edf1ff);\n}\n\nhtml[data-dsh-agent-plugins-market-page] [data-pane=\"conversation\"], html[data-dsh-agent-plugins-market-page] [class*=\"centerCol\"] {\n position: relative;\n}\n\n.qMtKNa_pageView {\n z-index: 60;\n background: var(--dsw-alias-bg-base, #f7f8fa);\n min-width: 0;\n min-height: 0;\n padding: 20px 24px;\n display: none;\n position: absolute;\n inset: 0;\n overflow: hidden;\n}\n\nhtml[data-dsh-agent-plugins-market-page] .qMtKNa_pageView {\n display: flex;\n}\n\nhtml[data-dsh-agent-plugins-market-page] [data-pane=\"conversation\"] > :not([data-dsh-agent-plugins-market-page-view]), html[data-dsh-agent-plugins-market-page] [class*=\"centerCol\"] > :not([data-dsh-agent-plugins-market-page-view]) {\n display: none !important;\n}\n\n.qMtKNa_pageEntry {\n width: 100%;\n min-height: 32px;\n color: var(--dsw-alias-label-primary, #1f2328);\n cursor: pointer;\n font: inherit;\n text-align: left;\n background: none;\n border: none;\n border-radius: 8px;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n font-size: 13px;\n line-height: 20px;\n display: flex;\n}\n\n.qMtKNa_pageEntry:hover {\n background: var(--dsw-alias-bg-hover, #0000000d);\n}\n\n.qMtKNa_pageEntry:active {\n background: var(--dsw-alias-bg-active, #00000014);\n}\n\n.qMtKNa_pageEntry svg {\n color: var(--dsw-alias-label-secondary, #6b7280);\n flex-shrink: 0;\n}\n\n.qMtKNa_pageEntry span {\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n overflow: hidden;\n}\n\n[data-dsh-frame][data-sidebar-collapsed] .qMtKNa_pageEntry {\n justify-content: center;\n padding-inline: 0;\n}\n\n[data-dsh-frame][data-sidebar-collapsed] .qMtKNa_pageEntry span {\n display: none;\n}\n\n.qMtKNa_pageEntry:focus-visible, .qMtKNa_srcTabMain:focus-visible, .qMtKNa_srcTabEdit:focus-visible, .qMtKNa_srcTabDel:focus-visible, .qMtKNa_seg:focus-visible, .qMtKNa_segOn:focus-visible, .qMtKNa_detailItemRow:focus-visible, .qMtKNa_detailItemOpen:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4f6ef7);\n outline-offset: 2px;\n}\n\n.qMtKNa_header {\n flex-direction: column;\n flex-shrink: 0;\n gap: 8px;\n display: flex;\n}\n\n.qMtKNa_titleRow {\n align-items: center;\n gap: 8px;\n display: flex;\n}\n\n.qMtKNa_title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n line-height: 24px;\n}\n\n.qMtKNa_sub {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n align-items: center;\n gap: 8px;\n min-width: 0;\n margin: 0;\n font-size: 13px;\n line-height: 20px;\n display: flex;\n overflow: hidden;\n}\n\n.qMtKNa_spacer {\n flex: 1;\n}\n\n.qMtKNa_searchGroup {\n align-items: center;\n gap: 2px;\n display: flex;\n}\n\n.qMtKNa_body {\n flex: 1;\n align-items: flex-start;\n gap: 20px;\n min-height: 0;\n display: flex;\n}\n\n.qMtKNa_sourceTabsRow {\n padding: 0;\n display: block;\n}\n\n.qMtKNa_sourceTabsScroll {\n grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));\n gap: 4px;\n display: grid;\n}\n\n.qMtKNa_srcTabEdit {\n font: inherit;\n color: var(--dsw-alias-label-tertiary, #9ca3af);\n cursor: pointer;\n background: none;\n border: none;\n flex-shrink: 0;\n padding: 2px;\n font-size: 12px;\n line-height: 18px;\n}\n\n.qMtKNa_srcTabEdit:hover {\n color: var(--dsw-alias-label-primary, #1f2328);\n}\n\n.qMtKNa_srcTabOn .qMtKNa_srcTabEdit, .qMtKNa_srcTabOn .qMtKNa_srcTabEdit:hover {\n color: var(--dsw-alias-label-primary-foreground, #fff);\n}\n\n.qMtKNa_srcTab, .qMtKNa_srcTabOn {\n border: 1px solid var(--dsw-alias-border-l3, #d9dde3);\n background: var(--dsw-alias-bg-layer-1, #fff);\n border-radius: 999px;\n justify-content: center;\n align-items: center;\n width: 100%;\n height: 24px;\n display: inline-flex;\n overflow: hidden;\n}\n\n.qMtKNa_srcTabMain {\n font: inherit;\n color: var(--dsw-alias-label-primary, #1f2328);\n cursor: pointer;\n white-space: nowrap;\n text-overflow: ellipsis;\n background: none;\n border: none;\n flex: 1;\n min-width: 0;\n padding: 2px 2px 2px 10px;\n font-size: 12px;\n line-height: 18px;\n overflow: hidden;\n}\n\n.qMtKNa_srcTabMain:hover {\n color: var(--dsw-alias-brand-primary, #4f6ef7);\n}\n\n.qMtKNa_srcTabOn {\n background: var(--dsw-alias-brand-primary-new-colorprimary-new-color, #4176e6);\n border-color: var(--dsw-alias-brand-primary-new-colorprimary-new-color, #4176e6);\n}\n\n.qMtKNa_srcTabOn .qMtKNa_srcTabMain {\n color: var(--dsw-alias-label-primary-foreground, #fff);\n font-weight: 600;\n}\n\n.qMtKNa_srcTabDel {\n font: inherit;\n color: var(--dsw-alias-label-tertiary, #9ca3af);\n cursor: pointer;\n background: none;\n border: none;\n flex-shrink: 0;\n padding: 2px 8px 2px 2px;\n font-size: 12px;\n line-height: 18px;\n}\n\n.qMtKNa_srcTabDel:hover {\n color: var(--dsw-alias-state-error-primary, #dc2626);\n}\n\n.qMtKNa_srcTabOn .qMtKNa_srcTabDel, .qMtKNa_srcTabOn .qMtKNa_srcTabDel:hover {\n color: var(--dsw-alias-label-primary-foreground, #fff);\n}\n\n.qMtKNa_grid {\n scrollbar-gutter: stable;\n flex: 1;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n align-content: start;\n gap: 12px;\n min-width: 0;\n min-height: 0;\n padding-right: 4px;\n display: grid;\n overflow-y: auto;\n}\n\n.qMtKNa_list {\n scrollbar-gutter: stable;\n flex-direction: column;\n flex: 1;\n gap: 8px;\n min-width: 0;\n min-height: 0;\n padding-right: 4px;\n display: flex;\n overflow-y: auto;\n}\n\n.qMtKNa_list .qMtKNa_card {\n flex-flow: wrap;\n align-items: center;\n gap: 8px 14px;\n}\n\n.qMtKNa_list .qMtKNa_cardTop {\n flex: none;\n}\n\n.qMtKNa_list .qMtKNa_cardDesc {\n -webkit-line-clamp: 1;\n flex: 1;\n min-width: 200px;\n min-height: 0;\n}\n\n.qMtKNa_list .qMtKNa_cardActions {\n flex: none;\n}\n\n.qMtKNa_list .qMtKNa_meta {\n flex-basis: 100%;\n}\n\n.qMtKNa_empty {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n text-align: center;\n grid-column: 1 / -1;\n padding: 48px 0;\n font-size: 13px;\n}\n\n.qMtKNa_card {\n background: var(--dsw-alias-bg-layer-1, #fff);\n border: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n border-radius: 12px;\n flex-direction: column;\n gap: 8px;\n min-width: 0;\n padding: 12px 14px;\n display: flex;\n}\n\n.qMtKNa_cardTop {\n align-items: center;\n gap: 8px;\n display: flex;\n}\n\n.qMtKNa_cardTitle {\n flex: 1;\n align-items: center;\n gap: 8px;\n min-width: 0;\n display: flex;\n}\n\n.qMtKNa_cardName {\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n font-weight: 600;\n line-height: 22px;\n overflow: hidden;\n}\n\n.qMtKNa_version {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n font-variant-numeric: tabular-nums;\n flex-shrink: 0;\n font-size: 12px;\n line-height: 20px;\n}\n\n.qMtKNa_cardActions {\n flex-shrink: 0;\n align-items: center;\n gap: 4px;\n display: flex;\n}\n\n.qMtKNa_switchOn, .qMtKNa_switchOff {\n cursor: pointer;\n border: none;\n border-radius: 999px;\n flex-shrink: 0;\n width: 38px;\n height: 22px;\n padding: 0;\n transition: background-color .15s;\n position: relative;\n}\n\n.qMtKNa_switchOn {\n background: var(--dsw-alias-state-success-primary, #22c55e);\n}\n\n.qMtKNa_switchOff {\n background: var(--dsw-alias-state-neutral, #d1d5db);\n}\n\n.qMtKNa_switchOn:disabled, .qMtKNa_switchOff:disabled {\n opacity: .6;\n cursor: default;\n}\n\n.qMtKNa_switchThumb {\n pointer-events: none;\n background: #fff;\n border-radius: 50%;\n width: 16px;\n height: 16px;\n transition: left .15s;\n position: absolute;\n top: 3px;\n left: 3px;\n box-shadow: 0 1px 2px #0003;\n}\n\n.qMtKNa_switchOn .qMtKNa_switchThumb {\n left: 19px;\n}\n\n.qMtKNa_desc {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n min-height: 36px;\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n display: -webkit-box;\n overflow: hidden;\n}\n\n.qMtKNa_meta {\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n display: flex;\n}\n\n.qMtKNa_src {\n color: var(--dsw-alias-label-secondary, #9ca3af);\n font-size: 12px;\n text-decoration: none;\n}\n\n.qMtKNa_tag {\n border: 1px solid var(--dsw-alias-border-l3, #d9dde3);\n color: var(--dsw-alias-label-secondary, #6b7280);\n border-radius: 4px;\n flex-shrink: 0;\n padding: 1px 6px;\n font-size: 12px;\n line-height: 18px;\n}\n\n.qMtKNa_okState {\n color: var(--dsw-alias-state-success-primary, #16a34a);\n white-space: nowrap;\n font-size: 12px;\n font-weight: 600;\n}\n\n.qMtKNa_warnLine {\n color: var(--dsw-alias-state-warn-primary, #b45309);\n cursor: help;\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n}\n\n.qMtKNa_modalFooter {\n justify-content: flex-end;\n gap: 8px;\n width: 100%;\n display: flex;\n}\n\n.qMtKNa_modalFooterLeft {\n gap: 8px;\n margin-right: auto;\n display: flex;\n}\n\n.qMtKNa_editorDialog {\n width: min(500px, 92vw);\n}\n\n.qMtKNa_editorForm {\n flex-direction: column;\n gap: 14px;\n min-width: 0;\n display: flex;\n}\n\n.qMtKNa_modeRow {\n border: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n background: var(--dsw-alias-bg-layer-2, #f3f4f6);\n border-radius: 10px;\n align-self: flex-start;\n gap: 6px;\n padding: 3px;\n display: flex;\n}\n\n.qMtKNa_seg, .qMtKNa_segOn {\n font: inherit;\n color: var(--dsw-alias-label-secondary, #6b7280);\n cursor: pointer;\n background: none;\n border: none;\n border-radius: 8px;\n padding: 5px 14px;\n font-size: 13px;\n line-height: 20px;\n}\n\n.qMtKNa_segOn {\n background: var(--dsw-alias-bg-layer-1, #fff);\n color: var(--dsw-alias-label-primary, #1f2328);\n font-weight: 600;\n box-shadow: 0 1px 2px #00000014;\n}\n\n.qMtKNa_fieldGroup {\n flex-direction: column;\n gap: 5px;\n display: flex;\n}\n\n.qMtKNa_fieldLabel {\n color: var(--dsw-alias-label-secondary, #6b7280);\n font-size: 12px;\n font-weight: 600;\n}\n\n.qMtKNa_fieldHint {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n font-size: 12px;\n line-height: 16px;\n}\n\n.qMtKNa_staticId {\n border: 1px dashed var(--dsw-alias-border-l3, #d9dde3);\n background: var(--dsw-alias-bg-layer-2, #f3f4f6);\n border-radius: 8px;\n align-items: center;\n gap: 8px;\n padding: 7px 10px;\n display: flex;\n}\n\n.qMtKNa_staticIdValue {\n color: var(--dsw-alias-label-primary, #1f2328);\n font-size: 13px;\n font-weight: 600;\n}\n\n.qMtKNa_detailDialog {\n width: min(800px, 94vw);\n}\n\n.qMtKNa_detailBody {\n flex-direction: column;\n gap: 14px;\n max-height: 78vh;\n display: flex;\n overflow-y: auto;\n}\n\n.qMtKNa_detailSections {\n flex-direction: column;\n gap: 14px;\n display: flex;\n}\n\n.qMtKNa_detailSection {\n flex-direction: column;\n gap: 6px;\n display: flex;\n}\n\n.qMtKNa_detailHead {\n color: var(--dsw-alias-label-secondary, #6b7280);\n border-bottom: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n margin: 0;\n padding-bottom: 4px;\n font-size: 13px;\n font-weight: 600;\n}\n\n.qMtKNa_detailGrid {\n grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\n gap: 6px 14px;\n display: grid;\n}\n\n.qMtKNa_detailCell {\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n display: flex;\n}\n\n.qMtKNa_detailKey {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n font-size: 12px;\n}\n\n.qMtKNa_detailValue {\n color: var(--dsw-alias-label-primary, #1f2328);\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n overflow: hidden;\n}\n\n.qMtKNa_detailDesc {\n color: var(--dsw-alias-label-secondary, #6b7280);\n margin: 4px 0 0;\n font-size: 13px;\n line-height: 20px;\n}\n\n.qMtKNa_mono {\n word-break: break-all;\n white-space: pre-wrap;\n color: var(--dsw-alias-label-primary, #1f2328);\n margin: 0;\n font-family: ui-monospace, Menlo, Consolas, monospace;\n font-size: 12px;\n line-height: 18px;\n}\n\n.qMtKNa_detailItem {\n border: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n border-radius: 8px;\n flex-direction: column;\n display: flex;\n overflow: hidden;\n}\n\n.qMtKNa_detailItemRow, .qMtKNa_detailItemOpen {\n width: 100%;\n font: inherit;\n text-align: left;\n cursor: pointer;\n color: var(--dsw-alias-label-primary, #1f2328);\n background: none;\n border: none;\n align-items: center;\n gap: 8px;\n padding: 7px 10px;\n display: flex;\n}\n\n.qMtKNa_detailItemRow:hover {\n background: var(--dsw-alias-bg-hover, #0000000d);\n}\n\n.qMtKNa_detailItemOpen {\n background: var(--dsw-alias-bg-selected, #4f6ef714);\n}\n\n.qMtKNa_detailItemName {\n flex-shrink: 0;\n font-size: 13px;\n font-weight: 600;\n}\n\n.qMtKNa_detailItemDesc {\n min-width: 0;\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n font-size: 12px;\n overflow: hidden;\n}\n\n.qMtKNa_detailChevron {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n flex-shrink: 0;\n}\n\n.qMtKNa_skillContent {\n border-top: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n max-height: 320px;\n color: var(--dsw-alias-label-primary, #1f2328);\n padding: 10px 12px;\n font-size: 13px;\n line-height: 20px;\n overflow-y: auto;\n}\n\n.qMtKNa_progress, .qMtKNa_progressError {\n border: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n background: var(--dsw-alias-bg-layer-2, #7f7f7f0f);\n color: var(--dsw-alias-label-primary, #1f2328);\n border-radius: 8px;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n font-size: 13px;\n line-height: 20px;\n display: flex;\n}\n\n.qMtKNa_progressError {\n border-color: var(--dsw-alias-danger, #e5484d);\n color: var(--dsw-alias-danger, #e5484d);\n}\n\n.qMtKNa_progressSpin {\n border: 2px solid var(--dsw-alias-border-l2, #e5e7eb);\n border-top-color: var(--dsw-alias-brand-primary, #4f6ef7);\n border-radius: 50%;\n flex-shrink: 0;\n width: 14px;\n height: 14px;\n animation: .8s linear infinite qMtKNa_dshApmSpin;\n}\n\n@keyframes qMtKNa_dshApmSpin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.qMtKNa_progressFail {\n flex-shrink: 0;\n font-size: 13px;\n}\n\n.qMtKNa_progressText {\n overflow-wrap: anywhere;\n min-width: 0;\n}\n\n@media (width <= 720px) {\n .qMtKNa_pageView {\n padding: 14px;\n }\n\n .qMtKNa_titleRow {\n flex-wrap: wrap;\n }\n\n .qMtKNa_title {\n flex: 1 0 auto;\n }\n\n .qMtKNa_sub {\n white-space: normal;\n flex: 1 0 100%;\n order: 3;\n }\n\n .qMtKNa_searchGroup {\n flex: 1 0 100%;\n order: 4;\n }\n\n .qMtKNa_sourceTabsScroll {\n scrollbar-width: thin;\n padding-bottom: 2px;\n display: flex;\n overflow-x: auto;\n }\n\n .qMtKNa_srcTab, .qMtKNa_srcTabOn {\n flex: none;\n width: auto;\n min-width: 128px;\n }\n\n .qMtKNa_grid {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .qMtKNa_list .qMtKNa_cardTop, .qMtKNa_list .qMtKNa_cardActions {\n max-width: 100%;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .qMtKNa_progressSpin, .qMtKNa_switchOn, .qMtKNa_switchOff, .qMtKNa_switchThumb {\n transition: none;\n animation: none;\n }\n}\n.R7YLDa_toolbar {\n grid-template-columns: minmax(0, 1fr) 12px auto auto auto 8px auto;\n align-items: flex-end;\n gap: 0;\n min-width: 0;\n display: grid;\n}\n\n.R7YLDa_filterGap, .R7YLDa_viewGap {\n min-width: 0;\n}\n\n.R7YLDa_search {\n box-sizing: border-box;\n align-items: center;\n width: 100%;\n min-width: 0;\n height: 36px;\n display: flex;\n}\n\n.R7YLDa_search input {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n height: 36px;\n min-height: 36px;\n max-height: 36px;\n padding-top: 0;\n padding-bottom: 0;\n font-size: 12px;\n line-height: 20px;\n}\n\n.R7YLDa_filter, .R7YLDa_filterOn {\n min-width: 54px;\n height: 36px;\n color: var(--dsw-alias-label-secondary, #6b7280);\n cursor: pointer;\n font: inherit;\n white-space: nowrap;\n background: none;\n border: none;\n border-bottom: 2px solid #0000;\n justify-content: center;\n align-items: center;\n gap: 5px;\n padding: 7px 9px;\n font-size: 13px;\n display: inline-flex;\n}\n\n.R7YLDa_filterOn {\n color: var(--dsw-alias-brand-primary, #4f6ef7);\n border-bottom-color: var(--dsw-alias-brand-primary, #4f6ef7);\n font-weight: 600;\n}\n\n.R7YLDa_filter svg, .R7YLDa_filterOn svg, .R7YLDa_viewSwitch svg {\n stroke: currentColor;\n stroke-width: 1.5px;\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n\n.R7YLDa_filterCount {\n font-variant-numeric: tabular-nums;\n}\n\n.R7YLDa_viewSwitch {\n width: 34px;\n height: 36px;\n color: var(--dsw-alias-label-tertiary, #9ca3af);\n cursor: pointer;\n background: none;\n border: none;\n border-bottom: 2px solid #0000;\n justify-content: center;\n align-items: center;\n display: inline-flex;\n}\n\n.R7YLDa_viewSwitch:hover {\n color: var(--dsw-alias-label-primary, #1f2328);\n}\n\n.R7YLDa_viewSwitch:focus-visible, .R7YLDa_filter:focus-visible, .R7YLDa_filterOn:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4f6ef7);\n outline-offset: 2px;\n}\n\n@media (width <= 760px) {\n .R7YLDa_toolbar {\n grid-template-columns: auto auto auto 8px auto;\n justify-content: end;\n overflow-x: auto;\n }\n\n .R7YLDa_search {\n grid-column: 1 / -1;\n }\n\n .R7YLDa_filterGap {\n display: none;\n }\n}\n.--KJaG_surface {\n height: 100%;\n min-height: 0;\n max-height: 100%;\n color: var(--dsw-alias-label-primary, #1f2328);\n flex-direction: column;\n flex: 1;\n display: flex;\n overflow: hidden;\n}\n\n.--KJaG_header {\n flex: none;\n align-items: center;\n gap: 8px;\n padding: 4px 0 8px;\n display: flex;\n}\n\n.--KJaG_title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n line-height: 24px;\n}\n\n.--KJaG_subtitle {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n margin: 2px 0 0;\n font-size: 13px;\n line-height: 20px;\n}\n\n.--KJaG_headerActions {\n align-items: center;\n gap: 8px;\n margin-left: auto;\n display: flex;\n}\n\n.--KJaG_summary {\n color: var(--dsw-alias-label-secondary, #667085);\n white-space: nowrap;\n align-items: center;\n gap: 7px;\n font-size: 12px;\n display: inline-flex;\n}\n\n.--KJaG_errorSummary {\n color: var(--dsw-alias-state-error-primary, #dc2626);\n font-variant-numeric: tabular-nums;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n display: inline-flex;\n}\n\n.--KJaG_summaryDotGreen, .--KJaG_summaryDotRed {\n border-radius: 50%;\n width: 7px;\n height: 7px;\n}\n\n.--KJaG_summaryDotGreen {\n background: var(--dsw-alias-state-success-primary, #16a34a);\n}\n\n.--KJaG_summaryDotRed {\n background: var(--dsw-alias-state-error-primary, #dc2626);\n}\n\n.--KJaG_toolbar {\n flex: none;\n margin-bottom: 24px;\n}\n\n.--KJaG_grid {\n scrollbar-gutter: stable;\n flex: 1;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n align-content: start;\n gap: 12px;\n min-width: 0;\n min-height: 0;\n padding-right: 4px;\n display: grid;\n overflow-y: auto;\n}\n\n.--KJaG_list {\n scrollbar-gutter: stable;\n flex-direction: column;\n flex: 1;\n gap: 8px;\n min-width: 0;\n min-height: 0;\n padding-right: 4px;\n display: flex;\n overflow-y: auto;\n}\n\n.--KJaG_list .--KJaG_card {\n flex-flow: wrap;\n align-items: center;\n gap: 8px 14px;\n}\n\n.--KJaG_list .--KJaG_cardTop {\n flex: 0 260px;\n}\n\n.--KJaG_list .--KJaG_endpoint {\n -webkit-line-clamp: 1;\n flex: 200px;\n min-height: 0;\n}\n\n.--KJaG_list .--KJaG_meta {\n flex: 0 auto;\n}\n\n.--KJaG_list .--KJaG_cardReason {\n flex-basis: 100%;\n}\n\n.--KJaG_card {\n min-width: 0;\n min-height: 0;\n color: inherit;\n background: var(--dsw-alias-bg-layer-1, #fff);\n border: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n cursor: pointer;\n font: inherit;\n text-align: left;\n border-radius: 12px;\n flex-direction: column;\n gap: 8px;\n padding: 12px 14px;\n display: flex;\n}\n\n.--KJaG_card:hover {\n border-color: var(--dsw-alias-border-l3, #d9dde3);\n background: var(--dsw-alias-bg-hover, #00000009);\n}\n\n.--KJaG_card:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4f6ef7);\n outline-offset: 2px;\n}\n\n.--KJaG_cardTop {\n align-items: center;\n gap: 8px;\n min-width: 0;\n display: flex;\n}\n\n.--KJaG_statusDot {\n background: var(--dsw-alias-state-success-primary, #16a34a);\n border-radius: 50%;\n flex: none;\n width: 7px;\n height: 7px;\n}\n\n.--KJaG_statusconnected {\n background: var(--dsw-alias-state-success-primary, #16a34a);\n}\n\n.--KJaG_statusdegraded {\n background: var(--dsw-alias-state-warn-primary, #b45309);\n}\n\n.--KJaG_statusfailed {\n background: var(--dsw-alias-state-error-primary, #dc2626);\n}\n\n.--KJaG_statusdisabled {\n background: var(--dsw-alias-label-tertiary, #98a2b3);\n}\n\n.--KJaG_service {\n flex: 1;\n min-width: 0;\n}\n\n.--KJaG_name {\n color: var(--dsw-alias-label-primary, #1f2328);\n text-overflow: ellipsis;\n white-space: nowrap;\n font: 600 13px / 22px ui-monospace, Menlo, Consolas, monospace;\n display: block;\n overflow: hidden;\n}\n\n.--KJaG_endpoint {\n min-height: 36px;\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n -webkit-line-clamp: 2;\n overflow-wrap: anywhere;\n -webkit-box-orient: vertical;\n margin: 0;\n font: 12px / 18px ui-monospace, Menlo, Consolas, monospace;\n display: -webkit-box;\n overflow: hidden;\n}\n\n.--KJaG_meta {\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n display: flex;\n}\n\n.--KJaG_sourcePlugin, .--KJaG_sourceDirect, .--KJaG_transport, .--KJaG_toolCount {\n min-width: 0;\n max-width: 100%;\n color: var(--dsw-alias-label-secondary, #6b7280);\n border: 1px solid var(--dsw-alias-border-l3, #d9dde3);\n text-overflow: ellipsis;\n white-space: nowrap;\n border-radius: 4px;\n align-items: center;\n gap: 5px;\n padding: 1px 6px;\n font-size: 12px;\n line-height: 18px;\n display: inline-flex;\n}\n\n.--KJaG_sourcePlugin svg, .--KJaG_sourceDirect svg {\n color: currentColor;\n stroke: currentColor;\n stroke-width: 1.35px;\n stroke-linecap: round;\n stroke-linejoin: round;\n flex: none;\n width: 14px;\n height: 14px;\n}\n\n.--KJaG_transport {\n font-family: ui-monospace, Menlo, Consolas, monospace;\n}\n\n.--KJaG_toolCount {\n color: var(--dsw-alias-label-primary, #1f2328);\n flex: none;\n font-weight: 600;\n}\n\n.--KJaG_cardReason {\n color: var(--dsw-alias-state-error-primary, #dc2626);\n overflow-wrap: anywhere;\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n}\n\n.--KJaG_state, .--KJaG_detailState {\n color: var(--dsw-alias-state-success-primary, #16a34a);\n white-space: nowrap;\n align-items: center;\n gap: 5px;\n font-size: 11px;\n display: inline-flex;\n}\n\n.--KJaG_state:before, .--KJaG_detailState:before {\n content: \"\";\n background: currentColor;\n border-radius: 50%;\n width: 6px;\n height: 6px;\n}\n\n.--KJaG_stateconnected, .--KJaG_detailStateconnected {\n color: var(--dsw-alias-state-success-primary, #16a34a);\n}\n\n.--KJaG_statedegraded, .--KJaG_detailStatedegraded {\n color: var(--dsw-alias-state-warn-primary, #b45309);\n}\n\n.--KJaG_statefailed, .--KJaG_detailStatefailed {\n color: var(--dsw-alias-state-error-primary, #dc2626);\n}\n\n.--KJaG_statedisabled, .--KJaG_detailStatedisabled {\n color: var(--dsw-alias-label-tertiary, #98a2b3);\n}\n\n.--KJaG_chevron {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n font-size: 18px;\n}\n\n.--KJaG_empty, .--KJaG_detailEmpty {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n text-align: center;\n padding: 24px;\n font-size: 12px;\n}\n\n.--KJaG_error {\n color: var(--dsw-alias-state-error-primary, #dc2626);\n align-items: center;\n gap: 8px;\n margin: 16px 0;\n font-size: 12px;\n display: flex;\n}\n\n.--KJaG_boundary {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n background: var(--dsw-alias-bg-layer-2, #f7f8fa);\n border-left: 2px solid var(--dsw-alias-border-l3, #d9dde3);\n margin: 10px 0 0;\n padding: 9px 10px;\n font-size: 11px;\n line-height: 17px;\n}\n\n.--KJaG_detailDialog {\n width: min(720px, 94vw);\n}\n\n.--KJaG_detailBody {\n max-height: 72vh;\n overflow-y: auto;\n}\n\n.--KJaG_modalFooter {\n justify-content: flex-end;\n width: 100%;\n display: flex;\n}\n\n.--KJaG_detail {\n flex-direction: column;\n gap: 16px;\n display: flex;\n}\n\n.--KJaG_detailMeta {\n flex-wrap: wrap;\n gap: 6px;\n display: flex;\n}\n\n.--KJaG_reason {\n color: var(--dsw-alias-state-error-primary, #dc2626);\n background: var(--dsw-alias-bg-error, #dc26260f);\n border-left: 2px solid;\n padding: 9px 10px;\n font-size: 11px;\n line-height: 16px;\n}\n\n.--KJaG_detailSection {\n flex-direction: column;\n gap: 7px;\n display: flex;\n}\n\n.--KJaG_detailHead {\n color: var(--dsw-alias-label-secondary, #667085);\n border-bottom: 1px solid var(--dsw-alias-border-l2, #e5e7eb);\n margin: 0;\n padding-bottom: 5px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.--KJaG_config {\n max-height: 220px;\n color: var(--dsw-alias-label-primary, #344054);\n background: var(--dsw-alias-bg-layer-2, #f6f8fc);\n border: 1px solid var(--dsw-alias-border-l1, #e2e7ef);\n white-space: pre-wrap;\n word-break: break-word;\n border-radius: 7px;\n margin: 0;\n padding: 10px;\n font: 11px / 17px ui-monospace, Menlo, Consolas, monospace;\n overflow: auto;\n}\n\n.--KJaG_toolList {\n flex-direction: column;\n display: flex;\n}\n\n.--KJaG_tool {\n border-bottom: 1px solid var(--dsw-alias-border-l1, #eef1f5);\n grid-template-columns: 26px minmax(120px, auto) minmax(0, 1fr);\n align-items: center;\n gap: 8px;\n padding: 7px 0;\n display: grid;\n}\n\n.--KJaG_tool:last-child {\n border-bottom: none;\n}\n\n.--KJaG_toolIndex {\n color: var(--dsw-alias-brand-primary, #4f6ef7);\n font: 10px / 16px ui-monospace, Menlo, Consolas, monospace;\n}\n\n.--KJaG_toolName {\n color: var(--dsw-alias-label-primary, #1f2328);\n text-overflow: ellipsis;\n white-space: nowrap;\n font: 11px / 16px ui-monospace, Menlo, Consolas, monospace;\n overflow: hidden;\n}\n\n.--KJaG_toolDescription {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 10px;\n overflow: hidden;\n}\n\n@media (width <= 760px) {\n .--KJaG_header, .--KJaG_toolbar {\n padding-left: 0;\n padding-right: 0;\n }\n\n .--KJaG_header {\n flex-direction: column;\n }\n\n .--KJaG_headerActions {\n justify-content: space-between;\n width: 100%;\n margin-left: 0;\n }\n\n .--KJaG_grid {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .--KJaG_list .--KJaG_cardTop, .--KJaG_list .--KJaG_meta {\n max-width: 100%;\n }\n\n .--KJaG_tool {\n grid-template-columns: 26px minmax(0, 1fr);\n }\n\n .--KJaG_toolDescription {\n display: none;\n }\n}\n";document.head.appendChild(s);}})();
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
7
|
//#region \0rolldown/runtime.js
|
|
8
8
|
var __create = Object.create;
|
|
@@ -29,7 +29,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
let react = require("react");
|
|
30
30
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
31
31
|
_deepseek_ai_dsh_client_ui_primitives = __toESM(_deepseek_ai_dsh_client_ui_primitives, 1);
|
|
32
|
+
let react_dom_client = require("react-dom/client");
|
|
32
33
|
//#region src/client/locales.ts
|
|
34
|
+
/** Chinese is the source-of-truth key set; English is checked against it below. */
|
|
33
35
|
const zh = {
|
|
34
36
|
nav: "Agent Plugins 市场",
|
|
35
37
|
subtitle: "发现与安装 Agent Plugins(agent-plugins.org 便携包)",
|
|
@@ -92,7 +94,7 @@ const zh = {
|
|
|
92
94
|
uninstall: "卸载",
|
|
93
95
|
uninstallConfirmTitle: "卸载 Agent Plugins",
|
|
94
96
|
uninstallConfirmDesc: "将从已安装列表移除该 Agent Plugins,其技能与 MCP 工具随即停止注入。仓库源克隆保留。",
|
|
95
|
-
removeSourceConfirmTitle: "
|
|
97
|
+
removeSourceConfirmTitle: "移除仓库源「{sourceId}」",
|
|
96
98
|
removeSourceConfirmDesc: "将删除该源的本地克隆与全部安装记录。",
|
|
97
99
|
enable: "启用",
|
|
98
100
|
disable: "禁用",
|
|
@@ -123,6 +125,8 @@ const zh = {
|
|
|
123
125
|
sourceNotCloned: "未克隆",
|
|
124
126
|
sourceCloned: "已克隆",
|
|
125
127
|
errors: "校验问题",
|
|
128
|
+
sourceErrorSeparator: ";",
|
|
129
|
+
viewMode: "视图模式",
|
|
126
130
|
grid: "网格",
|
|
127
131
|
list: "列表",
|
|
128
132
|
openSettings: "在设置中打开",
|
|
@@ -130,7 +134,32 @@ const zh = {
|
|
|
130
134
|
dataLabel: "Agent Plugins 数据目录",
|
|
131
135
|
countAll: "共 {n} 个 Agent Plugins",
|
|
132
136
|
countInstalled: "已装 {n}",
|
|
133
|
-
countEnabled: "启用 {n}"
|
|
137
|
+
countEnabled: "启用 {n}",
|
|
138
|
+
mcpStatusNav: "MCP 服务",
|
|
139
|
+
mcpStatusTitle: "MCP 服务",
|
|
140
|
+
mcpStatusSubtitle: "连接状态、来源和工具清单",
|
|
141
|
+
mcpSearch: "搜索 MCP 名称、来源或地址…",
|
|
142
|
+
mcpAll: "全部",
|
|
143
|
+
mcpPlugin: "Plugin",
|
|
144
|
+
mcpDirect: "直接安装",
|
|
145
|
+
mcpService: "服务",
|
|
146
|
+
mcpSource: "来源",
|
|
147
|
+
mcpTransport: "传输",
|
|
148
|
+
mcpTools: "工具",
|
|
149
|
+
mcpConnected: "已连接",
|
|
150
|
+
mcpDegraded: "降级",
|
|
151
|
+
mcpFailed: "失败",
|
|
152
|
+
mcpDisabled: "未启用",
|
|
153
|
+
mcpObservedEndpoint: "当前工具表观测",
|
|
154
|
+
mcpServiceDetail: "服务详情",
|
|
155
|
+
mcpConfig: "连接配置",
|
|
156
|
+
mcpSelectHint: "选择一个 MCP 服务查看配置与工具",
|
|
157
|
+
mcpEmpty: "没有匹配的 MCP 服务",
|
|
158
|
+
mcpNoTools: "当前没有已注册工具",
|
|
159
|
+
mcpDirectConfigUnavailable: "宿主未提供直接安装 MCP 的配置记录",
|
|
160
|
+
mcpDirectBoundary: "直接安装 MCP 仅显示当前工具表中可观测的服务;宿主未提供配置与连接状态 API。",
|
|
161
|
+
mcpBackToMarket: "返回市场",
|
|
162
|
+
mcpRetry: "重试"
|
|
134
163
|
};
|
|
135
164
|
const en = {
|
|
136
165
|
nav: "Agent Plugins Market",
|
|
@@ -194,7 +223,7 @@ const en = {
|
|
|
194
223
|
uninstall: "Uninstall",
|
|
195
224
|
uninstallConfirmTitle: "Uninstall suite",
|
|
196
225
|
uninstallConfirmDesc: "Removes the suite from the installed list; its skills and MCP tools stop injecting. The source clone stays.",
|
|
197
|
-
removeSourceConfirmTitle: "Remove source",
|
|
226
|
+
removeSourceConfirmTitle: "Remove source “{sourceId}”",
|
|
198
227
|
removeSourceConfirmDesc: "Deletes the local clone and all install records of this source.",
|
|
199
228
|
enable: "Enable",
|
|
200
229
|
disable: "Disable",
|
|
@@ -225,6 +254,8 @@ const en = {
|
|
|
225
254
|
sourceNotCloned: "not cloned",
|
|
226
255
|
sourceCloned: "cloned",
|
|
227
256
|
errors: "validation issues",
|
|
257
|
+
sourceErrorSeparator: "; ",
|
|
258
|
+
viewMode: "View mode",
|
|
228
259
|
grid: "grid",
|
|
229
260
|
list: "list",
|
|
230
261
|
openSettings: "Open in settings",
|
|
@@ -232,7 +263,32 @@ const en = {
|
|
|
232
263
|
dataLabel: "Suite data root",
|
|
233
264
|
countAll: "{n} suites",
|
|
234
265
|
countInstalled: "{n} installed",
|
|
235
|
-
countEnabled: "{n} enabled"
|
|
266
|
+
countEnabled: "{n} enabled",
|
|
267
|
+
mcpStatusNav: "MCP services",
|
|
268
|
+
mcpStatusTitle: "MCP services",
|
|
269
|
+
mcpStatusSubtitle: "Connection state, sources, and tools",
|
|
270
|
+
mcpSearch: "Search MCP names, sources, or endpoints…",
|
|
271
|
+
mcpAll: "All",
|
|
272
|
+
mcpPlugin: "Plugin",
|
|
273
|
+
mcpDirect: "Direct",
|
|
274
|
+
mcpService: "Service",
|
|
275
|
+
mcpSource: "Source",
|
|
276
|
+
mcpTransport: "Transport",
|
|
277
|
+
mcpTools: "tools",
|
|
278
|
+
mcpConnected: "connected",
|
|
279
|
+
mcpDegraded: "degraded",
|
|
280
|
+
mcpFailed: "failed",
|
|
281
|
+
mcpDisabled: "disabled",
|
|
282
|
+
mcpObservedEndpoint: "observed from tool registry",
|
|
283
|
+
mcpServiceDetail: "Service detail",
|
|
284
|
+
mcpConfig: "Connection config",
|
|
285
|
+
mcpSelectHint: "Select an MCP service to inspect config and tools",
|
|
286
|
+
mcpEmpty: "No matching MCP services",
|
|
287
|
+
mcpNoTools: "No registered tools",
|
|
288
|
+
mcpDirectConfigUnavailable: "The host does not expose direct-MCP configuration",
|
|
289
|
+
mcpDirectBoundary: "Direct MCP entries only show services observed in the current tool registry; the host exposes no config or connection-status API.",
|
|
290
|
+
mcpBackToMarket: "Back to market",
|
|
291
|
+
mcpRetry: "Retry"
|
|
236
292
|
};
|
|
237
293
|
//#endregion
|
|
238
294
|
//#region src/client/api.ts
|
|
@@ -251,6 +307,11 @@ async function fetchSuiteDetail(sourceId, suiteId) {
|
|
|
251
307
|
if (!response.ok) throw new Error(`suite detail failed: ${response.status}`);
|
|
252
308
|
return response.json();
|
|
253
309
|
}
|
|
310
|
+
async function fetchMcpStatus() {
|
|
311
|
+
const response = await fetch("/api/agent-plugins/mcp-status", { credentials: "same-origin" });
|
|
312
|
+
if (!response.ok) throw new Error(`MCP status failed: ${response.status}`);
|
|
313
|
+
return response.json();
|
|
314
|
+
}
|
|
254
315
|
async function fetchSkillContent(sourceId, suiteId, skill) {
|
|
255
316
|
const response = await fetch(`/api/agent-plugins/skill?sourceId=${encodeURIComponent(sourceId)}&suiteId=${encodeURIComponent(suiteId)}&skill=${encodeURIComponent(skill)}`, { credentials: "same-origin" });
|
|
256
317
|
if (!response.ok) throw new Error(`skill content failed: ${response.status}`);
|
|
@@ -327,20 +388,23 @@ var market_module_default = {
|
|
|
327
388
|
"header": "qMtKNa_header",
|
|
328
389
|
"list": "qMtKNa_list",
|
|
329
390
|
"market": "qMtKNa_market",
|
|
391
|
+
"marketControls": "qMtKNa_marketControls",
|
|
392
|
+
"mcpSurface": "qMtKNa_mcpSurface",
|
|
330
393
|
"meta": "qMtKNa_meta",
|
|
331
394
|
"modalFooter": "qMtKNa_modalFooter",
|
|
332
395
|
"modalFooterLeft": "qMtKNa_modalFooterLeft",
|
|
333
396
|
"modeRow": "qMtKNa_modeRow",
|
|
334
397
|
"mono": "qMtKNa_mono",
|
|
335
398
|
"okState": "qMtKNa_okState",
|
|
399
|
+
"pageEntry": "qMtKNa_pageEntry",
|
|
400
|
+
"pageMode": "qMtKNa_pageMode",
|
|
401
|
+
"pageView": "qMtKNa_pageView",
|
|
336
402
|
"progress": "qMtKNa_progress",
|
|
337
403
|
"progressError": "qMtKNa_progressError",
|
|
338
404
|
"progressFail": "qMtKNa_progressFail",
|
|
339
405
|
"progressSpin": "qMtKNa_progressSpin",
|
|
340
406
|
"progressText": "qMtKNa_progressText",
|
|
341
407
|
"searchGroup": "qMtKNa_searchGroup",
|
|
342
|
-
"searchInput": "qMtKNa_searchInput",
|
|
343
|
-
"searchWrap": "qMtKNa_searchWrap",
|
|
344
408
|
"seg": "qMtKNa_seg",
|
|
345
409
|
"segOn": "qMtKNa_segOn",
|
|
346
410
|
"skillContent": "qMtKNa_skillContent",
|
|
@@ -356,18 +420,14 @@ var market_module_default = {
|
|
|
356
420
|
"staticId": "qMtKNa_staticId",
|
|
357
421
|
"staticIdValue": "qMtKNa_staticIdValue",
|
|
358
422
|
"sub": "qMtKNa_sub",
|
|
423
|
+
"surfaceSwitch": "qMtKNa_surfaceSwitch",
|
|
359
424
|
"switchOff": "qMtKNa_switchOff",
|
|
360
425
|
"switchOn": "qMtKNa_switchOn",
|
|
361
426
|
"switchThumb": "qMtKNa_switchThumb",
|
|
362
|
-
"tab": "qMtKNa_tab",
|
|
363
|
-
"tabGap": "qMtKNa_tabGap",
|
|
364
|
-
"tabOn": "qMtKNa_tabOn",
|
|
365
|
-
"tabRow": "qMtKNa_tabRow",
|
|
366
427
|
"tag": "qMtKNa_tag",
|
|
367
428
|
"title": "qMtKNa_title",
|
|
368
429
|
"titleRow": "qMtKNa_titleRow",
|
|
369
430
|
"version": "qMtKNa_version",
|
|
370
|
-
"viewSwitch": "qMtKNa_viewSwitch",
|
|
371
431
|
"warnLine": "qMtKNa_warnLine"
|
|
372
432
|
};
|
|
373
433
|
//#endregion
|
|
@@ -421,7 +481,7 @@ function SuiteDetailModal({ t, sourceId, suiteId, onClose }) {
|
|
|
421
481
|
const toggleMcp = (key) => {
|
|
422
482
|
setOpenMcp(openMcp === key ? void 0 : key);
|
|
423
483
|
};
|
|
424
|
-
const layoutLabel = detail === void 0 ? "" : detail.layout === "agent-plugin-v1" ? t("layoutV1") : detail.layout === "claude-code" ? t("layoutCC") : detail.layout === "codex" ? t("layoutCodex") : detail.layout === "remote" ? t("layoutRemote") : t("layoutSkills");
|
|
484
|
+
const layoutLabel = detail === void 0 ? "" : detail.layout === "agent-plugin-v1" ? t("layoutV1") : detail.layout === "claude-code" ? t("layoutCC") : detail.layout === "codex" ? t("layoutCodex") : detail.layout === "universal" ? t("layoutUniversal") : detail.layout === "cursor" ? t("layoutCursor") : detail.layout === "kimi" ? t("layoutKimi") : detail.layout === "remote" ? t("layoutRemote") : t("layoutSkills");
|
|
425
485
|
return (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
426
486
|
open: true,
|
|
427
487
|
onClose,
|
|
@@ -448,7 +508,7 @@ function SuiteDetailModal({ t, sourceId, suiteId, onClose }) {
|
|
|
448
508
|
}, (0, react.createElement)("span", { className: market_module_default.detailItemName }, skill.name), (0, react.createElement)("span", { className: market_module_default.detailItemDesc }, skill.description), (0, react.createElement)("span", { className: market_module_default.detailChevron }, openSkill === skill.name ? "▾" : "▸")), openSkill !== skill.name ? null : (0, react.createElement)("div", { className: market_module_default.skillContent }, skillLoading ? t("loading") : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, { text: skillText ?? "" }))))), (0, react.createElement)("section", { className: market_module_default.detailSection }, (0, react.createElement)("h4", { className: market_module_default.detailHead }, `${t("mcpSection")} (${detail.mcpServers.length})`), detail.mcpErrors.length === 0 ? null : (0, react.createElement)("div", {
|
|
449
509
|
className: market_module_default.warnLine,
|
|
450
510
|
style: { margin: "0 0 6px" }
|
|
451
|
-
}, `⚠ ${detail.mcpErrors.join("
|
|
511
|
+
}, `⚠ ${detail.mcpErrors.join(t("sourceErrorSeparator"))}`), detail.mcpServers.length === 0 ? (0, react.createElement)("div", { className: market_module_default.sidebarEmpty }, "—") : detail.mcpServers.map((server) => (0, react.createElement)("div", {
|
|
452
512
|
key: server.key,
|
|
453
513
|
className: market_module_default.detailItem
|
|
454
514
|
}, (0, react.createElement)("button", {
|
|
@@ -506,6 +566,87 @@ function PreviewRow(props) {
|
|
|
506
566
|
}, (0, react.createElement)("span", { className: market_module_default.detailItemName }, name), description === void 0 ? null : (0, react.createElement)("span", { className: market_module_default.detailItemDesc }, description), (0, react.createElement)("span", { className: market_module_default.detailChevron }, open ? "▾" : "▸")), open ? (0, react.createElement)("div", { className: market_module_default.skillContent }, children) : null);
|
|
507
567
|
}
|
|
508
568
|
//#endregion
|
|
569
|
+
//#region src/client/SearchFilterToolbar.module.css
|
|
570
|
+
var SearchFilterToolbar_module_default = {
|
|
571
|
+
"filter": "R7YLDa_filter",
|
|
572
|
+
"filterCount": "R7YLDa_filterCount",
|
|
573
|
+
"filterGap": "R7YLDa_filterGap",
|
|
574
|
+
"filterOn": "R7YLDa_filterOn",
|
|
575
|
+
"search": "R7YLDa_search",
|
|
576
|
+
"toolbar": "R7YLDa_toolbar",
|
|
577
|
+
"viewGap": "R7YLDa_viewGap",
|
|
578
|
+
"viewSwitch": "R7YLDa_viewSwitch"
|
|
579
|
+
};
|
|
580
|
+
//#endregion
|
|
581
|
+
//#region src/client/SearchFilterToolbar.tsx
|
|
582
|
+
/**
|
|
583
|
+
* Shared search, filter, and view controls for catalog-style settings panels.
|
|
584
|
+
*/
|
|
585
|
+
/**
|
|
586
|
+
* Render a consistent control row for searchable grid and list content.
|
|
587
|
+
*
|
|
588
|
+
* @param props - Search state, selectable filters, and view-mode state.
|
|
589
|
+
* @returns Search input, filter tabs, and an accessible grid/list toggle.
|
|
590
|
+
*/
|
|
591
|
+
function SearchFilterToolbar(props) {
|
|
592
|
+
const nextView = props.view === "grid" ? "list" : "grid";
|
|
593
|
+
const nextViewLabel = nextView === "grid" ? props.gridLabel : props.listLabel;
|
|
594
|
+
return (0, react.createElement)("div", { className: props.className === void 0 ? SearchFilterToolbar_module_default.toolbar : `${SearchFilterToolbar_module_default.toolbar} ${props.className}` }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
595
|
+
className: SearchFilterToolbar_module_default.search,
|
|
596
|
+
value: props.search,
|
|
597
|
+
placeholder: props.searchPlaceholder,
|
|
598
|
+
"aria-label": props.searchLabel,
|
|
599
|
+
onChange: (event) => props.onSearchChange(event.target.value)
|
|
600
|
+
}), (0, react.createElement)("div", { className: SearchFilterToolbar_module_default.filterGap }), ...props.filters.map((filter) => (0, react.createElement)("button", {
|
|
601
|
+
key: filter.id,
|
|
602
|
+
type: "button",
|
|
603
|
+
className: filter.active ? SearchFilterToolbar_module_default.filterOn : SearchFilterToolbar_module_default.filter,
|
|
604
|
+
title: `${filter.label} ${filter.count}`,
|
|
605
|
+
"aria-label": `${filter.label} ${filter.count}`,
|
|
606
|
+
onClick: filter.onSelect
|
|
607
|
+
}, filter.icon, (0, react.createElement)("span", { className: SearchFilterToolbar_module_default.filterCount }, filter.count))), (0, react.createElement)("div", { className: SearchFilterToolbar_module_default.viewGap }), (0, react.createElement)("button", {
|
|
608
|
+
type: "button",
|
|
609
|
+
className: SearchFilterToolbar_module_default.viewSwitch,
|
|
610
|
+
"aria-label": nextViewLabel,
|
|
611
|
+
title: nextViewLabel,
|
|
612
|
+
onClick: () => props.onViewChange(nextView)
|
|
613
|
+
}, (0, react.createElement)(ViewIcon, { mode: nextView })));
|
|
614
|
+
}
|
|
615
|
+
function ViewIcon({ mode }) {
|
|
616
|
+
const common = {
|
|
617
|
+
width: 16,
|
|
618
|
+
height: 16,
|
|
619
|
+
viewBox: "0 0 16 16",
|
|
620
|
+
fill: "none",
|
|
621
|
+
"aria-hidden": true
|
|
622
|
+
};
|
|
623
|
+
return mode === "list" ? (0, react.createElement)("svg", common, (0, react.createElement)("path", { d: "M3 4h10M3 8h10M3 12h10" })) : (0, react.createElement)("svg", common, (0, react.createElement)("rect", {
|
|
624
|
+
x: 2.5,
|
|
625
|
+
y: 2.5,
|
|
626
|
+
width: 4,
|
|
627
|
+
height: 4,
|
|
628
|
+
rx: .8
|
|
629
|
+
}), (0, react.createElement)("rect", {
|
|
630
|
+
x: 9.5,
|
|
631
|
+
y: 2.5,
|
|
632
|
+
width: 4,
|
|
633
|
+
height: 4,
|
|
634
|
+
rx: .8
|
|
635
|
+
}), (0, react.createElement)("rect", {
|
|
636
|
+
x: 2.5,
|
|
637
|
+
y: 9.5,
|
|
638
|
+
width: 4,
|
|
639
|
+
height: 4,
|
|
640
|
+
rx: .8
|
|
641
|
+
}), (0, react.createElement)("rect", {
|
|
642
|
+
x: 9.5,
|
|
643
|
+
y: 9.5,
|
|
644
|
+
width: 4,
|
|
645
|
+
height: 4,
|
|
646
|
+
rx: .8
|
|
647
|
+
}));
|
|
648
|
+
}
|
|
649
|
+
//#endregion
|
|
509
650
|
//#region src/client/MarketSection.tsx
|
|
510
651
|
/**
|
|
511
652
|
* The Agent Plugins Market settings section.
|
|
@@ -546,6 +687,10 @@ function startProgressPolling(report) {
|
|
|
546
687
|
function progressStepLabel(step) {
|
|
547
688
|
return PROGRESS_STEP_LABELS[step] ?? step;
|
|
548
689
|
}
|
|
690
|
+
/** Keep parameterized copy compatible with hosts whose bound translator ignores params. */
|
|
691
|
+
function interpolate(text, params) {
|
|
692
|
+
return text.replace(/\{(\w+)\}/g, (match, key) => key in params ? String(params[key]) : match);
|
|
693
|
+
}
|
|
549
694
|
const EMPTY_OVERVIEW = {
|
|
550
695
|
sources: [],
|
|
551
696
|
suites: [],
|
|
@@ -584,7 +729,7 @@ function loadOverview() {
|
|
|
584
729
|
function dropCachedOverview() {
|
|
585
730
|
cachedOverview = void 0;
|
|
586
731
|
}
|
|
587
|
-
function MarketSection({ t }) {
|
|
732
|
+
function MarketSection({ t, mode = "settings" }) {
|
|
588
733
|
const [overview, setOverview] = (0, react.useState)(() => loadOverview().initial);
|
|
589
734
|
const [loading, setLoading] = (0, react.useState)(() => cachedOverview === void 0);
|
|
590
735
|
const [search, setSearch] = (0, react.useState)("");
|
|
@@ -684,7 +829,7 @@ function MarketSection({ t }) {
|
|
|
684
829
|
const selectedSource = category === "all" ? void 0 : overview.sources.find((source) => source.id === category);
|
|
685
830
|
return (0, react.createElement)(ErrorBoundary, {
|
|
686
831
|
fallback: (error) => (0, react.createElement)("div", { className: market_module_default.empty }, `${t("actionFail")}: ${error.message}`),
|
|
687
|
-
children: (0, react.createElement)("div", { className: market_module_default.market
|
|
832
|
+
children: (0, react.createElement)("div", { className: mode === "page" ? `${market_module_default.market} ${market_module_default.pageMode}` : market_module_default.market }, (0, react.createElement)("header", { className: market_module_default.header }, (0, react.createElement)("div", { className: market_module_default.titleRow }, (0, react.createElement)("h2", { className: market_module_default.title }, t("nav")), (0, react.createElement)("div", { className: market_module_default.spacer }), (0, react.createElement)("div", { className: market_module_default.searchGroup }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
688
833
|
variant: "ghost",
|
|
689
834
|
size: "sm",
|
|
690
835
|
title: t("addSource"),
|
|
@@ -696,12 +841,7 @@ function MarketSection({ t }) {
|
|
|
696
841
|
onClick: () => {
|
|
697
842
|
action("s:refresh:all", "sources/refresh", {});
|
|
698
843
|
}
|
|
699
|
-
}, "↻"), (0, react.createElement)("div", { className: market_module_default.
|
|
700
|
-
className: market_module_default.searchInput,
|
|
701
|
-
placeholder: t("searchPh"),
|
|
702
|
-
value: search,
|
|
703
|
-
onChange: (event) => setSearch(event.target.value)
|
|
704
|
-
})))), (0, react.createElement)("div", { className: market_module_default.sourceTabsRow }, (0, react.createElement)("div", { className: market_module_default.sourceTabsScroll }, (0, react.createElement)(SourceTab, {
|
|
844
|
+
}, "↻"))), (0, react.createElement)("div", { className: market_module_default.marketControls }, (0, react.createElement)("div", { className: market_module_default.sourceTabsRow }, (0, react.createElement)("div", { className: market_module_default.sourceTabsScroll }, (0, react.createElement)(SourceTab, {
|
|
705
845
|
key: "__all__",
|
|
706
846
|
t,
|
|
707
847
|
active: category === "all",
|
|
@@ -721,26 +861,42 @@ function MarketSection({ t }) {
|
|
|
721
861
|
mode: "edit",
|
|
722
862
|
source
|
|
723
863
|
}) : void 0
|
|
724
|
-
})))), (0, react.createElement)(
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
864
|
+
})))), (0, react.createElement)(SearchFilterToolbar, {
|
|
865
|
+
search,
|
|
866
|
+
searchLabel: t("searchPh"),
|
|
867
|
+
searchPlaceholder: t("searchPh"),
|
|
868
|
+
onSearchChange: setSearch,
|
|
869
|
+
filters: [
|
|
870
|
+
{
|
|
871
|
+
id: "all",
|
|
872
|
+
label: t("tabAll"),
|
|
873
|
+
count: scopeTotals.all,
|
|
874
|
+
icon: (0, react.createElement)(StatusIcon, { kind: "all" }),
|
|
875
|
+
active: tab === "all",
|
|
876
|
+
onSelect: () => setTab("all")
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
id: "installed",
|
|
880
|
+
label: t("tabInstalled"),
|
|
881
|
+
count: scopeTotals.installed,
|
|
882
|
+
icon: (0, react.createElement)(StatusIcon, { kind: "installed" }),
|
|
883
|
+
active: tab === "installed",
|
|
884
|
+
onSelect: () => setTab("installed")
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
id: "uninstalled",
|
|
888
|
+
label: t("tabUninstalled"),
|
|
889
|
+
count: scopeTotals.all - scopeTotals.installed,
|
|
890
|
+
icon: (0, react.createElement)(StatusIcon, { kind: "uninstalled" }),
|
|
891
|
+
active: tab === "uninstalled",
|
|
892
|
+
onSelect: () => setTab("uninstalled")
|
|
893
|
+
}
|
|
894
|
+
],
|
|
895
|
+
view,
|
|
896
|
+
gridLabel: t("grid"),
|
|
897
|
+
listLabel: t("list"),
|
|
898
|
+
onViewChange: (nextView) => setView(nextView)
|
|
899
|
+
}))), (0, react.createElement)("main", { className: view === "grid" ? market_module_default.grid : market_module_default.list }, loading ? (0, react.createElement)("div", { className: market_module_default.empty }, t("loading")) : filtered.length === 0 ? (0, react.createElement)("div", { className: market_module_default.empty }, tab === "installed" ? t("installedEmpty") : t("empty")) : filtered.map((suite) => (0, react.createElement)(SuiteCard, {
|
|
744
900
|
key: `${suite.sourceId}/${suite.suiteId}`,
|
|
745
901
|
t,
|
|
746
902
|
suite,
|
|
@@ -776,7 +932,7 @@ function MarketSection({ t }) {
|
|
|
776
932
|
}), confirm === void 0 ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
777
933
|
open: true,
|
|
778
934
|
onClose: () => setConfirm(void 0),
|
|
779
|
-
title: confirm.kind === "uninstall" ? t("uninstallConfirmTitle") :
|
|
935
|
+
title: confirm.kind === "uninstall" ? t("uninstallConfirmTitle") : interpolate(t("removeSourceConfirmTitle", { sourceId: confirm.sourceId }), { sourceId: confirm.sourceId }),
|
|
780
936
|
closeLabel: t("cancel"),
|
|
781
937
|
description: confirm.kind === "uninstall" ? t("uninstallConfirmDesc") : t("removeSourceConfirmDesc"),
|
|
782
938
|
footer: (0, react.createElement)("div", { className: market_module_default.modalFooter }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
@@ -852,12 +1008,21 @@ function MarketSection({ t }) {
|
|
|
852
1008
|
}))
|
|
853
1009
|
});
|
|
854
1010
|
}
|
|
855
|
-
function
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
1011
|
+
function StatusIcon({ kind }) {
|
|
1012
|
+
const common = {
|
|
1013
|
+
width: 16,
|
|
1014
|
+
height: 16,
|
|
1015
|
+
viewBox: "0 0 16 16",
|
|
1016
|
+
fill: "none",
|
|
1017
|
+
"aria-hidden": true
|
|
1018
|
+
};
|
|
1019
|
+
if (kind === "installed") return (0, react.createElement)("svg", common, (0, react.createElement)("circle", {
|
|
1020
|
+
cx: 8,
|
|
1021
|
+
cy: 8,
|
|
1022
|
+
r: 5.5
|
|
1023
|
+
}), (0, react.createElement)("path", { d: "m5.5 8 1.7 1.7 3.4-3.4" }));
|
|
1024
|
+
if (kind === "uninstalled") return (0, react.createElement)("svg", common, (0, react.createElement)("path", { d: "M8 2v8m-3-3 3 3 3-3M3 13h10" }));
|
|
1025
|
+
return (0, react.createElement)("svg", common, (0, react.createElement)("path", { d: "M2.5 5 8 2.5 13.5 5 8 7.5 2.5 5Zm0 3L8 10.5 13.5 8M2.5 11 8 13.5 13.5 11" }));
|
|
861
1026
|
}
|
|
862
1027
|
/** A source tab with a trailing delete control (deletion confirms at the section level). */
|
|
863
1028
|
function SourceTab(props) {
|
|
@@ -996,21 +1161,460 @@ function SuiteCard(props) {
|
|
|
996
1161
|
key: label,
|
|
997
1162
|
className: market_module_default.tag
|
|
998
1163
|
}, `${label} ${count}`)), suite.errors.length === 0 ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
999
|
-
label: suite.errors.slice(0, 8).join("
|
|
1164
|
+
label: suite.errors.slice(0, 8).join(t("sourceErrorSeparator")),
|
|
1000
1165
|
children: (0, react.createElement)("span", { className: market_module_default.warnLine }, `⚠ ${t("errors")} ${suite.errors.length}`)
|
|
1001
1166
|
}), (suite.mcpErrors?.length ?? 0) === 0 ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
1002
|
-
label: suite.mcpErrors.slice(0, 8).join("
|
|
1167
|
+
label: suite.mcpErrors.slice(0, 8).join(t("sourceErrorSeparator")),
|
|
1003
1168
|
children: (0, react.createElement)("span", { className: market_module_default.warnLine }, `⚠ ${t("mcpSection")} ${suite.mcpErrors.length}`)
|
|
1004
1169
|
})));
|
|
1005
1170
|
}
|
|
1006
1171
|
//#endregion
|
|
1172
|
+
//#region src/client/mcp-status.module.css
|
|
1173
|
+
var mcp_status_module_default = {
|
|
1174
|
+
"boundary": "--KJaG_boundary",
|
|
1175
|
+
"card": "--KJaG_card",
|
|
1176
|
+
"cardReason": "--KJaG_cardReason",
|
|
1177
|
+
"cardTop": "--KJaG_cardTop",
|
|
1178
|
+
"chevron": "--KJaG_chevron",
|
|
1179
|
+
"config": "--KJaG_config",
|
|
1180
|
+
"detail": "--KJaG_detail",
|
|
1181
|
+
"detailBody": "--KJaG_detailBody",
|
|
1182
|
+
"detailDialog": "--KJaG_detailDialog",
|
|
1183
|
+
"detailEmpty": "--KJaG_detailEmpty",
|
|
1184
|
+
"detailHead": "--KJaG_detailHead",
|
|
1185
|
+
"detailMeta": "--KJaG_detailMeta",
|
|
1186
|
+
"detailSection": "--KJaG_detailSection",
|
|
1187
|
+
"detailState": "--KJaG_detailState",
|
|
1188
|
+
"detailStateconnected": "--KJaG_detailStateconnected",
|
|
1189
|
+
"detailStatedegraded": "--KJaG_detailStatedegraded",
|
|
1190
|
+
"detailStatedisabled": "--KJaG_detailStatedisabled",
|
|
1191
|
+
"detailStatefailed": "--KJaG_detailStatefailed",
|
|
1192
|
+
"empty": "--KJaG_empty",
|
|
1193
|
+
"endpoint": "--KJaG_endpoint",
|
|
1194
|
+
"error": "--KJaG_error",
|
|
1195
|
+
"errorSummary": "--KJaG_errorSummary",
|
|
1196
|
+
"grid": "--KJaG_grid",
|
|
1197
|
+
"header": "--KJaG_header",
|
|
1198
|
+
"headerActions": "--KJaG_headerActions",
|
|
1199
|
+
"list": "--KJaG_list",
|
|
1200
|
+
"meta": "--KJaG_meta",
|
|
1201
|
+
"modalFooter": "--KJaG_modalFooter",
|
|
1202
|
+
"name": "--KJaG_name",
|
|
1203
|
+
"reason": "--KJaG_reason",
|
|
1204
|
+
"service": "--KJaG_service",
|
|
1205
|
+
"sourceDirect": "--KJaG_sourceDirect",
|
|
1206
|
+
"sourcePlugin": "--KJaG_sourcePlugin",
|
|
1207
|
+
"state": "--KJaG_state",
|
|
1208
|
+
"stateconnected": "--KJaG_stateconnected",
|
|
1209
|
+
"statedegraded": "--KJaG_statedegraded",
|
|
1210
|
+
"statedisabled": "--KJaG_statedisabled",
|
|
1211
|
+
"statefailed": "--KJaG_statefailed",
|
|
1212
|
+
"statusconnected": "--KJaG_statusconnected",
|
|
1213
|
+
"statusdegraded": "--KJaG_statusdegraded",
|
|
1214
|
+
"statusdisabled": "--KJaG_statusdisabled",
|
|
1215
|
+
"statusDot": "--KJaG_statusDot",
|
|
1216
|
+
"statusfailed": "--KJaG_statusfailed",
|
|
1217
|
+
"subtitle": "--KJaG_subtitle",
|
|
1218
|
+
"summary": "--KJaG_summary",
|
|
1219
|
+
"summaryDotGreen": "--KJaG_summaryDotGreen",
|
|
1220
|
+
"summaryDotRed": "--KJaG_summaryDotRed",
|
|
1221
|
+
"surface": "--KJaG_surface",
|
|
1222
|
+
"title": "--KJaG_title",
|
|
1223
|
+
"tool": "--KJaG_tool",
|
|
1224
|
+
"toolbar": "--KJaG_toolbar",
|
|
1225
|
+
"toolCount": "--KJaG_toolCount",
|
|
1226
|
+
"toolDescription": "--KJaG_toolDescription",
|
|
1227
|
+
"toolIndex": "--KJaG_toolIndex",
|
|
1228
|
+
"toolList": "--KJaG_toolList",
|
|
1229
|
+
"toolName": "--KJaG_toolName",
|
|
1230
|
+
"transport": "--KJaG_transport"
|
|
1231
|
+
};
|
|
1232
|
+
//#endregion
|
|
1233
|
+
//#region src/client/McpStatusPanel.tsx
|
|
1234
|
+
const EMPTY_STATUS = {
|
|
1235
|
+
entries: [],
|
|
1236
|
+
observedAt: "",
|
|
1237
|
+
totals: {
|
|
1238
|
+
all: 0,
|
|
1239
|
+
connected: 0,
|
|
1240
|
+
degraded: 0,
|
|
1241
|
+
failed: 0,
|
|
1242
|
+
disabled: 0
|
|
1243
|
+
},
|
|
1244
|
+
directObservationOnly: true
|
|
1245
|
+
};
|
|
1246
|
+
/** DSH-native MCP inventory: click a service card for a standard Modal detail. */
|
|
1247
|
+
function McpStatusPanel({ t }) {
|
|
1248
|
+
const [payload, setPayload] = (0, react.useState)(EMPTY_STATUS);
|
|
1249
|
+
const [loading, setLoading] = (0, react.useState)(true);
|
|
1250
|
+
const [error, setError] = (0, react.useState)(void 0);
|
|
1251
|
+
const [filter, setFilter] = (0, react.useState)("all");
|
|
1252
|
+
const [search, setSearch] = (0, react.useState)("");
|
|
1253
|
+
const [view, setView] = (0, react.useState)("grid");
|
|
1254
|
+
const [selected, setSelected] = (0, react.useState)(void 0);
|
|
1255
|
+
const refresh = () => {
|
|
1256
|
+
setLoading(true);
|
|
1257
|
+
setError(void 0);
|
|
1258
|
+
fetchMcpStatus().then(setPayload).catch((caught) => {
|
|
1259
|
+
setError(caught instanceof Error ? caught.message : String(caught));
|
|
1260
|
+
}).finally(() => setLoading(false));
|
|
1261
|
+
};
|
|
1262
|
+
(0, react.useEffect)(() => {
|
|
1263
|
+
refresh();
|
|
1264
|
+
}, []);
|
|
1265
|
+
const activeEntries = payload.entries.filter((entry) => entry.state !== "disabled");
|
|
1266
|
+
const visibleTotals = {
|
|
1267
|
+
all: activeEntries.length,
|
|
1268
|
+
connected: activeEntries.filter((entry) => entry.state === "connected").length,
|
|
1269
|
+
failed: activeEntries.filter((entry) => entry.state === "failed").length
|
|
1270
|
+
};
|
|
1271
|
+
const filtered = (0, react.useMemo)(() => {
|
|
1272
|
+
const query = search.trim().toLowerCase();
|
|
1273
|
+
return activeEntries.filter((entry) => {
|
|
1274
|
+
if (filter !== "all" && entry.kind !== filter) return false;
|
|
1275
|
+
if (query === "") return true;
|
|
1276
|
+
return `${entry.name} ${entry.source ?? ""} ${entry.endpoint ?? ""} ${entry.transport}`.toLowerCase().includes(query);
|
|
1277
|
+
});
|
|
1278
|
+
}, [
|
|
1279
|
+
activeEntries,
|
|
1280
|
+
filter,
|
|
1281
|
+
search
|
|
1282
|
+
]);
|
|
1283
|
+
return (0, react.createElement)("div", { className: mcp_status_module_default.surface }, (0, react.createElement)("header", { className: mcp_status_module_default.header }, (0, react.createElement)("div", {}, (0, react.createElement)("h2", { className: mcp_status_module_default.title }, t("mcpStatusTitle"))), (0, react.createElement)("div", { className: mcp_status_module_default.headerActions }, visibleTotals.failed > 0 ? (0, react.createElement)("span", {
|
|
1284
|
+
className: mcp_status_module_default.errorSummary,
|
|
1285
|
+
title: `${visibleTotals.failed} ${t("mcpFailed")}`
|
|
1286
|
+
}, (0, react.createElement)("span", { className: mcp_status_module_default.summaryDotRed }), visibleTotals.failed) : null, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1287
|
+
variant: "ghost",
|
|
1288
|
+
size: "sm",
|
|
1289
|
+
onClick: refresh,
|
|
1290
|
+
disabled: loading,
|
|
1291
|
+
title: t("refresh")
|
|
1292
|
+
}, "↻"))), (0, react.createElement)(SearchFilterToolbar, {
|
|
1293
|
+
className: mcp_status_module_default.toolbar,
|
|
1294
|
+
search,
|
|
1295
|
+
searchLabel: t("mcpSearch"),
|
|
1296
|
+
searchPlaceholder: t("mcpSearch"),
|
|
1297
|
+
onSearchChange: setSearch,
|
|
1298
|
+
filters: [
|
|
1299
|
+
"all",
|
|
1300
|
+
"plugin",
|
|
1301
|
+
"direct"
|
|
1302
|
+
].map((kind) => ({
|
|
1303
|
+
id: kind,
|
|
1304
|
+
label: filterLabel(t, kind),
|
|
1305
|
+
count: kind === "all" ? visibleTotals.all : activeEntries.filter((entry) => entry.kind === kind).length,
|
|
1306
|
+
icon: (0, react.createElement)(McpFilterIcon, { kind }),
|
|
1307
|
+
active: filter === kind,
|
|
1308
|
+
onSelect: () => setFilter(kind)
|
|
1309
|
+
})),
|
|
1310
|
+
view,
|
|
1311
|
+
gridLabel: t("grid"),
|
|
1312
|
+
listLabel: t("list"),
|
|
1313
|
+
onViewChange: (nextView) => setView(nextView)
|
|
1314
|
+
}), error !== void 0 ? (0, react.createElement)("div", { className: mcp_status_module_default.error }, error, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1315
|
+
variant: "ghost",
|
|
1316
|
+
size: "sm",
|
|
1317
|
+
onClick: refresh
|
|
1318
|
+
}, t("mcpRetry"))) : loading && activeEntries.length === 0 ? (0, react.createElement)("div", { className: mcp_status_module_default.empty }, t("loading")) : filtered.length === 0 ? (0, react.createElement)("div", { className: mcp_status_module_default.empty }, t("mcpEmpty")) : (0, react.createElement)("div", { className: view === "grid" ? mcp_status_module_default.grid : mcp_status_module_default.list }, filtered.map((entry) => (0, react.createElement)(McpCard, {
|
|
1319
|
+
key: entry.id,
|
|
1320
|
+
entry,
|
|
1321
|
+
t,
|
|
1322
|
+
onClick: () => setSelected(entry)
|
|
1323
|
+
}))), selected === void 0 ? null : (0, react.createElement)(McpDetailModal, {
|
|
1324
|
+
entry: selected,
|
|
1325
|
+
t,
|
|
1326
|
+
onClose: () => setSelected(void 0)
|
|
1327
|
+
}));
|
|
1328
|
+
}
|
|
1329
|
+
function McpCard({ entry, t, onClick }) {
|
|
1330
|
+
return (0, react.createElement)("button", {
|
|
1331
|
+
type: "button",
|
|
1332
|
+
className: mcp_status_module_default.card,
|
|
1333
|
+
onClick
|
|
1334
|
+
}, (0, react.createElement)("div", { className: mcp_status_module_default.cardTop }, (0, react.createElement)("span", {
|
|
1335
|
+
className: `${mcp_status_module_default.statusDot} ${mcp_status_module_default[`status${entry.state}`]}`,
|
|
1336
|
+
title: stateLabel(t, entry.state),
|
|
1337
|
+
"aria-label": stateLabel(t, entry.state)
|
|
1338
|
+
}), (0, react.createElement)("span", { className: mcp_status_module_default.service }, (0, react.createElement)("span", { className: mcp_status_module_default.name }, entry.name)), (0, react.createElement)("span", { className: mcp_status_module_default.toolCount }, `${t("mcpTools")} ${entry.tools.length}`)), (0, react.createElement)("p", { className: mcp_status_module_default.endpoint }, entry.endpoint ?? t("mcpObservedEndpoint")), (0, react.createElement)("div", { className: mcp_status_module_default.meta }, (0, react.createElement)(McpSourceBadge, {
|
|
1339
|
+
kind: entry.kind,
|
|
1340
|
+
label: entry.kind === "plugin" ? entry.source ?? "—" : t("mcpDirect"),
|
|
1341
|
+
t
|
|
1342
|
+
}), (0, react.createElement)("span", { className: mcp_status_module_default.transport }, entry.transport)), entry.reason === void 0 ? null : (0, react.createElement)("p", { className: mcp_status_module_default.cardReason }, entry.reason));
|
|
1343
|
+
}
|
|
1344
|
+
function McpSourceBadge({ kind, label, t }) {
|
|
1345
|
+
return (0, react.createElement)("span", { className: kind === "plugin" ? mcp_status_module_default.sourcePlugin : mcp_status_module_default.sourceDirect }, (0, react.createElement)(McpSourceIcon, { kind }), (0, react.createElement)("span", {}, kind === "plugin" ? label : t("mcpDirect")));
|
|
1346
|
+
}
|
|
1347
|
+
function McpSourceIcon({ kind }) {
|
|
1348
|
+
const common = {
|
|
1349
|
+
width: 16,
|
|
1350
|
+
height: 16,
|
|
1351
|
+
viewBox: "0 0 16 16",
|
|
1352
|
+
fill: "none",
|
|
1353
|
+
"aria-hidden": true
|
|
1354
|
+
};
|
|
1355
|
+
return kind === "plugin" ? (0, react.createElement)("svg", common, (0, react.createElement)("path", { d: "M6 2.5v2H4A1.5 1.5 0 0 0 2.5 6v2h2a1.5 1.5 0 1 1 0 3h-2v2A1.5 1.5 0 0 0 4 14.5h2v-2a1.5 1.5 0 1 1 3 0v2h2a1.5 1.5 0 0 0 1.5-1.5v-2h-2a1.5 1.5 0 1 1 0-3h2V6A1.5 1.5 0 0 0 11 4.5H9v-2a1.5 1.5 0 1 0-3 0Z" })) : (0, react.createElement)("svg", common, (0, react.createElement)("circle", {
|
|
1356
|
+
cx: 8,
|
|
1357
|
+
cy: 5,
|
|
1358
|
+
r: 2.2
|
|
1359
|
+
}), (0, react.createElement)("path", { d: "M3.5 13c.6-2.2 2.1-3.3 4.5-3.3s3.9 1.1 4.5 3.3" }));
|
|
1360
|
+
}
|
|
1361
|
+
function McpFilterIcon({ kind }) {
|
|
1362
|
+
if (kind === "plugin") return (0, react.createElement)(McpSourceIcon, { kind: "plugin" });
|
|
1363
|
+
if (kind === "direct") return (0, react.createElement)(McpSourceIcon, { kind: "direct" });
|
|
1364
|
+
return (0, react.createElement)("svg", {
|
|
1365
|
+
width: 16,
|
|
1366
|
+
height: 16,
|
|
1367
|
+
viewBox: "0 0 16 16",
|
|
1368
|
+
fill: "none",
|
|
1369
|
+
"aria-hidden": true
|
|
1370
|
+
}, (0, react.createElement)("path", { d: "M2.5 5 8 2.5 13.5 5 8 7.5 2.5 5Zm0 3L8 10.5 13.5 8M2.5 11 8 13.5 13.5 11" }));
|
|
1371
|
+
}
|
|
1372
|
+
function McpDetailModal({ entry, t, onClose }) {
|
|
1373
|
+
return (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1374
|
+
open: true,
|
|
1375
|
+
onClose,
|
|
1376
|
+
title: entry.name,
|
|
1377
|
+
description: t("mcpServiceDetail"),
|
|
1378
|
+
closeLabel: t("cancel"),
|
|
1379
|
+
className: mcp_status_module_default.detailDialog,
|
|
1380
|
+
contentClassName: mcp_status_module_default.detailBody,
|
|
1381
|
+
footer: (0, react.createElement)("div", { className: mcp_status_module_default.modalFooter }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1382
|
+
variant: "ghost",
|
|
1383
|
+
onClick: onClose
|
|
1384
|
+
}, t("cancel"))),
|
|
1385
|
+
children: (0, react.createElement)("div", { className: mcp_status_module_default.detail }, (0, react.createElement)("div", { className: mcp_status_module_default.detailMeta }, (0, react.createElement)(McpSourceBadge, {
|
|
1386
|
+
kind: entry.kind,
|
|
1387
|
+
label: entry.kind === "plugin" ? entry.source ?? "—" : t("mcpDirect"),
|
|
1388
|
+
t
|
|
1389
|
+
}), (0, react.createElement)("span", { className: mcp_status_module_default.transport }, entry.transport), (0, react.createElement)("span", { className: `${mcp_status_module_default.state} ${mcp_status_module_default[`state${entry.state}`]}` }, stateLabel(t, entry.state))), entry.reason === void 0 ? null : (0, react.createElement)("div", { className: mcp_status_module_default.reason }, entry.reason), (0, react.createElement)("section", { className: mcp_status_module_default.detailSection }, (0, react.createElement)("h4", { className: mcp_status_module_default.detailHead }, t("mcpConfig")), entry.config === void 0 ? (0, react.createElement)("div", { className: mcp_status_module_default.detailEmpty }, t("mcpDirectConfigUnavailable")) : (0, react.createElement)("pre", { className: mcp_status_module_default.config }, JSON.stringify(entry.config, null, 2))), (0, react.createElement)("section", { className: mcp_status_module_default.detailSection }, (0, react.createElement)("h4", { className: mcp_status_module_default.detailHead }, `${t("mcpTools")} (${entry.tools.length})`), entry.tools.length === 0 ? (0, react.createElement)("div", { className: mcp_status_module_default.detailEmpty }, t("mcpNoTools")) : (0, react.createElement)("div", { className: mcp_status_module_default.toolList }, entry.tools.map((tool, index) => (0, react.createElement)("div", {
|
|
1390
|
+
key: tool.name,
|
|
1391
|
+
className: mcp_status_module_default.tool
|
|
1392
|
+
}, (0, react.createElement)("span", { className: mcp_status_module_default.toolIndex }, String(index + 1).padStart(2, "0")), (0, react.createElement)("span", { className: mcp_status_module_default.toolName }, tool.name), (0, react.createElement)("span", { className: mcp_status_module_default.toolDescription }, tool.description ?? ""))))))
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
function filterLabel(t, kind) {
|
|
1396
|
+
if (kind === "plugin") return t("mcpPlugin");
|
|
1397
|
+
if (kind === "direct") return t("mcpDirect");
|
|
1398
|
+
return t("mcpAll");
|
|
1399
|
+
}
|
|
1400
|
+
function stateLabel(t, state) {
|
|
1401
|
+
if (state === "connected") return t("mcpConnected");
|
|
1402
|
+
if (state === "degraded") return t("mcpDegraded");
|
|
1403
|
+
if (state === "failed") return t("mcpFailed");
|
|
1404
|
+
return t("mcpDisabled");
|
|
1405
|
+
}
|
|
1406
|
+
//#endregion
|
|
1407
|
+
//#region src/client/page-mode-selection.ts
|
|
1408
|
+
/** Pure capability decision for the legacy page-mode fallback. */
|
|
1409
|
+
/**
|
|
1410
|
+
* Use the DOM page fallback only when the host has no settings page and does
|
|
1411
|
+
* expose a page shell for the fallback to mount into.
|
|
1412
|
+
*
|
|
1413
|
+
* @param settingsSurfaceAvailable - whether `settings.section` is live.
|
|
1414
|
+
* @param pageShellAvailable - whether the sidebar/conversation shell exists.
|
|
1415
|
+
* @returns true when the fallback is the only available market surface.
|
|
1416
|
+
*/
|
|
1417
|
+
function shouldUseLegacyPageMode(settingsSurfaceAvailable, pageShellAvailable) {
|
|
1418
|
+
return !settingsSurfaceAvailable && pageShellAvailable;
|
|
1419
|
+
}
|
|
1420
|
+
//#endregion
|
|
1421
|
+
//#region src/client/page-mode.tsx
|
|
1422
|
+
/**
|
|
1423
|
+
* Legacy Web page-mode adapter.
|
|
1424
|
+
*
|
|
1425
|
+
* Current DSH compositions expose `settings.section`; older compositions that
|
|
1426
|
+
* predate that slot can still host a top-level market panel through the DOM
|
|
1427
|
+
* shell used by the original page-mode integration. The adapter is deliberately
|
|
1428
|
+
* guarded by the live settings-slot state so one composition never renders two
|
|
1429
|
+
* market surfaces.
|
|
1430
|
+
*/
|
|
1431
|
+
const ACTIVE_ATTRIBUTE = "data-dsh-agent-plugins-market-page";
|
|
1432
|
+
const VIEW_ATTRIBUTE = "data-dsh-agent-plugins-market-page-view";
|
|
1433
|
+
const ENTRY_ATTRIBUTE = "data-dsh-agent-plugins-market-entry";
|
|
1434
|
+
const SURFACE_EVENT = "dsh-agent-plugins-market-settings-surface";
|
|
1435
|
+
const PANEL_EVENT = "dsh-panel-activate";
|
|
1436
|
+
const PANEL_NAME = "agent-plugins-market";
|
|
1437
|
+
/** Notify the page adapter that the settings-slot capability changed. */
|
|
1438
|
+
const LEGACY_PAGE_MODE_SURFACE_EVENT = SURFACE_EVENT;
|
|
1439
|
+
const SIDEBAR_COLUMN_SELECTOR = "[data-pane=\"sidebar\"], [class*=\"sidebarCol\"]";
|
|
1440
|
+
const CONVERSATION_COLUMN_SELECTOR = "[data-pane=\"conversation\"], [class*=\"centerCol\"]";
|
|
1441
|
+
const SIDEBAR_CONTEXT_SELECTOR = "[class*=\"sessionRow\"], [class*=\"projectRow\"], [class*=\"searchResultRow\"], [class*=\"searchResultWorkspace\"], [class*=\"newSession\"]";
|
|
1442
|
+
/**
|
|
1443
|
+
* Mount the page-mode fallback and its sidebar entry.
|
|
1444
|
+
*
|
|
1445
|
+
* The fallback remains dormant when the settings surface is present. It also
|
|
1446
|
+
* remains a no-op in non-browser runtimes or shells that expose neither the
|
|
1447
|
+
* sidebar nor the conversation column.
|
|
1448
|
+
*
|
|
1449
|
+
* @param options - page-mode dependencies and host capability probe.
|
|
1450
|
+
* @returns disposer that removes the injected entry, panel, listeners, and
|
|
1451
|
+
* active document marker.
|
|
1452
|
+
*/
|
|
1453
|
+
function mountLegacyPageMode(options) {
|
|
1454
|
+
if (typeof document === "undefined" || typeof MutationObserver === "undefined") return () => {};
|
|
1455
|
+
let stopped = false;
|
|
1456
|
+
let open = false;
|
|
1457
|
+
let root;
|
|
1458
|
+
let container;
|
|
1459
|
+
let entry;
|
|
1460
|
+
let entryLabel;
|
|
1461
|
+
let observer;
|
|
1462
|
+
const setActive = (next) => {
|
|
1463
|
+
open = next;
|
|
1464
|
+
if (open && !options.isSettingsSurfaceAvailable()) {
|
|
1465
|
+
document.documentElement.setAttribute(ACTIVE_ATTRIBUTE, "");
|
|
1466
|
+
document.dispatchEvent(new CustomEvent(PANEL_EVENT, { detail: PANEL_NAME }));
|
|
1467
|
+
} else document.documentElement.removeAttribute(ACTIVE_ATTRIBUTE);
|
|
1468
|
+
};
|
|
1469
|
+
const removeView = () => {
|
|
1470
|
+
setActive(false);
|
|
1471
|
+
root?.unmount();
|
|
1472
|
+
root = void 0;
|
|
1473
|
+
container?.remove();
|
|
1474
|
+
container = void 0;
|
|
1475
|
+
};
|
|
1476
|
+
const renderView = () => {
|
|
1477
|
+
if (root === void 0) return;
|
|
1478
|
+
root.render((0, react.createElement)(MarketSection, {
|
|
1479
|
+
t: options.t,
|
|
1480
|
+
mode: "page"
|
|
1481
|
+
}));
|
|
1482
|
+
};
|
|
1483
|
+
const updateEntryCopy = () => {
|
|
1484
|
+
if (entryLabel === void 0 || entry === void 0) return;
|
|
1485
|
+
const label = options.t("nav");
|
|
1486
|
+
entryLabel.textContent = label;
|
|
1487
|
+
entry.title = label;
|
|
1488
|
+
entry.setAttribute("aria-label", label);
|
|
1489
|
+
};
|
|
1490
|
+
const ensureView = () => {
|
|
1491
|
+
if (stopped || options.isSettingsSurfaceAvailable()) {
|
|
1492
|
+
removeView();
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
const column = conversationColumn();
|
|
1496
|
+
if (!shouldUseLegacyPageMode(options.isSettingsSurfaceAvailable(), column !== void 0)) {
|
|
1497
|
+
removeView();
|
|
1498
|
+
return;
|
|
1499
|
+
}
|
|
1500
|
+
if (column === void 0) return;
|
|
1501
|
+
if (container !== void 0 && container.isConnected) return;
|
|
1502
|
+
root?.unmount();
|
|
1503
|
+
container?.remove();
|
|
1504
|
+
container = document.createElement("div");
|
|
1505
|
+
container.setAttribute(VIEW_ATTRIBUTE, "");
|
|
1506
|
+
container.className = market_module_default.pageView;
|
|
1507
|
+
column.appendChild(container);
|
|
1508
|
+
root = (0, react_dom_client.createRoot)(container);
|
|
1509
|
+
renderView();
|
|
1510
|
+
};
|
|
1511
|
+
const ensureEntry = () => {
|
|
1512
|
+
if (stopped || options.isSettingsSurfaceAvailable()) {
|
|
1513
|
+
entry?.remove();
|
|
1514
|
+
return;
|
|
1515
|
+
}
|
|
1516
|
+
const rootElement = sidebarRoot();
|
|
1517
|
+
const anchor = rootElement === void 0 ? void 0 : newSessionButton(rootElement);
|
|
1518
|
+
if (rootElement === void 0 || anchor === void 0 || anchor.parentElement === null) return;
|
|
1519
|
+
if (entry === void 0) {
|
|
1520
|
+
entry = createEntry(() => {
|
|
1521
|
+
setActive(!open);
|
|
1522
|
+
ensureView();
|
|
1523
|
+
});
|
|
1524
|
+
entryLabel = entry.querySelector("[data-dsh-agent-plugins-market-label]") ?? void 0;
|
|
1525
|
+
updateEntryCopy();
|
|
1526
|
+
}
|
|
1527
|
+
if (entry.parentElement !== anchor.parentElement || entry.previousSibling !== anchor) anchor.insertAdjacentElement("afterend", entry);
|
|
1528
|
+
};
|
|
1529
|
+
const observeShell = () => {
|
|
1530
|
+
if (stopped || observer !== void 0 || options.isSettingsSurfaceAvailable()) return;
|
|
1531
|
+
observer = new MutationObserver(ensure);
|
|
1532
|
+
observer.observe(document.body ?? document.documentElement, {
|
|
1533
|
+
childList: true,
|
|
1534
|
+
subtree: true
|
|
1535
|
+
});
|
|
1536
|
+
};
|
|
1537
|
+
const stopObservingShell = () => {
|
|
1538
|
+
observer?.disconnect();
|
|
1539
|
+
observer = void 0;
|
|
1540
|
+
};
|
|
1541
|
+
const ensure = () => {
|
|
1542
|
+
if (stopped) return;
|
|
1543
|
+
if (options.isSettingsSurfaceAvailable()) {
|
|
1544
|
+
stopObservingShell();
|
|
1545
|
+
removeView();
|
|
1546
|
+
entry?.remove();
|
|
1547
|
+
return;
|
|
1548
|
+
}
|
|
1549
|
+
observeShell();
|
|
1550
|
+
ensureView();
|
|
1551
|
+
ensureEntry();
|
|
1552
|
+
};
|
|
1553
|
+
const onLocale = () => {
|
|
1554
|
+
updateEntryCopy();
|
|
1555
|
+
renderView();
|
|
1556
|
+
};
|
|
1557
|
+
const onSurfaceChange = () => {
|
|
1558
|
+
ensure();
|
|
1559
|
+
};
|
|
1560
|
+
const unsubscribeLocale = options.subscribeLocale?.(onLocale);
|
|
1561
|
+
const onPanelActivate = (event) => {
|
|
1562
|
+
if (event.detail !== PANEL_NAME && open) setActive(false);
|
|
1563
|
+
};
|
|
1564
|
+
const onSidebarContextClick = (event) => {
|
|
1565
|
+
if (!open) return;
|
|
1566
|
+
const target = event.target;
|
|
1567
|
+
if (!(target instanceof HTMLElement) || target.closest(SIDEBAR_CONTEXT_SELECTOR) === null) return;
|
|
1568
|
+
setActive(false);
|
|
1569
|
+
};
|
|
1570
|
+
document.addEventListener(PANEL_EVENT, onPanelActivate);
|
|
1571
|
+
document.addEventListener(SURFACE_EVENT, onSurfaceChange);
|
|
1572
|
+
document.addEventListener("click", onSidebarContextClick, true);
|
|
1573
|
+
queueMicrotask(ensure);
|
|
1574
|
+
return () => {
|
|
1575
|
+
stopped = true;
|
|
1576
|
+
unsubscribeLocale?.();
|
|
1577
|
+
document.removeEventListener(PANEL_EVENT, onPanelActivate);
|
|
1578
|
+
document.removeEventListener(SURFACE_EVENT, onSurfaceChange);
|
|
1579
|
+
document.removeEventListener("click", onSidebarContextClick, true);
|
|
1580
|
+
stopObservingShell();
|
|
1581
|
+
entry?.remove();
|
|
1582
|
+
removeView();
|
|
1583
|
+
};
|
|
1584
|
+
}
|
|
1585
|
+
function sidebarRoot() {
|
|
1586
|
+
const column = document.querySelector(SIDEBAR_COLUMN_SELECTOR);
|
|
1587
|
+
if (column === null) return void 0;
|
|
1588
|
+
return column.querySelector("[class*=\"logoRow\"]")?.parentElement ?? column.firstElementChild ?? void 0;
|
|
1589
|
+
}
|
|
1590
|
+
function newSessionButton(root) {
|
|
1591
|
+
const nested = root.querySelector("button[class*=\"newSession\"]");
|
|
1592
|
+
if (nested !== null) return nested;
|
|
1593
|
+
for (const child of root.children) if (child instanceof HTMLButtonElement) return child;
|
|
1594
|
+
}
|
|
1595
|
+
function conversationColumn() {
|
|
1596
|
+
return document.querySelector(CONVERSATION_COLUMN_SELECTOR) ?? void 0;
|
|
1597
|
+
}
|
|
1598
|
+
function createEntry(onClick) {
|
|
1599
|
+
const button = document.createElement("button");
|
|
1600
|
+
button.type = "button";
|
|
1601
|
+
button.setAttribute(ENTRY_ATTRIBUTE, "");
|
|
1602
|
+
button.className = market_module_default.pageEntry;
|
|
1603
|
+
button.innerHTML = "<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2\" y=\"2\" width=\"5\" height=\"5\" rx=\"1\"/><rect x=\"9\" y=\"2\" width=\"5\" height=\"5\" rx=\"1\"/><rect x=\"2\" y=\"9\" width=\"5\" height=\"5\" rx=\"1\"/><rect x=\"9\" y=\"9\" width=\"5\" height=\"5\" rx=\"1\"/></svg>";
|
|
1604
|
+
const label = document.createElement("span");
|
|
1605
|
+
label.dataset.dshAgentPluginsMarketLabel = "";
|
|
1606
|
+
button.append(label);
|
|
1607
|
+
button.addEventListener("click", onClick);
|
|
1608
|
+
return button;
|
|
1609
|
+
}
|
|
1610
|
+
//#endregion
|
|
1007
1611
|
//#region src/client/index.ts
|
|
1008
1612
|
/**
|
|
1009
1613
|
* dsh-agent-plugins-market client: registers the Agent Plugins Market section inside the Web
|
|
1010
|
-
* GUI's settings
|
|
1011
|
-
*
|
|
1012
|
-
*
|
|
1013
|
-
* packages the host does not serve.
|
|
1614
|
+
* GUI's settings page (the same settings.section seat dshmarket uses), with a
|
|
1615
|
+
* guarded legacy top-level page fallback for older shells. The bundle's
|
|
1616
|
+
* browser externals are React, ReactDOM, and the injected `dsh.client.inject`
|
|
1617
|
+
* module table, so it cannot reach packages the host does not serve.
|
|
1014
1618
|
*/
|
|
1015
1619
|
const NS = "dsh-agent-plugins-market";
|
|
1016
1620
|
const name = "dsh-agent-plugins-market";
|
|
@@ -1038,14 +1642,44 @@ function apply(ctx) {
|
|
|
1038
1642
|
console.warn(`[dsh-agent-plugins-market] host ui-primitives missing ${gaps.join(", ")} — Agent Plugins Market section disabled (dsh web >= 0.1.0-rc.6 required)`);
|
|
1039
1643
|
return;
|
|
1040
1644
|
}
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1645
|
+
let settingsSurfaceAvailable = false;
|
|
1646
|
+
ctx.effect(() => mountLegacyPageMode({
|
|
1647
|
+
t,
|
|
1648
|
+
isSettingsSurfaceAvailable: () => settingsSurfaceAvailable,
|
|
1649
|
+
subscribeLocale: ctx.locale.subscribe === void 0 ? void 0 : (listener) => ctx.locale.subscribe(listener)
|
|
1650
|
+
}), "dsh-agent-plugins-market: legacy page mode");
|
|
1651
|
+
ctx.slots.inject("settings.section", () => {
|
|
1652
|
+
settingsSurfaceAvailable = true;
|
|
1653
|
+
notifyPageModeSurfaceChange();
|
|
1654
|
+
const marketDispose = ctx.slots.register({
|
|
1655
|
+
name: "settings.section",
|
|
1656
|
+
id: "agent-plugin",
|
|
1657
|
+
order: 45,
|
|
1658
|
+
label: () => t("nav"),
|
|
1659
|
+
locale: NS,
|
|
1660
|
+
inject: () => ({ t })
|
|
1661
|
+
}, () => (0, react.createElement)(MarketSection, {
|
|
1662
|
+
t,
|
|
1663
|
+
mode: "settings"
|
|
1664
|
+
}));
|
|
1665
|
+
const mcpDispose = ctx.slots.register({
|
|
1666
|
+
name: "settings.section",
|
|
1667
|
+
id: "mcp-status",
|
|
1668
|
+
order: 46,
|
|
1669
|
+
label: () => t("mcpStatusNav"),
|
|
1670
|
+
locale: NS,
|
|
1671
|
+
inject: () => ({ t })
|
|
1672
|
+
}, () => (0, react.createElement)(McpStatusPanel, { t }));
|
|
1673
|
+
return () => {
|
|
1674
|
+
settingsSurfaceAvailable = false;
|
|
1675
|
+
notifyPageModeSurfaceChange();
|
|
1676
|
+
if (typeof mcpDispose === "function") mcpDispose();
|
|
1677
|
+
if (typeof marketDispose === "function") marketDispose();
|
|
1678
|
+
};
|
|
1679
|
+
});
|
|
1680
|
+
}
|
|
1681
|
+
function notifyPageModeSurfaceChange() {
|
|
1682
|
+
if (typeof document !== "undefined") document.dispatchEvent(new Event(LEGACY_PAGE_MODE_SURFACE_EVENT));
|
|
1049
1683
|
}
|
|
1050
1684
|
//#endregion
|
|
1051
1685
|
exports.REQUIRED_PRIMITIVES = REQUIRED_PRIMITIVES;
|