dsh-mcp-connector 0.2.68 → 0.2.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.en.md +3 -3
- package/README.md +3 -3
- package/docs/USER-GUIDE.md +2 -2
- package/lib/client.js +202 -53
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.2.69] - 2026-10-08
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- DSH `>=0.2.0-rc.2` 的左侧入口改用官方 `sidebar.panellist` 与 keyed `main` 席位,由宿主统一渲染行高、折叠提示、选中态和无障碍名称;市场主体与设置页快捷弹框共用(#129)。
|
|
12
|
+
- DSH `0.1.x` 仅在原生席位不可用时按需启用 footer/Portal 兼容适配器;席位延迟到达时会原子替换,不会同时显示两个入口。
|
|
13
|
+
- 关闭“在侧边栏显示 MCP连接器”会真正注销原生行;如果当前正在连接器面板,先安全返回会话界面。
|
|
14
|
+
|
|
15
|
+
### Verification
|
|
16
|
+
|
|
17
|
+
- 新增 DSH 0.2 原生席位、0.1.x 兼容回退、延迟席位替换和动态隐藏/恢复回归测试。
|
|
18
|
+
|
|
7
19
|
## [0.2.68] - 2026-10-06
|
|
8
20
|
|
|
9
21
|
### Fixed
|
package/README.en.md
CHANGED
|
@@ -62,7 +62,7 @@ If the plugin helps you connect an MCP server faster, consider [starring the rep
|
|
|
62
62
|
|
|
63
63
|
## Features
|
|
64
64
|
|
|
65
|
-
- A
|
|
65
|
+
- A native `sidebar.panellist` row and keyed main panel on DSH `>=0.2.0-rc.2`, inheriting host selection, collapsed tooltip, and accessibility behavior; DSH `0.1.x` automatically uses the compatibility entry.
|
|
66
66
|
- A profile-wide sidebar visibility preference; even when the shortcut is hidden, the existing connector dialog remains available from **Settings → Plugins → Plugin Configuration → MCP Connector**.
|
|
67
67
|
- Searchable Marketplace and Installed views; the default Marketplace groups cards into Featured plus nine business-category sections, previews four cards per section, keeps the category bar visible while scrolling, and shows every card when a single category is selected.
|
|
68
68
|
- OAuth 2.0 Authorization Code with PKCE, including DCR public clients and `client_secret_post` / `client_secret_basic`; API key/Bearer/unauthenticated HTTP configuration, stdio local-process configuration, and `mcpServers` JSON import.
|
|
@@ -85,7 +85,7 @@ If the plugin helps you connect an MCP server faster, consider [starring the rep
|
|
|
85
85
|
- Explicit, non-destructive migration from the two earlier Qichacha OAuth plugins, plus active-plugin conflict detection that blocks duplicate server management and credential overwrites.
|
|
86
86
|
|
|
87
87
|
<!-- catalog-stats:start -->
|
|
88
|
-
As of 2026-10-
|
|
88
|
+
As of 2026-10-06, the public Registry publishes 109 connector descriptors. After merging and deduplicating them with the 4 bundled Qichacha cards, the Marketplace exposes 113 cards across 9 business categories. Recommendations remain limited to the four Qichacha cards, PKULaw, and Wind, for 6 featured cards in total. The Registry evolves independently; the badge shown after a client refresh and the live badges above are the authoritative current counts.
|
|
89
89
|
<!-- catalog-stats:end -->
|
|
90
90
|
|
|
91
91
|
## Interface and demo
|
|
@@ -202,7 +202,7 @@ npm run dev:ui
|
|
|
202
202
|
|
|
203
203
|
Every Registry merge regenerates `catalog-stats.json`; an hourly workflow in this repository synchronizes the Chinese and English product copy plus a local stats snapshot. The static npm README updates with package releases, while the live badges above read the Registry directly and therefore stay current without another npm release.
|
|
204
204
|
|
|
205
|
-
The current public version is [`dsh-mcp-connector@0.2.
|
|
205
|
+
The current public version is [`dsh-mcp-connector@0.2.69`](https://www.npmjs.com/package/dsh-mcp-connector), with [GitHub Release v0.2.69](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.69).
|
|
206
206
|
|
|
207
207
|
See [CHANGELOG.md](CHANGELOG.md) for version history and [docs/DESKTOP-E2E.md](docs/DESKTOP-E2E.md) for the Desktop release checklist.
|
|
208
208
|
|
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ dsh plugin --profile web add dsh-mcp-connector
|
|
|
62
62
|
|
|
63
63
|
## 功能
|
|
64
64
|
|
|
65
|
-
-
|
|
65
|
+
- 左侧主导航入口:DSH `>=0.2.0-rc.2` 使用官方 `sidebar.panellist` 行与原生主面板,继承宿主选中态、折叠提示和无障碍行为;DSH `0.1.x` 自动回退到兼容入口。
|
|
66
66
|
- 侧边栏入口可按当前 profile 隐藏;隐藏后仍可从“设置 → 插件 → 插件配置 → MCP连接器”临时打开现有连接器弹框,用完即关。
|
|
67
67
|
- 图形化市场:默认“全部”按推荐与 9 类业务分类分章节展示,每章先展示 4 张并可展开;分类栏固定可见,单分类页展示全部卡片。
|
|
68
68
|
- 图形化添加:手动 HTTP/stdio、`mcpServers` JSON、连接器描述 URL 三种入口,失败时保留表单并给出修复建议。
|
|
@@ -86,7 +86,7 @@ dsh plugin --profile web add dsh-mcp-connector
|
|
|
86
86
|
- 对话工具:`mcp_connector_catalog`、`connect`、`configure`、`import_json`、`export_config`、`snapshot`、`install_from_url`、`status`、`scope`、`health_check`、`policy`、`set_enabled`、`session_tools`、`disconnect`、`refresh_catalog`、`publish`、`tools_list`、`tool_search`、`tool_detail`。搜索/详情只做渐进式能力发现,不执行目标 MCP 工具。
|
|
87
87
|
|
|
88
88
|
<!-- catalog-stats:start -->
|
|
89
|
-
截至 2026-10-
|
|
89
|
+
截至 2026-10-06,公共 Registry 已发布 109 条连接器描述;与随包的 4 张企查查卡片合并去重后,市场页可浏览 113 张卡片,覆盖企业数据、金融投资、法律合规、开发工具、办公协作、调研分析、设计创意、效率工具、其他 9 类。推荐位严格保留 4 张企查查卡片、北大法宝和 Wind,共 6 张;其他连接器按业务分类展示。Registry 可独立持续更新,实际数量以客户端刷新后的市场页签徽标和上方实时统计徽标为准。
|
|
90
90
|
<!-- catalog-stats:end -->
|
|
91
91
|
|
|
92
92
|
## 界面与演示
|
|
@@ -197,7 +197,7 @@ npm run dev:ui
|
|
|
197
197
|
|
|
198
198
|
公共 Registry 每次合并后会生成 `catalog-stats.json`;本仓库的定时工作流每小时同步中英文介绍和统计快照。npm 页面中的静态正文随版本发布更新,上方动态统计徽标则直接读取 Registry,可在不发布新 npm 版本时保持实时数量一致。
|
|
199
199
|
|
|
200
|
-
当前公开版本为 [`dsh-mcp-connector@0.2.
|
|
200
|
+
当前公开版本为 [`dsh-mcp-connector@0.2.69`](https://www.npmjs.com/package/dsh-mcp-connector),对应 [GitHub Release v0.2.69](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.69)。
|
|
201
201
|
|
|
202
202
|
版本能力与变更记录见 [CHANGELOG.md](CHANGELOG.md)。
|
|
203
203
|
Desktop 发版回归见 [docs/DESKTOP-E2E.md](docs/DESKTOP-E2E.md)。
|
package/docs/USER-GUIDE.md
CHANGED
|
@@ -47,10 +47,10 @@ dsh web
|
|
|
47
47
|
|
|
48
48
|
重启后,可以用以下任一方式打开:
|
|
49
49
|
|
|
50
|
-
- 在 DSH 左侧主导航点击“MCP
|
|
50
|
+
- 在 DSH 左侧主导航点击“MCP连接器”。DSH `>=0.2.0-rc.2` 使用宿主原生面板行,展开、折叠、选中态和键盘操作均与其他主导航一致;DSH `0.1.x` 自动使用左侧底部兼容入口。
|
|
51
51
|
- 打开“设置 → 插件 → 插件配置 → MCP连接器”,展开卡片并点击“打开 MCP连接器”。该按钮直接复用同一个连接器弹框,不要求侧边栏入口可见;关闭弹框后仍回到设置页。
|
|
52
52
|
|
|
53
|
-
如需腾出侧边栏空间,可在同一配置卡片关闭“在侧边栏显示 MCP连接器”。该偏好作用于当前 DSH profile,并在重启后保留;它只隐藏快捷入口,不停用插件、已连接 MCP Server
|
|
53
|
+
如需腾出侧边栏空间,可在同一配置卡片关闭“在侧边栏显示 MCP连接器”。该偏好作用于当前 DSH profile,并在重启后保留;它只隐藏快捷入口,不停用插件、已连接 MCP Server 或工具。如果隐藏时正在原生连接器面板,页面会先返回当前会话;之后仍可从该配置卡片直接打开弹框,或重新开启入口。旧版 DSH 没有 Settings 能力时,插件保持入口可见,不会因设置功能进入 Safe Mode。
|
|
54
54
|
|
|
55
55
|
页面顶部提供:
|
|
56
56
|
|
package/lib/client.js
CHANGED
|
@@ -38,9 +38,9 @@ window.__ModuleLoader__.load({
|
|
|
38
38
|
]);
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
* sidebar.footer.action
|
|
42
|
-
*
|
|
43
|
-
*
|
|
41
|
+
* DSH 0.1.x 的 sidebar.footer.action 兼容入口样式。新版宿主使用
|
|
42
|
+
* sidebar.panellist 原生行,不会安装本段 CSS。兼容适配器只样式化
|
|
43
|
+
* 本插件节点,不改写公共槽位或其它插件子项(#124)。
|
|
44
44
|
*/
|
|
45
45
|
const SIDEBAR_STYLE_ID = "dsh-mcp-connector-sidebar";
|
|
46
46
|
const sidebarCss = `
|
|
@@ -763,6 +763,7 @@ window.__ModuleLoader__.load({
|
|
|
763
763
|
function createMarketViewStore() {
|
|
764
764
|
let sidebarVisible = true;
|
|
765
765
|
const liveActions = new Set();
|
|
766
|
+
const visibilityListeners = new Set();
|
|
766
767
|
const spec = {
|
|
767
768
|
init: () => ({ open: false, detailOpen: false, sidebarVisible }),
|
|
768
769
|
actions: {
|
|
@@ -775,9 +776,19 @@ window.__ModuleLoader__.load({
|
|
|
775
776
|
};
|
|
776
777
|
return {
|
|
777
778
|
spec,
|
|
779
|
+
getSidebarVisible() {
|
|
780
|
+
return sidebarVisible;
|
|
781
|
+
},
|
|
782
|
+
subscribeSidebarVisible(listener) {
|
|
783
|
+
visibilityListeners.add(listener);
|
|
784
|
+
return () => { visibilityListeners.delete(listener); };
|
|
785
|
+
},
|
|
778
786
|
syncSidebarVisible(visible) {
|
|
779
|
-
|
|
787
|
+
const next = visible !== false;
|
|
788
|
+
if (sidebarVisible === next) return;
|
|
789
|
+
sidebarVisible = next;
|
|
780
790
|
for (const actions of liveActions) actions.setSidebarVisible(sidebarVisible);
|
|
791
|
+
for (const listener of visibilityListeners) listener(sidebarVisible);
|
|
781
792
|
},
|
|
782
793
|
create() {
|
|
783
794
|
let state = spec.init();
|
|
@@ -1079,17 +1090,24 @@ window.__ModuleLoader__.load({
|
|
|
1079
1090
|
return sessionId;
|
|
1080
1091
|
}
|
|
1081
1092
|
|
|
1082
|
-
/**
|
|
1093
|
+
/** 市场主体:原生 main 面板与设置页快捷弹框共用。 */
|
|
1083
1094
|
function MarketOverlay(props) {
|
|
1084
1095
|
const {
|
|
1085
1096
|
wide,
|
|
1086
1097
|
useStore,
|
|
1087
1098
|
actions,
|
|
1099
|
+
presentation = "modal",
|
|
1100
|
+
closePanel = null,
|
|
1088
1101
|
startPromptSession: launchPromptSession,
|
|
1089
1102
|
workspaceContext = () => null,
|
|
1090
1103
|
workspaceOptions = () => []
|
|
1091
1104
|
} = props;
|
|
1092
|
-
const
|
|
1105
|
+
const modalOpen = useStore((state) => state.open);
|
|
1106
|
+
const open = presentation === "panel" || modalOpen;
|
|
1107
|
+
const closeView = () => {
|
|
1108
|
+
if (presentation === "panel") closePanel?.();
|
|
1109
|
+
else actions.close();
|
|
1110
|
+
};
|
|
1093
1111
|
const detailOpen = useStore((state) => state.detailOpen);
|
|
1094
1112
|
const [versionStatus, setVersionStatus] = (0, react.useState)(null);
|
|
1095
1113
|
const [updateProviderState, setUpdateProviderState] = (0, react.useState)("checking");
|
|
@@ -1144,7 +1162,7 @@ window.__ModuleLoader__.load({
|
|
|
1144
1162
|
}
|
|
1145
1163
|
Promise.resolve(launchPromptSession(prompt)).then(() => {
|
|
1146
1164
|
reply(true, "已带入新会话");
|
|
1147
|
-
window.requestAnimationFrame(
|
|
1165
|
+
window.requestAnimationFrame(closeView);
|
|
1148
1166
|
}, (error) => {
|
|
1149
1167
|
const message = error instanceof Error ? error.message : String(error);
|
|
1150
1168
|
console.error("[mcp-connector] start prompt session failed:", error);
|
|
@@ -1153,7 +1171,7 @@ window.__ModuleLoader__.load({
|
|
|
1153
1171
|
};
|
|
1154
1172
|
window.addEventListener("message", onMessage);
|
|
1155
1173
|
return () => { window.removeEventListener("message", onMessage); };
|
|
1156
|
-
}, [actions, launchPromptSession, workspaceContext]);
|
|
1174
|
+
}, [actions, closePanel, launchPromptSession, presentation, workspaceContext]);
|
|
1157
1175
|
(0, react.useEffect)(() => {
|
|
1158
1176
|
if (!open) return void 0;
|
|
1159
1177
|
let disposed = false;
|
|
@@ -1284,14 +1302,14 @@ window.__ModuleLoader__.load({
|
|
|
1284
1302
|
};
|
|
1285
1303
|
}, [open, updateOperation?.operationId, updateProviderSelection?.provider?.id, expectedUpdateVersion]);
|
|
1286
1304
|
(0, react.useEffect)(() => {
|
|
1287
|
-
if (!open) return void 0;
|
|
1305
|
+
if (!open || presentation === "panel") return void 0;
|
|
1288
1306
|
const opener = document.activeElement;
|
|
1289
1307
|
closeRef.current?.focus?.();
|
|
1290
1308
|
const onKeyDown = (event) => {
|
|
1291
1309
|
if (event.key !== "Escape") return;
|
|
1292
1310
|
event.preventDefault();
|
|
1293
1311
|
event.stopPropagation();
|
|
1294
|
-
|
|
1312
|
+
closeView();
|
|
1295
1313
|
};
|
|
1296
1314
|
// Capture at window before the underlying Settings dialog receives
|
|
1297
1315
|
// Escape on document; only the topmost connector dialog should close.
|
|
@@ -1300,7 +1318,7 @@ window.__ModuleLoader__.load({
|
|
|
1300
1318
|
window.removeEventListener("keydown", onKeyDown, true);
|
|
1301
1319
|
if (opener?.isConnected !== false) opener?.focus?.();
|
|
1302
1320
|
};
|
|
1303
|
-
}, [open, actions]);
|
|
1321
|
+
}, [open, actions, closePanel, presentation]);
|
|
1304
1322
|
if (!open) return null;
|
|
1305
1323
|
const updateRunning = updateStarting || updateOperation !== null && ["queued", "running"].includes(updateOperation.state);
|
|
1306
1324
|
const startUpdate = (force = false) => {
|
|
@@ -1567,30 +1585,21 @@ window.__ModuleLoader__.load({
|
|
|
1567
1585
|
});
|
|
1568
1586
|
};
|
|
1569
1587
|
const src = window.location.origin + "/mcp-connector/ui/";
|
|
1570
|
-
const
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
background: "rgba(0,0,0,0.4)",
|
|
1575
|
-
display: "flex",
|
|
1576
|
-
alignItems: "center",
|
|
1577
|
-
justifyContent: "center",
|
|
1578
|
-
zIndex: CONNECTOR_MODAL_Z_INDEX
|
|
1579
|
-
},
|
|
1580
|
-
onClick: (event) => { if (event.target === event.currentTarget) actions.close(); },
|
|
1581
|
-
children: [
|
|
1582
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1588
|
+
const titleId = presentation === "panel"
|
|
1589
|
+
? "mcp-connector-native-title"
|
|
1590
|
+
: "mcp-connector-modal-title";
|
|
1591
|
+
const marketPanel = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1583
1592
|
className: "mcpConnectorMarketPanel",
|
|
1584
|
-
role: "dialog",
|
|
1585
|
-
"aria-modal": true,
|
|
1586
|
-
"aria-labelledby":
|
|
1593
|
+
role: presentation === "panel" ? "region" : "dialog",
|
|
1594
|
+
"aria-modal": presentation === "panel" ? void 0 : true,
|
|
1595
|
+
"aria-labelledby": titleId,
|
|
1587
1596
|
style: {
|
|
1588
|
-
borderRadius: 16,
|
|
1589
|
-
width: "min(800px, 90%)",
|
|
1590
|
-
height: "min(800px, 85%)",
|
|
1597
|
+
borderRadius: presentation === "panel" ? 0 : 16,
|
|
1598
|
+
width: presentation === "panel" ? "100%" : "min(800px, 90%)",
|
|
1599
|
+
height: presentation === "panel" ? "100%" : "min(800px, 85%)",
|
|
1591
1600
|
display: "flex",
|
|
1592
1601
|
flexDirection: "column",
|
|
1593
|
-
boxShadow: "0 20px 60px rgba(0,0,0,0.15)",
|
|
1602
|
+
boxShadow: presentation === "panel" ? "none" : "0 20px 60px rgba(0,0,0,0.15)",
|
|
1594
1603
|
overflow: "hidden"
|
|
1595
1604
|
},
|
|
1596
1605
|
children: [
|
|
@@ -1626,7 +1635,7 @@ window.__ModuleLoader__.load({
|
|
|
1626
1635
|
]
|
|
1627
1636
|
})
|
|
1628
1637
|
}),
|
|
1629
|
-
|
|
1638
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { id: titleId, className: "mcpConnectorMarketTitle", style: { fontSize: 18, fontWeight: 600 }, children: "MCP连接器" }),
|
|
1630
1639
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1631
1640
|
className: "mcpConnectorVersion",
|
|
1632
1641
|
title: versionStatus === null ? "正在检查插件版本" : `当前版本 v${versionStatus.installedVersion}`,
|
|
@@ -1657,8 +1666,8 @@ window.__ModuleLoader__.load({
|
|
|
1657
1666
|
ref: closeRef,
|
|
1658
1667
|
className: "mcpConnectorMarketClose",
|
|
1659
1668
|
type: "button",
|
|
1660
|
-
"aria-label": "关闭 MCP连接器",
|
|
1661
|
-
onClick:
|
|
1669
|
+
"aria-label": presentation === "panel" ? "返回会话" : "关闭 MCP连接器",
|
|
1670
|
+
onClick: closeView,
|
|
1662
1671
|
style: {
|
|
1663
1672
|
background: "transparent",
|
|
1664
1673
|
border: "none",
|
|
@@ -1689,8 +1698,20 @@ window.__ModuleLoader__.load({
|
|
|
1689
1698
|
}
|
|
1690
1699
|
})
|
|
1691
1700
|
]
|
|
1692
|
-
})
|
|
1693
|
-
|
|
1701
|
+
});
|
|
1702
|
+
if (presentation === "panel") return marketPanel;
|
|
1703
|
+
const modal = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1704
|
+
style: {
|
|
1705
|
+
position: "fixed",
|
|
1706
|
+
inset: 0,
|
|
1707
|
+
background: "rgba(0,0,0,0.4)",
|
|
1708
|
+
display: "flex",
|
|
1709
|
+
alignItems: "center",
|
|
1710
|
+
justifyContent: "center",
|
|
1711
|
+
zIndex: CONNECTOR_MODAL_Z_INDEX
|
|
1712
|
+
},
|
|
1713
|
+
onClick: (event) => { if (event.target === event.currentTarget) closeView(); },
|
|
1714
|
+
children: marketPanel
|
|
1694
1715
|
});
|
|
1695
1716
|
// shell.overlay lives inside a z-index:20 stacking context, while DSH
|
|
1696
1717
|
// Settings is a root-level z-index:1000 modal. Portal to body so the
|
|
@@ -1702,8 +1723,8 @@ window.__ModuleLoader__.load({
|
|
|
1702
1723
|
return modal;
|
|
1703
1724
|
}
|
|
1704
1725
|
|
|
1705
|
-
/**
|
|
1706
|
-
function
|
|
1726
|
+
/** DSH 0.1.x 兼容入口:仅在原生面板席位不完整时挂载。 */
|
|
1727
|
+
function LegacySidebarEntry(props) {
|
|
1707
1728
|
const { wide, useStore, actions } = props;
|
|
1708
1729
|
const open = useStore((state) => state.open);
|
|
1709
1730
|
const visible = useStore((state) => state.sidebarVisible !== false);
|
|
@@ -1772,6 +1793,147 @@ window.__ModuleLoader__.load({
|
|
|
1772
1793
|
}), topMount);
|
|
1773
1794
|
}
|
|
1774
1795
|
|
|
1796
|
+
/** 新版 DSH 会渲染整行按钮;插件只提供随 size/currentColor 变化的字形。 */
|
|
1797
|
+
function NativeSidebarIcon(props) {
|
|
1798
|
+
const size = Number.isFinite(props?.size) ? props.size : 16;
|
|
1799
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
1800
|
+
viewBox: "0 0 16 16",
|
|
1801
|
+
width: size,
|
|
1802
|
+
height: size,
|
|
1803
|
+
fill: "none",
|
|
1804
|
+
stroke: "currentColor",
|
|
1805
|
+
"aria-hidden": "true",
|
|
1806
|
+
style: { display: "block" },
|
|
1807
|
+
children: [
|
|
1808
|
+
(0, react_jsx_runtime.jsx)("path", { d: "M6 2V4.5", strokeLinecap: "round" }),
|
|
1809
|
+
(0, react_jsx_runtime.jsx)("path", { d: "M10 2V4.5", strokeLinecap: "round" }),
|
|
1810
|
+
(0, react_jsx_runtime.jsx)("path", { d: "M3.5 4.5H12.5V8.25C12.5 10.7353 10.4853 12.75 8 12.75C5.51472 12.75 3.5 10.7353 3.5 8.25V4.5Z", strokeLinejoin: "round" }),
|
|
1811
|
+
(0, react_jsx_runtime.jsx)("path", { d: "M8 12.75V14.5", strokeLinecap: "round" })
|
|
1812
|
+
]
|
|
1813
|
+
});
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
function marketRuntimeProps(ctx) {
|
|
1817
|
+
return {
|
|
1818
|
+
startPromptSession: (promptText) => startPromptSession(ctx, promptText),
|
|
1819
|
+
workspaceContext: () => currentWorkspaceContext(ctx),
|
|
1820
|
+
workspaceOptions: () => availableWorkspaceContexts(ctx)
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
|
|
1824
|
+
/**
|
|
1825
|
+
* 原生 main + sidebar.panellist 优先;两个席位未同时就绪时才启用
|
|
1826
|
+
* DSH 0.1.x footer/Portal 兼容适配器。席位可以延迟声明,因此状态不依赖 DOM 探测。
|
|
1827
|
+
*/
|
|
1828
|
+
function installSidebarSlots(ctx, marketView) {
|
|
1829
|
+
let mainReady = false;
|
|
1830
|
+
let panelListReady = false;
|
|
1831
|
+
let footerReady = false;
|
|
1832
|
+
let nativeEntryDispose = null;
|
|
1833
|
+
let fallbackEntryDispose = null;
|
|
1834
|
+
|
|
1835
|
+
const layout = () => typeof ctx.get === "function" ? ctx.get("layout") ?? ctx.layout : ctx.layout;
|
|
1836
|
+
const leaveNativePanel = () => {
|
|
1837
|
+
const controller = layout();
|
|
1838
|
+
try {
|
|
1839
|
+
if (controller?.panelInfo?.getSnapshot?.().activePanelId === "mcp-connector") {
|
|
1840
|
+
controller.selectPanel(null);
|
|
1841
|
+
}
|
|
1842
|
+
} catch (error) {
|
|
1843
|
+
console.warn("[mcp-connector] failed to leave native panel:", error);
|
|
1844
|
+
}
|
|
1845
|
+
};
|
|
1846
|
+
const disposeNativeEntry = () => {
|
|
1847
|
+
if (nativeEntryDispose === null) return;
|
|
1848
|
+
leaveNativePanel();
|
|
1849
|
+
nativeEntryDispose();
|
|
1850
|
+
nativeEntryDispose = null;
|
|
1851
|
+
};
|
|
1852
|
+
const disposeFallbackEntry = () => {
|
|
1853
|
+
if (fallbackEntryDispose === null) return;
|
|
1854
|
+
fallbackEntryDispose();
|
|
1855
|
+
fallbackEntryDispose = null;
|
|
1856
|
+
};
|
|
1857
|
+
const syncEntries = () => {
|
|
1858
|
+
const visible = marketView.getSidebarVisible();
|
|
1859
|
+
const nativeReady = mainReady && panelListReady;
|
|
1860
|
+
if (nativeReady) {
|
|
1861
|
+
disposeFallbackEntry();
|
|
1862
|
+
if (visible && nativeEntryDispose === null) {
|
|
1863
|
+
nativeEntryDispose = ctx.slots.register({
|
|
1864
|
+
name: "sidebar.panellist",
|
|
1865
|
+
id: "mcp-connector",
|
|
1866
|
+
order: 40,
|
|
1867
|
+
label: "MCP连接器"
|
|
1868
|
+
}, NativeSidebarIcon);
|
|
1869
|
+
} else if (!visible) {
|
|
1870
|
+
disposeNativeEntry();
|
|
1871
|
+
}
|
|
1872
|
+
return;
|
|
1873
|
+
}
|
|
1874
|
+
disposeNativeEntry();
|
|
1875
|
+
if (footerReady && visible && fallbackEntryDispose === null) {
|
|
1876
|
+
fallbackEntryDispose = ctx.slots.register({
|
|
1877
|
+
name: "sidebar.footer.action",
|
|
1878
|
+
id: "mcp-connector",
|
|
1879
|
+
order: 0,
|
|
1880
|
+
store: marketView
|
|
1881
|
+
}, LegacySidebarEntry);
|
|
1882
|
+
} else if (!visible) {
|
|
1883
|
+
disposeFallbackEntry();
|
|
1884
|
+
}
|
|
1885
|
+
};
|
|
1886
|
+
|
|
1887
|
+
ctx.effect(() => {
|
|
1888
|
+
const unsubscribe = marketView.subscribeSidebarVisible(syncEntries);
|
|
1889
|
+
return () => {
|
|
1890
|
+
unsubscribe();
|
|
1891
|
+
disposeNativeEntry();
|
|
1892
|
+
disposeFallbackEntry();
|
|
1893
|
+
};
|
|
1894
|
+
}, "mcp-connector: sidebar entry visibility");
|
|
1895
|
+
|
|
1896
|
+
// main 必须先于 panellist 行就绪,否则宿主会拒绝选中缺页面的行。
|
|
1897
|
+
ctx.slots.inject("main", () => {
|
|
1898
|
+
const disposeMain = ctx.slots.register({
|
|
1899
|
+
name: "main",
|
|
1900
|
+
key: "mcp-connector",
|
|
1901
|
+
store: marketView,
|
|
1902
|
+
inject: () => ({
|
|
1903
|
+
...marketRuntimeProps(ctx),
|
|
1904
|
+
presentation: "panel",
|
|
1905
|
+
closePanel: () => layout()?.selectPanel?.(null)
|
|
1906
|
+
})
|
|
1907
|
+
}, MarketOverlay);
|
|
1908
|
+
mainReady = true;
|
|
1909
|
+
syncEntries();
|
|
1910
|
+
return () => {
|
|
1911
|
+
leaveNativePanel();
|
|
1912
|
+
mainReady = false;
|
|
1913
|
+
syncEntries();
|
|
1914
|
+
disposeMain();
|
|
1915
|
+
};
|
|
1916
|
+
});
|
|
1917
|
+
|
|
1918
|
+
ctx.slots.inject("sidebar.panellist", () => {
|
|
1919
|
+
panelListReady = true;
|
|
1920
|
+
syncEntries();
|
|
1921
|
+
return () => {
|
|
1922
|
+
panelListReady = false;
|
|
1923
|
+
syncEntries();
|
|
1924
|
+
};
|
|
1925
|
+
});
|
|
1926
|
+
|
|
1927
|
+
ctx.slots.inject("sidebar.footer.action", () => {
|
|
1928
|
+
footerReady = true;
|
|
1929
|
+
syncEntries();
|
|
1930
|
+
return () => {
|
|
1931
|
+
footerReady = false;
|
|
1932
|
+
disposeFallbackEntry();
|
|
1933
|
+
};
|
|
1934
|
+
});
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1775
1937
|
function apply(ctx) {
|
|
1776
1938
|
console.log('[mcp-connector] client apply() called');
|
|
1777
1939
|
try {
|
|
@@ -1787,24 +1949,11 @@ window.__ModuleLoader__.load({
|
|
|
1787
1949
|
id: "mcp-connector",
|
|
1788
1950
|
order: 100,
|
|
1789
1951
|
store: marketView,
|
|
1790
|
-
inject: () => (
|
|
1791
|
-
startPromptSession: (promptText) => startPromptSession(ctx, promptText),
|
|
1792
|
-
workspaceContext: () => currentWorkspaceContext(ctx),
|
|
1793
|
-
workspaceOptions: () => availableWorkspaceContexts(ctx)
|
|
1794
|
-
})
|
|
1952
|
+
inject: () => marketRuntimeProps(ctx)
|
|
1795
1953
|
}, MarketOverlay);
|
|
1796
1954
|
});
|
|
1797
1955
|
|
|
1798
|
-
|
|
1799
|
-
ctx.slots.inject("sidebar.footer.action", () => {
|
|
1800
|
-
console.log('[mcp-connector] registering sidebar.footer.action slot');
|
|
1801
|
-
return ctx.slots.register({
|
|
1802
|
-
name: "sidebar.footer.action",
|
|
1803
|
-
id: "mcp-connector",
|
|
1804
|
-
order: 0,
|
|
1805
|
-
store: marketView
|
|
1806
|
-
}, SidebarEntry);
|
|
1807
|
-
});
|
|
1956
|
+
installSidebarSlots(ctx, marketView);
|
|
1808
1957
|
console.log('[mcp-connector] client apply() completed');
|
|
1809
1958
|
} catch (error) {
|
|
1810
1959
|
console.error('[mcp-connector] client apply() failed:', error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-mcp-connector",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.69",
|
|
4
4
|
"description": "DeepSeek Harness MCP Connector: connect servers, search tools across active connections, and troubleshoot discovery. Includes a continuously updated catalog; supports OAuth 2.0 PKCE, API keys, Streamable HTTP/stdio, and mcpServers JSON import.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|