dsh-agent-plugins-market 0.4.6 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +16 -10
  2. package/README.zh.md +16 -10
  3. package/client/client.js +540 -417
  4. package/client/client.js.map +1 -1
  5. package/lib/application/catalog.js +447 -0
  6. package/lib/application/details.js +136 -0
  7. package/lib/application/queries.js +1 -0
  8. package/lib/{discovery → catalog}/manifests.js +20 -12
  9. package/lib/{paths.js → catalog/paths.js} +5 -1
  10. package/lib/{skills-parse.js → catalog/skills-parse.js} +7 -4
  11. package/lib/catalog/source-catalog.js +38 -0
  12. package/lib/{discovery.js → catalog/suite-scanner.js} +28 -86
  13. package/lib/{discovery → catalog}/surfaces.js +9 -11
  14. package/lib/{validate.js → catalog/validate.js} +3 -3
  15. package/lib/context.js +11 -13
  16. package/lib/contracts/market.js +27 -0
  17. package/lib/contracts/mcp-status.js +2 -0
  18. package/lib/index.js +32 -49
  19. package/lib/{state.js → model/state.js} +2 -2
  20. package/lib/routes.js +21 -21
  21. package/lib/{commands-mounts.js → runtime/commands-mounts.js} +10 -11
  22. package/lib/{hooks-mounts.js → runtime/hooks-mounts.js} +1 -1
  23. package/lib/{mcp-config.js → runtime/mcp-config.js} +7 -4
  24. package/lib/{mcp-status.js → runtime/mcp-status.js} +8 -41
  25. package/lib/runtime/reconciler.js +46 -0
  26. package/lib/{skills-provider.js → runtime/skills-provider.js} +26 -23
  27. package/lib/runtime/tool-registry-observer.js +35 -0
  28. package/lib/types/application/catalog.d.ts +113 -0
  29. package/lib/types/application/details.d.ts +12 -0
  30. package/lib/types/application/queries.d.ts +33 -0
  31. package/lib/types/{discovery → catalog}/manifests.d.ts +1 -1
  32. package/lib/types/catalog/source-catalog.d.ts +3 -0
  33. package/lib/types/catalog/suite-scanner.d.ts +9 -0
  34. package/lib/types/{discovery → catalog}/surfaces.d.ts +1 -1
  35. package/lib/types/{validate.d.ts → catalog/validate.d.ts} +1 -1
  36. package/lib/types/context.d.ts +2 -2
  37. package/lib/types/contracts/market.d.ts +153 -0
  38. package/lib/types/contracts/mcp-status.d.ts +38 -0
  39. package/lib/types/index.d.ts +1 -1
  40. package/lib/types/{types.d.ts → model/types.d.ts} +2 -42
  41. package/lib/types/routes.d.ts +2 -2
  42. package/lib/types/{commands-mounts.d.ts → runtime/commands-mounts.d.ts} +1 -1
  43. package/lib/types/{hooks-mounts.d.ts → runtime/hooks-mounts.d.ts} +1 -1
  44. package/lib/types/{mcp-config.d.ts → runtime/mcp-config.d.ts} +1 -1
  45. package/lib/types/{mcp-mounts.d.ts → runtime/mcp-mounts.d.ts} +1 -1
  46. package/lib/types/runtime/mcp-status.d.ts +13 -0
  47. package/lib/types/runtime/reconciler.d.ts +33 -0
  48. package/lib/types/{skills-provider.d.ts → runtime/skills-provider.d.ts} +3 -3
  49. package/lib/types/runtime/tool-registry-observer.d.ts +14 -0
  50. package/package.json +34 -19
  51. package/schemas/README.md +2 -5
  52. package/lib/manager.js +0 -581
  53. package/lib/types/discovery.d.ts +0 -19
  54. package/lib/types/manager.d.ts +0 -124
  55. package/lib/types/mcp-status.d.ts +0 -51
  56. /package/lib/{git.js → catalog/git.js} +0 -0
  57. /package/lib/{types.js → model/types.js} +0 -0
  58. /package/lib/{mcp-mounts.js → runtime/mcp-mounts.js} +0 -0
  59. /package/lib/types/{git.d.ts → catalog/git.d.ts} +0 -0
  60. /package/lib/types/{paths.d.ts → catalog/paths.d.ts} +0 -0
  61. /package/lib/types/{skills-parse.d.ts → catalog/skills-parse.d.ts} +0 -0
  62. /package/lib/types/{state.d.ts → model/state.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_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.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;
@@ -291,34 +291,64 @@ const en = {
291
291
  mcpRetry: "Retry"
292
292
  };
293
293
  //#endregion
294
+ //#region src/contracts/market.ts
295
+ /** Browser-safe market wire records and route constants shared by host and client. */
296
+ /** Prefix for all Agent Plugins Market HTTP routes. */
297
+ const MARKET_API_PREFIX = "/api/agent-plugins/";
298
+ /** Fixed Agent Plugins Market HTTP routes. */
299
+ const MARKET_ROUTES = {
300
+ overview: `${MARKET_API_PREFIX}overview`,
301
+ mcpStatus: `${MARKET_API_PREFIX}mcp-status`,
302
+ progress: `${MARKET_API_PREFIX}progress`,
303
+ config: `${MARKET_API_PREFIX}config`,
304
+ suite: `${MARKET_API_PREFIX}suite`,
305
+ skill: `${MARKET_API_PREFIX}skill`,
306
+ addSource: `${MARKET_API_PREFIX}sources/add`,
307
+ updateSource: `${MARKET_API_PREFIX}sources/update`,
308
+ removeSource: `${MARKET_API_PREFIX}sources/remove`,
309
+ refreshSource: `${MARKET_API_PREFIX}sources/refresh`,
310
+ install: `${MARKET_API_PREFIX}install`,
311
+ uninstall: `${MARKET_API_PREFIX}uninstall`,
312
+ setEnabled: `${MARKET_API_PREFIX}set-enabled`
313
+ };
314
+ /** Build a suite-detail URL without duplicating route or query encoding logic. */
315
+ function suiteRoute(sourceId, suiteId) {
316
+ return `${MARKET_ROUTES.suite}?sourceId=${encodeURIComponent(sourceId)}&suiteId=${encodeURIComponent(suiteId)}`;
317
+ }
318
+ /** Build a skill-content URL without duplicating route or query encoding logic. */
319
+ function skillRoute(sourceId, suiteId, skill) {
320
+ return `${MARKET_ROUTES.skill}?sourceId=${encodeURIComponent(sourceId)}&suiteId=${encodeURIComponent(suiteId)}&skill=${encodeURIComponent(skill)}`;
321
+ }
322
+ //#endregion
294
323
  //#region src/client/api.ts
324
+ /** Typed fetch helpers over the host's `/api/agent-plugins/*` routes. */
295
325
  async function fetchOverview() {
296
- const response = await fetch("/api/agent-plugins/overview", { credentials: "same-origin" });
326
+ const response = await fetch(MARKET_ROUTES.overview, { credentials: "same-origin" });
297
327
  if (!response.ok) throw new Error(`overview failed: ${response.status}`);
298
328
  return response.json();
299
329
  }
300
330
  async function fetchSourceProgress() {
301
- const response = await fetch("/api/agent-plugins/progress", { credentials: "same-origin" });
331
+ const response = await fetch(MARKET_ROUTES.progress, { credentials: "same-origin" });
302
332
  if (!response.ok) throw new Error(`progress failed: ${response.status}`);
303
333
  return response.json();
304
334
  }
305
335
  async function fetchSuiteDetail(sourceId, suiteId) {
306
- const response = await fetch(`/api/agent-plugins/suite?sourceId=${encodeURIComponent(sourceId)}&suiteId=${encodeURIComponent(suiteId)}`, { credentials: "same-origin" });
336
+ const response = await fetch(suiteRoute(sourceId, suiteId), { credentials: "same-origin" });
307
337
  if (!response.ok) throw new Error(`suite detail failed: ${response.status}`);
308
338
  return response.json();
309
339
  }
310
340
  async function fetchMcpStatus() {
311
- const response = await fetch("/api/agent-plugins/mcp-status", { credentials: "same-origin" });
341
+ const response = await fetch(MARKET_ROUTES.mcpStatus, { credentials: "same-origin" });
312
342
  if (!response.ok) throw new Error(`MCP status failed: ${response.status}`);
313
343
  return response.json();
314
344
  }
315
345
  async function fetchSkillContent(sourceId, suiteId, skill) {
316
- const response = await fetch(`/api/agent-plugins/skill?sourceId=${encodeURIComponent(sourceId)}&suiteId=${encodeURIComponent(suiteId)}&skill=${encodeURIComponent(skill)}`, { credentials: "same-origin" });
346
+ const response = await fetch(skillRoute(sourceId, suiteId, skill), { credentials: "same-origin" });
317
347
  if (!response.ok) throw new Error(`skill content failed: ${response.status}`);
318
348
  return response.json();
319
349
  }
320
350
  async function postAction(path, body) {
321
- const response = await fetch(`/api/agent-plugins/${path}`, {
351
+ const response = await fetch(`${MARKET_API_PREFIX}${path}`, {
322
352
  method: "POST",
323
353
  credentials: "same-origin",
324
354
  headers: { "content-type": "application/json" },
@@ -329,6 +359,368 @@ async function postAction(path, body) {
329
359
  return payload;
330
360
  }
331
361
  //#endregion
362
+ //#region src/client/features/market/market-resource.ts
363
+ /** Market overview cache, invalidation, and source-progress resource helpers. */
364
+ const EMPTY_OVERVIEW = {
365
+ sources: [],
366
+ suites: [],
367
+ totals: {
368
+ all: 0,
369
+ installed: 0,
370
+ enabled: 0
371
+ },
372
+ roots: {
373
+ user: "",
374
+ data: ""
375
+ }
376
+ };
377
+ let cachedOverview;
378
+ let inflightOverview;
379
+ /** Load the last overview immediately and revalidate one shared request. */
380
+ function loadOverview() {
381
+ const initial = cachedOverview ?? EMPTY_OVERVIEW;
382
+ if (inflightOverview === void 0) inflightOverview = fetchOverview().then((data) => {
383
+ cachedOverview = data;
384
+ return data;
385
+ }).finally(() => {
386
+ inflightOverview = void 0;
387
+ });
388
+ return {
389
+ initial,
390
+ revalidating: cachedOverview === void 0,
391
+ promise: inflightOverview
392
+ };
393
+ }
394
+ /** Invalidate the shared overview after a mutating action. */
395
+ function invalidateOverview() {
396
+ cachedOverview = void 0;
397
+ }
398
+ /**
399
+ * Poll source mutation progress until stopped. Poll failures remain silent
400
+ * because the add-source request is authoritative for mutation success.
401
+ */
402
+ function startSourceProgressPolling(report, resolveStep = (step) => step) {
403
+ let stopped = false;
404
+ let timer;
405
+ const tick = async () => {
406
+ if (stopped) return;
407
+ try {
408
+ const progress = await fetchSourceProgress();
409
+ if (!stopped && progress.active) report({
410
+ step: resolveStep(progress.step),
411
+ error: void 0
412
+ });
413
+ } catch {}
414
+ if (!stopped) timer = setTimeout(() => {
415
+ tick();
416
+ }, 800);
417
+ };
418
+ timer = setTimeout(() => {
419
+ tick();
420
+ }, 400);
421
+ return { stop: () => {
422
+ stopped = true;
423
+ if (timer !== void 0) clearTimeout(timer);
424
+ } };
425
+ }
426
+ //#endregion
427
+ //#region src/client/features/market/market-view-model.ts
428
+ const searchableCache$1 = /* @__PURE__ */ new WeakMap();
429
+ /** Derive visible cards and scope counts in one pass over a normalized payload. */
430
+ function deriveMarketViewModel(overview, search, filter, category) {
431
+ const searchable = searchableFor$1(overview);
432
+ const needle = search.trim().toLowerCase();
433
+ let all = 0;
434
+ let installed = 0;
435
+ let enabled = 0;
436
+ const visible = [];
437
+ for (const entry of searchable) {
438
+ const suite = entry.suite;
439
+ if (category !== "all" && suite.sourceId !== category) continue;
440
+ all++;
441
+ if (suite.installed) installed++;
442
+ if (suite.enabled) enabled++;
443
+ if (filter === "installed" && !suite.installed) continue;
444
+ if (filter === "uninstalled" && suite.installed) continue;
445
+ if (needle !== "" && !entry.haystack.includes(needle)) continue;
446
+ visible.push(suite);
447
+ }
448
+ return {
449
+ scopeTotals: {
450
+ all,
451
+ installed,
452
+ enabled
453
+ },
454
+ filtered: visible
455
+ };
456
+ }
457
+ function searchableFor$1(overview) {
458
+ const cached = searchableCache$1.get(overview);
459
+ if (cached !== void 0) return cached;
460
+ const searchable = overview.suites.map((suite) => ({
461
+ suite,
462
+ haystack: `${suite.name} ${suite.description ?? ""} ${suite.keywords.join(" ")}`.toLowerCase()
463
+ }));
464
+ searchableCache$1.set(overview, searchable);
465
+ return searchable;
466
+ }
467
+ //#endregion
468
+ //#region src/client/market.module.css
469
+ var market_module_default = {
470
+ "body": "_72qoAq_body",
471
+ "card": "_72qoAq_card",
472
+ "cardActions": "_72qoAq_cardActions",
473
+ "cardDesc": "_72qoAq_cardDesc",
474
+ "cardName": "_72qoAq_cardName",
475
+ "cardTitle": "_72qoAq_cardTitle",
476
+ "cardTop": "_72qoAq_cardTop",
477
+ "desc": "_72qoAq_desc",
478
+ "detailBody": "_72qoAq_detailBody",
479
+ "detailCell": "_72qoAq_detailCell",
480
+ "detailChevron": "_72qoAq_detailChevron",
481
+ "detailDesc": "_72qoAq_detailDesc",
482
+ "detailDialog": "_72qoAq_detailDialog",
483
+ "detailGrid": "_72qoAq_detailGrid",
484
+ "detailHead": "_72qoAq_detailHead",
485
+ "detailItem": "_72qoAq_detailItem",
486
+ "detailItemDesc": "_72qoAq_detailItemDesc",
487
+ "detailItemName": "_72qoAq_detailItemName",
488
+ "detailItemOpen": "_72qoAq_detailItemOpen",
489
+ "detailItemRow": "_72qoAq_detailItemRow",
490
+ "detailKey": "_72qoAq_detailKey",
491
+ "detailSection": "_72qoAq_detailSection",
492
+ "detailSections": "_72qoAq_detailSections",
493
+ "detailValue": "_72qoAq_detailValue",
494
+ "dshApmSpin": "_72qoAq_dshApmSpin",
495
+ "editorDialog": "_72qoAq_editorDialog",
496
+ "editorForm": "_72qoAq_editorForm",
497
+ "empty": "_72qoAq_empty",
498
+ "fieldGroup": "_72qoAq_fieldGroup",
499
+ "fieldHint": "_72qoAq_fieldHint",
500
+ "fieldLabel": "_72qoAq_fieldLabel",
501
+ "grid": "_72qoAq_grid",
502
+ "header": "_72qoAq_header",
503
+ "list": "_72qoAq_list",
504
+ "market": "_72qoAq_market",
505
+ "marketControls": "_72qoAq_marketControls",
506
+ "mcpSurface": "_72qoAq_mcpSurface",
507
+ "meta": "_72qoAq_meta",
508
+ "modalFooter": "_72qoAq_modalFooter",
509
+ "modalFooterLeft": "_72qoAq_modalFooterLeft",
510
+ "modeRow": "_72qoAq_modeRow",
511
+ "mono": "_72qoAq_mono",
512
+ "okState": "_72qoAq_okState",
513
+ "pageEntry": "_72qoAq_pageEntry",
514
+ "pageMode": "_72qoAq_pageMode",
515
+ "pageView": "_72qoAq_pageView",
516
+ "progress": "_72qoAq_progress",
517
+ "progressError": "_72qoAq_progressError",
518
+ "progressFail": "_72qoAq_progressFail",
519
+ "progressSpin": "_72qoAq_progressSpin",
520
+ "progressText": "_72qoAq_progressText",
521
+ "searchGroup": "_72qoAq_searchGroup",
522
+ "seg": "_72qoAq_seg",
523
+ "segOn": "_72qoAq_segOn",
524
+ "skillContent": "_72qoAq_skillContent",
525
+ "sourceTabsRow": "_72qoAq_sourceTabsRow",
526
+ "sourceTabsScroll": "_72qoAq_sourceTabsScroll",
527
+ "spacer": "_72qoAq_spacer",
528
+ "src": "_72qoAq_src",
529
+ "srcTab": "_72qoAq_srcTab",
530
+ "srcTabDel": "_72qoAq_srcTabDel",
531
+ "srcTabEdit": "_72qoAq_srcTabEdit",
532
+ "srcTabMain": "_72qoAq_srcTabMain",
533
+ "srcTabOn": "_72qoAq_srcTabOn",
534
+ "staticId": "_72qoAq_staticId",
535
+ "staticIdValue": "_72qoAq_staticIdValue",
536
+ "sub": "_72qoAq_sub",
537
+ "surfaceSwitch": "_72qoAq_surfaceSwitch",
538
+ "switchOff": "_72qoAq_switchOff",
539
+ "switchOn": "_72qoAq_switchOn",
540
+ "switchThumb": "_72qoAq_switchThumb",
541
+ "tag": "_72qoAq_tag",
542
+ "title": "_72qoAq_title",
543
+ "titleRow": "_72qoAq_titleRow",
544
+ "version": "_72qoAq_version",
545
+ "warnLine": "_72qoAq_warnLine"
546
+ };
547
+ //#endregion
548
+ //#region src/client/features/market/SourceTab.tsx
549
+ /** A source tab with trailing edit and delete controls. */
550
+ /** A source chip with a trailing delete control (deletion confirms at the section level). */
551
+ function SourceTab(props) {
552
+ const { t, active = false, label, onSelect, onDelete, onEdit } = props;
553
+ return (0, react.createElement)("div", { className: active ? market_module_default.srcTabOn : market_module_default.srcTab }, (0, react.createElement)("button", {
554
+ type: "button",
555
+ className: market_module_default.srcTabMain,
556
+ onClick: onSelect
557
+ }, label), onEdit === void 0 ? null : (0, react.createElement)("button", {
558
+ type: "button",
559
+ className: market_module_default.srcTabEdit,
560
+ title: t("editSource"),
561
+ onClick: (event) => {
562
+ event.stopPropagation();
563
+ onEdit();
564
+ }
565
+ }, "✎"), onDelete === void 0 ? null : (0, react.createElement)("button", {
566
+ type: "button",
567
+ className: market_module_default.srcTabDel,
568
+ title: t("remove"),
569
+ onClick: (event) => {
570
+ event.stopPropagation();
571
+ onDelete();
572
+ }
573
+ }, "×"));
574
+ }
575
+ //#endregion
576
+ //#region src/client/features/market/SourceEditorModal.tsx
577
+ /** Source editor modal for adding or editing a catalog source. */
578
+ function SourceEditorModal(props) {
579
+ const { t, editor } = props;
580
+ const [local, setLocal] = (0, react.useState)(editor.mode === "edit" && editor.source.local === true);
581
+ const [url, setUrl] = (0, react.useState)(editor.mode === "edit" ? editor.source.url : "");
582
+ const [branch, setBranch] = (0, react.useState)(editor.mode === "edit" ? editor.source.branch ?? "" : "");
583
+ const id = editor.mode === "edit" ? editor.source.id : "";
584
+ const title = editor.mode === "edit" ? t("editSourceTitle") : t("addSourceTitle");
585
+ return (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
586
+ open: true,
587
+ onClose: props.onClose,
588
+ title,
589
+ description: t("editorHint"),
590
+ closeLabel: t("cancel"),
591
+ className: market_module_default.editorDialog,
592
+ 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, {
593
+ variant: "ghost",
594
+ onClick: () => props.onRemove(id)
595
+ }, `🗑 ${t("remove")}`) : null), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
596
+ variant: "ghost",
597
+ onClick: props.onClose
598
+ }, t("cancel")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
599
+ variant: "primary",
600
+ disabled: props.busy,
601
+ onClick: () => {
602
+ props.onSave(url.trim(), branch.trim(), local);
603
+ }
604
+ }, t("save"))),
605
+ children: (0, react.createElement)("div", { className: market_module_default.editorForm }, (0, react.createElement)("div", { className: market_module_default.modeRow }, (0, react.createElement)("button", {
606
+ type: "button",
607
+ className: local ? market_module_default.seg : market_module_default.segOn,
608
+ onClick: () => setLocal(false)
609
+ }, t("sourceModeGit")), (0, react.createElement)("button", {
610
+ type: "button",
611
+ className: local ? market_module_default.segOn : market_module_default.seg,
612
+ onClick: () => setLocal(true)
613
+ }, 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, {
614
+ placeholder: local ? t("sourceUrlLocalPh") : t("sourceUrlPh"),
615
+ value: url,
616
+ onChange: (event) => setUrl(event.target.value)
617
+ }), (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, {
618
+ placeholder: t("branchPh"),
619
+ value: branch,
620
+ onChange: (event) => setBranch(event.target.value)
621
+ }), (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}`)))
622
+ });
623
+ }
624
+ //#endregion
625
+ //#region src/client/ui/ToggleSwitch.tsx
626
+ /** Shared green/gray switch control used by suite cards. */
627
+ /** A green/gray switch control for suite enable state. */
628
+ function ToggleSwitch(props) {
629
+ return (0, react.createElement)("button", {
630
+ type: "button",
631
+ role: "switch",
632
+ "aria-checked": props.on,
633
+ title: props.title,
634
+ disabled: props.disabled,
635
+ className: props.on ? market_module_default.switchOn : market_module_default.switchOff,
636
+ onClick: (event) => {
637
+ event.stopPropagation();
638
+ props.onChange();
639
+ }
640
+ }, (0, react.createElement)("span", { className: market_module_default.switchThumb }));
641
+ }
642
+ //#endregion
643
+ //#region src/client/features/market/SuiteCard.tsx
644
+ /** A suite card in the market grid/list. */
645
+ function SuiteCard(props) {
646
+ const { t, suite, busy } = props;
647
+ const tags = [
648
+ [t("surfaceSkills"), suite.surfaces.skills],
649
+ [t("surfaceMcp"), suite.surfaces.mcp],
650
+ [t("surfaceHooks"), suite.surfaces.hooks],
651
+ [t("surfaceCommands"), suite.surfaces.commands],
652
+ [t("surfaceAgents"), suite.surfaces.agents],
653
+ [t("surfaceLsp"), suite.surfaces.lsp]
654
+ ].filter(([, count]) => count > 0);
655
+ 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");
656
+ const isRemote = suite.remoteUrl !== void 0;
657
+ const stop = (callback) => (event) => {
658
+ event.stopPropagation();
659
+ callback();
660
+ };
661
+ return (0, react.createElement)("article", {
662
+ className: market_module_default.card,
663
+ onClick: props.onOpen
664
+ }, (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, {
665
+ on: suite.enabled,
666
+ disabled: busy,
667
+ title: suite.enabled ? t("disable") : t("enable"),
668
+ onChange: props.onToggle
669
+ }) : isRemote ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
670
+ variant: "primary",
671
+ size: "sm",
672
+ disabled: busy,
673
+ title: suite.remoteUrl,
674
+ onClick: stop(props.onAddSource)
675
+ }, t("addSource")) : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
676
+ variant: "primary",
677
+ size: "sm",
678
+ disabled: busy,
679
+ onClick: stop(props.onInstall)
680
+ }, t("install")), suite.installed ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
681
+ variant: "ghost",
682
+ size: "sm",
683
+ title: t("refresh"),
684
+ disabled: busy,
685
+ onClick: stop(props.onRefresh)
686
+ }, "↻") : null, suite.installed ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
687
+ variant: "ghost",
688
+ size: "sm",
689
+ title: t("uninstall"),
690
+ disabled: busy,
691
+ onClick: stop(props.onUninstall)
692
+ }, "🗑") : 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", {
693
+ key: label,
694
+ className: market_module_default.tag
695
+ }, `${label} ${count}`)), suite.errors.length === 0 ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
696
+ label: suite.errors.slice(0, 8).join(t("sourceErrorSeparator")),
697
+ children: (0, react.createElement)("span", { className: market_module_default.warnLine }, `⚠ ${t("errors")} ${suite.errors.length}`)
698
+ }), (suite.mcpErrors?.length ?? 0) === 0 ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
699
+ label: suite.mcpErrors.slice(0, 8).join(t("sourceErrorSeparator")),
700
+ children: (0, react.createElement)("span", { className: market_module_default.warnLine }, `⚠ ${t("mcpSection")} ${suite.mcpErrors.length}`)
701
+ })));
702
+ }
703
+ //#endregion
704
+ //#region src/client/ui/StatusIcon.tsx
705
+ /** Shared status icon used by market and MCP status filter tabs. */
706
+ /** An SVG status icon for the all/installed/uninstalled filter tabs. */
707
+ function StatusIcon({ kind }) {
708
+ const common = {
709
+ width: 16,
710
+ height: 16,
711
+ viewBox: "0 0 16 16",
712
+ fill: "none",
713
+ "aria-hidden": true
714
+ };
715
+ if (kind === "installed") return (0, react.createElement)("svg", common, (0, react.createElement)("circle", {
716
+ cx: 8,
717
+ cy: 8,
718
+ r: 5.5
719
+ }), (0, react.createElement)("path", { d: "m5.5 8 1.7 1.7 3.4-3.4" }));
720
+ if (kind === "uninstalled") return (0, react.createElement)("svg", common, (0, react.createElement)("path", { d: "M8 2v8m-3-3 3 3 3-3M3 13h10" }));
721
+ 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" }));
722
+ }
723
+ //#endregion
332
724
  //#region src/client/ErrorBoundary.tsx
333
725
  /**
334
726
  * Error boundary for untrusted preview content.
@@ -351,85 +743,18 @@ var ErrorBoundary = class extends react.Component {
351
743
  }
352
744
  };
353
745
  //#endregion
354
- //#region src/client/market.module.css
355
- var market_module_default = {
356
- "body": "qMtKNa_body",
357
- "card": "qMtKNa_card",
358
- "cardActions": "qMtKNa_cardActions",
359
- "cardDesc": "qMtKNa_cardDesc",
360
- "cardName": "qMtKNa_cardName",
361
- "cardTitle": "qMtKNa_cardTitle",
362
- "cardTop": "qMtKNa_cardTop",
363
- "desc": "qMtKNa_desc",
364
- "detailBody": "qMtKNa_detailBody",
365
- "detailCell": "qMtKNa_detailCell",
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
- };
746
+ //#region src/client/features/suite-detail/suite-detail-resource.ts
747
+ /** Create a request guard for one detail modal instance. */
748
+ function createLatestRequestGuard() {
749
+ let revision = 0;
750
+ return {
751
+ next: () => ++revision,
752
+ invalidate: () => {
753
+ revision++;
754
+ },
755
+ isCurrent: (requestId) => requestId === revision
756
+ };
757
+ }
433
758
  //#endregion
434
759
  //#region src/client/SuiteDetail.tsx
435
760
  /**
@@ -446,12 +771,16 @@ function SuiteDetailModal({ t, sourceId, suiteId, onClose }) {
446
771
  const [openSkill, setOpenSkill] = (0, react.useState)(void 0);
447
772
  const [skillText, setSkillText] = (0, react.useState)(void 0);
448
773
  const [skillLoading, setSkillLoading] = (0, react.useState)(false);
774
+ const skillRequestGuard = (0, react.useRef)(createLatestRequestGuard());
449
775
  const [openMcp, setOpenMcp] = (0, react.useState)(void 0);
450
776
  const [openPreview, setOpenPreview] = (0, react.useState)(void 0);
451
777
  (0, react.useEffect)(() => {
452
778
  let cancelled = false;
779
+ skillRequestGuard.current.invalidate();
453
780
  setDetail(void 0);
454
781
  setError(void 0);
782
+ setOpenSkill(void 0);
783
+ setSkillText(void 0);
455
784
  fetchSuiteDetail(sourceId, suiteId).then((value) => {
456
785
  if (!cancelled) setDetail(value);
457
786
  }).catch((reason) => {
@@ -459,9 +788,11 @@ function SuiteDetailModal({ t, sourceId, suiteId, onClose }) {
459
788
  });
460
789
  return () => {
461
790
  cancelled = true;
791
+ skillRequestGuard.current.invalidate();
462
792
  };
463
793
  }, [sourceId, suiteId]);
464
794
  const toggleSkill = async (name) => {
795
+ const requestId = skillRequestGuard.current.next();
465
796
  if (openSkill === name) {
466
797
  setOpenSkill(void 0);
467
798
  return;
@@ -471,11 +802,11 @@ function SuiteDetailModal({ t, sourceId, suiteId, onClose }) {
471
802
  setSkillText(void 0);
472
803
  try {
473
804
  const content = await fetchSkillContent(sourceId, suiteId, name);
474
- setSkillText(content.content);
805
+ if (skillRequestGuard.current.isCurrent(requestId)) setSkillText(content.content);
475
806
  } catch (reason) {
476
- setSkillText(`⚠ ${reason instanceof Error ? reason.message : String(reason)}`);
807
+ if (skillRequestGuard.current.isCurrent(requestId)) setSkillText(`⚠ ${reason instanceof Error ? reason.message : String(reason)}`);
477
808
  } finally {
478
- setSkillLoading(false);
809
+ if (skillRequestGuard.current.isCurrent(requestId)) setSkillLoading(false);
479
810
  }
480
811
  };
481
812
  const toggleMcp = (key) => {
@@ -558,7 +889,7 @@ function mcpSummary(server) {
558
889
  return server.url ?? server.type;
559
890
  }
560
891
  function PreviewRow(props) {
561
- const { t: _t, name, description, open, onToggle, children } = props;
892
+ const { name, description, open, onToggle, children } = props;
562
893
  return (0, react.createElement)("div", { className: market_module_default.detailItem }, (0, react.createElement)("button", {
563
894
  type: "button",
564
895
  className: open ? market_module_default.detailItemOpen : market_module_default.detailItemRow,
@@ -568,14 +899,14 @@ function PreviewRow(props) {
568
899
  //#endregion
569
900
  //#region src/client/SearchFilterToolbar.module.css
570
901
  var SearchFilterToolbar_module_default = {
571
- "filter": "R7YLDa_filter",
572
- "filterCount": "R7YLDa_filterCount",
573
- "filterGap": "R7YLDa_filterGap",
574
- "filterOn": "R7YLDa_filterOn",
575
- "search": "R7YLDa_search",
576
- "toolbar": "R7YLDa_toolbar",
577
- "viewGap": "R7YLDa_viewGap",
578
- "viewSwitch": "R7YLDa_viewSwitch"
902
+ "filter": "vavGuW_filter",
903
+ "filterCount": "vavGuW_filterCount",
904
+ "filterGap": "vavGuW_filterGap",
905
+ "filterOn": "vavGuW_filterOn",
906
+ "search": "vavGuW_search",
907
+ "toolbar": "vavGuW_toolbar",
908
+ "viewGap": "vavGuW_viewGap",
909
+ "viewSwitch": "vavGuW_viewSwitch"
579
910
  };
580
911
  //#endregion
581
912
  //#region src/client/SearchFilterToolbar.tsx
@@ -661,77 +992,17 @@ const PROGRESS_STEP_LABELS = {
661
992
  cloning: "progressCloning",
662
993
  reading: "progressReading"
663
994
  };
664
- /**
665
- * Poll the host's source-mutation progress while an add-source request runs.
666
- * Failures of the poll itself never surface: the add request is the authority.
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;
995
+ function progressStepLabel(t, step) {
996
+ const key = PROGRESS_STEP_LABELS[step];
997
+ return key === void 0 ? step : t(key);
689
998
  }
690
999
  /** Keep parameterized copy compatible with hosts whose bound translator ignores params. */
691
1000
  function interpolate(text, params) {
692
1001
  return text.replace(/\{(\w+)\}/g, (match, key) => key in params ? String(params[key]) : match);
693
1002
  }
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
1003
  function MarketSection({ t, mode = "settings" }) {
733
1004
  const [overview, setOverview] = (0, react.useState)(() => loadOverview().initial);
734
- const [loading, setLoading] = (0, react.useState)(() => cachedOverview === void 0);
1005
+ const [loading, setLoading] = (0, react.useState)(() => loadOverview().revalidating);
735
1006
  const [search, setSearch] = (0, react.useState)("");
736
1007
  const [tab, setTab] = (0, react.useState)("all");
737
1008
  const [category, setCategory] = (0, react.useState)("all");
@@ -746,7 +1017,7 @@ function MarketSection({ t, mode = "settings" }) {
746
1017
  error: void 0
747
1018
  });
748
1019
  const refresh = (0, react.useCallback)(async () => {
749
- dropCachedOverview();
1020
+ invalidateOverview();
750
1021
  try {
751
1022
  const data = await loadOverview().promise;
752
1023
  setOverview(data);
@@ -766,7 +1037,7 @@ function MarketSection({ t, mode = "settings" }) {
766
1037
  setBusy(key);
767
1038
  try {
768
1039
  await postAction(path, body);
769
- dropCachedOverview();
1040
+ invalidateOverview();
770
1041
  await refresh();
771
1042
  return true;
772
1043
  } catch (error) {
@@ -779,25 +1050,7 @@ function MarketSection({ t, mode = "settings" }) {
779
1050
  setBusy(void 0);
780
1051
  }
781
1052
  }, [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
- }, [
1053
+ const { scopeTotals, filtered } = (0, react.useMemo)(() => deriveMarketViewModel(overview, search, tab, category), [
801
1054
  overview,
802
1055
  search,
803
1056
  tab,
@@ -968,10 +1221,10 @@ function MarketSection({ t, mode = "settings" }) {
968
1221
  step: t("progressStarting"),
969
1222
  error: void 0
970
1223
  });
971
- const poll = startProgressPolling(setProgress);
1224
+ const poll = startSourceProgressPolling(setProgress, (step) => progressStepLabel(t, step));
972
1225
  try {
973
1226
  const derived = (await postAction("sources/add", body))["source"]?.id;
974
- dropCachedOverview();
1227
+ invalidateOverview();
975
1228
  await refresh();
976
1229
  setEditor(void 0);
977
1230
  if (derived !== void 0) setCategory(derived);
@@ -1008,226 +1261,113 @@ function MarketSection({ t, mode = "settings" }) {
1008
1261
  }))
1009
1262
  });
1010
1263
  }
1011
- function StatusIcon({ kind }) {
1012
- const common = {
1013
- width: 16,
1014
- height: 16,
1015
- viewBox: "0 0 16 16",
1016
- fill: "none",
1017
- "aria-hidden": true
1264
+ //#endregion
1265
+ //#region src/client/features/mcp-status/mcp-status-view-model.ts
1266
+ const searchableCache = /* @__PURE__ */ new WeakMap();
1267
+ /** Derive active rows, filter counts, and visible rows in one pass. */
1268
+ function deriveMcpStatusViewModel(payload, filter, search) {
1269
+ const searchable = searchableFor(payload);
1270
+ const activeEntries = searchable.map((item) => item.entry);
1271
+ const filterCounts = {
1272
+ all: 0,
1273
+ plugin: 0,
1274
+ direct: 0
1018
1275
  };
1019
- if (kind === "installed") return (0, react.createElement)("svg", common, (0, react.createElement)("circle", {
1020
- cx: 8,
1021
- cy: 8,
1022
- r: 5.5
1023
- }), (0, react.createElement)("path", { d: "m5.5 8 1.7 1.7 3.4-3.4" }));
1024
- if (kind === "uninstalled") return (0, react.createElement)("svg", common, (0, react.createElement)("path", { d: "M8 2v8m-3-3 3 3 3-3M3 13h10" }));
1025
- return (0, react.createElement)("svg", common, (0, react.createElement)("path", { d: "M2.5 5 8 2.5 13.5 5 8 7.5 2.5 5Zm0 3L8 10.5 13.5 8M2.5 11 8 13.5 13.5 11" }));
1026
- }
1027
- /** A source tab with a trailing delete control (deletion confirms at the section level). */
1028
- function SourceTab(props) {
1029
- const { t, active = false, label, onSelect, onDelete, onEdit } = props;
1030
- return (0, react.createElement)("div", { className: active ? market_module_default.srcTabOn : market_module_default.srcTab }, (0, react.createElement)("button", {
1031
- type: "button",
1032
- className: market_module_default.srcTabMain,
1033
- onClick: onSelect
1034
- }, label), onEdit === void 0 ? null : (0, react.createElement)("button", {
1035
- type: "button",
1036
- className: market_module_default.srcTabEdit,
1037
- title: t("editSource"),
1038
- onClick: (event) => {
1039
- event.stopPropagation();
1040
- onEdit();
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();
1276
+ let connected = 0;
1277
+ let failed = 0;
1278
+ const filtered = [];
1279
+ const needle = search.trim().toLowerCase();
1280
+ for (const item of searchable) {
1281
+ const entry = item.entry;
1282
+ filterCounts.all++;
1283
+ filterCounts[entry.kind]++;
1284
+ if (entry.state === "connected") connected++;
1285
+ if (entry.state === "failed") failed++;
1286
+ if (filter !== "all" && entry.kind !== filter) continue;
1287
+ if (needle !== "" && !item.haystack.includes(needle)) continue;
1288
+ filtered.push(entry);
1289
+ }
1290
+ return {
1291
+ activeEntries,
1292
+ filtered,
1293
+ filterCounts,
1294
+ visibleTotals: {
1295
+ all: activeEntries.length,
1296
+ connected,
1297
+ failed
1110
1298
  }
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
1299
  };
1129
- return (0, react.createElement)("article", {
1130
- className: market_module_default.card,
1131
- onClick: props.onOpen
1132
- }, (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, {
1133
- on: suite.enabled,
1134
- disabled: busy,
1135
- title: suite.enabled ? t("disable") : t("enable"),
1136
- onChange: props.onToggle
1137
- }) : isRemote ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1138
- variant: "primary",
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
- })));
1300
+ }
1301
+ function searchableFor(payload) {
1302
+ const cached = searchableCache.get(payload);
1303
+ if (cached !== void 0) return cached;
1304
+ const searchable = payload.entries.filter((entry) => entry.state !== "disabled").map((entry) => ({
1305
+ entry,
1306
+ haystack: `${entry.name} ${entry.source ?? ""} ${entry.endpoint ?? ""} ${entry.transport}`.toLowerCase()
1307
+ }));
1308
+ searchableCache.set(payload, searchable);
1309
+ return searchable;
1170
1310
  }
1171
1311
  //#endregion
1172
1312
  //#region src/client/mcp-status.module.css
1173
1313
  var mcp_status_module_default = {
1174
- "boundary": "--KJaG_boundary",
1175
- "card": "--KJaG_card",
1176
- "cardReason": "--KJaG_cardReason",
1177
- "cardTop": "--KJaG_cardTop",
1178
- "chevron": "--KJaG_chevron",
1179
- "config": "--KJaG_config",
1180
- "detail": "--KJaG_detail",
1181
- "detailBody": "--KJaG_detailBody",
1182
- "detailDialog": "--KJaG_detailDialog",
1183
- "detailEmpty": "--KJaG_detailEmpty",
1184
- "detailHead": "--KJaG_detailHead",
1185
- "detailMeta": "--KJaG_detailMeta",
1186
- "detailSection": "--KJaG_detailSection",
1187
- "detailState": "--KJaG_detailState",
1188
- "detailStateconnected": "--KJaG_detailStateconnected",
1189
- "detailStatedegraded": "--KJaG_detailStatedegraded",
1190
- "detailStatedisabled": "--KJaG_detailStatedisabled",
1191
- "detailStatefailed": "--KJaG_detailStatefailed",
1192
- "empty": "--KJaG_empty",
1193
- "endpoint": "--KJaG_endpoint",
1194
- "error": "--KJaG_error",
1195
- "errorSummary": "--KJaG_errorSummary",
1196
- "grid": "--KJaG_grid",
1197
- "header": "--KJaG_header",
1198
- "headerActions": "--KJaG_headerActions",
1199
- "list": "--KJaG_list",
1200
- "meta": "--KJaG_meta",
1201
- "modalFooter": "--KJaG_modalFooter",
1202
- "name": "--KJaG_name",
1203
- "reason": "--KJaG_reason",
1204
- "service": "--KJaG_service",
1205
- "sourceDirect": "--KJaG_sourceDirect",
1206
- "sourcePlugin": "--KJaG_sourcePlugin",
1207
- "state": "--KJaG_state",
1208
- "stateconnected": "--KJaG_stateconnected",
1209
- "statedegraded": "--KJaG_statedegraded",
1210
- "statedisabled": "--KJaG_statedisabled",
1211
- "statefailed": "--KJaG_statefailed",
1212
- "statusconnected": "--KJaG_statusconnected",
1213
- "statusdegraded": "--KJaG_statusdegraded",
1214
- "statusdisabled": "--KJaG_statusdisabled",
1215
- "statusDot": "--KJaG_statusDot",
1216
- "statusfailed": "--KJaG_statusfailed",
1217
- "subtitle": "--KJaG_subtitle",
1218
- "summary": "--KJaG_summary",
1219
- "summaryDotGreen": "--KJaG_summaryDotGreen",
1220
- "summaryDotRed": "--KJaG_summaryDotRed",
1221
- "surface": "--KJaG_surface",
1222
- "title": "--KJaG_title",
1223
- "tool": "--KJaG_tool",
1224
- "toolbar": "--KJaG_toolbar",
1225
- "toolCount": "--KJaG_toolCount",
1226
- "toolDescription": "--KJaG_toolDescription",
1227
- "toolIndex": "--KJaG_toolIndex",
1228
- "toolList": "--KJaG_toolList",
1229
- "toolName": "--KJaG_toolName",
1230
- "transport": "--KJaG_transport"
1314
+ "boundary": "AUWlZW_boundary",
1315
+ "card": "AUWlZW_card",
1316
+ "cardReason": "AUWlZW_cardReason",
1317
+ "cardTop": "AUWlZW_cardTop",
1318
+ "chevron": "AUWlZW_chevron",
1319
+ "config": "AUWlZW_config",
1320
+ "detail": "AUWlZW_detail",
1321
+ "detailBody": "AUWlZW_detailBody",
1322
+ "detailDialog": "AUWlZW_detailDialog",
1323
+ "detailEmpty": "AUWlZW_detailEmpty",
1324
+ "detailHead": "AUWlZW_detailHead",
1325
+ "detailMeta": "AUWlZW_detailMeta",
1326
+ "detailSection": "AUWlZW_detailSection",
1327
+ "detailState": "AUWlZW_detailState",
1328
+ "detailStateconnected": "AUWlZW_detailStateconnected",
1329
+ "detailStatedegraded": "AUWlZW_detailStatedegraded",
1330
+ "detailStatedisabled": "AUWlZW_detailStatedisabled",
1331
+ "detailStatefailed": "AUWlZW_detailStatefailed",
1332
+ "empty": "AUWlZW_empty",
1333
+ "endpoint": "AUWlZW_endpoint",
1334
+ "error": "AUWlZW_error",
1335
+ "errorSummary": "AUWlZW_errorSummary",
1336
+ "grid": "AUWlZW_grid",
1337
+ "header": "AUWlZW_header",
1338
+ "headerActions": "AUWlZW_headerActions",
1339
+ "list": "AUWlZW_list",
1340
+ "meta": "AUWlZW_meta",
1341
+ "modalFooter": "AUWlZW_modalFooter",
1342
+ "name": "AUWlZW_name",
1343
+ "reason": "AUWlZW_reason",
1344
+ "service": "AUWlZW_service",
1345
+ "sourceDirect": "AUWlZW_sourceDirect",
1346
+ "sourcePlugin": "AUWlZW_sourcePlugin",
1347
+ "state": "AUWlZW_state",
1348
+ "stateconnected": "AUWlZW_stateconnected",
1349
+ "statedegraded": "AUWlZW_statedegraded",
1350
+ "statedisabled": "AUWlZW_statedisabled",
1351
+ "statefailed": "AUWlZW_statefailed",
1352
+ "statusconnected": "AUWlZW_statusconnected",
1353
+ "statusdegraded": "AUWlZW_statusdegraded",
1354
+ "statusdisabled": "AUWlZW_statusdisabled",
1355
+ "statusDot": "AUWlZW_statusDot",
1356
+ "statusfailed": "AUWlZW_statusfailed",
1357
+ "subtitle": "AUWlZW_subtitle",
1358
+ "summary": "AUWlZW_summary",
1359
+ "summaryDotGreen": "AUWlZW_summaryDotGreen",
1360
+ "summaryDotRed": "AUWlZW_summaryDotRed",
1361
+ "surface": "AUWlZW_surface",
1362
+ "title": "AUWlZW_title",
1363
+ "tool": "AUWlZW_tool",
1364
+ "toolbar": "AUWlZW_toolbar",
1365
+ "toolCount": "AUWlZW_toolCount",
1366
+ "toolDescription": "AUWlZW_toolDescription",
1367
+ "toolIndex": "AUWlZW_toolIndex",
1368
+ "toolList": "AUWlZW_toolList",
1369
+ "toolName": "AUWlZW_toolName",
1370
+ "transport": "AUWlZW_transport"
1231
1371
  };
1232
1372
  //#endregion
1233
1373
  //#region src/client/McpStatusPanel.tsx
@@ -1262,24 +1402,7 @@ function McpStatusPanel({ t }) {
1262
1402
  (0, react.useEffect)(() => {
1263
1403
  refresh();
1264
1404
  }, []);
1265
- const activeEntries = payload.entries.filter((entry) => entry.state !== "disabled");
1266
- const visibleTotals = {
1267
- all: activeEntries.length,
1268
- connected: activeEntries.filter((entry) => entry.state === "connected").length,
1269
- failed: activeEntries.filter((entry) => entry.state === "failed").length
1270
- };
1271
- const filtered = (0, react.useMemo)(() => {
1272
- const query = search.trim().toLowerCase();
1273
- return activeEntries.filter((entry) => {
1274
- if (filter !== "all" && entry.kind !== filter) return false;
1275
- if (query === "") return true;
1276
- return `${entry.name} ${entry.source ?? ""} ${entry.endpoint ?? ""} ${entry.transport}`.toLowerCase().includes(query);
1277
- });
1278
- }, [
1279
- activeEntries,
1280
- filter,
1281
- search
1282
- ]);
1405
+ const { activeEntries, filtered, filterCounts, visibleTotals } = deriveMcpStatusViewModel(payload, filter, search);
1283
1406
  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
1407
  className: mcp_status_module_default.errorSummary,
1285
1408
  title: `${visibleTotals.failed} ${t("mcpFailed")}`
@@ -1302,7 +1425,7 @@ function McpStatusPanel({ t }) {
1302
1425
  ].map((kind) => ({
1303
1426
  id: kind,
1304
1427
  label: filterLabel(t, kind),
1305
- count: kind === "all" ? visibleTotals.all : activeEntries.filter((entry) => entry.kind === kind).length,
1428
+ count: filterCounts[kind],
1306
1429
  icon: (0, react.createElement)(McpFilterIcon, { kind }),
1307
1430
  active: filter === kind,
1308
1431
  onSelect: () => setFilter(kind)