dsh-vscode-mode 0.1.15 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -3
- package/lib/client.js +140 -33
- package/lib/client.js.map +1 -1
- package/lib/index.js +386 -198
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/compat.ts +91 -0
- package/src/client/fileOpeners.ts +2 -1
- package/src/client/index.ts +18 -10
- package/src/client/openPathRouter.ts +5 -5
- package/src/client/settingsContext.ts +7 -17
- package/src/client/styles/mcp.css +8 -0
- package/src/client/ui/McpSettings.ts +36 -1
- package/src/compat.ts +146 -0
- package/src/fileOpenSettings.ts +58 -6
- package/src/index.ts +33 -5
- package/src/mcp.ts +8 -9
- package/src/mcpIsolation.ts +6 -12
- package/src/routes.ts +26 -7
- package/src/rpc.ts +2 -0
- package/src/shared/compat.ts +20 -0
- package/src/shared/rpc.ts +3 -0
package/README.md
CHANGED
|
@@ -84,25 +84,35 @@ npm pack # 产物 tgz(含 lib/assets/src/cordis.patch.yml)
|
|
|
84
84
|
|
|
85
85
|
```
|
|
86
86
|
src/
|
|
87
|
-
├── index.ts Host 入口:name/inject/apply
|
|
87
|
+
├── index.ts Host 入口:name/inject/apply(薄装配,含兼容性报告启动日志)
|
|
88
88
|
├── shared/ ★ 双面契约(禁 node/react):types.ts(记录/归档/摘要)+ rpc.ts(11 个方法类型化)
|
|
89
|
+
│ + compat.ts(兼容性报告形状)+ mcp.ts(MCP 契约)
|
|
90
|
+
├── compat.ts ★ Host 兼容层:身份常量、外部插件探测、路由/重复装配护栏、依赖守卫、兼容性报告
|
|
89
91
|
├── model.ts Host 纯域逻辑(可单测):normalize/markDecision/resolved/summary/reconstruct/批次/归档
|
|
90
92
|
├── store.ts Host 存储层:sidecar 读写合并 + 归档持久化 + stale 检测
|
|
91
93
|
├── workspace.ts Host 工作区文件扫描(TTL 缓存)+ 快速打开搜索
|
|
92
94
|
├── revert.ts Host 回滚/删除(fs + subprocess,fs.contains 边界校验)
|
|
93
95
|
├── registry.ts Host 每工作区记录桶注册表
|
|
94
|
-
├── rpc.ts Host RPC 分发表(类型化 handler 表替代巨型 switch)
|
|
95
|
-
├── routes.ts Host webServer 路由(/edrv/rpc、/edrv/assets/*、/edrv/vendor
|
|
96
|
+
├── rpc.ts Host RPC 分发表(类型化 handler 表替代巨型 switch,含 compat)
|
|
97
|
+
├── routes.ts Host webServer 路由(/edrv/rpc、/edrv/assets/*、/edrv/vendor/*,带冲突护栏)
|
|
96
98
|
└── client/
|
|
97
99
|
├── index.ts Client 入口:slot 注册(inject=['slots','timer'])
|
|
100
|
+
├── compat.ts ★ Client 兼容层:设置桥三级降级(webUiSettings→settingsScope)、slot 安全注册、openPath 链式补丁、外部插件常量
|
|
98
101
|
├── rpc.ts Client 类型化 fetch 包装 + 诊断日志
|
|
99
102
|
├── events.ts 窗口事件助手(edrv:refresh/open-editor/show-launcher)
|
|
100
103
|
├── state/ records.ts(摘要/计数/空差异)+ regions.ts(差异区域/行裁剪)纯函数
|
|
101
104
|
├── monaco/ loader.ts(AMD 加载/语言映射)+ diffRender.ts(差异自绘渲染器)
|
|
102
105
|
├── styles/editor.css 编辑区样式(tsdown CSS-inline 注入)
|
|
103
106
|
└── ui/ EditorView(编排)/ QuickOpen / DiffBox / DiffBarEmpty / DiffLauncher / DiffBadge
|
|
107
|
+
/ McpSettings(含「兼容性」子 Tab)
|
|
104
108
|
```
|
|
105
109
|
|
|
110
|
+
**兼容层(`src/compat.ts` + `src/client/compat.ts`)**:集中处理与其他插件 / DSH 版本的适配——
|
|
111
|
+
运行时探测 `@deepseek-ai/dsh-mcp-client`、设置桥(`webUiSettings` → `settingsScope`)等外部依赖,
|
|
112
|
+
护栏检测 `/edrv` 路由前缀冲突与本插件重复装配(duplicate loader entry),
|
|
113
|
+
`@deepseek-ai/dsh-settings` / `schemastery` 以动态加载引入(缺失时插件仍可加载,设置持久化降级)。
|
|
114
|
+
「VSCodeMode」设置页 →「兼容性」子 Tab 或 RPC `edrv.compat` 可查看完整报告。
|
|
115
|
+
|
|
106
116
|
**扩展缝(VSCode 化后续迭代)**:新能力 = `shared/rpc.ts` 加方法 + `src/rpc.ts` 加 handler +
|
|
107
117
|
`client/ui/` 加组件,其余模块零改动;`monaco/*` 是可复用的编辑器服务(资源树/对比/诊断面板共用)。
|
|
108
118
|
|
package/lib/client.js
CHANGED
|
@@ -2200,7 +2200,7 @@ window.__ModuleLoader__.load({
|
|
|
2200
2200
|
}
|
|
2201
2201
|
//#endregion
|
|
2202
2202
|
//#region \0dsh-css:/home/runner/work/DSH_VsCodeMode/DSH_VsCodeMode/src/client/styles/mcp.css.mjs
|
|
2203
|
-
const css = "/* dsh-vscode-mode MCP 管理界面样式。\n 全部使用 DSH 真实主题变量(--dsw-alias-*),不再用不存在的 fg-* 变量。 */\n.vsm-mcp-page{display:flex;flex-direction:column;gap:18px;width:100%;max-width:920px;box-sizing:border-box;color:var(--dsw-alias-label-primary,#e6e6e6);padding-bottom:32px}\n\n/* 顶部:标题 + 副标题 + 添加按钮 */\n.vsm-mcp-header{display:flex;align-items:flex-start;justify-content:space-between;gap:20px}\n.vsm-mcp-header h2{margin:0 0 4px;font-size:20px;font-weight:600;line-height:1.35;color:var(--dsw-alias-label-primary,#e6e6e6)}\n.vsm-mcp-header p{margin:0;color:var(--dsw-alias-label-tertiary,#9aa5b1);font-size:13px;line-height:1.5}\n.vsm-primary{border:0;border-radius:6px;padding:8px 16px;background:var(--dsw-alias-button-primary-fill,#6d55ff);color:var(--dsw-alias-button-contrast-fill,#fff);font-size:13px;font-weight:500;cursor:pointer;white-space:nowrap}\n.vsm-primary:hover{background:var(--dsw-alias-button-primary-hover,#5a46e6)}\n.vsm-primary:disabled{opacity:.55;cursor:default}\n\n/* 子 Tab:我的 MCP / MCP 市场 */\n.vsm-mcp-tabs{display:flex;gap:24px;border-bottom:1px solid var(--dsw-alias-border-l2,#3a3a3a)}\n.vsm-mcp-tabs button{border:0;background:none;color:var(--dsw-alias-label-tertiary,#9aa5b1);padding:9px 2px 11px;cursor:pointer;font-size:14px;position:relative}\n.vsm-mcp-tabs button:hover{color:var(--dsw-alias-label-secondary,#c8c8c8)}\n.vsm-mcp-tabs button.active{color:var(--dsw-alias-label-primary,#fff);font-weight:500}\n.vsm-mcp-tabs button.active::after{content:\"\";position:absolute;left:0;right:0;bottom:-1px;height:2px;background:var(--dsw-alias-brand-primary,#6d55ff);border-radius:2px}\n\n/* 通用设置 */\n.vsm-general-page{display:flex;flex-direction:column;gap:10px;max-width:720px}\n.vsm-general-page h2{margin:0;font-size:20px;color:var(--dsw-alias-label-primary,#e6e6e6)}\n.vsm-general-page p{margin:0 0 8px;color:var(--dsw-alias-label-tertiary,#9aa5b1);font-size:13px}\n.vsm-general-row{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:14px 0;border-bottom:1px solid var(--dsw-alias-border-l1,#333);color:var(--dsw-alias-label-primary,#eee);font-size:14px}\n.vsm-general-row select{min-width:220px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#555);border-radius:6px;background:var(--dsw-alias-bg-layer-1,#2b2b2b);color:var(--dsw-alias-label-primary,#eee);font:inherit}\n.vsm-general-row small{color:var(--dsw-alias-label-tertiary,#9aa5b1)}\n\n/* 服务卡片 */\n.vsm-mcp-card{border:1px solid var(--dsw-alias-border-l2,#3a3a3a);border-radius:10px;padding:14px 16px;margin-bottom:10px;background:var(--dsw-alias-bg-layer-2,transparent);transition:border-color .15s}\n.vsm-mcp-card:hover{border-color:var(--dsw-alias-border-l3,#555)}\n.vsm-mcp-card-head{display:flex;justify-content:space-between;align-items:center;gap:12px}\n.vsm-mcp-title{display:flex;align-items:center;gap:9px;font-weight:600;font-size:14px;color:var(--dsw-alias-label-primary,#e6e6e6);min-width:0}\n.vsm-mcp-source{font-size:11px;font-weight:400;padding:2px 7px;border-radius:4px;background:var(--dsw-alias-bg-mask-2,#ffffff22);color:var(--dsw-alias-label-tertiary,#9aa5b1);flex-shrink:0}\n.vsm-mcp-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;background:var(--dsw-alias-state-error-primary,#e05252)}\n.vsm-mcp-dot.connected{background:var(--dsw-alias-state-success-primary,#38bd75)}\n.vsm-mcp-dot.connecting{background:var(--dsw-alias-state-warn-primary,#e5b93f)}\n.vsm-mcp-dot.disabled{background:var(--dsw-alias-label-tertiary,#9aa5b1)}\n.vsm-mcp-actions{display:flex;align-items:center;gap:4px;flex-shrink:0}\n.vsm-mcp-actions button{border:0;background:none;color:var(--dsw-alias-label-tertiary,#9aa5b1);cursor:pointer;font-size:15px;width:28px;height:28px;border-radius:6px;line-height:1}\n.vsm-mcp-actions button:hover{color:var(--dsw-alias-label-primary,#fff);background:var(--dsw-alias-interactive-bg-hover,#ffffff14)}\n.vsm-mcp-actions button.vsm-danger:hover{color:var(--dsw-alias-state-error-primary,#f07878);background:var(--dsw-alias-interactive-bg-hover-danger,#ff000014)}\n.vsm-switch{font-size:14px !important}\n.vsm-switch.on{color:var(--dsw-alias-state-success-primary,#38bd75)}\n.vsm-mcp-meta{font-size:12px;color:var(--dsw-alias-label-tertiary,#9aa5b1);margin:9px 0}\n.vsm-mcp-error{color:var(--dsw-alias-state-error-primary,#f07878);font-size:12px;margin:8px 0}\n.vsm-mcp-banner{padding:9px 12px;border:1px solid var(--dsw-alias-state-error-secondary,#d9534f55);border-radius:6px;background:var(--dsw-alias-state-error-secondary,#d9534f1a);margin-bottom:10px}\n\n/* 工具 chips */\n.vsm-mcp-tools{display:flex;flex-wrap:wrap;gap:6px}\n.vsm-mcp-chip{font:12px var(--ds-font-family-code,ui-monospace,monospace);padding:4px 8px;border-radius:5px;background:var(--dsw-alias-bg-mask-2,#ffffff14);color:var(--dsw-alias-label-secondary,#c8c8c8);border:1px solid var(--dsw-alias-border-l1,#333)}\n\n/* 空态 / 加载态 */\n.vsm-mcp-empty{text-align:center;padding:56px 20px;color:var(--dsw-alias-label-tertiary,#9aa5b1);border:1px dashed var(--dsw-alias-border-l2,#3a3a3a);border-radius:8px;font-size:13px}\n\n/* 项目搜索下拉框 */\n.vsm-project-picker{position:relative;width:100%;z-index:4}\n.vsm-project-picker-trigger{width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border:1px solid var(--dsw-alias-border-l2,#3a3a3a);border-radius:8px;background:var(--dsw-alias-bg-layer-1,transparent);color:var(--dsw-alias-label-primary,#e6e6e6);cursor:pointer;text-align:left}\n.vsm-project-picker-trigger:hover{border-color:var(--dsw-alias-brand-primary,#6d55ff)}\n.vsm-project-picker-label{display:flex;flex-direction:column;min-width:0;font-size:13px;font-weight:500}\n.vsm-project-picker-label small{margin-top:3px;color:var(--dsw-alias-label-tertiary,#9aa5b1);font:11px var(--ds-font-family-code,ui-monospace,monospace);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.vsm-project-picker-arrow{color:var(--dsw-alias-label-tertiary,#9aa5b1);font-size:16px}\n.vsm-project-picker-menu{position:absolute;top:calc(100% + 6px);left:0;right:0;padding:8px;border:1px solid var(--dsw-alias-border-l2,#3a3a3a);border-radius:9px;background:var(--dsw-alias-bg-overlay,#202020);box-shadow:0 12px 36px #0008}\n.vsm-project-picker-search{width:100%;box-sizing:border-box;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#555);border-radius:6px;background:var(--dsw-alias-bg-layer-1,#2b2b2b);color:var(--dsw-alias-label-primary,#eee);outline:none}\n.vsm-project-picker-search:focus{border-color:var(--dsw-alias-brand-primary,#6d55ff)}\n.vsm-project-picker-options{max-height:260px;overflow:auto;margin-top:6px}\n.vsm-project-option{display:flex;width:100%;flex-direction:column;gap:3px;padding:8px 9px;border:0;border-radius:6px;background:none;color:var(--dsw-alias-label-primary,#eee);cursor:pointer;text-align:left}\n.vsm-project-option:hover,.vsm-project-option.highlight{background:var(--dsw-alias-interactive-bg-hover,#ffffff14)}\n.vsm-project-option.selected{color:var(--dsw-alias-brand-primary,#6d55ff)}\n.vsm-project-option small{overflow:hidden;color:var(--dsw-alias-label-tertiary,#9aa5b1);font:11px var(--ds-font-family-code,ui-monospace,monospace);text-overflow:ellipsis;white-space:nowrap}\n.vsm-project-picker-empty{padding:18px 8px;color:var(--dsw-alias-label-tertiary,#9aa5b1);font-size:12px;text-align:center}\n\n/* 项目级 MCP 分组 */\n.vsm-project{border:1px solid var(--dsw-alias-border-l2,#3a3a3a);border-radius:12px;margin-bottom:14px;overflow:hidden;background:var(--dsw-alias-bg-layer-1,transparent)}\n.vsm-project-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 16px;border-bottom:1px solid var(--dsw-alias-border-l1,#333);background:var(--dsw-alias-bg-mask-1,#ffffff0a)}\n.vsm-project-title{display:flex;align-items:center;gap:10px;min-width:0}\n.vsm-project-icon{color:var(--dsw-alias-brand-primary,#6d55ff);font-size:15px;flex-shrink:0}\n.vsm-project-name{font-size:14px;font-weight:600;color:var(--dsw-alias-label-primary,#e6e6e6);display:block}\n.vsm-project-path{font-size:11px;color:var(--dsw-alias-label-tertiary,#9aa5b1);font-family:var(--ds-font-family-code,ui-monospace,monospace);display:block;margin-top:2px;word-break:break-all}\n.vsm-primary.vsm-small{padding:5px 12px;font-size:12px}\n.vsm-project-empty{text-align:center;padding:26px 16px;color:var(--dsw-alias-label-tertiary,#9aa5b1);font-size:12px}\n.vsm-project .vsm-mcp-card{border:0;border-radius:0;margin:0;border-bottom:1px solid var(--dsw-alias-border-l1,#333);background:transparent}\n.vsm-project .vsm-mcp-card:last-child{border-bottom:0}\n.vsm-project .vsm-mcp-banner{border-radius:0;margin:0}\n\n/* 新增 MCP 弹窗 */\n.vsm-mcp-modal{position:fixed;inset:0;background:var(--dsw-alias-bg-mask-drop,#000000aa);display:flex;align-items:center;justify-content:center;z-index:50}\n.vsm-mcp-dialog{width:min(560px,calc(100vw - 40px));max-height:88vh;overflow:auto;padding:22px 24px;border-radius:12px;background:var(--dsw-alias-bg-overlay,#202020);border:1px solid var(--dsw-alias-border-l2,#444);box-shadow:0 16px 60px #000c;color:var(--dsw-alias-label-primary,#e6e6e6)}\n.vsm-mcp-dialog h3{margin:0 0 14px;font-size:16px;font-weight:600}\n.vsm-mcp-dialog label{display:flex;flex-direction:column;gap:6px;margin:12px 0;font-size:12px;color:var(--dsw-alias-label-secondary,#aaa)}\n.vsm-mcp-dialog input,.vsm-mcp-dialog select,.vsm-mcp-dialog textarea{font:inherit;color:var(--dsw-alias-label-primary,#eee);background:var(--dsw-alias-bg-layer-1,#2b2b2b);border:1px solid var(--dsw-alias-border-l2,#555);border-radius:6px;padding:8px 10px}\n.vsm-mcp-dialog input:focus,.vsm-mcp-dialog select:focus,.vsm-mcp-dialog textarea:focus{outline:none;border-color:var(--dsw-alias-brand-primary,#6d55ff)}\n.vsm-mcp-dialog textarea{min-height:64px;resize:vertical;font-family:var(--ds-font-family-code,ui-monospace,monospace)}\n.vsm-mcp-dialog-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:20px}\n.vsm-mcp-dialog-actions button{padding:8px 14px;border:1px solid var(--dsw-alias-border-l2,#555);border-radius:6px;background:none;color:var(--dsw-alias-label-primary,#eee);cursor:pointer;font-size:13px}\n.vsm-mcp-dialog-actions button:hover{background:var(--dsw-alias-interactive-bg-hover,#ffffff14)}\n";
|
|
2203
|
+
const css = "/* dsh-vscode-mode MCP 管理界面样式。\n 全部使用 DSH 真实主题变量(--dsw-alias-*),不再用不存在的 fg-* 变量。 */\n.vsm-mcp-page{display:flex;flex-direction:column;gap:18px;width:100%;max-width:920px;box-sizing:border-box;color:var(--dsw-alias-label-primary,#e6e6e6);padding-bottom:32px}\n\n/* 顶部:标题 + 副标题 + 添加按钮 */\n.vsm-mcp-header{display:flex;align-items:flex-start;justify-content:space-between;gap:20px}\n.vsm-mcp-header h2{margin:0 0 4px;font-size:20px;font-weight:600;line-height:1.35;color:var(--dsw-alias-label-primary,#e6e6e6)}\n.vsm-mcp-header p{margin:0;color:var(--dsw-alias-label-tertiary,#9aa5b1);font-size:13px;line-height:1.5}\n.vsm-primary{border:0;border-radius:6px;padding:8px 16px;background:var(--dsw-alias-button-primary-fill,#6d55ff);color:var(--dsw-alias-button-contrast-fill,#fff);font-size:13px;font-weight:500;cursor:pointer;white-space:nowrap}\n.vsm-primary:hover{background:var(--dsw-alias-button-primary-hover,#5a46e6)}\n.vsm-primary:disabled{opacity:.55;cursor:default}\n\n/* 子 Tab:我的 MCP / MCP 市场 */\n.vsm-mcp-tabs{display:flex;gap:24px;border-bottom:1px solid var(--dsw-alias-border-l2,#3a3a3a)}\n.vsm-mcp-tabs button{border:0;background:none;color:var(--dsw-alias-label-tertiary,#9aa5b1);padding:9px 2px 11px;cursor:pointer;font-size:14px;position:relative}\n.vsm-mcp-tabs button:hover{color:var(--dsw-alias-label-secondary,#c8c8c8)}\n.vsm-mcp-tabs button.active{color:var(--dsw-alias-label-primary,#fff);font-weight:500}\n.vsm-mcp-tabs button.active::after{content:\"\";position:absolute;left:0;right:0;bottom:-1px;height:2px;background:var(--dsw-alias-brand-primary,#6d55ff);border-radius:2px}\n\n/* 通用设置 */\n.vsm-general-page{display:flex;flex-direction:column;gap:10px;max-width:720px}\n.vsm-general-page h2{margin:0;font-size:20px;color:var(--dsw-alias-label-primary,#e6e6e6)}\n.vsm-general-page p{margin:0 0 8px;color:var(--dsw-alias-label-tertiary,#9aa5b1);font-size:13px}\n.vsm-general-row{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:14px 0;border-bottom:1px solid var(--dsw-alias-border-l1,#333);color:var(--dsw-alias-label-primary,#eee);font-size:14px}\n.vsm-general-row select{min-width:220px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#555);border-radius:6px;background:var(--dsw-alias-bg-layer-1,#2b2b2b);color:var(--dsw-alias-label-primary,#eee);font:inherit}\n.vsm-general-row small{color:var(--dsw-alias-label-tertiary,#9aa5b1)}\n\n/* 服务卡片 */\n.vsm-mcp-card{border:1px solid var(--dsw-alias-border-l2,#3a3a3a);border-radius:10px;padding:14px 16px;margin-bottom:10px;background:var(--dsw-alias-bg-layer-2,transparent);transition:border-color .15s}\n.vsm-mcp-card:hover{border-color:var(--dsw-alias-border-l3,#555)}\n.vsm-mcp-card-head{display:flex;justify-content:space-between;align-items:center;gap:12px}\n.vsm-mcp-title{display:flex;align-items:center;gap:9px;font-weight:600;font-size:14px;color:var(--dsw-alias-label-primary,#e6e6e6);min-width:0}\n.vsm-mcp-source{font-size:11px;font-weight:400;padding:2px 7px;border-radius:4px;background:var(--dsw-alias-bg-mask-2,#ffffff22);color:var(--dsw-alias-label-tertiary,#9aa5b1);flex-shrink:0}\n.vsm-mcp-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;background:var(--dsw-alias-state-error-primary,#e05252)}\n.vsm-mcp-dot.connected{background:var(--dsw-alias-state-success-primary,#38bd75)}\n.vsm-mcp-dot.connecting{background:var(--dsw-alias-state-warn-primary,#e5b93f)}\n.vsm-mcp-dot.disabled{background:var(--dsw-alias-label-tertiary,#9aa5b1)}\n.vsm-mcp-actions{display:flex;align-items:center;gap:4px;flex-shrink:0}\n.vsm-mcp-actions button{border:0;background:none;color:var(--dsw-alias-label-tertiary,#9aa5b1);cursor:pointer;font-size:15px;width:28px;height:28px;border-radius:6px;line-height:1}\n.vsm-mcp-actions button:hover{color:var(--dsw-alias-label-primary,#fff);background:var(--dsw-alias-interactive-bg-hover,#ffffff14)}\n.vsm-mcp-actions button.vsm-danger:hover{color:var(--dsw-alias-state-error-primary,#f07878);background:var(--dsw-alias-interactive-bg-hover-danger,#ff000014)}\n.vsm-switch{font-size:14px !important}\n.vsm-switch.on{color:var(--dsw-alias-state-success-primary,#38bd75)}\n.vsm-mcp-meta{font-size:12px;color:var(--dsw-alias-label-tertiary,#9aa5b1);margin:9px 0}\n.vsm-mcp-error{color:var(--dsw-alias-state-error-primary,#f07878);font-size:12px;margin:8px 0}\n.vsm-mcp-banner{padding:9px 12px;border:1px solid var(--dsw-alias-state-error-secondary,#d9534f55);border-radius:6px;background:var(--dsw-alias-state-error-secondary,#d9534f1a);margin-bottom:10px}\n\n/* 工具 chips */\n.vsm-mcp-tools{display:flex;flex-wrap:wrap;gap:6px}\n.vsm-mcp-chip{font:12px var(--ds-font-family-code,ui-monospace,monospace);padding:4px 8px;border-radius:5px;background:var(--dsw-alias-bg-mask-2,#ffffff14);color:var(--dsw-alias-label-secondary,#c8c8c8);border:1px solid var(--dsw-alias-border-l1,#333)}\n\n/* 空态 / 加载态 */\n.vsm-mcp-empty{text-align:center;padding:56px 20px;color:var(--dsw-alias-label-tertiary,#9aa5b1);border:1px dashed var(--dsw-alias-border-l2,#3a3a3a);border-radius:8px;font-size:13px}\n\n/* 项目搜索下拉框 */\n.vsm-project-picker{position:relative;width:100%;z-index:4}\n.vsm-project-picker-trigger{width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border:1px solid var(--dsw-alias-border-l2,#3a3a3a);border-radius:8px;background:var(--dsw-alias-bg-layer-1,transparent);color:var(--dsw-alias-label-primary,#e6e6e6);cursor:pointer;text-align:left}\n.vsm-project-picker-trigger:hover{border-color:var(--dsw-alias-brand-primary,#6d55ff)}\n.vsm-project-picker-label{display:flex;flex-direction:column;min-width:0;font-size:13px;font-weight:500}\n.vsm-project-picker-label small{margin-top:3px;color:var(--dsw-alias-label-tertiary,#9aa5b1);font:11px var(--ds-font-family-code,ui-monospace,monospace);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.vsm-project-picker-arrow{color:var(--dsw-alias-label-tertiary,#9aa5b1);font-size:16px}\n.vsm-project-picker-menu{position:absolute;top:calc(100% + 6px);left:0;right:0;padding:8px;border:1px solid var(--dsw-alias-border-l2,#3a3a3a);border-radius:9px;background:var(--dsw-alias-bg-overlay,#202020);box-shadow:0 12px 36px #0008}\n.vsm-project-picker-search{width:100%;box-sizing:border-box;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2,#555);border-radius:6px;background:var(--dsw-alias-bg-layer-1,#2b2b2b);color:var(--dsw-alias-label-primary,#eee);outline:none}\n.vsm-project-picker-search:focus{border-color:var(--dsw-alias-brand-primary,#6d55ff)}\n.vsm-project-picker-options{max-height:260px;overflow:auto;margin-top:6px}\n.vsm-project-option{display:flex;width:100%;flex-direction:column;gap:3px;padding:8px 9px;border:0;border-radius:6px;background:none;color:var(--dsw-alias-label-primary,#eee);cursor:pointer;text-align:left}\n.vsm-project-option:hover,.vsm-project-option.highlight{background:var(--dsw-alias-interactive-bg-hover,#ffffff14)}\n.vsm-project-option.selected{color:var(--dsw-alias-brand-primary,#6d55ff)}\n.vsm-project-option small{overflow:hidden;color:var(--dsw-alias-label-tertiary,#9aa5b1);font:11px var(--ds-font-family-code,ui-monospace,monospace);text-overflow:ellipsis;white-space:nowrap}\n.vsm-project-picker-empty{padding:18px 8px;color:var(--dsw-alias-label-tertiary,#9aa5b1);font-size:12px;text-align:center}\n\n/* 项目级 MCP 分组 */\n.vsm-project{border:1px solid var(--dsw-alias-border-l2,#3a3a3a);border-radius:12px;margin-bottom:14px;overflow:hidden;background:var(--dsw-alias-bg-layer-1,transparent)}\n.vsm-project-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 16px;border-bottom:1px solid var(--dsw-alias-border-l1,#333);background:var(--dsw-alias-bg-mask-1,#ffffff0a)}\n.vsm-project-title{display:flex;align-items:center;gap:10px;min-width:0}\n.vsm-project-icon{color:var(--dsw-alias-brand-primary,#6d55ff);font-size:15px;flex-shrink:0}\n.vsm-project-name{font-size:14px;font-weight:600;color:var(--dsw-alias-label-primary,#e6e6e6);display:block}\n.vsm-project-path{font-size:11px;color:var(--dsw-alias-label-tertiary,#9aa5b1);font-family:var(--ds-font-family-code,ui-monospace,monospace);display:block;margin-top:2px;word-break:break-all}\n.vsm-primary.vsm-small{padding:5px 12px;font-size:12px}\n.vsm-project-empty{text-align:center;padding:26px 16px;color:var(--dsw-alias-label-tertiary,#9aa5b1);font-size:12px}\n.vsm-project .vsm-mcp-card{border:0;border-radius:0;margin:0;border-bottom:1px solid var(--dsw-alias-border-l1,#333);background:transparent}\n.vsm-project .vsm-mcp-card:last-child{border-bottom:0}\n.vsm-project .vsm-mcp-banner{border-radius:0;margin:0}\n\n/* 新增 MCP 弹窗 */\n.vsm-mcp-modal{position:fixed;inset:0;background:var(--dsw-alias-bg-mask-drop,#000000aa);display:flex;align-items:center;justify-content:center;z-index:50}\n.vsm-mcp-dialog{width:min(560px,calc(100vw - 40px));max-height:88vh;overflow:auto;padding:22px 24px;border-radius:12px;background:var(--dsw-alias-bg-overlay,#202020);border:1px solid var(--dsw-alias-border-l2,#444);box-shadow:0 16px 60px #000c;color:var(--dsw-alias-label-primary,#e6e6e6)}\n.vsm-mcp-dialog h3{margin:0 0 14px;font-size:16px;font-weight:600}\n.vsm-mcp-dialog label{display:flex;flex-direction:column;gap:6px;margin:12px 0;font-size:12px;color:var(--dsw-alias-label-secondary,#aaa)}\n.vsm-mcp-dialog input,.vsm-mcp-dialog select,.vsm-mcp-dialog textarea{font:inherit;color:var(--dsw-alias-label-primary,#eee);background:var(--dsw-alias-bg-layer-1,#2b2b2b);border:1px solid var(--dsw-alias-border-l2,#555);border-radius:6px;padding:8px 10px}\n.vsm-mcp-dialog input:focus,.vsm-mcp-dialog select:focus,.vsm-mcp-dialog textarea:focus{outline:none;border-color:var(--dsw-alias-brand-primary,#6d55ff)}\n.vsm-mcp-dialog textarea{min-height:64px;resize:vertical;font-family:var(--ds-font-family-code,ui-monospace,monospace)}\n.vsm-mcp-dialog-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:20px}\n.vsm-mcp-dialog-actions button{padding:8px 14px;border:1px solid var(--dsw-alias-border-l2,#555);border-radius:6px;background:none;color:var(--dsw-alias-label-primary,#eee);cursor:pointer;font-size:13px}\n.vsm-mcp-dialog-actions button:hover{background:var(--dsw-alias-interactive-bg-hover,#ffffff14)}\n\n/* 兼容性小节 */\n.vsm-compat-h3{margin:16px 0 2px;font-size:14px;font-weight:600;color:var(--dsw-alias-label-secondary,#c8c8c8)}\n.vsm-compat-item{display:flex;align-items:baseline;justify-content:space-between;gap:16px;padding:10px 0;border-bottom:1px solid var(--dsw-alias-border-l1,#333);font-size:13px;color:var(--dsw-alias-label-primary,#eee)}\n.vsm-compat-item.ok .vsm-compat-name::before{content:\"● \";color:var(--dsw-alias-state-success-primary,#38bd75)}\n.vsm-compat-item.warn .vsm-compat-name::before{content:\"● \";color:var(--dsw-alias-state-warn-primary,#e5b93f)}\n.vsm-compat-name{font-weight:500;min-width:0}\n.vsm-compat-note{color:var(--dsw-alias-label-tertiary,#9aa5b1);font-size:12px;text-align:right;min-width:0}\n";
|
|
2204
2204
|
const tagId = "dsh-vscode-mode/mcp.css";
|
|
2205
2205
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
2206
2206
|
const tag = document.createElement("style");
|
|
@@ -2210,6 +2210,76 @@ window.__ModuleLoader__.load({
|
|
|
2210
2210
|
document.head.appendChild(tag);
|
|
2211
2211
|
}
|
|
2212
2212
|
//#endregion
|
|
2213
|
+
//#region src/client/compat.ts
|
|
2214
|
+
/**
|
|
2215
|
+
* dsh-vscode-mode client — 兼容层:设置桥选择 / slot 安全注册 / openPath 链式补丁 / 外部插件常量。
|
|
2216
|
+
* 纯逻辑与薄 ctx 胶水,node 环境可单测(不依赖 DOM)。
|
|
2217
|
+
* 作者 ddj 2026年08月24号
|
|
2218
|
+
*/
|
|
2219
|
+
/** 本插件包名(与 host compat.PLUGIN_NAME 对应)。 */
|
|
2220
|
+
const PLUGIN_NAME = "dsh-vscode-mode";
|
|
2221
|
+
/** 外部侧栏插件名(dsh-web-ui-all 家族的文件打开能力提供方)。 */
|
|
2222
|
+
const SIDEBAR_PLUGIN = "dsh-better-sidebar";
|
|
2223
|
+
/**
|
|
2224
|
+
* 设置桥三级优先:webUiSettings(linxin666 兼容桥)→ settingsScope(官方)→ 无。
|
|
2225
|
+
* 桥绑定抛错时降级到下一级,不让单个桥异常拖垮设置装配。
|
|
2226
|
+
* @author ddj 2026年08月24号
|
|
2227
|
+
* @param ctx 客户端服务上下文
|
|
2228
|
+
* @returns 激活的桥名称与绑定 scope
|
|
2229
|
+
*/
|
|
2230
|
+
function pickSettingsBinder(ctx) {
|
|
2231
|
+
for (const service of ["webUiSettings", "settingsScope"]) try {
|
|
2232
|
+
const scope = ctx.get(service)?.bind?.({ namespace: PLUGIN_NAME });
|
|
2233
|
+
if (scope) return {
|
|
2234
|
+
service,
|
|
2235
|
+
scope
|
|
2236
|
+
};
|
|
2237
|
+
} catch {}
|
|
2238
|
+
return {
|
|
2239
|
+
service: "none",
|
|
2240
|
+
scope: void 0
|
|
2241
|
+
};
|
|
2242
|
+
}
|
|
2243
|
+
/**
|
|
2244
|
+
* 跨版本 slot 安全注册:封装 ctx.slots.inject 等待声明模式(新老 DSH 通用),
|
|
2245
|
+
* 服务缺失或注册抛错时降级为警告,不让单条 slot 拖垮装配。
|
|
2246
|
+
* 注意:方法必须挂在服务对象上调用(slots.register 是依赖 this.records 的类方法,
|
|
2247
|
+
* 解构后 this 丢失会静默失败),故禁止解构。
|
|
2248
|
+
* @author ddj 2026年08月24号
|
|
2249
|
+
* @param ctx 客户端上下文(slots 服务)
|
|
2250
|
+
* @param spec slot 描述
|
|
2251
|
+
* @param render 渲染函数
|
|
2252
|
+
*/
|
|
2253
|
+
function registerSlotSafely(ctx, spec, render) {
|
|
2254
|
+
const slots = ctx?.slots;
|
|
2255
|
+
if (!slots || typeof slots.inject !== "function" || typeof slots.register !== "function") {
|
|
2256
|
+
console.warn("[dsh-vscode-mode] slots 服务不可用,跳过 slot " + spec.name);
|
|
2257
|
+
return;
|
|
2258
|
+
}
|
|
2259
|
+
try {
|
|
2260
|
+
slots.inject(spec.name, () => slots.register(spec, render));
|
|
2261
|
+
} catch (error) {
|
|
2262
|
+
console.warn("[dsh-vscode-mode] slot " + spec.name + " 注册失败(" + String(error) + "),已跳过");
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
/**
|
|
2266
|
+
* 链式补丁对象方法:保存原实现、装入包装实现,dispose 恢复。
|
|
2267
|
+
* 恢复带归属校验(仅当当前实现仍是本包装时还原),多插件补丁按栈序互不踩踏。
|
|
2268
|
+
* @author ddj 2026年08月24号
|
|
2269
|
+
* @param owner 目标对象
|
|
2270
|
+
* @param key 方法名
|
|
2271
|
+
* @param wrapper 包装实现(original 为补丁前的实现)
|
|
2272
|
+
* @returns 恢复函数(幂等)
|
|
2273
|
+
*/
|
|
2274
|
+
function patchMethod(owner, key, wrapper) {
|
|
2275
|
+
const original = owner[key];
|
|
2276
|
+
const patched = ((...args) => wrapper(original, ...args));
|
|
2277
|
+
owner[key] = patched;
|
|
2278
|
+
return () => {
|
|
2279
|
+
if (owner[key] === patched) owner[key] = original;
|
|
2280
|
+
};
|
|
2281
|
+
}
|
|
2282
|
+
//#endregion
|
|
2213
2283
|
//#region src/client/fileOpeners.ts
|
|
2214
2284
|
/**
|
|
2215
2285
|
* dsh-vscode-mode client — 文件打开器注册表与自动选择。
|
|
@@ -2217,7 +2287,7 @@ window.__ModuleLoader__.load({
|
|
|
2217
2287
|
*/
|
|
2218
2288
|
const AUTO_OPEN_TOOL = "auto";
|
|
2219
2289
|
const VSCODE_OPEN_TOOL = "dsh-vscode-mode";
|
|
2220
|
-
const SIDEBAR_OPEN_TOOL =
|
|
2290
|
+
const SIDEBAR_OPEN_TOOL = SIDEBAR_PLUGIN;
|
|
2221
2291
|
/**
|
|
2222
2292
|
* 写入外部打开器并触发注册表通知。
|
|
2223
2293
|
* @author ddj 2026年08月24号
|
|
@@ -2347,24 +2417,10 @@ window.__ModuleLoader__.load({
|
|
|
2347
2417
|
//#region src/client/settingsContext.ts
|
|
2348
2418
|
/**
|
|
2349
2419
|
* dsh-vscode-mode client — 设置 scope 的跨组件上下文。
|
|
2350
|
-
*
|
|
2420
|
+
* 绑定逻辑(webUiSettings 兼容桥 → 官方 settingsScope 降级)统一由 compat 层提供。
|
|
2421
|
+
* 作者 ddj 2026年08月24号
|
|
2351
2422
|
*/
|
|
2352
2423
|
const SettingsContext = react.default.createContext(void 0);
|
|
2353
|
-
/**
|
|
2354
|
-
* 从 Cordis 服务绑定 VSCodeMode 设置 scope。
|
|
2355
|
-
* @author ddj 2026年08月24号
|
|
2356
|
-
* @param ctx 客户端上下文
|
|
2357
|
-
* @returns 设置 scope 或 undefined
|
|
2358
|
-
*/
|
|
2359
|
-
/**
|
|
2360
|
-
* 绑定官方设置 scope,优先使用 web-ui 兼容桥。
|
|
2361
|
-
* @author ddj 2026年08月24号
|
|
2362
|
-
* @param ctx 客户端服务上下文
|
|
2363
|
-
* @returns 设置 scope;未安装设置服务时返回 undefined
|
|
2364
|
-
*/
|
|
2365
|
-
function getSettingsScope(ctx) {
|
|
2366
|
-
return (ctx.get("webUiSettings") ?? ctx.get("settingsScope"))?.bind?.({ namespace: "dsh-vscode-mode" });
|
|
2367
|
-
}
|
|
2368
2424
|
//#endregion
|
|
2369
2425
|
//#region src/client/ui/McpSettings.ts
|
|
2370
2426
|
/**
|
|
@@ -2566,9 +2622,37 @@ window.__ModuleLoader__.load({
|
|
|
2566
2622
|
value: item.id
|
|
2567
2623
|
}, item.label))), loading && react.default.createElement("small", null, "读取中…")));
|
|
2568
2624
|
}
|
|
2625
|
+
/** 兼容性小节:host 报告(RPC compat)+ 客户端本地适配项。 */
|
|
2626
|
+
function CompatSection({ getSummary }) {
|
|
2627
|
+
const [report, setReport] = react.default.useState(null);
|
|
2628
|
+
const [error, setError] = react.default.useState("");
|
|
2629
|
+
react.default.useEffect(() => {
|
|
2630
|
+
let alive = true;
|
|
2631
|
+
rpc("compat", {}).then((result) => {
|
|
2632
|
+
if (!alive) return;
|
|
2633
|
+
if (!result.ok) setError(String(result.error));
|
|
2634
|
+
else setReport(result.report);
|
|
2635
|
+
}).catch((e) => {
|
|
2636
|
+
if (alive) setError(String(e));
|
|
2637
|
+
});
|
|
2638
|
+
return () => {
|
|
2639
|
+
alive = false;
|
|
2640
|
+
};
|
|
2641
|
+
}, []);
|
|
2642
|
+
const renderItems = (list) => (list ?? []).map((item) => react.default.createElement("div", {
|
|
2643
|
+
key: item.name,
|
|
2644
|
+
className: "vsm-compat-item " + (item.active ? "ok" : "warn")
|
|
2645
|
+
}, react.default.createElement("span", { className: "vsm-compat-name" }, item.name), react.default.createElement("span", { className: "vsm-compat-note" }, item.note ?? (item.active ? "正常" : "未生效"))));
|
|
2646
|
+
const warnings = report?.warnings ?? [];
|
|
2647
|
+
return react.default.createElement("section", { className: "vsm-general-page" }, react.default.createElement("h2", null, "兼容性"), react.default.createElement("p", null, "检测与其他插件 / DSH 版本的适配状态与已知问题。" + (report?.pluginVersion ? "(插件版本 " + report.pluginVersion + ")" : "")), error && react.default.createElement("div", { className: "vsm-mcp-error vsm-mcp-banner" }, error), react.default.createElement("h3", { className: "vsm-compat-h3" }, "外部插件与服务"), renderItems(report?.external), react.default.createElement("h3", { className: "vsm-compat-h3" }, "客户端适配"), renderItems(getSummary?.() ?? []), react.default.createElement("h3", { className: "vsm-compat-h3" }, "护栏"), renderItems(report?.guards), react.default.createElement("h3", { className: "vsm-compat-h3" }, "警告"), warnings.length ? warnings.map((w, index) => react.default.createElement("div", {
|
|
2648
|
+
key: index,
|
|
2649
|
+
className: "vsm-mcp-error vsm-mcp-banner"
|
|
2650
|
+
}, w)) : react.default.createElement("div", { className: "vsm-compat-item ok" }, react.default.createElement("span", { className: "vsm-compat-name" }, "未检测到兼容性问题"), react.default.createElement("span", { className: "vsm-compat-note" }, "")));
|
|
2651
|
+
}
|
|
2569
2652
|
/** MCP 管理主面板。 */
|
|
2570
2653
|
function McpSettings(props) {
|
|
2571
2654
|
const openerRegistry = props?.openerRegistry ?? { list: () => [] };
|
|
2655
|
+
const compatSummary = props?.compatSummary ?? (() => []);
|
|
2572
2656
|
const [servers, setServers] = react.default.useState([]);
|
|
2573
2657
|
const [projects, setProjects] = react.default.useState([]);
|
|
2574
2658
|
const [loading, setLoading] = react.default.useState(true);
|
|
@@ -2694,6 +2778,7 @@ window.__ModuleLoader__.load({
|
|
|
2694
2778
|
onRemove: removeGlobal
|
|
2695
2779
|
})) : react.default.createElement("div", { className: "vsm-mcp-empty" }, "还没有配置全局 MCP"));
|
|
2696
2780
|
else if (tab === "projects") body = projectBody;
|
|
2781
|
+
else if (tab === "compat") body = react.default.createElement(CompatSection, { getSummary: compatSummary });
|
|
2697
2782
|
else body = marketBody;
|
|
2698
2783
|
const form = showForm ? react.default.createElement(McpForm, {
|
|
2699
2784
|
title: "添加全局 MCP",
|
|
@@ -2728,7 +2813,10 @@ window.__ModuleLoader__.load({
|
|
|
2728
2813
|
}, "项目 MCP"), react.default.createElement("button", {
|
|
2729
2814
|
className: tab === "market" ? "active" : "",
|
|
2730
2815
|
onClick: () => setTab("market")
|
|
2731
|
-
}, "MCP 市场")
|
|
2816
|
+
}, "MCP 市场"), react.default.createElement("button", {
|
|
2817
|
+
className: tab === "compat" ? "active" : "",
|
|
2818
|
+
onClick: () => setTab("compat")
|
|
2819
|
+
}, "兼容性")), error && react.default.createElement("div", { className: "vsm-mcp-error vsm-mcp-banner" }, error), body, form);
|
|
2732
2820
|
}
|
|
2733
2821
|
/** MCP 新增表单(全局/项目共用)。 */
|
|
2734
2822
|
function McpForm({ title, draft, busy, edit, save, close }) {
|
|
@@ -2757,7 +2845,8 @@ window.__ModuleLoader__.load({
|
|
|
2757
2845
|
//#region src/client/openPathRouter.ts
|
|
2758
2846
|
/**
|
|
2759
2847
|
* dsh-vscode-mode client — DSH 对话文件链接的统一打开路由。
|
|
2760
|
-
*
|
|
2848
|
+
* openPath 补丁经 compat.patchMethod 安装(链式恢复,多插件补丁互不踩踏)。
|
|
2849
|
+
* 作者 ddj 2026年08月24号
|
|
2761
2850
|
*/
|
|
2762
2851
|
/**
|
|
2763
2852
|
* 安装可卸载的 workspaces.openPath 路由。
|
|
@@ -2766,8 +2855,7 @@ window.__ModuleLoader__.load({
|
|
|
2766
2855
|
* @returns 恢复原方法的 disposer
|
|
2767
2856
|
*/
|
|
2768
2857
|
function installOpenPathRouter(options) {
|
|
2769
|
-
const
|
|
2770
|
-
const open = async (path) => {
|
|
2858
|
+
const open = async (original, path) => {
|
|
2771
2859
|
const context = options.context();
|
|
2772
2860
|
const opener = selectOpener(options.registry, options.selected());
|
|
2773
2861
|
if (!opener || !isAvailable(opener)) return original.call(options.workspaces, path);
|
|
@@ -2779,10 +2867,7 @@ window.__ModuleLoader__.load({
|
|
|
2779
2867
|
else throw error;
|
|
2780
2868
|
}
|
|
2781
2869
|
};
|
|
2782
|
-
options.workspaces
|
|
2783
|
-
return () => {
|
|
2784
|
-
options.workspaces.openPath = original;
|
|
2785
|
-
};
|
|
2870
|
+
return patchMethod(options.workspaces, "openPath", open);
|
|
2786
2871
|
}
|
|
2787
2872
|
/**
|
|
2788
2873
|
* 创建 VSCodeMode 内置文件打开器。
|
|
@@ -2843,8 +2928,27 @@ window.__ModuleLoader__.load({
|
|
|
2843
2928
|
const workspaces = ctx.get("workspaces");
|
|
2844
2929
|
const sessions = ctx.get("sessions");
|
|
2845
2930
|
const originalOpenPath = workspaces?.openPath;
|
|
2846
|
-
const
|
|
2931
|
+
const binder = pickSettingsBinder(ctx);
|
|
2932
|
+
const settings = binder.scope;
|
|
2847
2933
|
let selected = autoValue("auto");
|
|
2934
|
+
/** 客户端侧兼容摘要(与 host 报告合并展示;惰性求值保证 HMR 后仍新鲜)。 */
|
|
2935
|
+
const compatSummary = () => [
|
|
2936
|
+
{
|
|
2937
|
+
name: "设置桥",
|
|
2938
|
+
active: settings !== void 0,
|
|
2939
|
+
note: settings !== void 0 ? "使用 " + binder.service + " 桥" : "未绑定设置服务(fileOpenTool 持久化不可用)"
|
|
2940
|
+
},
|
|
2941
|
+
{
|
|
2942
|
+
name: "文件打开路由(workspaces.openPath)",
|
|
2943
|
+
active: Boolean(workspaces?.openPath),
|
|
2944
|
+
note: "vscode 打开器优先,失败回退系统打开"
|
|
2945
|
+
},
|
|
2946
|
+
{
|
|
2947
|
+
name: "侧边栏打开器(dsh-better-sidebar)",
|
|
2948
|
+
active: registry.get(SIDEBAR_PLUGIN) !== void 0,
|
|
2949
|
+
note: registry.get("dsh-better-sidebar") !== void 0 ? "已注册(优先级 80)" : "未检测到侧边栏打开能力"
|
|
2950
|
+
}
|
|
2951
|
+
];
|
|
2848
2952
|
ctx.provide("fileOpeners", registry);
|
|
2849
2953
|
ctx.effect(() => registry.register(vscodeOpener()), "vscode-mode: file opener");
|
|
2850
2954
|
ctx.effect(() => registry.register({
|
|
@@ -2882,25 +2986,28 @@ window.__ModuleLoader__.load({
|
|
|
2882
2986
|
},
|
|
2883
2987
|
logger: (message) => console.warn("[dsh-vscode-mode] " + message)
|
|
2884
2988
|
}), "vscode-mode: file link routing");
|
|
2885
|
-
ctx
|
|
2989
|
+
registerSlotSafely(ctx, {
|
|
2886
2990
|
name: "conversation.view",
|
|
2887
2991
|
id: "edrv-editor",
|
|
2888
2992
|
order: 5,
|
|
2889
2993
|
label: "文件编辑",
|
|
2890
2994
|
inject: (sessionId) => ({ sessionId })
|
|
2891
|
-
}, (props) => react.default.createElement(EditorView, Object.assign({}, props, { schedule })))
|
|
2892
|
-
ctx
|
|
2995
|
+
}, (props) => react.default.createElement(EditorView, Object.assign({}, props, { schedule })));
|
|
2996
|
+
registerSlotSafely(ctx, {
|
|
2893
2997
|
name: "conversation.session.header.utilities",
|
|
2894
2998
|
id: "edrv-diff-badge",
|
|
2895
2999
|
order: 90,
|
|
2896
3000
|
label: "差异"
|
|
2897
|
-
}, (props) => react.default.createElement(DiffBadge, Object.assign({}, props)))
|
|
2898
|
-
ctx
|
|
3001
|
+
}, (props) => react.default.createElement(DiffBadge, Object.assign({}, props)));
|
|
3002
|
+
registerSlotSafely(ctx, {
|
|
2899
3003
|
name: "settings.section",
|
|
2900
3004
|
id: "vscode-mode",
|
|
2901
3005
|
order: 30,
|
|
2902
3006
|
label: "VSCodeMode"
|
|
2903
|
-
}, () => react.default.createElement(SettingsContext.Provider, { value: settings }, react.default.createElement(McpSettings, {
|
|
3007
|
+
}, () => react.default.createElement(SettingsContext.Provider, { value: settings }, react.default.createElement(McpSettings, {
|
|
3008
|
+
openerRegistry: registry,
|
|
3009
|
+
compatSummary
|
|
3010
|
+
})));
|
|
2904
3011
|
}
|
|
2905
3012
|
//#endregion
|
|
2906
3013
|
exports.apply = apply;
|