dsh-agent-plugins-market 0.4.6 → 0.5.1
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 +19 -11
- package/README.zh.md +19 -11
- package/client/client.js +850 -434
- package/client/client.js.map +1 -1
- package/lib/application/catalog.js +544 -0
- package/lib/application/details.js +139 -0
- package/lib/application/queries.js +1 -0
- package/lib/{discovery → catalog}/manifests.js +20 -12
- package/lib/catalog/native-project.js +73 -0
- package/lib/{paths.js → catalog/paths.js} +5 -1
- package/lib/{skills-parse.js → catalog/skills-parse.js} +7 -4
- package/lib/catalog/source-catalog.js +47 -0
- package/lib/{discovery.js → catalog/suite-scanner.js} +28 -86
- package/lib/{discovery → catalog}/surfaces.js +9 -11
- package/lib/{validate.js → catalog/validate.js} +3 -3
- package/lib/context.js +21 -23
- package/lib/contracts/market.js +30 -0
- package/lib/contracts/mcp-status.js +2 -0
- package/lib/index.js +42 -49
- package/lib/{state.js → model/state.js} +19 -1
- package/lib/model/types.js +21 -0
- package/lib/routes.js +58 -21
- package/lib/{commands-mounts.js → runtime/commands-mounts.js} +23 -15
- package/lib/{hooks-mounts.js → runtime/hooks-mounts.js} +4 -3
- package/lib/runtime/host-locale.js +67 -0
- package/lib/{mcp-config.js → runtime/mcp-config.js} +18 -8
- package/lib/{mcp-mounts.js → runtime/mcp-mounts.js} +16 -12
- package/lib/runtime/mcp-overrides.js +113 -0
- package/lib/{mcp-status.js → runtime/mcp-status.js} +13 -42
- package/lib/runtime/reconciler.js +51 -0
- package/lib/{skills-provider.js → runtime/skills-provider.js} +47 -35
- package/lib/runtime/tool-registry-observer.js +35 -0
- package/lib/types/application/catalog.d.ts +141 -0
- package/lib/types/application/details.d.ts +12 -0
- package/lib/types/application/queries.d.ts +37 -0
- package/lib/types/{discovery → catalog}/manifests.d.ts +1 -1
- package/lib/types/catalog/native-project.d.ts +17 -0
- package/lib/types/catalog/source-catalog.d.ts +3 -0
- package/lib/types/catalog/suite-scanner.d.ts +9 -0
- package/lib/types/{discovery → catalog}/surfaces.d.ts +1 -1
- package/lib/types/{validate.d.ts → catalog/validate.d.ts} +1 -1
- package/lib/types/context.d.ts +3 -2
- package/lib/types/contracts/market.d.ts +179 -0
- package/lib/types/contracts/mcp-status.d.ts +38 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/{state.d.ts → model/state.d.ts} +1 -1
- package/lib/types/{types.d.ts → model/types.d.ts} +15 -43
- package/lib/types/routes.d.ts +2 -2
- package/lib/types/{commands-mounts.d.ts → runtime/commands-mounts.d.ts} +5 -3
- package/lib/types/{hooks-mounts.d.ts → runtime/hooks-mounts.d.ts} +1 -1
- package/lib/types/runtime/host-locale.d.ts +13 -0
- package/lib/types/{mcp-config.d.ts → runtime/mcp-config.d.ts} +6 -2
- package/lib/types/{mcp-mounts.d.ts → runtime/mcp-mounts.d.ts} +7 -2
- package/lib/types/runtime/mcp-overrides.d.ts +37 -0
- package/lib/types/runtime/mcp-status.d.ts +14 -0
- package/lib/types/runtime/reconciler.d.ts +36 -0
- package/lib/types/{skills-provider.d.ts → runtime/skills-provider.d.ts} +5 -3
- package/lib/types/runtime/tool-registry-observer.d.ts +14 -0
- package/package.json +34 -19
- package/schemas/README.md +2 -5
- package/lib/manager.js +0 -581
- package/lib/types/discovery.d.ts +0 -19
- package/lib/types/manager.d.ts +0 -124
- package/lib/types/mcp-status.d.ts +0 -51
- package/lib/types.js +0 -10
- /package/lib/{git.js → catalog/git.js} +0 -0
- /package/lib/types/{git.d.ts → catalog/git.d.ts} +0 -0
- /package/lib/types/{paths.d.ts → catalog/paths.d.ts} +0 -0
- /package/lib/types/{skills-parse.d.ts → catalog/skills-parse.d.ts} +0 -0
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: 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);}})();
|
|
5
|
+
(function(){if(typeof document!=="undefined"){var s=document.createElement("style");s.setAttribute("data-dsh-client","dsh-agent-plugins-market");s.textContent="._72qoAq_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._72qoAq_pageMode {\n width: 100%;\n min-width: 0;\n}\n\n._72qoAq_marketControls {\n flex-direction: column;\n gap: 8px;\n min-height: 0;\n display: flex;\n}\n\n._72qoAq_mcpSurface {\n flex: 1;\n min-height: 0;\n display: flex;\n}\n\n._72qoAq_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._72qoAq_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._72qoAq_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] ._72qoAq_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._72qoAq_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._72qoAq_pageEntry:hover {\n background: var(--dsw-alias-bg-hover, #0000000d);\n}\n\n._72qoAq_pageEntry:active {\n background: var(--dsw-alias-bg-active, #00000014);\n}\n\n._72qoAq_pageEntry svg {\n color: var(--dsw-alias-label-secondary, #6b7280);\n flex-shrink: 0;\n}\n\n._72qoAq_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] ._72qoAq_pageEntry {\n justify-content: center;\n padding-inline: 0;\n}\n\n[data-dsh-frame][data-sidebar-collapsed] ._72qoAq_pageEntry span {\n display: none;\n}\n\n._72qoAq_pageEntry:focus-visible, ._72qoAq_srcTabMain:focus-visible, ._72qoAq_srcTabEdit:focus-visible, ._72qoAq_srcTabDel:focus-visible, ._72qoAq_seg:focus-visible, ._72qoAq_segOn:focus-visible, ._72qoAq_detailItemRow:focus-visible, ._72qoAq_detailItemOpen:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4f6ef7);\n outline-offset: 2px;\n}\n\n._72qoAq_header {\n flex-direction: column;\n flex-shrink: 0;\n gap: 8px;\n display: flex;\n}\n\n._72qoAq_titleRow {\n align-items: center;\n gap: 8px;\n display: flex;\n}\n\n._72qoAq_title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n line-height: 24px;\n}\n\n._72qoAq_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._72qoAq_spacer {\n flex: 1;\n}\n\n._72qoAq_searchGroup {\n align-items: center;\n gap: 2px;\n display: flex;\n}\n\n._72qoAq_body {\n flex: 1;\n align-items: flex-start;\n gap: 20px;\n min-height: 0;\n display: flex;\n}\n\n._72qoAq_sourceTabsRow {\n padding: 0;\n display: block;\n}\n\n._72qoAq_sourceTabsScroll {\n grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));\n gap: 4px;\n display: grid;\n}\n\n._72qoAq_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._72qoAq_srcTabEdit:hover {\n color: var(--dsw-alias-label-primary, #1f2328);\n}\n\n._72qoAq_srcTabOn ._72qoAq_srcTabEdit, ._72qoAq_srcTabOn ._72qoAq_srcTabEdit:hover {\n color: var(--dsw-alias-label-primary-foreground, #fff);\n}\n\n._72qoAq_srcTab, ._72qoAq_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._72qoAq_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._72qoAq_srcTabMain:hover {\n color: var(--dsw-alias-brand-primary, #4f6ef7);\n}\n\n._72qoAq_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._72qoAq_srcTabOn ._72qoAq_srcTabMain {\n color: var(--dsw-alias-label-primary-foreground, #fff);\n font-weight: 600;\n}\n\n._72qoAq_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._72qoAq_srcTabDel:hover {\n color: var(--dsw-alias-state-error-primary, #dc2626);\n}\n\n._72qoAq_srcTabOn ._72qoAq_srcTabDel, ._72qoAq_srcTabOn ._72qoAq_srcTabDel:hover {\n color: var(--dsw-alias-label-primary-foreground, #fff);\n}\n\n._72qoAq_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._72qoAq_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._72qoAq_list ._72qoAq_card {\n flex-flow: wrap;\n align-items: center;\n gap: 8px 14px;\n}\n\n._72qoAq_list ._72qoAq_cardTop {\n flex: none;\n}\n\n._72qoAq_list ._72qoAq_cardDesc {\n -webkit-line-clamp: 1;\n flex: 1;\n min-width: 200px;\n min-height: 0;\n}\n\n._72qoAq_list ._72qoAq_cardActions {\n flex: none;\n}\n\n._72qoAq_list ._72qoAq_meta {\n flex-basis: 100%;\n}\n\n._72qoAq_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._72qoAq_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._72qoAq_cardTop {\n align-items: center;\n gap: 8px;\n display: flex;\n}\n\n._72qoAq_cardTitle {\n flex: 1;\n align-items: center;\n gap: 8px;\n min-width: 0;\n display: flex;\n}\n\n._72qoAq_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._72qoAq_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._72qoAq_cardActions {\n flex-shrink: 0;\n align-items: center;\n gap: 4px;\n display: flex;\n}\n\n._72qoAq_switchOn, ._72qoAq_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._72qoAq_switchOn {\n background: var(--dsw-alias-state-success-primary, #22c55e);\n}\n\n._72qoAq_switchOff {\n background: var(--dsw-alias-state-neutral, #d1d5db);\n}\n\n._72qoAq_switchOn:disabled, ._72qoAq_switchOff:disabled {\n opacity: .6;\n cursor: default;\n}\n\n._72qoAq_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._72qoAq_switchOn ._72qoAq_switchThumb {\n left: 19px;\n}\n\n._72qoAq_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._72qoAq_meta {\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n display: flex;\n}\n\n._72qoAq_src {\n color: var(--dsw-alias-label-secondary, #9ca3af);\n font-size: 12px;\n text-decoration: none;\n}\n\n._72qoAq_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._72qoAq_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._72qoAq_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._72qoAq_modalFooter {\n justify-content: flex-end;\n gap: 8px;\n width: 100%;\n display: flex;\n}\n\n._72qoAq_modalFooterLeft {\n gap: 8px;\n margin-right: auto;\n display: flex;\n}\n\n._72qoAq_editorDialog {\n width: min(500px, 92vw);\n}\n\n._72qoAq_installConfirmBody {\n flex-direction: column;\n gap: 10px;\n min-width: 0;\n display: flex;\n}\n\n._72qoAq_installConfirmSuite {\n color: var(--dsw-alias-label-primary, #111827);\n font-weight: 600;\n}\n\n._72qoAq_installConfirmMeta {\n color: var(--dsw-alias-label-secondary, #4b5563);\n font-size: 12px;\n}\n\n._72qoAq_installConfirmTags {\n flex-wrap: wrap;\n gap: 6px;\n display: flex;\n}\n\n._72qoAq_installConfirmWarn {\n color: var(--dsw-alias-danger, #b45309);\n border: 1px solid var(--dsw-alias-danger, #b45309);\n border-radius: 8px;\n padding: 8px 10px;\n font-size: 12px;\n}\n\n._72qoAq_editorForm {\n flex-direction: column;\n gap: 14px;\n min-width: 0;\n display: flex;\n}\n\n._72qoAq_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._72qoAq_seg, ._72qoAq_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._72qoAq_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._72qoAq_fieldGroup {\n flex-direction: column;\n gap: 5px;\n display: flex;\n}\n\n._72qoAq_fieldLabel {\n color: var(--dsw-alias-label-secondary, #6b7280);\n font-size: 12px;\n font-weight: 600;\n}\n\n._72qoAq_fieldHint {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n font-size: 12px;\n line-height: 16px;\n}\n\n._72qoAq_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._72qoAq_staticIdValue {\n color: var(--dsw-alias-label-primary, #1f2328);\n font-size: 13px;\n font-weight: 600;\n}\n\n._72qoAq_detailDialog {\n width: min(800px, 94vw);\n}\n\n._72qoAq_detailBody {\n flex-direction: column;\n gap: 14px;\n max-height: 78vh;\n display: flex;\n overflow-y: auto;\n}\n\n._72qoAq_detailSections {\n flex-direction: column;\n gap: 14px;\n display: flex;\n}\n\n._72qoAq_detailSection {\n flex-direction: column;\n gap: 6px;\n display: flex;\n}\n\n._72qoAq_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._72qoAq_detailGrid {\n grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\n gap: 6px 14px;\n display: grid;\n}\n\n._72qoAq_detailCell {\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n display: flex;\n}\n\n._72qoAq_detailKey {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n font-size: 12px;\n}\n\n._72qoAq_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._72qoAq_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._72qoAq_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._72qoAq_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._72qoAq_detailItemRow, ._72qoAq_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._72qoAq_detailItemRow:hover {\n background: var(--dsw-alias-bg-hover, #0000000d);\n}\n\n._72qoAq_detailItemOpen {\n background: var(--dsw-alias-bg-selected, #4f6ef714);\n}\n\n._72qoAq_detailItemName {\n flex-shrink: 0;\n font-size: 13px;\n font-weight: 600;\n}\n\n._72qoAq_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._72qoAq_detailChevron {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n flex-shrink: 0;\n}\n\n._72qoAq_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._72qoAq_progress, ._72qoAq_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._72qoAq_progressError {\n border-color: var(--dsw-alias-danger, #e5484d);\n color: var(--dsw-alias-danger, #e5484d);\n}\n\n._72qoAq_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 _72qoAq_dshApmSpin;\n}\n\n@keyframes _72qoAq_dshApmSpin {\n to {\n transform: rotate(360deg);\n }\n}\n\n._72qoAq_progressFail {\n flex-shrink: 0;\n font-size: 13px;\n}\n\n._72qoAq_progressText {\n overflow-wrap: anywhere;\n min-width: 0;\n}\n\n@media (width <= 720px) {\n ._72qoAq_pageView {\n padding: 14px;\n }\n\n ._72qoAq_titleRow {\n flex-wrap: wrap;\n }\n\n ._72qoAq_title {\n flex: 1 0 auto;\n }\n\n ._72qoAq_sub {\n white-space: normal;\n flex: 1 0 100%;\n order: 3;\n }\n\n ._72qoAq_searchGroup {\n flex: 1 0 100%;\n order: 4;\n }\n\n ._72qoAq_sourceTabsScroll {\n scrollbar-width: thin;\n padding-bottom: 2px;\n display: flex;\n overflow-x: auto;\n }\n\n ._72qoAq_srcTab, ._72qoAq_srcTabOn {\n flex: none;\n width: auto;\n min-width: 128px;\n }\n\n ._72qoAq_grid {\n grid-template-columns: minmax(0, 1fr);\n }\n\n ._72qoAq_list ._72qoAq_cardTop, ._72qoAq_list ._72qoAq_cardActions {\n max-width: 100%;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n ._72qoAq_progressSpin, ._72qoAq_switchOn, ._72qoAq_switchOff, ._72qoAq_switchThumb {\n transition: none;\n animation: none;\n }\n}\n\n._72qoAq_surfaceToggles {\n flex-wrap: wrap;\n align-items: center;\n gap: 4px 14px;\n display: flex;\n}\n\n._72qoAq_surfaceToggle {\n color: var(--dsw-alias-text-2, #5a6070);\n cursor: pointer;\n user-select: none;\n align-items: center;\n gap: 5px;\n font-size: 12px;\n display: inline-flex;\n}\n\n._72qoAq_surfaceToggle input[type=\"checkbox\"] {\n accent-color: var(--dsw-alias-accent, #4b6bfb);\n margin: 0;\n}\n\n._72qoAq_mcpOverrideForm {\n border: 1px solid var(--dsw-alias-border, #d8dbe2);\n border-radius: 8px;\n flex-direction: column;\n gap: 8px;\n margin: 0 0 10px;\n padding: 10px;\n display: flex;\n}\n\n._72qoAq_mcpOverrideCheck {\n cursor: pointer;\n user-select: none;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n display: inline-flex;\n}\n\n._72qoAq_mcpOverrideInput {\n box-sizing: border-box;\n width: 100%;\n padding: 6px 8px;\n font-size: 12px;\n}\n\n._72qoAq_mcpOverrideArea {\n box-sizing: border-box;\n resize: vertical;\n width: 100%;\n padding: 6px 8px;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 12px;\n}\n\n._72qoAq_mcpOverrideActions {\n gap: 8px;\n display: flex;\n}\n.vavGuW_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.vavGuW_filterGap, .vavGuW_viewGap {\n min-width: 0;\n}\n\n.vavGuW_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.vavGuW_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.vavGuW_filter, .vavGuW_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.vavGuW_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.vavGuW_filter svg, .vavGuW_filterOn svg, .vavGuW_viewSwitch svg {\n stroke: currentColor;\n stroke-width: 1.5px;\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n\n.vavGuW_filterCount {\n font-variant-numeric: tabular-nums;\n}\n\n.vavGuW_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.vavGuW_viewSwitch:hover {\n color: var(--dsw-alias-label-primary, #1f2328);\n}\n\n.vavGuW_viewSwitch:focus-visible, .vavGuW_filter:focus-visible, .vavGuW_filterOn:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4f6ef7);\n outline-offset: 2px;\n}\n\n@media (width <= 760px) {\n .vavGuW_toolbar {\n grid-template-columns: auto auto auto 8px auto;\n justify-content: end;\n overflow-x: auto;\n }\n\n .vavGuW_search {\n grid-column: 1 / -1;\n }\n\n .vavGuW_filterGap {\n display: none;\n }\n}\n.AUWlZW_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.AUWlZW_header {\n flex: none;\n align-items: center;\n gap: 8px;\n padding: 4px 0 8px;\n display: flex;\n}\n\n.AUWlZW_title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n line-height: 24px;\n}\n\n.AUWlZW_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.AUWlZW_headerActions {\n align-items: center;\n gap: 8px;\n margin-left: auto;\n display: flex;\n}\n\n.AUWlZW_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.AUWlZW_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.AUWlZW_summaryDotGreen, .AUWlZW_summaryDotRed {\n border-radius: 50%;\n width: 7px;\n height: 7px;\n}\n\n.AUWlZW_summaryDotGreen {\n background: var(--dsw-alias-state-success-primary, #16a34a);\n}\n\n.AUWlZW_summaryDotRed {\n background: var(--dsw-alias-state-error-primary, #dc2626);\n}\n\n.AUWlZW_toolbar {\n flex: none;\n margin-bottom: 24px;\n}\n\n.AUWlZW_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.AUWlZW_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.AUWlZW_list .AUWlZW_card {\n flex-flow: wrap;\n align-items: center;\n gap: 8px 14px;\n}\n\n.AUWlZW_list .AUWlZW_cardTop {\n flex: 0 260px;\n}\n\n.AUWlZW_list .AUWlZW_endpoint {\n -webkit-line-clamp: 1;\n flex: 200px;\n min-height: 0;\n}\n\n.AUWlZW_list .AUWlZW_meta {\n flex: 0 auto;\n}\n\n.AUWlZW_list .AUWlZW_cardReason {\n flex-basis: 100%;\n}\n\n.AUWlZW_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.AUWlZW_card:hover {\n border-color: var(--dsw-alias-border-l3, #d9dde3);\n background: var(--dsw-alias-bg-hover, #00000009);\n}\n\n.AUWlZW_card:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary, #4f6ef7);\n outline-offset: 2px;\n}\n\n.AUWlZW_cardTop {\n align-items: center;\n gap: 8px;\n min-width: 0;\n display: flex;\n}\n\n.AUWlZW_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.AUWlZW_statusconnected {\n background: var(--dsw-alias-state-success-primary, #16a34a);\n}\n\n.AUWlZW_statusdegraded {\n background: var(--dsw-alias-state-warn-primary, #b45309);\n}\n\n.AUWlZW_statusfailed {\n background: var(--dsw-alias-state-error-primary, #dc2626);\n}\n\n.AUWlZW_statusdisabled {\n background: var(--dsw-alias-label-tertiary, #98a2b3);\n}\n\n.AUWlZW_service {\n flex: 1;\n min-width: 0;\n}\n\n.AUWlZW_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.AUWlZW_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.AUWlZW_meta {\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n display: flex;\n}\n\n.AUWlZW_sourcePlugin, .AUWlZW_sourceDirect, .AUWlZW_transport, .AUWlZW_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.AUWlZW_sourcePlugin svg, .AUWlZW_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.AUWlZW_transport {\n font-family: ui-monospace, Menlo, Consolas, monospace;\n}\n\n.AUWlZW_toolCount {\n color: var(--dsw-alias-label-primary, #1f2328);\n flex: none;\n font-weight: 600;\n}\n\n.AUWlZW_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.AUWlZW_state, .AUWlZW_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.AUWlZW_state:before, .AUWlZW_detailState:before {\n content: \"\";\n background: currentColor;\n border-radius: 50%;\n width: 6px;\n height: 6px;\n}\n\n.AUWlZW_stateconnected, .AUWlZW_detailStateconnected {\n color: var(--dsw-alias-state-success-primary, #16a34a);\n}\n\n.AUWlZW_statedegraded, .AUWlZW_detailStatedegraded {\n color: var(--dsw-alias-state-warn-primary, #b45309);\n}\n\n.AUWlZW_statefailed, .AUWlZW_detailStatefailed {\n color: var(--dsw-alias-state-error-primary, #dc2626);\n}\n\n.AUWlZW_statedisabled, .AUWlZW_detailStatedisabled {\n color: var(--dsw-alias-label-tertiary, #98a2b3);\n}\n\n.AUWlZW_chevron {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n font-size: 18px;\n}\n\n.AUWlZW_empty, .AUWlZW_detailEmpty {\n color: var(--dsw-alias-label-tertiary, #8b93a1);\n text-align: center;\n padding: 24px;\n font-size: 12px;\n}\n\n.AUWlZW_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.AUWlZW_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.AUWlZW_detailDialog {\n width: min(720px, 94vw);\n}\n\n.AUWlZW_detailBody {\n max-height: 72vh;\n overflow-y: auto;\n}\n\n.AUWlZW_modalFooter {\n justify-content: flex-end;\n width: 100%;\n display: flex;\n}\n\n.AUWlZW_detail {\n flex-direction: column;\n gap: 16px;\n display: flex;\n}\n\n.AUWlZW_detailMeta {\n flex-wrap: wrap;\n gap: 6px;\n display: flex;\n}\n\n.AUWlZW_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.AUWlZW_detailSection {\n flex-direction: column;\n gap: 7px;\n display: flex;\n}\n\n.AUWlZW_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.AUWlZW_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.AUWlZW_toolList {\n flex-direction: column;\n display: flex;\n}\n\n.AUWlZW_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.AUWlZW_tool:last-child {\n border-bottom: none;\n}\n\n.AUWlZW_toolIndex {\n color: var(--dsw-alias-brand-primary, #4f6ef7);\n font: 10px / 16px ui-monospace, Menlo, Consolas, monospace;\n}\n\n.AUWlZW_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.AUWlZW_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 .AUWlZW_header, .AUWlZW_toolbar {\n padding-left: 0;\n padding-right: 0;\n }\n\n .AUWlZW_header {\n flex-direction: column;\n }\n\n .AUWlZW_headerActions {\n justify-content: space-between;\n width: 100%;\n margin-left: 0;\n }\n\n .AUWlZW_grid {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .AUWlZW_list .AUWlZW_cardTop, .AUWlZW_list .AUWlZW_meta {\n max-width: 100%;\n }\n\n .AUWlZW_tool {\n grid-template-columns: 26px minmax(0, 1fr);\n }\n\n .AUWlZW_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;
|
|
@@ -69,6 +69,19 @@ const zh = {
|
|
|
69
69
|
keywordsLabel: "关键词",
|
|
70
70
|
disabledLabel: "已停用",
|
|
71
71
|
notInstalledLabel: "未安装",
|
|
72
|
+
surfaceTogglesSection: "运行时注入开关",
|
|
73
|
+
surfaceTogglesHint: "按能力面控制注入:关闭后立即卸载对应注入(技能 / MCP / Hooks / 命令 / 子代理)",
|
|
74
|
+
mcpOverrideEdit: "编辑覆盖",
|
|
75
|
+
mcpOverrideSave: "保存覆盖",
|
|
76
|
+
mcpOverrideReset: "重置为源配置",
|
|
77
|
+
mcpOverrideEnabled: "挂载此服务",
|
|
78
|
+
mcpOverrideUrlLabel: "URL 覆盖",
|
|
79
|
+
mcpOverrideHeadersLabel: "Headers 覆盖(每行 KEY=VALUE)",
|
|
80
|
+
mcpOverrideEnvLabel: "Env 覆盖(每行 KEY=VALUE)",
|
|
81
|
+
mcpOverrideArgsLabel: "Args 覆盖(每行一个参数)",
|
|
82
|
+
mcpOverrideKvHint: "值可写 ${ENV_NAME} 引用进程环境变量,密钥不必明文保存。",
|
|
83
|
+
mcpOverriddenBadge: "已覆盖",
|
|
84
|
+
mcpOverrideDisabledBadge: "已停用",
|
|
72
85
|
noSkills: "(无技能)",
|
|
73
86
|
noMcp: "(无 MCP 服务)",
|
|
74
87
|
loading: "加载中…",
|
|
@@ -94,6 +107,12 @@ const zh = {
|
|
|
94
107
|
uninstall: "卸载",
|
|
95
108
|
uninstallConfirmTitle: "卸载 Agent Plugins",
|
|
96
109
|
uninstallConfirmDesc: "将从已安装列表移除该 Agent Plugins,其技能与 MCP 工具随即停止注入。仓库源克隆保留。",
|
|
110
|
+
installConfirmTitle: "确认安装",
|
|
111
|
+
installConfirmDesc: "启用后以下能力将注入当前会话。请确认来源可信,详情可查看插件卡片。",
|
|
112
|
+
installAndEnable: "确认安装",
|
|
113
|
+
installConfirmNoSurfaces: "该套件未声明任何运行时能力。",
|
|
114
|
+
installConfirmExecutable: "风险提示:启用后将启动该套件的 MCP 子进程并挂载 hooks(第三方代码)。请确认来源可信后再启用。",
|
|
115
|
+
installConfirmSource: "来源",
|
|
97
116
|
removeSourceConfirmTitle: "移除仓库源「{sourceId}」",
|
|
98
117
|
removeSourceConfirmDesc: "将删除该源的本地克隆与全部安装记录。",
|
|
99
118
|
enable: "启用",
|
|
@@ -115,6 +134,7 @@ const zh = {
|
|
|
115
134
|
layoutCursor: "Cursor",
|
|
116
135
|
layoutKimi: "Kimi",
|
|
117
136
|
layoutRemote: "远程引用",
|
|
137
|
+
layoutProjectNative: "项目原生",
|
|
118
138
|
remoteRef: "远程",
|
|
119
139
|
surfaceSkills: "技能",
|
|
120
140
|
surfaceMcp: "MCP",
|
|
@@ -198,6 +218,19 @@ const en = {
|
|
|
198
218
|
keywordsLabel: "Keywords",
|
|
199
219
|
disabledLabel: "disabled",
|
|
200
220
|
notInstalledLabel: "not installed",
|
|
221
|
+
surfaceTogglesSection: "Runtime injection toggles",
|
|
222
|
+
surfaceTogglesHint: "Control injection per surface: turning one off unmounts that surface immediately (skills / MCP / hooks / commands / subagents)",
|
|
223
|
+
mcpOverrideEdit: "Edit override",
|
|
224
|
+
mcpOverrideSave: "Save override",
|
|
225
|
+
mcpOverrideReset: "Reset to source config",
|
|
226
|
+
mcpOverrideEnabled: "Mount this server",
|
|
227
|
+
mcpOverrideUrlLabel: "URL override",
|
|
228
|
+
mcpOverrideHeadersLabel: "Headers override (one KEY=VALUE per line)",
|
|
229
|
+
mcpOverrideEnvLabel: "Env override (one KEY=VALUE per line)",
|
|
230
|
+
mcpOverrideArgsLabel: "Args override (one argument per line)",
|
|
231
|
+
mcpOverrideKvHint: "Values may reference process env vars as ${ENV_NAME} so secrets never persist here.",
|
|
232
|
+
mcpOverriddenBadge: "overridden",
|
|
233
|
+
mcpOverrideDisabledBadge: "disabled",
|
|
201
234
|
noSkills: "(no skills)",
|
|
202
235
|
noMcp: "(no MCP servers)",
|
|
203
236
|
loading: "Loading…",
|
|
@@ -223,6 +256,12 @@ const en = {
|
|
|
223
256
|
uninstall: "Uninstall",
|
|
224
257
|
uninstallConfirmTitle: "Uninstall suite",
|
|
225
258
|
uninstallConfirmDesc: "Removes the suite from the installed list; its skills and MCP tools stop injecting. The source clone stays.",
|
|
259
|
+
installConfirmTitle: "Confirm install",
|
|
260
|
+
installConfirmDesc: "Once enabled, the surfaces below inject into your sessions. Confirm you trust the source; see the suite card for details.",
|
|
261
|
+
installAndEnable: "Install",
|
|
262
|
+
installConfirmNoSurfaces: "This suite declares no runtime surfaces.",
|
|
263
|
+
installConfirmExecutable: "Risk notice: enabling starts this suite's MCP child processes and mounts hooks (third-party code). Enable only if you trust the source.",
|
|
264
|
+
installConfirmSource: "Source",
|
|
226
265
|
removeSourceConfirmTitle: "Remove source “{sourceId}”",
|
|
227
266
|
removeSourceConfirmDesc: "Deletes the local clone and all install records of this source.",
|
|
228
267
|
enable: "Enable",
|
|
@@ -244,6 +283,7 @@ const en = {
|
|
|
244
283
|
layoutCursor: "Cursor",
|
|
245
284
|
layoutKimi: "Kimi",
|
|
246
285
|
layoutRemote: "remote reference",
|
|
286
|
+
layoutProjectNative: "project native",
|
|
247
287
|
remoteRef: "remote",
|
|
248
288
|
surfaceSkills: "skills",
|
|
249
289
|
surfaceMcp: "MCP",
|
|
@@ -291,34 +331,67 @@ const en = {
|
|
|
291
331
|
mcpRetry: "Retry"
|
|
292
332
|
};
|
|
293
333
|
//#endregion
|
|
334
|
+
//#region src/contracts/market.ts
|
|
335
|
+
/** Browser-safe market wire records and route constants shared by host and client. */
|
|
336
|
+
/** Prefix for all Agent Plugins Market HTTP routes. */
|
|
337
|
+
const MARKET_API_PREFIX = "/api/agent-plugins/";
|
|
338
|
+
/** Fixed Agent Plugins Market HTTP routes. */
|
|
339
|
+
const MARKET_ROUTES = {
|
|
340
|
+
overview: `${MARKET_API_PREFIX}overview`,
|
|
341
|
+
mcpStatus: `${MARKET_API_PREFIX}mcp-status`,
|
|
342
|
+
progress: `${MARKET_API_PREFIX}progress`,
|
|
343
|
+
config: `${MARKET_API_PREFIX}config`,
|
|
344
|
+
suite: `${MARKET_API_PREFIX}suite`,
|
|
345
|
+
skill: `${MARKET_API_PREFIX}skill`,
|
|
346
|
+
addSource: `${MARKET_API_PREFIX}sources/add`,
|
|
347
|
+
updateSource: `${MARKET_API_PREFIX}sources/update`,
|
|
348
|
+
removeSource: `${MARKET_API_PREFIX}sources/remove`,
|
|
349
|
+
refreshSource: `${MARKET_API_PREFIX}sources/refresh`,
|
|
350
|
+
install: `${MARKET_API_PREFIX}install`,
|
|
351
|
+
uninstall: `${MARKET_API_PREFIX}uninstall`,
|
|
352
|
+
setEnabled: `${MARKET_API_PREFIX}set-enabled`,
|
|
353
|
+
setSurface: `${MARKET_API_PREFIX}set-surface`,
|
|
354
|
+
mcpOverrides: `${MARKET_API_PREFIX}mcp-overrides`,
|
|
355
|
+
setMcpOverride: `${MARKET_API_PREFIX}set-mcp-override`
|
|
356
|
+
};
|
|
357
|
+
/** Build a suite-detail URL without duplicating route or query encoding logic. */
|
|
358
|
+
function suiteRoute(sourceId, suiteId) {
|
|
359
|
+
return `${MARKET_ROUTES.suite}?sourceId=${encodeURIComponent(sourceId)}&suiteId=${encodeURIComponent(suiteId)}`;
|
|
360
|
+
}
|
|
361
|
+
/** Build a skill-content URL without duplicating route or query encoding logic. */
|
|
362
|
+
function skillRoute(sourceId, suiteId, skill) {
|
|
363
|
+
return `${MARKET_ROUTES.skill}?sourceId=${encodeURIComponent(sourceId)}&suiteId=${encodeURIComponent(suiteId)}&skill=${encodeURIComponent(skill)}`;
|
|
364
|
+
}
|
|
365
|
+
//#endregion
|
|
294
366
|
//#region src/client/api.ts
|
|
367
|
+
/** Typed fetch helpers over the host's `/api/agent-plugins/*` routes. */
|
|
295
368
|
async function fetchOverview() {
|
|
296
|
-
const response = await fetch(
|
|
369
|
+
const response = await fetch(MARKET_ROUTES.overview, { credentials: "same-origin" });
|
|
297
370
|
if (!response.ok) throw new Error(`overview failed: ${response.status}`);
|
|
298
371
|
return response.json();
|
|
299
372
|
}
|
|
300
373
|
async function fetchSourceProgress() {
|
|
301
|
-
const response = await fetch(
|
|
374
|
+
const response = await fetch(MARKET_ROUTES.progress, { credentials: "same-origin" });
|
|
302
375
|
if (!response.ok) throw new Error(`progress failed: ${response.status}`);
|
|
303
376
|
return response.json();
|
|
304
377
|
}
|
|
305
378
|
async function fetchSuiteDetail(sourceId, suiteId) {
|
|
306
|
-
const response = await fetch(
|
|
379
|
+
const response = await fetch(suiteRoute(sourceId, suiteId), { credentials: "same-origin" });
|
|
307
380
|
if (!response.ok) throw new Error(`suite detail failed: ${response.status}`);
|
|
308
381
|
return response.json();
|
|
309
382
|
}
|
|
310
383
|
async function fetchMcpStatus() {
|
|
311
|
-
const response = await fetch(
|
|
384
|
+
const response = await fetch(MARKET_ROUTES.mcpStatus, { credentials: "same-origin" });
|
|
312
385
|
if (!response.ok) throw new Error(`MCP status failed: ${response.status}`);
|
|
313
386
|
return response.json();
|
|
314
387
|
}
|
|
315
388
|
async function fetchSkillContent(sourceId, suiteId, skill) {
|
|
316
|
-
const response = await fetch(
|
|
389
|
+
const response = await fetch(skillRoute(sourceId, suiteId, skill), { credentials: "same-origin" });
|
|
317
390
|
if (!response.ok) throw new Error(`skill content failed: ${response.status}`);
|
|
318
391
|
return response.json();
|
|
319
392
|
}
|
|
320
393
|
async function postAction(path, body) {
|
|
321
|
-
const response = await fetch(
|
|
394
|
+
const response = await fetch(`${MARKET_API_PREFIX}${path}`, {
|
|
322
395
|
method: "POST",
|
|
323
396
|
credentials: "same-origin",
|
|
324
397
|
headers: { "content-type": "application/json" },
|
|
@@ -329,6 +402,435 @@ async function postAction(path, body) {
|
|
|
329
402
|
return payload;
|
|
330
403
|
}
|
|
331
404
|
//#endregion
|
|
405
|
+
//#region src/client/features/market/market-resource.ts
|
|
406
|
+
/** Market overview cache, invalidation, and source-progress resource helpers. */
|
|
407
|
+
const EMPTY_OVERVIEW = {
|
|
408
|
+
sources: [],
|
|
409
|
+
suites: [],
|
|
410
|
+
totals: {
|
|
411
|
+
all: 0,
|
|
412
|
+
installed: 0,
|
|
413
|
+
enabled: 0
|
|
414
|
+
},
|
|
415
|
+
roots: {
|
|
416
|
+
user: "",
|
|
417
|
+
data: ""
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
let cachedOverview;
|
|
421
|
+
let inflightOverview;
|
|
422
|
+
/** Load the last overview immediately and revalidate one shared request. */
|
|
423
|
+
function loadOverview() {
|
|
424
|
+
const initial = cachedOverview ?? EMPTY_OVERVIEW;
|
|
425
|
+
if (inflightOverview === void 0) inflightOverview = fetchOverview().then((data) => {
|
|
426
|
+
cachedOverview = data;
|
|
427
|
+
return data;
|
|
428
|
+
}).finally(() => {
|
|
429
|
+
inflightOverview = void 0;
|
|
430
|
+
});
|
|
431
|
+
return {
|
|
432
|
+
initial,
|
|
433
|
+
revalidating: cachedOverview === void 0,
|
|
434
|
+
promise: inflightOverview
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
/** Invalidate the shared overview after a mutating action. */
|
|
438
|
+
function invalidateOverview() {
|
|
439
|
+
cachedOverview = void 0;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Poll source mutation progress until stopped. Poll failures remain silent
|
|
443
|
+
* because the add-source request is authoritative for mutation success.
|
|
444
|
+
*/
|
|
445
|
+
function startSourceProgressPolling(report, resolveStep = (step) => step) {
|
|
446
|
+
let stopped = false;
|
|
447
|
+
let timer;
|
|
448
|
+
const tick = async () => {
|
|
449
|
+
if (stopped) return;
|
|
450
|
+
try {
|
|
451
|
+
const progress = await fetchSourceProgress();
|
|
452
|
+
if (!stopped && progress.active) report({
|
|
453
|
+
step: resolveStep(progress.step),
|
|
454
|
+
error: void 0
|
|
455
|
+
});
|
|
456
|
+
} catch {}
|
|
457
|
+
if (!stopped) timer = setTimeout(() => {
|
|
458
|
+
tick();
|
|
459
|
+
}, 800);
|
|
460
|
+
};
|
|
461
|
+
timer = setTimeout(() => {
|
|
462
|
+
tick();
|
|
463
|
+
}, 400);
|
|
464
|
+
return { stop: () => {
|
|
465
|
+
stopped = true;
|
|
466
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
467
|
+
} };
|
|
468
|
+
}
|
|
469
|
+
//#endregion
|
|
470
|
+
//#region src/client/features/market/market-view-model.ts
|
|
471
|
+
const searchableCache$1 = /* @__PURE__ */ new WeakMap();
|
|
472
|
+
/** Derive visible cards and scope counts in one pass over a normalized payload. */
|
|
473
|
+
function deriveMarketViewModel(overview, search, filter, category) {
|
|
474
|
+
const searchable = searchableFor$1(overview);
|
|
475
|
+
const needle = search.trim().toLowerCase();
|
|
476
|
+
let all = 0;
|
|
477
|
+
let installed = 0;
|
|
478
|
+
let enabled = 0;
|
|
479
|
+
const visible = [];
|
|
480
|
+
for (const entry of searchable) {
|
|
481
|
+
const suite = entry.suite;
|
|
482
|
+
if (category !== "all" && suite.sourceId !== category) continue;
|
|
483
|
+
all++;
|
|
484
|
+
if (suite.installed) installed++;
|
|
485
|
+
if (suite.enabled) enabled++;
|
|
486
|
+
if (filter === "installed" && !suite.installed) continue;
|
|
487
|
+
if (filter === "uninstalled" && suite.installed) continue;
|
|
488
|
+
if (needle !== "" && !entry.haystack.includes(needle)) continue;
|
|
489
|
+
visible.push(suite);
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
scopeTotals: {
|
|
493
|
+
all,
|
|
494
|
+
installed,
|
|
495
|
+
enabled
|
|
496
|
+
},
|
|
497
|
+
filtered: visible
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
function searchableFor$1(overview) {
|
|
501
|
+
const cached = searchableCache$1.get(overview);
|
|
502
|
+
if (cached !== void 0) return cached;
|
|
503
|
+
const searchable = overview.suites.map((suite) => ({
|
|
504
|
+
suite,
|
|
505
|
+
haystack: `${suite.name} ${suite.description ?? ""} ${suite.keywords.join(" ")}`.toLowerCase()
|
|
506
|
+
}));
|
|
507
|
+
searchableCache$1.set(overview, searchable);
|
|
508
|
+
return searchable;
|
|
509
|
+
}
|
|
510
|
+
//#endregion
|
|
511
|
+
//#region src/client/market.module.css
|
|
512
|
+
var market_module_default = {
|
|
513
|
+
"body": "_72qoAq_body",
|
|
514
|
+
"card": "_72qoAq_card",
|
|
515
|
+
"cardActions": "_72qoAq_cardActions",
|
|
516
|
+
"cardDesc": "_72qoAq_cardDesc",
|
|
517
|
+
"cardName": "_72qoAq_cardName",
|
|
518
|
+
"cardTitle": "_72qoAq_cardTitle",
|
|
519
|
+
"cardTop": "_72qoAq_cardTop",
|
|
520
|
+
"desc": "_72qoAq_desc",
|
|
521
|
+
"detailBody": "_72qoAq_detailBody",
|
|
522
|
+
"detailCell": "_72qoAq_detailCell",
|
|
523
|
+
"detailChevron": "_72qoAq_detailChevron",
|
|
524
|
+
"detailDesc": "_72qoAq_detailDesc",
|
|
525
|
+
"detailDialog": "_72qoAq_detailDialog",
|
|
526
|
+
"detailGrid": "_72qoAq_detailGrid",
|
|
527
|
+
"detailHead": "_72qoAq_detailHead",
|
|
528
|
+
"detailItem": "_72qoAq_detailItem",
|
|
529
|
+
"detailItemDesc": "_72qoAq_detailItemDesc",
|
|
530
|
+
"detailItemName": "_72qoAq_detailItemName",
|
|
531
|
+
"detailItemOpen": "_72qoAq_detailItemOpen",
|
|
532
|
+
"detailItemRow": "_72qoAq_detailItemRow",
|
|
533
|
+
"detailKey": "_72qoAq_detailKey",
|
|
534
|
+
"detailSection": "_72qoAq_detailSection",
|
|
535
|
+
"detailSections": "_72qoAq_detailSections",
|
|
536
|
+
"detailValue": "_72qoAq_detailValue",
|
|
537
|
+
"dshApmSpin": "_72qoAq_dshApmSpin",
|
|
538
|
+
"editorDialog": "_72qoAq_editorDialog",
|
|
539
|
+
"editorForm": "_72qoAq_editorForm",
|
|
540
|
+
"empty": "_72qoAq_empty",
|
|
541
|
+
"fieldGroup": "_72qoAq_fieldGroup",
|
|
542
|
+
"fieldHint": "_72qoAq_fieldHint",
|
|
543
|
+
"fieldLabel": "_72qoAq_fieldLabel",
|
|
544
|
+
"grid": "_72qoAq_grid",
|
|
545
|
+
"header": "_72qoAq_header",
|
|
546
|
+
"installConfirmBody": "_72qoAq_installConfirmBody",
|
|
547
|
+
"installConfirmMeta": "_72qoAq_installConfirmMeta",
|
|
548
|
+
"installConfirmSuite": "_72qoAq_installConfirmSuite",
|
|
549
|
+
"installConfirmTags": "_72qoAq_installConfirmTags",
|
|
550
|
+
"installConfirmWarn": "_72qoAq_installConfirmWarn",
|
|
551
|
+
"list": "_72qoAq_list",
|
|
552
|
+
"market": "_72qoAq_market",
|
|
553
|
+
"marketControls": "_72qoAq_marketControls",
|
|
554
|
+
"mcpOverrideActions": "_72qoAq_mcpOverrideActions",
|
|
555
|
+
"mcpOverrideArea": "_72qoAq_mcpOverrideArea",
|
|
556
|
+
"mcpOverrideCheck": "_72qoAq_mcpOverrideCheck",
|
|
557
|
+
"mcpOverrideForm": "_72qoAq_mcpOverrideForm",
|
|
558
|
+
"mcpOverrideInput": "_72qoAq_mcpOverrideInput",
|
|
559
|
+
"mcpSurface": "_72qoAq_mcpSurface",
|
|
560
|
+
"meta": "_72qoAq_meta",
|
|
561
|
+
"modalFooter": "_72qoAq_modalFooter",
|
|
562
|
+
"modalFooterLeft": "_72qoAq_modalFooterLeft",
|
|
563
|
+
"modeRow": "_72qoAq_modeRow",
|
|
564
|
+
"mono": "_72qoAq_mono",
|
|
565
|
+
"okState": "_72qoAq_okState",
|
|
566
|
+
"pageEntry": "_72qoAq_pageEntry",
|
|
567
|
+
"pageMode": "_72qoAq_pageMode",
|
|
568
|
+
"pageView": "_72qoAq_pageView",
|
|
569
|
+
"progress": "_72qoAq_progress",
|
|
570
|
+
"progressError": "_72qoAq_progressError",
|
|
571
|
+
"progressFail": "_72qoAq_progressFail",
|
|
572
|
+
"progressSpin": "_72qoAq_progressSpin",
|
|
573
|
+
"progressText": "_72qoAq_progressText",
|
|
574
|
+
"searchGroup": "_72qoAq_searchGroup",
|
|
575
|
+
"seg": "_72qoAq_seg",
|
|
576
|
+
"segOn": "_72qoAq_segOn",
|
|
577
|
+
"skillContent": "_72qoAq_skillContent",
|
|
578
|
+
"sourceTabsRow": "_72qoAq_sourceTabsRow",
|
|
579
|
+
"sourceTabsScroll": "_72qoAq_sourceTabsScroll",
|
|
580
|
+
"spacer": "_72qoAq_spacer",
|
|
581
|
+
"src": "_72qoAq_src",
|
|
582
|
+
"srcTab": "_72qoAq_srcTab",
|
|
583
|
+
"srcTabDel": "_72qoAq_srcTabDel",
|
|
584
|
+
"srcTabEdit": "_72qoAq_srcTabEdit",
|
|
585
|
+
"srcTabMain": "_72qoAq_srcTabMain",
|
|
586
|
+
"srcTabOn": "_72qoAq_srcTabOn",
|
|
587
|
+
"staticId": "_72qoAq_staticId",
|
|
588
|
+
"staticIdValue": "_72qoAq_staticIdValue",
|
|
589
|
+
"sub": "_72qoAq_sub",
|
|
590
|
+
"surfaceSwitch": "_72qoAq_surfaceSwitch",
|
|
591
|
+
"surfaceToggle": "_72qoAq_surfaceToggle",
|
|
592
|
+
"surfaceToggles": "_72qoAq_surfaceToggles",
|
|
593
|
+
"switchOff": "_72qoAq_switchOff",
|
|
594
|
+
"switchOn": "_72qoAq_switchOn",
|
|
595
|
+
"switchThumb": "_72qoAq_switchThumb",
|
|
596
|
+
"tag": "_72qoAq_tag",
|
|
597
|
+
"title": "_72qoAq_title",
|
|
598
|
+
"titleRow": "_72qoAq_titleRow",
|
|
599
|
+
"version": "_72qoAq_version",
|
|
600
|
+
"warnLine": "_72qoAq_warnLine"
|
|
601
|
+
};
|
|
602
|
+
//#endregion
|
|
603
|
+
//#region src/client/features/market/SourceTab.tsx
|
|
604
|
+
/** A source tab with trailing edit and delete controls. */
|
|
605
|
+
/** A source chip with a trailing delete control (deletion confirms at the section level). */
|
|
606
|
+
function SourceTab(props) {
|
|
607
|
+
const { t, active = false, label, onSelect, onDelete, onEdit } = props;
|
|
608
|
+
return (0, react.createElement)("div", { className: active ? market_module_default.srcTabOn : market_module_default.srcTab }, (0, react.createElement)("button", {
|
|
609
|
+
type: "button",
|
|
610
|
+
className: market_module_default.srcTabMain,
|
|
611
|
+
onClick: onSelect
|
|
612
|
+
}, label), onEdit === void 0 ? null : (0, react.createElement)("button", {
|
|
613
|
+
type: "button",
|
|
614
|
+
className: market_module_default.srcTabEdit,
|
|
615
|
+
title: t("editSource"),
|
|
616
|
+
onClick: (event) => {
|
|
617
|
+
event.stopPropagation();
|
|
618
|
+
onEdit();
|
|
619
|
+
}
|
|
620
|
+
}, "✎"), onDelete === void 0 ? null : (0, react.createElement)("button", {
|
|
621
|
+
type: "button",
|
|
622
|
+
className: market_module_default.srcTabDel,
|
|
623
|
+
title: t("remove"),
|
|
624
|
+
onClick: (event) => {
|
|
625
|
+
event.stopPropagation();
|
|
626
|
+
onDelete();
|
|
627
|
+
}
|
|
628
|
+
}, "×"));
|
|
629
|
+
}
|
|
630
|
+
//#endregion
|
|
631
|
+
//#region src/client/features/market/SourceEditorModal.tsx
|
|
632
|
+
/** Source editor modal for adding or editing a catalog source. */
|
|
633
|
+
function SourceEditorModal(props) {
|
|
634
|
+
const { t, editor } = props;
|
|
635
|
+
const [local, setLocal] = (0, react.useState)(editor.mode === "edit" && editor.source.local === true);
|
|
636
|
+
const [url, setUrl] = (0, react.useState)(editor.mode === "edit" ? editor.source.url : "");
|
|
637
|
+
const [branch, setBranch] = (0, react.useState)(editor.mode === "edit" ? editor.source.branch ?? "" : "");
|
|
638
|
+
const id = editor.mode === "edit" ? editor.source.id : "";
|
|
639
|
+
const title = editor.mode === "edit" ? t("editSourceTitle") : t("addSourceTitle");
|
|
640
|
+
return (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
641
|
+
open: true,
|
|
642
|
+
onClose: props.onClose,
|
|
643
|
+
title,
|
|
644
|
+
description: t("editorHint"),
|
|
645
|
+
closeLabel: t("cancel"),
|
|
646
|
+
className: market_module_default.editorDialog,
|
|
647
|
+
footer: (0, react.createElement)("div", { className: market_module_default.modalFooter }, (0, react.createElement)("div", { className: market_module_default.modalFooterLeft }, editor.mode === "edit" ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
648
|
+
variant: "ghost",
|
|
649
|
+
onClick: () => props.onRemove(id)
|
|
650
|
+
}, `🗑 ${t("remove")}`) : null), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
651
|
+
variant: "ghost",
|
|
652
|
+
onClick: props.onClose
|
|
653
|
+
}, t("cancel")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
654
|
+
variant: "primary",
|
|
655
|
+
disabled: props.busy,
|
|
656
|
+
onClick: () => {
|
|
657
|
+
props.onSave(url.trim(), branch.trim(), local);
|
|
658
|
+
}
|
|
659
|
+
}, t("save"))),
|
|
660
|
+
children: (0, react.createElement)("div", { className: market_module_default.editorForm }, (0, react.createElement)("div", { className: market_module_default.modeRow }, (0, react.createElement)("button", {
|
|
661
|
+
type: "button",
|
|
662
|
+
className: local ? market_module_default.seg : market_module_default.segOn,
|
|
663
|
+
onClick: () => setLocal(false)
|
|
664
|
+
}, t("sourceModeGit")), (0, react.createElement)("button", {
|
|
665
|
+
type: "button",
|
|
666
|
+
className: local ? market_module_default.segOn : market_module_default.seg,
|
|
667
|
+
onClick: () => setLocal(true)
|
|
668
|
+
}, t("sourceModeLocal"))), editor.mode === "edit" ? (0, react.createElement)("div", { className: market_module_default.fieldGroup }, (0, react.createElement)("label", { className: market_module_default.fieldLabel }, t("sourceIdPh")), (0, react.createElement)("div", { className: market_module_default.staticId }, (0, react.createElement)("span", { className: market_module_default.staticIdValue }, id), (0, react.createElement)("span", { className: market_module_default.fieldHint }, t("idFixed")))) : null, (0, react.createElement)("div", { className: market_module_default.fieldGroup }, (0, react.createElement)("label", { className: market_module_default.fieldLabel }, local ? t("sourceUrlLocalPh") : t("sourceUrlPh")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
669
|
+
placeholder: local ? t("sourceUrlLocalPh") : t("sourceUrlPh"),
|
|
670
|
+
value: url,
|
|
671
|
+
onChange: (event) => setUrl(event.target.value)
|
|
672
|
+
}), (0, react.createElement)("span", { className: market_module_default.fieldHint }, local ? t("urlLocalHint") : t("urlGitHint"))), local ? null : (0, react.createElement)("div", { className: market_module_default.fieldGroup }, (0, react.createElement)("label", { className: market_module_default.fieldLabel }, t("branchPh")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
673
|
+
placeholder: t("branchPh"),
|
|
674
|
+
value: branch,
|
|
675
|
+
onChange: (event) => setBranch(event.target.value)
|
|
676
|
+
}), (0, react.createElement)("span", { className: market_module_default.fieldHint }, t("branchHint"))), props.progress.error === void 0 && props.progress.step === void 0 ? null : (0, react.createElement)("div", { className: props.progress.error === void 0 ? market_module_default.progress : market_module_default.progressError }, props.progress.error === void 0 ? (0, react.createElement)("span", { className: market_module_default.progressSpin }) : (0, react.createElement)("span", { className: market_module_default.progressFail }, "✕"), (0, react.createElement)("span", { className: market_module_default.progressText }, props.progress.error === void 0 ? props.progress.step : `${t("actionFail")}: ${props.progress.error}`)))
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
//#endregion
|
|
680
|
+
//#region src/client/features/market/InstallConfirmModal.tsx
|
|
681
|
+
/** Pre-install confirmation modal: concise surface counts plus a risk notice. */
|
|
682
|
+
/** Surface count tags shown on the card; keys mirror SuiteCard's tag list. */
|
|
683
|
+
const SURFACE_TAGS = [
|
|
684
|
+
{
|
|
685
|
+
key: "skills",
|
|
686
|
+
labelKey: "surfaceSkills"
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
key: "mcp",
|
|
690
|
+
labelKey: "surfaceMcp"
|
|
691
|
+
},
|
|
692
|
+
{
|
|
693
|
+
key: "hooks",
|
|
694
|
+
labelKey: "surfaceHooks"
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
key: "commands",
|
|
698
|
+
labelKey: "surfaceCommands"
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
key: "agents",
|
|
702
|
+
labelKey: "surfaceAgents"
|
|
703
|
+
}
|
|
704
|
+
];
|
|
705
|
+
function InstallConfirmModal(props) {
|
|
706
|
+
const { t, state, busy } = props;
|
|
707
|
+
const surfaces = state.suite.surfaces;
|
|
708
|
+
const tags = SURFACE_TAGS.filter((tag) => surfaces[tag.key] > 0);
|
|
709
|
+
const executable = surfaces.mcp > 0 || surfaces.hooks > 0;
|
|
710
|
+
return (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
711
|
+
open: true,
|
|
712
|
+
onClose: props.onClose,
|
|
713
|
+
title: t("installConfirmTitle"),
|
|
714
|
+
description: t("installConfirmDesc"),
|
|
715
|
+
closeLabel: t("cancel"),
|
|
716
|
+
className: market_module_default.editorDialog,
|
|
717
|
+
footer: (0, react.createElement)("div", { className: market_module_default.modalFooter }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
718
|
+
variant: "ghost",
|
|
719
|
+
disabled: busy,
|
|
720
|
+
onClick: props.onClose
|
|
721
|
+
}, t("cancel")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
722
|
+
variant: "primary",
|
|
723
|
+
disabled: busy,
|
|
724
|
+
onClick: () => {
|
|
725
|
+
props.onConfirm();
|
|
726
|
+
}
|
|
727
|
+
}, t("installAndEnable"))),
|
|
728
|
+
children: (0, react.createElement)("div", { className: market_module_default.installConfirmBody }, (0, react.createElement)("div", { className: market_module_default.installConfirmSuite }, `${state.suite.sourceId} / ${state.suite.name}`), state.suite.version === void 0 ? null : (0, react.createElement)("div", { className: market_module_default.installConfirmMeta }, `${t("version")}: v${state.suite.version}`), tags.length === 0 ? (0, react.createElement)("div", { className: market_module_default.installConfirmMeta }, t("installConfirmNoSurfaces")) : (0, react.createElement)("div", { className: market_module_default.installConfirmTags }, tags.map((tag) => (0, react.createElement)("span", {
|
|
729
|
+
key: tag.key,
|
|
730
|
+
className: market_module_default.tag
|
|
731
|
+
}, `${t(tag.labelKey)} ${surfaces[tag.key]}`))), executable ? (0, react.createElement)("div", { className: market_module_default.installConfirmWarn }, t("installConfirmExecutable")) : null)
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
//#endregion
|
|
735
|
+
//#region src/client/ui/ToggleSwitch.tsx
|
|
736
|
+
/** Shared green/gray switch control used by suite cards. */
|
|
737
|
+
/** A green/gray switch control for suite enable state. */
|
|
738
|
+
function ToggleSwitch(props) {
|
|
739
|
+
return (0, react.createElement)("button", {
|
|
740
|
+
type: "button",
|
|
741
|
+
role: "switch",
|
|
742
|
+
"aria-checked": props.on,
|
|
743
|
+
title: props.title,
|
|
744
|
+
disabled: props.disabled,
|
|
745
|
+
className: props.on ? market_module_default.switchOn : market_module_default.switchOff,
|
|
746
|
+
onClick: (event) => {
|
|
747
|
+
event.stopPropagation();
|
|
748
|
+
props.onChange();
|
|
749
|
+
}
|
|
750
|
+
}, (0, react.createElement)("span", { className: market_module_default.switchThumb }));
|
|
751
|
+
}
|
|
752
|
+
//#endregion
|
|
753
|
+
//#region src/client/features/market/SuiteCard.tsx
|
|
754
|
+
/** A suite card in the market grid/list. */
|
|
755
|
+
function SuiteCard(props) {
|
|
756
|
+
const { t, suite, busy } = props;
|
|
757
|
+
const tags = [
|
|
758
|
+
[t("surfaceSkills"), suite.surfaces.skills],
|
|
759
|
+
[t("surfaceMcp"), suite.surfaces.mcp],
|
|
760
|
+
[t("surfaceHooks"), suite.surfaces.hooks],
|
|
761
|
+
[t("surfaceCommands"), suite.surfaces.commands],
|
|
762
|
+
[t("surfaceAgents"), suite.surfaces.agents],
|
|
763
|
+
[t("surfaceLsp"), suite.surfaces.lsp]
|
|
764
|
+
].filter(([, count]) => count > 0);
|
|
765
|
+
const layoutLabel = suite.layout === "agent-plugin-v1" ? t("layoutV1") : suite.layout === "claude-code" ? t("layoutCC") : suite.layout === "codex" ? t("layoutCodex") : suite.layout === "universal" ? t("layoutUniversal") : suite.layout === "cursor" ? t("layoutCursor") : suite.layout === "kimi" ? t("layoutKimi") : suite.layout === "remote" ? t("layoutRemote") : suite.layout === "project-native" ? t("layoutProjectNative") : t("layoutSkills");
|
|
766
|
+
const isRemote = suite.remoteUrl !== void 0;
|
|
767
|
+
const stop = (callback) => (event) => {
|
|
768
|
+
event.stopPropagation();
|
|
769
|
+
callback();
|
|
770
|
+
};
|
|
771
|
+
return (0, react.createElement)("article", {
|
|
772
|
+
className: market_module_default.card,
|
|
773
|
+
onClick: props.onOpen
|
|
774
|
+
}, (0, react.createElement)("div", { className: market_module_default.cardTop }, (0, react.createElement)("div", { className: market_module_default.cardTitle }, (0, react.createElement)("span", { className: market_module_default.cardName }, suite.name), suite.version === void 0 ? null : (0, react.createElement)("span", { className: market_module_default.version }, `v${suite.version}`)), (0, react.createElement)("div", { className: market_module_default.cardActions }, suite.installed ? (0, react.createElement)(ToggleSwitch, {
|
|
775
|
+
on: suite.enabled,
|
|
776
|
+
disabled: busy,
|
|
777
|
+
title: suite.enabled ? t("disable") : t("enable"),
|
|
778
|
+
onChange: props.onToggle
|
|
779
|
+
}) : isRemote ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
780
|
+
variant: "primary",
|
|
781
|
+
size: "sm",
|
|
782
|
+
disabled: busy,
|
|
783
|
+
title: suite.remoteUrl,
|
|
784
|
+
onClick: stop(props.onAddSource)
|
|
785
|
+
}, t("addSource")) : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
786
|
+
variant: "primary",
|
|
787
|
+
size: "sm",
|
|
788
|
+
disabled: busy,
|
|
789
|
+
onClick: stop(props.onInstall)
|
|
790
|
+
}, t("install")), suite.installed ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
791
|
+
variant: "ghost",
|
|
792
|
+
size: "sm",
|
|
793
|
+
title: t("refresh"),
|
|
794
|
+
disabled: busy,
|
|
795
|
+
onClick: stop(props.onRefresh)
|
|
796
|
+
}, "↻") : null, suite.installed ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
797
|
+
variant: "ghost",
|
|
798
|
+
size: "sm",
|
|
799
|
+
title: t("uninstall"),
|
|
800
|
+
disabled: busy,
|
|
801
|
+
onClick: stop(props.onUninstall)
|
|
802
|
+
}, "🗑") : null)), (0, react.createElement)("p", { className: market_module_default.desc }, suite.description ?? ""), (0, react.createElement)("div", { className: market_module_default.meta }, (0, react.createElement)("span", { className: market_module_default.src }, `${suite.sourceId} · ${isRemote ? t("remoteRef") : suite.dimension === "user" ? t("dimensionUser") : t("dimensionProject")}`), (0, react.createElement)("span", { className: market_module_default.tag }, layoutLabel), suite.installed ? (0, react.createElement)("span", { className: suite.enabled ? market_module_default.okState : market_module_default.tag }, suite.enabled ? `✓ ${t("installedBadge")}` : t("installedBadge")) : null, ...tags.map(([label, count]) => (0, react.createElement)("span", {
|
|
803
|
+
key: label,
|
|
804
|
+
className: market_module_default.tag
|
|
805
|
+
}, `${label} ${count}`)), suite.errors.length === 0 ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
806
|
+
label: suite.errors.slice(0, 8).join(t("sourceErrorSeparator")),
|
|
807
|
+
children: (0, react.createElement)("span", { className: market_module_default.warnLine }, `⚠ ${t("errors")} ${suite.errors.length}`)
|
|
808
|
+
}), (suite.mcpErrors?.length ?? 0) === 0 ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
809
|
+
label: suite.mcpErrors.slice(0, 8).join(t("sourceErrorSeparator")),
|
|
810
|
+
children: (0, react.createElement)("span", { className: market_module_default.warnLine }, `⚠ ${t("mcpSection")} ${suite.mcpErrors.length}`)
|
|
811
|
+
})));
|
|
812
|
+
}
|
|
813
|
+
//#endregion
|
|
814
|
+
//#region src/client/ui/StatusIcon.tsx
|
|
815
|
+
/** Shared status icon used by market and MCP status filter tabs. */
|
|
816
|
+
/** An SVG status icon for the all/installed/uninstalled filter tabs. */
|
|
817
|
+
function StatusIcon({ kind }) {
|
|
818
|
+
const common = {
|
|
819
|
+
width: 16,
|
|
820
|
+
height: 16,
|
|
821
|
+
viewBox: "0 0 16 16",
|
|
822
|
+
fill: "none",
|
|
823
|
+
"aria-hidden": true
|
|
824
|
+
};
|
|
825
|
+
if (kind === "installed") return (0, react.createElement)("svg", common, (0, react.createElement)("circle", {
|
|
826
|
+
cx: 8,
|
|
827
|
+
cy: 8,
|
|
828
|
+
r: 5.5
|
|
829
|
+
}), (0, react.createElement)("path", { d: "m5.5 8 1.7 1.7 3.4-3.4" }));
|
|
830
|
+
if (kind === "uninstalled") return (0, react.createElement)("svg", common, (0, react.createElement)("path", { d: "M8 2v8m-3-3 3 3 3-3M3 13h10" }));
|
|
831
|
+
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" }));
|
|
832
|
+
}
|
|
833
|
+
//#endregion
|
|
332
834
|
//#region src/client/ErrorBoundary.tsx
|
|
333
835
|
/**
|
|
334
836
|
* Error boundary for untrusted preview content.
|
|
@@ -351,85 +853,18 @@ var ErrorBoundary = class extends react.Component {
|
|
|
351
853
|
}
|
|
352
854
|
};
|
|
353
855
|
//#endregion
|
|
354
|
-
//#region src/client/
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
"detailChevron": "qMtKNa_detailChevron",
|
|
367
|
-
"detailDesc": "qMtKNa_detailDesc",
|
|
368
|
-
"detailDialog": "qMtKNa_detailDialog",
|
|
369
|
-
"detailGrid": "qMtKNa_detailGrid",
|
|
370
|
-
"detailHead": "qMtKNa_detailHead",
|
|
371
|
-
"detailItem": "qMtKNa_detailItem",
|
|
372
|
-
"detailItemDesc": "qMtKNa_detailItemDesc",
|
|
373
|
-
"detailItemName": "qMtKNa_detailItemName",
|
|
374
|
-
"detailItemOpen": "qMtKNa_detailItemOpen",
|
|
375
|
-
"detailItemRow": "qMtKNa_detailItemRow",
|
|
376
|
-
"detailKey": "qMtKNa_detailKey",
|
|
377
|
-
"detailSection": "qMtKNa_detailSection",
|
|
378
|
-
"detailSections": "qMtKNa_detailSections",
|
|
379
|
-
"detailValue": "qMtKNa_detailValue",
|
|
380
|
-
"dshApmSpin": "qMtKNa_dshApmSpin",
|
|
381
|
-
"editorDialog": "qMtKNa_editorDialog",
|
|
382
|
-
"editorForm": "qMtKNa_editorForm",
|
|
383
|
-
"empty": "qMtKNa_empty",
|
|
384
|
-
"fieldGroup": "qMtKNa_fieldGroup",
|
|
385
|
-
"fieldHint": "qMtKNa_fieldHint",
|
|
386
|
-
"fieldLabel": "qMtKNa_fieldLabel",
|
|
387
|
-
"grid": "qMtKNa_grid",
|
|
388
|
-
"header": "qMtKNa_header",
|
|
389
|
-
"list": "qMtKNa_list",
|
|
390
|
-
"market": "qMtKNa_market",
|
|
391
|
-
"marketControls": "qMtKNa_marketControls",
|
|
392
|
-
"mcpSurface": "qMtKNa_mcpSurface",
|
|
393
|
-
"meta": "qMtKNa_meta",
|
|
394
|
-
"modalFooter": "qMtKNa_modalFooter",
|
|
395
|
-
"modalFooterLeft": "qMtKNa_modalFooterLeft",
|
|
396
|
-
"modeRow": "qMtKNa_modeRow",
|
|
397
|
-
"mono": "qMtKNa_mono",
|
|
398
|
-
"okState": "qMtKNa_okState",
|
|
399
|
-
"pageEntry": "qMtKNa_pageEntry",
|
|
400
|
-
"pageMode": "qMtKNa_pageMode",
|
|
401
|
-
"pageView": "qMtKNa_pageView",
|
|
402
|
-
"progress": "qMtKNa_progress",
|
|
403
|
-
"progressError": "qMtKNa_progressError",
|
|
404
|
-
"progressFail": "qMtKNa_progressFail",
|
|
405
|
-
"progressSpin": "qMtKNa_progressSpin",
|
|
406
|
-
"progressText": "qMtKNa_progressText",
|
|
407
|
-
"searchGroup": "qMtKNa_searchGroup",
|
|
408
|
-
"seg": "qMtKNa_seg",
|
|
409
|
-
"segOn": "qMtKNa_segOn",
|
|
410
|
-
"skillContent": "qMtKNa_skillContent",
|
|
411
|
-
"sourceTabsRow": "qMtKNa_sourceTabsRow",
|
|
412
|
-
"sourceTabsScroll": "qMtKNa_sourceTabsScroll",
|
|
413
|
-
"spacer": "qMtKNa_spacer",
|
|
414
|
-
"src": "qMtKNa_src",
|
|
415
|
-
"srcTab": "qMtKNa_srcTab",
|
|
416
|
-
"srcTabDel": "qMtKNa_srcTabDel",
|
|
417
|
-
"srcTabEdit": "qMtKNa_srcTabEdit",
|
|
418
|
-
"srcTabMain": "qMtKNa_srcTabMain",
|
|
419
|
-
"srcTabOn": "qMtKNa_srcTabOn",
|
|
420
|
-
"staticId": "qMtKNa_staticId",
|
|
421
|
-
"staticIdValue": "qMtKNa_staticIdValue",
|
|
422
|
-
"sub": "qMtKNa_sub",
|
|
423
|
-
"surfaceSwitch": "qMtKNa_surfaceSwitch",
|
|
424
|
-
"switchOff": "qMtKNa_switchOff",
|
|
425
|
-
"switchOn": "qMtKNa_switchOn",
|
|
426
|
-
"switchThumb": "qMtKNa_switchThumb",
|
|
427
|
-
"tag": "qMtKNa_tag",
|
|
428
|
-
"title": "qMtKNa_title",
|
|
429
|
-
"titleRow": "qMtKNa_titleRow",
|
|
430
|
-
"version": "qMtKNa_version",
|
|
431
|
-
"warnLine": "qMtKNa_warnLine"
|
|
432
|
-
};
|
|
856
|
+
//#region src/client/features/suite-detail/suite-detail-resource.ts
|
|
857
|
+
/** Create a request guard for one detail modal instance. */
|
|
858
|
+
function createLatestRequestGuard() {
|
|
859
|
+
let revision = 0;
|
|
860
|
+
return {
|
|
861
|
+
next: () => ++revision,
|
|
862
|
+
invalidate: () => {
|
|
863
|
+
revision++;
|
|
864
|
+
},
|
|
865
|
+
isCurrent: (requestId) => requestId === revision
|
|
866
|
+
};
|
|
867
|
+
}
|
|
433
868
|
//#endregion
|
|
434
869
|
//#region src/client/SuiteDetail.tsx
|
|
435
870
|
/**
|
|
@@ -440,18 +875,30 @@ var market_module_default = {
|
|
|
440
875
|
* mcp.json servers (each expands to its full config), command/subagent file
|
|
441
876
|
* lists, hook/LSP counts, and validation diagnostics.
|
|
442
877
|
*/
|
|
878
|
+
/** Toggleable surface keys paired with their translation keys. */
|
|
879
|
+
const SURFACE_TOGGLE_ROWS = [
|
|
880
|
+
["skills", "surfaceSkills"],
|
|
881
|
+
["mcp", "surfaceMcp"],
|
|
882
|
+
["hooks", "surfaceHooks"],
|
|
883
|
+
["commands", "surfaceCommands"],
|
|
884
|
+
["agents", "surfaceAgents"]
|
|
885
|
+
];
|
|
443
886
|
function SuiteDetailModal({ t, sourceId, suiteId, onClose }) {
|
|
444
887
|
const [detail, setDetail] = (0, react.useState)(void 0);
|
|
445
888
|
const [error, setError] = (0, react.useState)(void 0);
|
|
446
889
|
const [openSkill, setOpenSkill] = (0, react.useState)(void 0);
|
|
447
890
|
const [skillText, setSkillText] = (0, react.useState)(void 0);
|
|
448
891
|
const [skillLoading, setSkillLoading] = (0, react.useState)(false);
|
|
892
|
+
const skillRequestGuard = (0, react.useRef)(createLatestRequestGuard());
|
|
449
893
|
const [openMcp, setOpenMcp] = (0, react.useState)(void 0);
|
|
450
894
|
const [openPreview, setOpenPreview] = (0, react.useState)(void 0);
|
|
451
895
|
(0, react.useEffect)(() => {
|
|
452
896
|
let cancelled = false;
|
|
897
|
+
skillRequestGuard.current.invalidate();
|
|
453
898
|
setDetail(void 0);
|
|
454
899
|
setError(void 0);
|
|
900
|
+
setOpenSkill(void 0);
|
|
901
|
+
setSkillText(void 0);
|
|
455
902
|
fetchSuiteDetail(sourceId, suiteId).then((value) => {
|
|
456
903
|
if (!cancelled) setDetail(value);
|
|
457
904
|
}).catch((reason) => {
|
|
@@ -459,9 +906,11 @@ function SuiteDetailModal({ t, sourceId, suiteId, onClose }) {
|
|
|
459
906
|
});
|
|
460
907
|
return () => {
|
|
461
908
|
cancelled = true;
|
|
909
|
+
skillRequestGuard.current.invalidate();
|
|
462
910
|
};
|
|
463
911
|
}, [sourceId, suiteId]);
|
|
464
912
|
const toggleSkill = async (name) => {
|
|
913
|
+
const requestId = skillRequestGuard.current.next();
|
|
465
914
|
if (openSkill === name) {
|
|
466
915
|
setOpenSkill(void 0);
|
|
467
916
|
return;
|
|
@@ -471,17 +920,53 @@ function SuiteDetailModal({ t, sourceId, suiteId, onClose }) {
|
|
|
471
920
|
setSkillText(void 0);
|
|
472
921
|
try {
|
|
473
922
|
const content = await fetchSkillContent(sourceId, suiteId, name);
|
|
474
|
-
setSkillText(content.content);
|
|
923
|
+
if (skillRequestGuard.current.isCurrent(requestId)) setSkillText(content.content);
|
|
924
|
+
} catch (reason) {
|
|
925
|
+
if (skillRequestGuard.current.isCurrent(requestId)) setSkillText(`⚠ ${reason instanceof Error ? reason.message : String(reason)}`);
|
|
926
|
+
} finally {
|
|
927
|
+
if (skillRequestGuard.current.isCurrent(requestId)) setSkillLoading(false);
|
|
928
|
+
}
|
|
929
|
+
};
|
|
930
|
+
const toggleMcp = (key) => {
|
|
931
|
+
setOpenMcp(openMcp === key ? void 0 : key);
|
|
932
|
+
};
|
|
933
|
+
const [surfaceBusy, setSurfaceBusy] = (0, react.useState)(false);
|
|
934
|
+
const toggleSurface = async (surface, enabled) => {
|
|
935
|
+
setSurfaceBusy(true);
|
|
936
|
+
try {
|
|
937
|
+
await postAction("set-surface", {
|
|
938
|
+
sourceId,
|
|
939
|
+
suiteId,
|
|
940
|
+
surface,
|
|
941
|
+
enabled
|
|
942
|
+
});
|
|
943
|
+
const next = await fetchSuiteDetail(sourceId, suiteId);
|
|
944
|
+
setDetail(next);
|
|
945
|
+
} catch (reason) {
|
|
946
|
+
setError(reason instanceof Error ? reason.message : String(reason));
|
|
947
|
+
} finally {
|
|
948
|
+
setSurfaceBusy(false);
|
|
949
|
+
}
|
|
950
|
+
};
|
|
951
|
+
/** Save or clear one server's MCP override, then refresh the detail. */
|
|
952
|
+
const saveMcpOverride = async (serverKey, patch) => {
|
|
953
|
+
setSurfaceBusy(true);
|
|
954
|
+
try {
|
|
955
|
+
await postAction("set-mcp-override", {
|
|
956
|
+
sourceId,
|
|
957
|
+
suiteId,
|
|
958
|
+
serverKey,
|
|
959
|
+
override: patch
|
|
960
|
+
});
|
|
961
|
+
const next = await fetchSuiteDetail(sourceId, suiteId);
|
|
962
|
+
setDetail(next);
|
|
475
963
|
} catch (reason) {
|
|
476
|
-
|
|
964
|
+
setError(reason instanceof Error ? reason.message : String(reason));
|
|
477
965
|
} finally {
|
|
478
|
-
|
|
966
|
+
setSurfaceBusy(false);
|
|
479
967
|
}
|
|
480
968
|
};
|
|
481
|
-
const
|
|
482
|
-
setOpenMcp(openMcp === key ? void 0 : key);
|
|
483
|
-
};
|
|
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");
|
|
969
|
+
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") : detail.layout === "project-native" ? t("layoutProjectNative") : t("layoutSkills");
|
|
485
970
|
return (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
486
971
|
open: true,
|
|
487
972
|
onClose,
|
|
@@ -496,7 +981,20 @@ function SuiteDetailModal({ t, sourceId, suiteId, onClose }) {
|
|
|
496
981
|
}, t("cancel"))),
|
|
497
982
|
children: (0, react.createElement)(ErrorBoundary, {
|
|
498
983
|
fallback: (boundaryError) => (0, react.createElement)("div", { className: market_module_default.warnLine }, `${t("actionFail")}: ${boundaryError.message}`),
|
|
499
|
-
children: error !== void 0 ? (0, react.createElement)("div", { className: market_module_default.warnLine }, error) : detail === void 0 ? (0, react.createElement)("div", { className: market_module_default.empty }, t("loading")) : (0, react.createElement)("div", { className: market_module_default.detailSections }, (0, react.createElement)("section", { className: market_module_default.detailSection }, (0, react.createElement)("h4", { className: market_module_default.detailHead }, t("overviewSection")), (0, react.createElement)("div", { className: market_module_default.detailGrid }, (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("sourceLabel")), (0, react.createElement)("span", { className: market_module_default.detailValue }, detail.sourceId)), (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("dimensionLabel")), (0, react.createElement)("span", { className: market_module_default.detailValue }, detail.dimension === "user" ? t("dimensionUser") : t("dimensionProject"))), (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("layoutLabel")), (0, react.createElement)("span", { className: market_module_default.detailValue }, layoutLabel)), (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("statusLabel")), (0, react.createElement)("span", { className: detail.enabled ? market_module_default.okState : market_module_default.detailValue }, detail.installed ? detail.enabled ? t("installedBadge") : t("disabledLabel") : t("notInstalledLabel"))), detail.author === null ? null : (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("authorLabel")), (0, react.createElement)("span", { className: market_module_default.detailValue }, detail.author)), detail.keywords.length === 0 ? null : (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("keywordsLabel")), (0, react.createElement)("span", { className: market_module_default.detailValue }, detail.keywords.join(", ")))), detail.description === null ? null : (0, react.createElement)("p", { className: market_module_default.detailDesc }, detail.description), (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("rootLabel")), (0, react.createElement)("span", { className: market_module_default.mono }, detail.root))
|
|
984
|
+
children: error !== void 0 ? (0, react.createElement)("div", { className: market_module_default.warnLine }, error) : detail === void 0 ? (0, react.createElement)("div", { className: market_module_default.empty }, t("loading")) : (0, react.createElement)("div", { className: market_module_default.detailSections }, (0, react.createElement)("section", { className: market_module_default.detailSection }, (0, react.createElement)("h4", { className: market_module_default.detailHead }, t("overviewSection")), (0, react.createElement)("div", { className: market_module_default.detailGrid }, (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("sourceLabel")), (0, react.createElement)("span", { className: market_module_default.detailValue }, detail.sourceId)), (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("dimensionLabel")), (0, react.createElement)("span", { className: market_module_default.detailValue }, detail.dimension === "user" ? t("dimensionUser") : t("dimensionProject"))), (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("layoutLabel")), (0, react.createElement)("span", { className: market_module_default.detailValue }, layoutLabel)), (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("statusLabel")), (0, react.createElement)("span", { className: detail.enabled ? market_module_default.okState : market_module_default.detailValue }, detail.installed ? detail.enabled ? t("installedBadge") : t("disabledLabel") : t("notInstalledLabel"))), detail.author === null ? null : (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("authorLabel")), (0, react.createElement)("span", { className: market_module_default.detailValue }, detail.author)), detail.keywords.length === 0 ? null : (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("keywordsLabel")), (0, react.createElement)("span", { className: market_module_default.detailValue }, detail.keywords.join(", ")))), detail.description === null ? null : (0, react.createElement)("p", { className: market_module_default.detailDesc }, detail.description), (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("rootLabel")), (0, react.createElement)("span", { className: market_module_default.mono }, detail.root)), detail.installed === false || detail.surfaceToggles === null ? null : (0, react.createElement)("div", { className: market_module_default.detailCell }, (0, react.createElement)("span", { className: market_module_default.detailKey }, t("surfaceTogglesSection")), (0, react.createElement)("div", {
|
|
985
|
+
className: market_module_default.surfaceToggles,
|
|
986
|
+
title: t("surfaceTogglesHint")
|
|
987
|
+
}, ...SURFACE_TOGGLE_ROWS.map(([key, labelKey]) => (0, react.createElement)("label", {
|
|
988
|
+
key,
|
|
989
|
+
className: market_module_default.surfaceToggle
|
|
990
|
+
}, (0, react.createElement)("input", {
|
|
991
|
+
type: "checkbox",
|
|
992
|
+
checked: detail.surfaceToggles[key],
|
|
993
|
+
disabled: surfaceBusy,
|
|
994
|
+
onChange: (event) => {
|
|
995
|
+
toggleSurface(key, event.target.checked);
|
|
996
|
+
}
|
|
997
|
+
}), t(labelKey)))))), (0, react.createElement)("section", { className: market_module_default.detailSection }, (0, react.createElement)("h4", { className: market_module_default.detailHead }, `${t("skillsSection")} (${detail.skills.length})`), detail.skills.length === 0 ? (0, react.createElement)("div", { className: market_module_default.sidebarEmpty }, "—") : detail.skills.map((skill) => (0, react.createElement)("div", {
|
|
500
998
|
key: skill.name,
|
|
501
999
|
className: market_module_default.detailItem
|
|
502
1000
|
}, (0, react.createElement)("button", {
|
|
@@ -508,14 +1006,27 @@ function SuiteDetailModal({ t, sourceId, suiteId, onClose }) {
|
|
|
508
1006
|
}, (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", {
|
|
509
1007
|
className: market_module_default.warnLine,
|
|
510
1008
|
style: { margin: "0 0 6px" }
|
|
511
|
-
}, `⚠ ${detail.mcpErrors.join(t("sourceErrorSeparator"))}`), detail.mcpServers.length === 0 ? (0, react.createElement)("div", { className: market_module_default.sidebarEmpty }, "—") : detail.mcpServers.map((server) =>
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
1009
|
+
}, `⚠ ${detail.mcpErrors.join(t("sourceErrorSeparator"))}`), detail.mcpServers.length === 0 ? (0, react.createElement)("div", { className: market_module_default.sidebarEmpty }, "—") : detail.mcpServers.map((server) => {
|
|
1010
|
+
const override = detail.mcpOverrides?.[server.key];
|
|
1011
|
+
const overridden = override !== void 0 && Object.keys(override).length > 0;
|
|
1012
|
+
const disabled = override?.enabled === false;
|
|
1013
|
+
return (0, react.createElement)("div", {
|
|
1014
|
+
key: server.key,
|
|
1015
|
+
className: market_module_default.detailItem
|
|
1016
|
+
}, (0, react.createElement)("button", {
|
|
1017
|
+
type: "button",
|
|
1018
|
+
className: openMcp === server.key ? market_module_default.detailItemOpen : market_module_default.detailItemRow,
|
|
1019
|
+
onClick: () => toggleMcp(server.key)
|
|
1020
|
+
}, (0, react.createElement)("span", { className: market_module_default.detailItemName }, server.key), (0, react.createElement)("span", { className: market_module_default.detailItemDesc }, `${mcpSummary(server)}${disabled ? ` · ${t("mcpOverrideDisabledBadge")}` : overridden ? ` · ${t("mcpOverriddenBadge")}` : ""}`), (0, react.createElement)("span", { className: market_module_default.detailChevron }, openMcp === server.key ? "▾" : "▸")), openMcp === server.key ? (0, react.createElement)("div", { className: market_module_default.skillContent }, detail.installed && detail.surfaceToggles?.mcp !== false ? (0, react.createElement)(McpOverrideEditor, {
|
|
1021
|
+
t,
|
|
1022
|
+
serverKey: server.key,
|
|
1023
|
+
transport: server.type,
|
|
1024
|
+
override: override ?? {},
|
|
1025
|
+
busy: surfaceBusy,
|
|
1026
|
+
onSave: (patch) => saveMcpOverride(server.key, patch),
|
|
1027
|
+
onReset: () => saveMcpOverride(server.key, null)
|
|
1028
|
+
}) : null, (0, react.createElement)("pre", { className: market_module_default.mono }, JSON.stringify(server, null, 2))) : null);
|
|
1029
|
+
})), (0, react.createElement)("section", { className: market_module_default.detailSection }, (0, react.createElement)("h4", { className: market_module_default.detailHead }, `${t("commandsSection")} (${detail.commands.length})`), detail.commands.length === 0 ? (0, react.createElement)("div", { className: market_module_default.sidebarEmpty }, "—") : detail.commands.map((command) => (0, react.createElement)(PreviewRow, {
|
|
519
1030
|
key: `c:${command.name}`,
|
|
520
1031
|
t,
|
|
521
1032
|
name: `/${command.name}`,
|
|
@@ -557,8 +1068,110 @@ function mcpSummary(server) {
|
|
|
557
1068
|
if (server.type === "stdio") return server.command ?? server.type;
|
|
558
1069
|
return server.url ?? server.type;
|
|
559
1070
|
}
|
|
1071
|
+
/** Parse `KEY=VALUE` lines into a record; blank and comment lines are skipped. */
|
|
1072
|
+
function parseKvLines(text) {
|
|
1073
|
+
const result = {};
|
|
1074
|
+
for (const line of text.split("\n")) {
|
|
1075
|
+
const trimmed = line.trim();
|
|
1076
|
+
if (trimmed === "" || trimmed.startsWith("#")) continue;
|
|
1077
|
+
const eq = trimmed.indexOf("=");
|
|
1078
|
+
if (eq <= 0) continue;
|
|
1079
|
+
result[trimmed.slice(0, eq).trim()] = trimmed.slice(eq + 1).trim();
|
|
1080
|
+
}
|
|
1081
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
1082
|
+
}
|
|
1083
|
+
/** Format a record back into sorted `KEY=VALUE` lines for editing. */
|
|
1084
|
+
function formatKvLines(map) {
|
|
1085
|
+
if (map === void 0) return "";
|
|
1086
|
+
return Object.keys(map).sort().map((key) => `${key}=${map[key]}`).join("\n");
|
|
1087
|
+
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Per-server MCP override editor: enable/disable plus connection-input
|
|
1090
|
+
* replacement (url/headers for http servers, args/env for stdio). The
|
|
1091
|
+
* suite's own mcp.json stays source-owned; everything here persists as a
|
|
1092
|
+
* user override layered on top at mount time.
|
|
1093
|
+
*/
|
|
1094
|
+
function McpOverrideEditor(props) {
|
|
1095
|
+
const { t, transport, override, busy } = props;
|
|
1096
|
+
const [draft, setDraft] = (0, react.useState)(override);
|
|
1097
|
+
const kvHint = t("mcpOverrideKvHint");
|
|
1098
|
+
const isHttp = transport !== "stdio";
|
|
1099
|
+
/** Gather the draft fields into one sanitized override patch and save it. */
|
|
1100
|
+
const submit = () => {
|
|
1101
|
+
const patch = {};
|
|
1102
|
+
patch["enabled"] = draft["enabled"] !== false;
|
|
1103
|
+
if (isHttp && typeof draft["url"] === "string" && draft["url"] !== "") patch["url"] = draft["url"];
|
|
1104
|
+
const headers = parseKvLines(isHttp ? String(draft["__headers"] ?? "") : "");
|
|
1105
|
+
if (headers !== void 0) patch["headers"] = headers;
|
|
1106
|
+
const env = parseKvLines(!isHttp ? String(draft["__env"] ?? "") : "");
|
|
1107
|
+
if (env !== void 0) patch["env"] = env;
|
|
1108
|
+
const args = (!isHttp ? String(draft["__args"] ?? "") : "").split("\n").map((line) => line.trim()).filter((line) => line !== "");
|
|
1109
|
+
if (args.length > 0) patch["args"] = args;
|
|
1110
|
+
props.onSave(patch);
|
|
1111
|
+
};
|
|
1112
|
+
return (0, react.createElement)("div", { className: market_module_default.mcpOverrideForm }, (0, react.createElement)("label", { className: market_module_default.mcpOverrideCheck }, (0, react.createElement)("input", {
|
|
1113
|
+
type: "checkbox",
|
|
1114
|
+
checked: draft["enabled"] !== false,
|
|
1115
|
+
disabled: busy,
|
|
1116
|
+
onChange: (event) => setDraft({
|
|
1117
|
+
...draft,
|
|
1118
|
+
enabled: event.target.checked
|
|
1119
|
+
})
|
|
1120
|
+
}), t("mcpOverrideEnabled")), isHttp ? (0, react.createElement)("input", {
|
|
1121
|
+
className: market_module_default.mcpOverrideInput,
|
|
1122
|
+
value: typeof draft["url"] === "string" ? draft["url"] : "",
|
|
1123
|
+
placeholder: t("mcpOverrideUrlLabel"),
|
|
1124
|
+
disabled: busy,
|
|
1125
|
+
onChange: (event) => setDraft({
|
|
1126
|
+
...draft,
|
|
1127
|
+
url: event.target.value
|
|
1128
|
+
})
|
|
1129
|
+
}) : null, isHttp ? (0, react.createElement)("textarea", {
|
|
1130
|
+
className: market_module_default.mcpOverrideArea,
|
|
1131
|
+
rows: 3,
|
|
1132
|
+
placeholder: t("mcpOverrideHeadersLabel"),
|
|
1133
|
+
title: kvHint,
|
|
1134
|
+
value: typeof draft["__headers"] === "string" ? draft["__headers"] : formatKvLines(override["headers"]),
|
|
1135
|
+
disabled: busy,
|
|
1136
|
+
onChange: (event) => setDraft({
|
|
1137
|
+
...draft,
|
|
1138
|
+
__headers: event.target.value
|
|
1139
|
+
})
|
|
1140
|
+
}) : null, !isHttp ? (0, react.createElement)("textarea", {
|
|
1141
|
+
className: market_module_default.mcpOverrideArea,
|
|
1142
|
+
rows: 3,
|
|
1143
|
+
placeholder: t("mcpOverrideEnvLabel"),
|
|
1144
|
+
title: kvHint,
|
|
1145
|
+
value: typeof draft["__env"] === "string" ? draft["__env"] : formatKvLines(override["env"]),
|
|
1146
|
+
disabled: busy,
|
|
1147
|
+
onChange: (event) => setDraft({
|
|
1148
|
+
...draft,
|
|
1149
|
+
__env: event.target.value
|
|
1150
|
+
})
|
|
1151
|
+
}) : null, !isHttp ? (0, react.createElement)("textarea", {
|
|
1152
|
+
className: market_module_default.mcpOverrideArea,
|
|
1153
|
+
rows: 3,
|
|
1154
|
+
placeholder: t("mcpOverrideArgsLabel"),
|
|
1155
|
+
value: typeof draft["__args"] === "string" ? draft["__args"] : Array.isArray(override["args"]) ? override["args"].join("\n") : "",
|
|
1156
|
+
disabled: busy,
|
|
1157
|
+
onChange: (event) => setDraft({
|
|
1158
|
+
...draft,
|
|
1159
|
+
__args: event.target.value
|
|
1160
|
+
})
|
|
1161
|
+
}) : null, (0, react.createElement)("div", { className: market_module_default.mcpOverrideActions }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1162
|
+
variant: "primary",
|
|
1163
|
+
size: "sm",
|
|
1164
|
+
disabled: busy,
|
|
1165
|
+
onClick: submit
|
|
1166
|
+
}, t("mcpOverrideSave")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1167
|
+
variant: "ghost",
|
|
1168
|
+
size: "sm",
|
|
1169
|
+
disabled: busy,
|
|
1170
|
+
onClick: () => void props.onReset()
|
|
1171
|
+
}, t("mcpOverrideReset"))), (0, react.createElement)("div", { className: market_module_default.detailItemDesc }, kvHint));
|
|
1172
|
+
}
|
|
560
1173
|
function PreviewRow(props) {
|
|
561
|
-
const {
|
|
1174
|
+
const { name, description, open, onToggle, children } = props;
|
|
562
1175
|
return (0, react.createElement)("div", { className: market_module_default.detailItem }, (0, react.createElement)("button", {
|
|
563
1176
|
type: "button",
|
|
564
1177
|
className: open ? market_module_default.detailItemOpen : market_module_default.detailItemRow,
|
|
@@ -568,14 +1181,14 @@ function PreviewRow(props) {
|
|
|
568
1181
|
//#endregion
|
|
569
1182
|
//#region src/client/SearchFilterToolbar.module.css
|
|
570
1183
|
var SearchFilterToolbar_module_default = {
|
|
571
|
-
"filter": "
|
|
572
|
-
"filterCount": "
|
|
573
|
-
"filterGap": "
|
|
574
|
-
"filterOn": "
|
|
575
|
-
"search": "
|
|
576
|
-
"toolbar": "
|
|
577
|
-
"viewGap": "
|
|
578
|
-
"viewSwitch": "
|
|
1184
|
+
"filter": "vavGuW_filter",
|
|
1185
|
+
"filterCount": "vavGuW_filterCount",
|
|
1186
|
+
"filterGap": "vavGuW_filterGap",
|
|
1187
|
+
"filterOn": "vavGuW_filterOn",
|
|
1188
|
+
"search": "vavGuW_search",
|
|
1189
|
+
"toolbar": "vavGuW_toolbar",
|
|
1190
|
+
"viewGap": "vavGuW_viewGap",
|
|
1191
|
+
"viewSwitch": "vavGuW_viewSwitch"
|
|
579
1192
|
};
|
|
580
1193
|
//#endregion
|
|
581
1194
|
//#region src/client/SearchFilterToolbar.tsx
|
|
@@ -661,77 +1274,17 @@ const PROGRESS_STEP_LABELS = {
|
|
|
661
1274
|
cloning: "progressCloning",
|
|
662
1275
|
reading: "progressReading"
|
|
663
1276
|
};
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
*/
|
|
668
|
-
function startProgressPolling(report) {
|
|
669
|
-
let stopped = false;
|
|
670
|
-
const tick = async () => {
|
|
671
|
-
if (stopped) return;
|
|
672
|
-
try {
|
|
673
|
-
const progress = await fetchSourceProgress();
|
|
674
|
-
if (!stopped && progress.active) report({
|
|
675
|
-
step: progressStepLabel(progress.step),
|
|
676
|
-
error: void 0
|
|
677
|
-
});
|
|
678
|
-
} catch {}
|
|
679
|
-
if (!stopped) timer = setTimeout(tick, 800);
|
|
680
|
-
};
|
|
681
|
-
let timer = setTimeout(tick, 400);
|
|
682
|
-
return { stop: () => {
|
|
683
|
-
stopped = true;
|
|
684
|
-
clearTimeout(timer);
|
|
685
|
-
} };
|
|
686
|
-
}
|
|
687
|
-
function progressStepLabel(step) {
|
|
688
|
-
return PROGRESS_STEP_LABELS[step] ?? step;
|
|
1277
|
+
function progressStepLabel(t, step) {
|
|
1278
|
+
const key = PROGRESS_STEP_LABELS[step];
|
|
1279
|
+
return key === void 0 ? step : t(key);
|
|
689
1280
|
}
|
|
690
1281
|
/** Keep parameterized copy compatible with hosts whose bound translator ignores params. */
|
|
691
1282
|
function interpolate(text, params) {
|
|
692
1283
|
return text.replace(/\{(\w+)\}/g, (match, key) => key in params ? String(params[key]) : match);
|
|
693
1284
|
}
|
|
694
|
-
const EMPTY_OVERVIEW = {
|
|
695
|
-
sources: [],
|
|
696
|
-
suites: [],
|
|
697
|
-
totals: {
|
|
698
|
-
all: 0,
|
|
699
|
-
installed: 0,
|
|
700
|
-
enabled: 0
|
|
701
|
-
},
|
|
702
|
-
roots: {
|
|
703
|
-
user: "",
|
|
704
|
-
data: ""
|
|
705
|
-
}
|
|
706
|
-
};
|
|
707
|
-
/**
|
|
708
|
-
* Session-level overview cache: the first mount paints the last snapshot
|
|
709
|
-
* instantly (no empty-state flash on reopen), then revalidates in the
|
|
710
|
-
* background. Every refresh overwrites the cached copy.
|
|
711
|
-
*/
|
|
712
|
-
let cachedOverview;
|
|
713
|
-
let inflightOverview;
|
|
714
|
-
function loadOverview() {
|
|
715
|
-
const initial = cachedOverview ?? EMPTY_OVERVIEW;
|
|
716
|
-
if (inflightOverview === void 0) inflightOverview = fetchOverview().then((data) => {
|
|
717
|
-
cachedOverview = data;
|
|
718
|
-
return data;
|
|
719
|
-
}).finally(() => {
|
|
720
|
-
inflightOverview = void 0;
|
|
721
|
-
});
|
|
722
|
-
return {
|
|
723
|
-
initial,
|
|
724
|
-
revalidating: cachedOverview === void 0,
|
|
725
|
-
promise: inflightOverview
|
|
726
|
-
};
|
|
727
|
-
}
|
|
728
|
-
/** Invalidate the cached overview after any mutating action. */
|
|
729
|
-
function dropCachedOverview() {
|
|
730
|
-
cachedOverview = void 0;
|
|
731
|
-
}
|
|
732
1285
|
function MarketSection({ t, mode = "settings" }) {
|
|
733
1286
|
const [overview, setOverview] = (0, react.useState)(() => loadOverview().initial);
|
|
734
|
-
const [loading, setLoading] = (0, react.useState)(() =>
|
|
1287
|
+
const [loading, setLoading] = (0, react.useState)(() => loadOverview().revalidating);
|
|
735
1288
|
const [search, setSearch] = (0, react.useState)("");
|
|
736
1289
|
const [tab, setTab] = (0, react.useState)("all");
|
|
737
1290
|
const [category, setCategory] = (0, react.useState)("all");
|
|
@@ -739,6 +1292,7 @@ function MarketSection({ t, mode = "settings" }) {
|
|
|
739
1292
|
const [busy, setBusy] = (0, react.useState)(void 0);
|
|
740
1293
|
const [toast, setToast] = (0, react.useState)(void 0);
|
|
741
1294
|
const [confirm, setConfirm] = (0, react.useState)(void 0);
|
|
1295
|
+
const [installConfirm, setInstallConfirm] = (0, react.useState)(void 0);
|
|
742
1296
|
const [editor, setEditor] = (0, react.useState)(void 0);
|
|
743
1297
|
const [detail, setDetail] = (0, react.useState)(void 0);
|
|
744
1298
|
const [progress, setProgress] = (0, react.useState)({
|
|
@@ -746,7 +1300,7 @@ function MarketSection({ t, mode = "settings" }) {
|
|
|
746
1300
|
error: void 0
|
|
747
1301
|
});
|
|
748
1302
|
const refresh = (0, react.useCallback)(async () => {
|
|
749
|
-
|
|
1303
|
+
invalidateOverview();
|
|
750
1304
|
try {
|
|
751
1305
|
const data = await loadOverview().promise;
|
|
752
1306
|
setOverview(data);
|
|
@@ -766,7 +1320,7 @@ function MarketSection({ t, mode = "settings" }) {
|
|
|
766
1320
|
setBusy(key);
|
|
767
1321
|
try {
|
|
768
1322
|
await postAction(path, body);
|
|
769
|
-
|
|
1323
|
+
invalidateOverview();
|
|
770
1324
|
await refresh();
|
|
771
1325
|
return true;
|
|
772
1326
|
} catch (error) {
|
|
@@ -779,25 +1333,7 @@ function MarketSection({ t, mode = "settings" }) {
|
|
|
779
1333
|
setBusy(void 0);
|
|
780
1334
|
}
|
|
781
1335
|
}, [refresh, t]);
|
|
782
|
-
const scopeTotals = (0, react.useMemo)(() =>
|
|
783
|
-
if (category === "all") return overview.totals;
|
|
784
|
-
const scoped = overview.suites.filter((suite) => suite.sourceId === category);
|
|
785
|
-
return {
|
|
786
|
-
all: scoped.length,
|
|
787
|
-
installed: scoped.filter((suite) => suite.installed).length,
|
|
788
|
-
enabled: scoped.filter((suite) => suite.enabled).length
|
|
789
|
-
};
|
|
790
|
-
}, [overview, category]);
|
|
791
|
-
const filtered = (0, react.useMemo)(() => {
|
|
792
|
-
const needle = search.trim().toLowerCase();
|
|
793
|
-
return overview.suites.filter((suite) => {
|
|
794
|
-
if (category !== "all" && suite.sourceId !== category) return false;
|
|
795
|
-
if (tab === "installed" && !suite.installed) return false;
|
|
796
|
-
if (tab === "uninstalled" && suite.installed) return false;
|
|
797
|
-
if (needle === "") return true;
|
|
798
|
-
return `${suite.name} ${suite.description ?? ""} ${suite.keywords.join(" ")}`.toLowerCase().includes(needle);
|
|
799
|
-
});
|
|
800
|
-
}, [
|
|
1336
|
+
const { scopeTotals, filtered } = (0, react.useMemo)(() => deriveMarketViewModel(overview, search, tab, category), [
|
|
801
1337
|
overview,
|
|
802
1338
|
search,
|
|
803
1339
|
tab,
|
|
@@ -906,10 +1442,7 @@ function MarketSection({ t, mode = "settings" }) {
|
|
|
906
1442
|
suiteId: suite.suiteId
|
|
907
1443
|
}),
|
|
908
1444
|
onInstall: () => {
|
|
909
|
-
|
|
910
|
-
sourceId: suite.sourceId,
|
|
911
|
-
suiteId: suite.suiteId
|
|
912
|
-
});
|
|
1445
|
+
setInstallConfirm({ suite });
|
|
913
1446
|
},
|
|
914
1447
|
onAddSource: () => {
|
|
915
1448
|
if (suite.remoteUrl !== void 0) action(`a:${suite.suiteId}`, "sources/add", { url: suite.remoteUrl });
|
|
@@ -929,6 +1462,19 @@ function MarketSection({ t, mode = "settings" }) {
|
|
|
929
1462
|
key: toast.key,
|
|
930
1463
|
text: toast.message,
|
|
931
1464
|
onDone: () => setToast(void 0)
|
|
1465
|
+
}), installConfirm === void 0 ? null : (0, react.createElement)(InstallConfirmModal, {
|
|
1466
|
+
t,
|
|
1467
|
+
state: installConfirm,
|
|
1468
|
+
busy: busy !== void 0,
|
|
1469
|
+
onClose: () => setInstallConfirm(void 0),
|
|
1470
|
+
onConfirm: async () => {
|
|
1471
|
+
const ok = await action(`i:${installConfirm.suite.suiteId}`, "install", {
|
|
1472
|
+
sourceId: installConfirm.suite.sourceId,
|
|
1473
|
+
suiteId: installConfirm.suite.suiteId
|
|
1474
|
+
});
|
|
1475
|
+
if (ok) setInstallConfirm(void 0);
|
|
1476
|
+
return ok;
|
|
1477
|
+
}
|
|
932
1478
|
}), confirm === void 0 ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
933
1479
|
open: true,
|
|
934
1480
|
onClose: () => setConfirm(void 0),
|
|
@@ -968,10 +1514,10 @@ function MarketSection({ t, mode = "settings" }) {
|
|
|
968
1514
|
step: t("progressStarting"),
|
|
969
1515
|
error: void 0
|
|
970
1516
|
});
|
|
971
|
-
const poll =
|
|
1517
|
+
const poll = startSourceProgressPolling(setProgress, (step) => progressStepLabel(t, step));
|
|
972
1518
|
try {
|
|
973
1519
|
const derived = (await postAction("sources/add", body))["source"]?.id;
|
|
974
|
-
|
|
1520
|
+
invalidateOverview();
|
|
975
1521
|
await refresh();
|
|
976
1522
|
setEditor(void 0);
|
|
977
1523
|
if (derived !== void 0) setCategory(derived);
|
|
@@ -1008,226 +1554,113 @@ function MarketSection({ t, mode = "settings" }) {
|
|
|
1008
1554
|
}))
|
|
1009
1555
|
});
|
|
1010
1556
|
}
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1557
|
+
//#endregion
|
|
1558
|
+
//#region src/client/features/mcp-status/mcp-status-view-model.ts
|
|
1559
|
+
const searchableCache = /* @__PURE__ */ new WeakMap();
|
|
1560
|
+
/** Derive active rows, filter counts, and visible rows in one pass. */
|
|
1561
|
+
function deriveMcpStatusViewModel(payload, filter, search) {
|
|
1562
|
+
const searchable = searchableFor(payload);
|
|
1563
|
+
const activeEntries = searchable.map((item) => item.entry);
|
|
1564
|
+
const filterCounts = {
|
|
1565
|
+
all: 0,
|
|
1566
|
+
plugin: 0,
|
|
1567
|
+
direct: 0
|
|
1018
1568
|
};
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
}
|
|
1042
|
-
}, "✎"), onDelete === void 0 ? null : (0, react.createElement)("button", {
|
|
1043
|
-
type: "button",
|
|
1044
|
-
className: market_module_default.srcTabDel,
|
|
1045
|
-
title: t("remove"),
|
|
1046
|
-
onClick: (event) => {
|
|
1047
|
-
event.stopPropagation();
|
|
1048
|
-
onDelete();
|
|
1049
|
-
}
|
|
1050
|
-
}, "×"));
|
|
1051
|
-
}
|
|
1052
|
-
function SourceEditorModal(props) {
|
|
1053
|
-
const { t, editor } = props;
|
|
1054
|
-
const [local, setLocal] = (0, react.useState)(editor.mode === "edit" && editor.source.local === true);
|
|
1055
|
-
const [url, setUrl] = (0, react.useState)(editor.mode === "edit" ? editor.source.url : "");
|
|
1056
|
-
const [branch, setBranch] = (0, react.useState)(editor.mode === "edit" ? editor.source.branch ?? "" : "");
|
|
1057
|
-
const id = editor.mode === "edit" ? editor.source.id : "";
|
|
1058
|
-
const title = editor.mode === "edit" ? t("editSourceTitle") : t("addSourceTitle");
|
|
1059
|
-
return (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
1060
|
-
open: true,
|
|
1061
|
-
onClose: props.onClose,
|
|
1062
|
-
title,
|
|
1063
|
-
description: t("editorHint"),
|
|
1064
|
-
closeLabel: t("cancel"),
|
|
1065
|
-
className: market_module_default.editorDialog,
|
|
1066
|
-
footer: (0, react.createElement)("div", { className: market_module_default.modalFooter }, (0, react.createElement)("div", { className: market_module_default.modalFooterLeft }, editor.mode === "edit" ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1067
|
-
variant: "ghost",
|
|
1068
|
-
onClick: () => props.onRemove(id)
|
|
1069
|
-
}, `🗑 ${t("remove")}`) : null), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1070
|
-
variant: "ghost",
|
|
1071
|
-
onClick: props.onClose
|
|
1072
|
-
}, t("cancel")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1073
|
-
variant: "primary",
|
|
1074
|
-
disabled: props.busy,
|
|
1075
|
-
onClick: () => {
|
|
1076
|
-
props.onSave(url.trim(), branch.trim(), local);
|
|
1077
|
-
}
|
|
1078
|
-
}, t("save"))),
|
|
1079
|
-
children: (0, react.createElement)("div", { className: market_module_default.editorForm }, (0, react.createElement)("div", { className: market_module_default.modeRow }, (0, react.createElement)("button", {
|
|
1080
|
-
type: "button",
|
|
1081
|
-
className: local ? market_module_default.seg : market_module_default.segOn,
|
|
1082
|
-
onClick: () => setLocal(false)
|
|
1083
|
-
}, t("sourceModeGit")), (0, react.createElement)("button", {
|
|
1084
|
-
type: "button",
|
|
1085
|
-
className: local ? market_module_default.segOn : market_module_default.seg,
|
|
1086
|
-
onClick: () => setLocal(true)
|
|
1087
|
-
}, t("sourceModeLocal"))), editor.mode === "edit" ? (0, react.createElement)("div", { className: market_module_default.fieldGroup }, (0, react.createElement)("label", { className: market_module_default.fieldLabel }, t("sourceIdPh")), (0, react.createElement)("div", { className: market_module_default.staticId }, (0, react.createElement)("span", { className: market_module_default.staticIdValue }, id), (0, react.createElement)("span", { className: market_module_default.fieldHint }, t("idFixed")))) : null, (0, react.createElement)("div", { className: market_module_default.fieldGroup }, (0, react.createElement)("label", { className: market_module_default.fieldLabel }, local ? t("sourceUrlLocalPh") : t("sourceUrlPh")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
1088
|
-
placeholder: local ? t("sourceUrlLocalPh") : t("sourceUrlPh"),
|
|
1089
|
-
value: url,
|
|
1090
|
-
onChange: (event) => setUrl(event.target.value)
|
|
1091
|
-
}), (0, react.createElement)("span", { className: market_module_default.fieldHint }, local ? t("urlLocalHint") : t("urlGitHint"))), local ? null : (0, react.createElement)("div", { className: market_module_default.fieldGroup }, (0, react.createElement)("label", { className: market_module_default.fieldLabel }, t("branchPh")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
1092
|
-
placeholder: t("branchPh"),
|
|
1093
|
-
value: branch,
|
|
1094
|
-
onChange: (event) => setBranch(event.target.value)
|
|
1095
|
-
}), (0, react.createElement)("span", { className: market_module_default.fieldHint }, t("branchHint"))), props.progress.error === void 0 && props.progress.step === void 0 ? null : (0, react.createElement)("div", { className: props.progress.error === void 0 ? market_module_default.progress : market_module_default.progressError }, props.progress.error === void 0 ? (0, react.createElement)("span", { className: market_module_default.progressSpin }) : (0, react.createElement)("span", { className: market_module_default.progressFail }, "✕"), (0, react.createElement)("span", { className: market_module_default.progressText }, props.progress.error === void 0 ? props.progress.step : `${t("actionFail")}: ${props.progress.error}`)))
|
|
1096
|
-
});
|
|
1097
|
-
}
|
|
1098
|
-
/** A green/gray switch control for suite enable state. */
|
|
1099
|
-
function ToggleSwitch(props) {
|
|
1100
|
-
return (0, react.createElement)("button", {
|
|
1101
|
-
type: "button",
|
|
1102
|
-
role: "switch",
|
|
1103
|
-
"aria-checked": props.on,
|
|
1104
|
-
title: props.title,
|
|
1105
|
-
disabled: props.disabled,
|
|
1106
|
-
className: props.on ? market_module_default.switchOn : market_module_default.switchOff,
|
|
1107
|
-
onClick: (event) => {
|
|
1108
|
-
event.stopPropagation();
|
|
1109
|
-
props.onChange();
|
|
1569
|
+
let connected = 0;
|
|
1570
|
+
let failed = 0;
|
|
1571
|
+
const filtered = [];
|
|
1572
|
+
const needle = search.trim().toLowerCase();
|
|
1573
|
+
for (const item of searchable) {
|
|
1574
|
+
const entry = item.entry;
|
|
1575
|
+
filterCounts.all++;
|
|
1576
|
+
filterCounts[entry.kind]++;
|
|
1577
|
+
if (entry.state === "connected") connected++;
|
|
1578
|
+
if (entry.state === "failed") failed++;
|
|
1579
|
+
if (filter !== "all" && entry.kind !== filter) continue;
|
|
1580
|
+
if (needle !== "" && !item.haystack.includes(needle)) continue;
|
|
1581
|
+
filtered.push(entry);
|
|
1582
|
+
}
|
|
1583
|
+
return {
|
|
1584
|
+
activeEntries,
|
|
1585
|
+
filtered,
|
|
1586
|
+
filterCounts,
|
|
1587
|
+
visibleTotals: {
|
|
1588
|
+
all: activeEntries.length,
|
|
1589
|
+
connected,
|
|
1590
|
+
failed
|
|
1110
1591
|
}
|
|
1111
|
-
}, (0, react.createElement)("span", { className: market_module_default.switchThumb }));
|
|
1112
|
-
}
|
|
1113
|
-
function SuiteCard(props) {
|
|
1114
|
-
const { t, suite, busy } = props;
|
|
1115
|
-
const tags = [
|
|
1116
|
-
[t("surfaceSkills"), suite.surfaces.skills],
|
|
1117
|
-
[t("surfaceMcp"), suite.surfaces.mcp],
|
|
1118
|
-
[t("surfaceHooks"), suite.surfaces.hooks],
|
|
1119
|
-
[t("surfaceCommands"), suite.surfaces.commands],
|
|
1120
|
-
[t("surfaceAgents"), suite.surfaces.agents],
|
|
1121
|
-
[t("surfaceLsp"), suite.surfaces.lsp]
|
|
1122
|
-
].filter(([, count]) => count > 0);
|
|
1123
|
-
const layoutLabel = suite.layout === "agent-plugin-v1" ? t("layoutV1") : suite.layout === "claude-code" ? t("layoutCC") : suite.layout === "codex" ? t("layoutCodex") : suite.layout === "universal" ? t("layoutUniversal") : suite.layout === "cursor" ? t("layoutCursor") : suite.layout === "kimi" ? t("layoutKimi") : suite.layout === "remote" ? t("layoutRemote") : t("layoutSkills");
|
|
1124
|
-
const isRemote = suite.remoteUrl !== void 0;
|
|
1125
|
-
const stop = (callback) => (event) => {
|
|
1126
|
-
event.stopPropagation();
|
|
1127
|
-
callback();
|
|
1128
1592
|
};
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
size: "sm",
|
|
1140
|
-
disabled: busy,
|
|
1141
|
-
title: suite.remoteUrl,
|
|
1142
|
-
onClick: stop(props.onAddSource)
|
|
1143
|
-
}, t("addSource")) : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1144
|
-
variant: "primary",
|
|
1145
|
-
size: "sm",
|
|
1146
|
-
disabled: busy,
|
|
1147
|
-
onClick: stop(props.onInstall)
|
|
1148
|
-
}, t("install")), suite.installed ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1149
|
-
variant: "ghost",
|
|
1150
|
-
size: "sm",
|
|
1151
|
-
title: t("refresh"),
|
|
1152
|
-
disabled: busy,
|
|
1153
|
-
onClick: stop(props.onRefresh)
|
|
1154
|
-
}, "↻") : null, suite.installed ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1155
|
-
variant: "ghost",
|
|
1156
|
-
size: "sm",
|
|
1157
|
-
title: t("uninstall"),
|
|
1158
|
-
disabled: busy,
|
|
1159
|
-
onClick: stop(props.onUninstall)
|
|
1160
|
-
}, "🗑") : null)), (0, react.createElement)("p", { className: market_module_default.desc }, suite.description ?? ""), (0, react.createElement)("div", { className: market_module_default.meta }, (0, react.createElement)("span", { className: market_module_default.src }, `${suite.sourceId} · ${isRemote ? t("remoteRef") : suite.dimension === "user" ? t("dimensionUser") : t("dimensionProject")}`), (0, react.createElement)("span", { className: market_module_default.tag }, layoutLabel), suite.installed ? (0, react.createElement)("span", { className: suite.enabled ? market_module_default.okState : market_module_default.tag }, suite.enabled ? `✓ ${t("installedBadge")}` : t("installedBadge")) : null, ...tags.map(([label, count]) => (0, react.createElement)("span", {
|
|
1161
|
-
key: label,
|
|
1162
|
-
className: market_module_default.tag
|
|
1163
|
-
}, `${label} ${count}`)), suite.errors.length === 0 ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
1164
|
-
label: suite.errors.slice(0, 8).join(t("sourceErrorSeparator")),
|
|
1165
|
-
children: (0, react.createElement)("span", { className: market_module_default.warnLine }, `⚠ ${t("errors")} ${suite.errors.length}`)
|
|
1166
|
-
}), (suite.mcpErrors?.length ?? 0) === 0 ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
1167
|
-
label: suite.mcpErrors.slice(0, 8).join(t("sourceErrorSeparator")),
|
|
1168
|
-
children: (0, react.createElement)("span", { className: market_module_default.warnLine }, `⚠ ${t("mcpSection")} ${suite.mcpErrors.length}`)
|
|
1169
|
-
})));
|
|
1593
|
+
}
|
|
1594
|
+
function searchableFor(payload) {
|
|
1595
|
+
const cached = searchableCache.get(payload);
|
|
1596
|
+
if (cached !== void 0) return cached;
|
|
1597
|
+
const searchable = payload.entries.filter((entry) => entry.state !== "disabled").map((entry) => ({
|
|
1598
|
+
entry,
|
|
1599
|
+
haystack: `${entry.name} ${entry.source ?? ""} ${entry.endpoint ?? ""} ${entry.transport}`.toLowerCase()
|
|
1600
|
+
}));
|
|
1601
|
+
searchableCache.set(payload, searchable);
|
|
1602
|
+
return searchable;
|
|
1170
1603
|
}
|
|
1171
1604
|
//#endregion
|
|
1172
1605
|
//#region src/client/mcp-status.module.css
|
|
1173
1606
|
var mcp_status_module_default = {
|
|
1174
|
-
"boundary": "
|
|
1175
|
-
"card": "
|
|
1176
|
-
"cardReason": "
|
|
1177
|
-
"cardTop": "
|
|
1178
|
-
"chevron": "
|
|
1179
|
-
"config": "
|
|
1180
|
-
"detail": "
|
|
1181
|
-
"detailBody": "
|
|
1182
|
-
"detailDialog": "
|
|
1183
|
-
"detailEmpty": "
|
|
1184
|
-
"detailHead": "
|
|
1185
|
-
"detailMeta": "
|
|
1186
|
-
"detailSection": "
|
|
1187
|
-
"detailState": "
|
|
1188
|
-
"detailStateconnected": "
|
|
1189
|
-
"detailStatedegraded": "
|
|
1190
|
-
"detailStatedisabled": "
|
|
1191
|
-
"detailStatefailed": "
|
|
1192
|
-
"empty": "
|
|
1193
|
-
"endpoint": "
|
|
1194
|
-
"error": "
|
|
1195
|
-
"errorSummary": "
|
|
1196
|
-
"grid": "
|
|
1197
|
-
"header": "
|
|
1198
|
-
"headerActions": "
|
|
1199
|
-
"list": "
|
|
1200
|
-
"meta": "
|
|
1201
|
-
"modalFooter": "
|
|
1202
|
-
"name": "
|
|
1203
|
-
"reason": "
|
|
1204
|
-
"service": "
|
|
1205
|
-
"sourceDirect": "
|
|
1206
|
-
"sourcePlugin": "
|
|
1207
|
-
"state": "
|
|
1208
|
-
"stateconnected": "
|
|
1209
|
-
"statedegraded": "
|
|
1210
|
-
"statedisabled": "
|
|
1211
|
-
"statefailed": "
|
|
1212
|
-
"statusconnected": "
|
|
1213
|
-
"statusdegraded": "
|
|
1214
|
-
"statusdisabled": "
|
|
1215
|
-
"statusDot": "
|
|
1216
|
-
"statusfailed": "
|
|
1217
|
-
"subtitle": "
|
|
1218
|
-
"summary": "
|
|
1219
|
-
"summaryDotGreen": "
|
|
1220
|
-
"summaryDotRed": "
|
|
1221
|
-
"surface": "
|
|
1222
|
-
"title": "
|
|
1223
|
-
"tool": "
|
|
1224
|
-
"toolbar": "
|
|
1225
|
-
"toolCount": "
|
|
1226
|
-
"toolDescription": "
|
|
1227
|
-
"toolIndex": "
|
|
1228
|
-
"toolList": "
|
|
1229
|
-
"toolName": "
|
|
1230
|
-
"transport": "
|
|
1607
|
+
"boundary": "AUWlZW_boundary",
|
|
1608
|
+
"card": "AUWlZW_card",
|
|
1609
|
+
"cardReason": "AUWlZW_cardReason",
|
|
1610
|
+
"cardTop": "AUWlZW_cardTop",
|
|
1611
|
+
"chevron": "AUWlZW_chevron",
|
|
1612
|
+
"config": "AUWlZW_config",
|
|
1613
|
+
"detail": "AUWlZW_detail",
|
|
1614
|
+
"detailBody": "AUWlZW_detailBody",
|
|
1615
|
+
"detailDialog": "AUWlZW_detailDialog",
|
|
1616
|
+
"detailEmpty": "AUWlZW_detailEmpty",
|
|
1617
|
+
"detailHead": "AUWlZW_detailHead",
|
|
1618
|
+
"detailMeta": "AUWlZW_detailMeta",
|
|
1619
|
+
"detailSection": "AUWlZW_detailSection",
|
|
1620
|
+
"detailState": "AUWlZW_detailState",
|
|
1621
|
+
"detailStateconnected": "AUWlZW_detailStateconnected",
|
|
1622
|
+
"detailStatedegraded": "AUWlZW_detailStatedegraded",
|
|
1623
|
+
"detailStatedisabled": "AUWlZW_detailStatedisabled",
|
|
1624
|
+
"detailStatefailed": "AUWlZW_detailStatefailed",
|
|
1625
|
+
"empty": "AUWlZW_empty",
|
|
1626
|
+
"endpoint": "AUWlZW_endpoint",
|
|
1627
|
+
"error": "AUWlZW_error",
|
|
1628
|
+
"errorSummary": "AUWlZW_errorSummary",
|
|
1629
|
+
"grid": "AUWlZW_grid",
|
|
1630
|
+
"header": "AUWlZW_header",
|
|
1631
|
+
"headerActions": "AUWlZW_headerActions",
|
|
1632
|
+
"list": "AUWlZW_list",
|
|
1633
|
+
"meta": "AUWlZW_meta",
|
|
1634
|
+
"modalFooter": "AUWlZW_modalFooter",
|
|
1635
|
+
"name": "AUWlZW_name",
|
|
1636
|
+
"reason": "AUWlZW_reason",
|
|
1637
|
+
"service": "AUWlZW_service",
|
|
1638
|
+
"sourceDirect": "AUWlZW_sourceDirect",
|
|
1639
|
+
"sourcePlugin": "AUWlZW_sourcePlugin",
|
|
1640
|
+
"state": "AUWlZW_state",
|
|
1641
|
+
"stateconnected": "AUWlZW_stateconnected",
|
|
1642
|
+
"statedegraded": "AUWlZW_statedegraded",
|
|
1643
|
+
"statedisabled": "AUWlZW_statedisabled",
|
|
1644
|
+
"statefailed": "AUWlZW_statefailed",
|
|
1645
|
+
"statusconnected": "AUWlZW_statusconnected",
|
|
1646
|
+
"statusdegraded": "AUWlZW_statusdegraded",
|
|
1647
|
+
"statusdisabled": "AUWlZW_statusdisabled",
|
|
1648
|
+
"statusDot": "AUWlZW_statusDot",
|
|
1649
|
+
"statusfailed": "AUWlZW_statusfailed",
|
|
1650
|
+
"subtitle": "AUWlZW_subtitle",
|
|
1651
|
+
"summary": "AUWlZW_summary",
|
|
1652
|
+
"summaryDotGreen": "AUWlZW_summaryDotGreen",
|
|
1653
|
+
"summaryDotRed": "AUWlZW_summaryDotRed",
|
|
1654
|
+
"surface": "AUWlZW_surface",
|
|
1655
|
+
"title": "AUWlZW_title",
|
|
1656
|
+
"tool": "AUWlZW_tool",
|
|
1657
|
+
"toolbar": "AUWlZW_toolbar",
|
|
1658
|
+
"toolCount": "AUWlZW_toolCount",
|
|
1659
|
+
"toolDescription": "AUWlZW_toolDescription",
|
|
1660
|
+
"toolIndex": "AUWlZW_toolIndex",
|
|
1661
|
+
"toolList": "AUWlZW_toolList",
|
|
1662
|
+
"toolName": "AUWlZW_toolName",
|
|
1663
|
+
"transport": "AUWlZW_transport"
|
|
1231
1664
|
};
|
|
1232
1665
|
//#endregion
|
|
1233
1666
|
//#region src/client/McpStatusPanel.tsx
|
|
@@ -1262,24 +1695,7 @@ function McpStatusPanel({ t }) {
|
|
|
1262
1695
|
(0, react.useEffect)(() => {
|
|
1263
1696
|
refresh();
|
|
1264
1697
|
}, []);
|
|
1265
|
-
const activeEntries = payload
|
|
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
|
-
]);
|
|
1698
|
+
const { activeEntries, filtered, filterCounts, visibleTotals } = deriveMcpStatusViewModel(payload, filter, search);
|
|
1283
1699
|
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
1700
|
className: mcp_status_module_default.errorSummary,
|
|
1285
1701
|
title: `${visibleTotals.failed} ${t("mcpFailed")}`
|
|
@@ -1302,7 +1718,7 @@ function McpStatusPanel({ t }) {
|
|
|
1302
1718
|
].map((kind) => ({
|
|
1303
1719
|
id: kind,
|
|
1304
1720
|
label: filterLabel(t, kind),
|
|
1305
|
-
count: kind
|
|
1721
|
+
count: filterCounts[kind],
|
|
1306
1722
|
icon: (0, react.createElement)(McpFilterIcon, { kind }),
|
|
1307
1723
|
active: filter === kind,
|
|
1308
1724
|
onSelect: () => setFilter(kind)
|