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/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(";")}`), detail.mcpServers.length === 0 ? (0, react.createElement)("div", { className: market_module_default.sidebarEmpty }, "—") : detail.mcpServers.map((server) => (0, react.createElement)("div", {
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 }, (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)("p", { className: market_module_default.sub }, t("subtitle")), (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, {
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.searchWrap }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Input, {
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)("div", { className: market_module_default.tabRow }, (0, react.createElement)(TabButton, {
725
- t,
726
- active: tab === "all",
727
- label: `${t("tabAll")} ${scopeTotals.all}`,
728
- onClick: () => setTab("all")
729
- }), (0, react.createElement)(TabButton, {
730
- t,
731
- active: tab === "installed",
732
- label: `${t("tabInstalled")} ${scopeTotals.installed}`,
733
- onClick: () => setTab("installed")
734
- }), (0, react.createElement)(TabButton, {
735
- t,
736
- active: tab === "uninstalled",
737
- label: `${t("tabUninstalled")} ${scopeTotals.all - scopeTotals.installed}`,
738
- onClick: () => setTab("uninstalled")
739
- }), (0, react.createElement)("div", { className: market_module_default.tabGap }), (0, react.createElement)("button", {
740
- type: "button",
741
- className: market_module_default.viewSwitch,
742
- onClick: () => setView(view === "grid" ? "list" : "grid")
743
- }, view === "grid" ? t("list") : t("grid")))), (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 }, "…") : 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, {
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") : `${t("removeSourceConfirmTitle")}「${confirm.sourceId}」`,
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 TabButton({ t: _t, active, label, onClick }) {
856
- return (0, react.createElement)("button", {
857
- type: "button",
858
- className: active ? market_module_default.tabOn : market_module_default.tab,
859
- onClick
860
- }, label);
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 dialog (the same settings.section seat dshmarket uses).
1011
- * Mirrors the market's integration contract: the bundle's only externals are
1012
- * react and the injected `dsh.client.inject` module table, so it cannot reach
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
- ctx.slots.inject("settings.section", () => ctx.slots.register({
1042
- name: "settings.section",
1043
- id: "agent-plugin",
1044
- order: 45,
1045
- label: () => t("nav"),
1046
- locale: NS,
1047
- inject: () => ({ t })
1048
- }, () => (0, react.createElement)(MarketSection, { t })));
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;