dsh-vscode-mode 0.1.12 → 0.1.15
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/lib/client.js +319 -7
- package/lib/client.js.map +1 -1
- package/lib/index.js +709 -91
- package/lib/index.js.map +1 -1
- package/package.json +9 -1
- package/src/capture.ts +4 -10
- package/src/client/fileOpeners.ts +172 -0
- package/src/client/index.ts +49 -2
- package/src/client/openPathRouter.ts +57 -0
- package/src/client/settingsContext.ts +31 -0
- package/src/client/styles/mcp.css +8 -0
- package/src/client/ui/EditorView.ts +5 -2
- package/src/client/ui/McpSettings.ts +41 -3
- package/src/fileOpenSettings.ts +72 -0
- package/src/host-deps.d.ts +14 -0
- package/src/index.ts +6 -1
- package/src/rpc.ts +28 -24
- package/src/search/fallback.ts +76 -0
- package/src/search/orchestrator.ts +276 -0
- package/src/search/query.ts +62 -0
- package/src/search/ranker.ts +48 -0
- package/src/search/ripgrep.ts +144 -0
- package/src/search/types.ts +47 -0
- package/src/shared/rpc.ts +4 -0
package/lib/client.js
CHANGED
|
@@ -1347,7 +1347,7 @@ window.__ModuleLoader__.load({
|
|
|
1347
1347
|
if (!diffRendererRef.current) diffRendererRef.current = createDiffRenderer((sid, t) => dbg(sid, t));
|
|
1348
1348
|
const currentRecords = react.default.useMemo(() => {
|
|
1349
1349
|
const list = [];
|
|
1350
|
-
for (const rec of Object.values(records)) if (rec.path === active) list.push(rec);
|
|
1350
|
+
for (const rec of Object.values(records)) if (rec.path === active && rec.archived !== true) list.push(rec);
|
|
1351
1351
|
return list;
|
|
1352
1352
|
}, [records, active]);
|
|
1353
1353
|
const regions = react.default.useMemo(() => diffRegions(currentRecords, content).filter((r) => !r.superseded), [currentRecords, content]);
|
|
@@ -1386,7 +1386,10 @@ window.__ModuleLoader__.load({
|
|
|
1386
1386
|
rpc("edrv.list", { sessionId }).then((res) => {
|
|
1387
1387
|
if (!res || !res.ok || !Array.isArray(res.records)) return;
|
|
1388
1388
|
const map = {};
|
|
1389
|
-
for (const r of res.records)
|
|
1389
|
+
for (const r of res.records) {
|
|
1390
|
+
if (r.archived === true) continue;
|
|
1391
|
+
map[r.callId] = r;
|
|
1392
|
+
}
|
|
1390
1393
|
setRecords(map);
|
|
1391
1394
|
}).catch((e) => setError("list异常:" + String(e)));
|
|
1392
1395
|
};
|
|
@@ -2197,7 +2200,7 @@ window.__ModuleLoader__.load({
|
|
|
2197
2200
|
}
|
|
2198
2201
|
//#endregion
|
|
2199
2202
|
//#region \0dsh-css:/home/runner/work/DSH_VsCodeMode/DSH_VsCodeMode/src/client/styles/mcp.css.mjs
|
|
2200
|
-
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-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";
|
|
2201
2204
|
const tagId = "dsh-vscode-mode/mcp.css";
|
|
2202
2205
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
2203
2206
|
const tag = document.createElement("style");
|
|
@@ -2207,6 +2210,162 @@ window.__ModuleLoader__.load({
|
|
|
2207
2210
|
document.head.appendChild(tag);
|
|
2208
2211
|
}
|
|
2209
2212
|
//#endregion
|
|
2213
|
+
//#region src/client/fileOpeners.ts
|
|
2214
|
+
/**
|
|
2215
|
+
* dsh-vscode-mode client — 文件打开器注册表与自动选择。
|
|
2216
|
+
* @author ddj 2026年08月24号
|
|
2217
|
+
*/
|
|
2218
|
+
const AUTO_OPEN_TOOL = "auto";
|
|
2219
|
+
const VSCODE_OPEN_TOOL = "dsh-vscode-mode";
|
|
2220
|
+
const SIDEBAR_OPEN_TOOL = "dsh-better-sidebar";
|
|
2221
|
+
/**
|
|
2222
|
+
* 写入外部打开器并触发注册表通知。
|
|
2223
|
+
* @author ddj 2026年08月24号
|
|
2224
|
+
* @param entries 打开器存储
|
|
2225
|
+
* @param notify 变更通知
|
|
2226
|
+
* @param opener 打开器
|
|
2227
|
+
*/
|
|
2228
|
+
function registryRegister(entries, notify, opener) {
|
|
2229
|
+
if (!opener.id || typeof opener.open !== "function") throw new TypeError("文件打开器必须提供 id 和 open");
|
|
2230
|
+
entries.set(opener.id, opener);
|
|
2231
|
+
notify();
|
|
2232
|
+
}
|
|
2233
|
+
/**
|
|
2234
|
+
* 创建生命周期独立的文件打开器注册表。
|
|
2235
|
+
* @author ddj 2026年08月24号
|
|
2236
|
+
* @returns 文件打开器注册表
|
|
2237
|
+
*/
|
|
2238
|
+
function createFileOpenerRegistry() {
|
|
2239
|
+
const entries = /* @__PURE__ */ new Map();
|
|
2240
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
2241
|
+
const notify = () => {
|
|
2242
|
+
for (const listener of listeners) listener();
|
|
2243
|
+
};
|
|
2244
|
+
const list = () => [...entries.values()].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
2245
|
+
return {
|
|
2246
|
+
register(opener) {
|
|
2247
|
+
registryRegister(entries, notify, opener);
|
|
2248
|
+
return () => {
|
|
2249
|
+
if (entries.get(opener.id) !== opener) return;
|
|
2250
|
+
entries.delete(opener.id);
|
|
2251
|
+
notify();
|
|
2252
|
+
};
|
|
2253
|
+
},
|
|
2254
|
+
registerFileOpener(opener) {
|
|
2255
|
+
registryRegister(entries, notify, opener);
|
|
2256
|
+
return () => {
|
|
2257
|
+
if (entries.get(opener.id) !== opener) return;
|
|
2258
|
+
entries.delete(opener.id);
|
|
2259
|
+
notify();
|
|
2260
|
+
};
|
|
2261
|
+
},
|
|
2262
|
+
list,
|
|
2263
|
+
subscribe(listener) {
|
|
2264
|
+
listeners.add(listener);
|
|
2265
|
+
return () => listeners.delete(listener);
|
|
2266
|
+
},
|
|
2267
|
+
get: (id) => entries.get(id)
|
|
2268
|
+
};
|
|
2269
|
+
}
|
|
2270
|
+
/**
|
|
2271
|
+
* 检查打开器当前是否可用。
|
|
2272
|
+
* @author ddj 2026年08月24号
|
|
2273
|
+
* @param opener 待检查打开器
|
|
2274
|
+
* @returns 是否可用
|
|
2275
|
+
*/
|
|
2276
|
+
function isAvailable(opener) {
|
|
2277
|
+
try {
|
|
2278
|
+
return opener.isAvailable ? opener.isAvailable() : true;
|
|
2279
|
+
} catch {
|
|
2280
|
+
return false;
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
/**
|
|
2284
|
+
* 返回当前可展示的文件打开器。
|
|
2285
|
+
* @author ddj 2026年08月24号
|
|
2286
|
+
* @param registry 文件打开器注册表
|
|
2287
|
+
* @returns 可用打开器列表
|
|
2288
|
+
*/
|
|
2289
|
+
function availableOpeners(registry) {
|
|
2290
|
+
return registry.list().filter(isAvailable);
|
|
2291
|
+
}
|
|
2292
|
+
/**
|
|
2293
|
+
* 按设置选择打开器,不可用时回退自动优先级。
|
|
2294
|
+
* @author ddj 2026年08月24号
|
|
2295
|
+
* @param registry 文件打开器注册表
|
|
2296
|
+
* @param selected 用户选择的打开器 id
|
|
2297
|
+
* @returns 选中的打开器
|
|
2298
|
+
*/
|
|
2299
|
+
function selectOpener(registry, selected) {
|
|
2300
|
+
if (selected !== "auto") {
|
|
2301
|
+
const requested = registry.get(selected);
|
|
2302
|
+
if (requested && isAvailable(requested)) return requested;
|
|
2303
|
+
}
|
|
2304
|
+
return availableOpeners(registry)[0];
|
|
2305
|
+
}
|
|
2306
|
+
/**
|
|
2307
|
+
* 结构化探测 dsh-better-sidebar 的文件打开能力。
|
|
2308
|
+
* @author ddj 2026年08月24号
|
|
2309
|
+
* @param ctx 客户端服务上下文
|
|
2310
|
+
* @returns 侧边栏打开器或 undefined
|
|
2311
|
+
*/
|
|
2312
|
+
function scanSidebar(ctx) {
|
|
2313
|
+
try {
|
|
2314
|
+
const service = ctx.get("betterSidebar");
|
|
2315
|
+
if (!service || typeof service.openFile !== "function") return void 0;
|
|
2316
|
+
if (!(service.features?.includes("openFile") ?? true)) return void 0;
|
|
2317
|
+
if (!(typeof service.isTabEnabled !== "function" || service.isTabEnabled("editor"))) return void 0;
|
|
2318
|
+
return {
|
|
2319
|
+
id: SIDEBAR_OPEN_TOOL,
|
|
2320
|
+
label: "dsh-better-sidebar",
|
|
2321
|
+
description: "在 dsh-web-ui-all 侧边栏编辑器中打开",
|
|
2322
|
+
priority: 80,
|
|
2323
|
+
isAvailable: () => typeof service.openFile === "function" && (service.features?.includes("openFile") ?? true) && (typeof service.isTabEnabled !== "function" || service.isTabEnabled("editor")),
|
|
2324
|
+
open: (path, context) => {
|
|
2325
|
+
if (!context.sessionId) throw new Error("当前没有活动会话");
|
|
2326
|
+
service.openFile({
|
|
2327
|
+
sessionId: context.sessionId,
|
|
2328
|
+
cwd: context.cwd
|
|
2329
|
+
}, path, baseName(path));
|
|
2330
|
+
}
|
|
2331
|
+
};
|
|
2332
|
+
} catch {
|
|
2333
|
+
return;
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
/**
|
|
2337
|
+
* 从路径提取文件名。
|
|
2338
|
+
* @author ddj 2026年08月24号
|
|
2339
|
+
* @param path 文件路径
|
|
2340
|
+
* @returns 文件名
|
|
2341
|
+
*/
|
|
2342
|
+
function baseName(path) {
|
|
2343
|
+
const normalized = path.replace(/\\/g, "/");
|
|
2344
|
+
return normalized.slice(normalized.lastIndexOf("/") + 1) || path;
|
|
2345
|
+
}
|
|
2346
|
+
//#endregion
|
|
2347
|
+
//#region src/client/settingsContext.ts
|
|
2348
|
+
/**
|
|
2349
|
+
* dsh-vscode-mode client — 设置 scope 的跨组件上下文。
|
|
2350
|
+
* @author ddj 2026年08月24号
|
|
2351
|
+
*/
|
|
2352
|
+
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
|
+
//#endregion
|
|
2210
2369
|
//#region src/client/ui/McpSettings.ts
|
|
2211
2370
|
/**
|
|
2212
2371
|
* dsh-vscode-mode client — VSCodeMode 设置区内的 MCP 管理。
|
|
@@ -2359,14 +2518,63 @@ window.__ModuleLoader__.load({
|
|
|
2359
2518
|
}));
|
|
2360
2519
|
return react.default.createElement("section", { className: "vsm-project" }, head, body);
|
|
2361
2520
|
}
|
|
2521
|
+
/** 通用设置:选择当前对话文件链接的打开器。 */
|
|
2522
|
+
function GeneralSettings({ registry }) {
|
|
2523
|
+
const [tool, setTool] = react.default.useState(AUTO_OPEN_TOOL);
|
|
2524
|
+
const [busy, setBusy] = react.default.useState(false);
|
|
2525
|
+
const [error, setError] = react.default.useState("");
|
|
2526
|
+
const settings = react.default.useContext(SettingsContext);
|
|
2527
|
+
const snapshot = settings?.getSnapshot?.();
|
|
2528
|
+
const loading = !snapshot || snapshot.status === "loading";
|
|
2529
|
+
const unavailable = snapshot?.status === "unavailable" || !settings;
|
|
2530
|
+
const notReady = snapshot?.status !== "ready";
|
|
2531
|
+
react.default.useEffect(() => {
|
|
2532
|
+
const onChange = () => {
|
|
2533
|
+
const next = settings?.getSnapshot?.().value?.fileOpenTool;
|
|
2534
|
+
if (typeof next === "string") setTool(next);
|
|
2535
|
+
};
|
|
2536
|
+
onChange();
|
|
2537
|
+
return settings?.subscribe?.(onChange);
|
|
2538
|
+
}, [settings]);
|
|
2539
|
+
const save = (value) => {
|
|
2540
|
+
setTool(value);
|
|
2541
|
+
setBusy(true);
|
|
2542
|
+
setError("");
|
|
2543
|
+
if (!settings?.set) {
|
|
2544
|
+
setError("设置服务不可用");
|
|
2545
|
+
setBusy(false);
|
|
2546
|
+
return;
|
|
2547
|
+
}
|
|
2548
|
+
settings.set("fileOpenTool", value).catch((e) => setError(String(e))).finally(() => setBusy(false));
|
|
2549
|
+
};
|
|
2550
|
+
const options = [{
|
|
2551
|
+
id: AUTO_OPEN_TOOL,
|
|
2552
|
+
label: "自动选择",
|
|
2553
|
+
description: "按当前已注册工具自动选择"
|
|
2554
|
+
}, ...availableOpeners(registry).map((item) => ({
|
|
2555
|
+
id: item.id,
|
|
2556
|
+
label: item.label,
|
|
2557
|
+
description: item.description
|
|
2558
|
+
}))];
|
|
2559
|
+
const currentOption = options.some((item) => item.id === tool) ? tool : AUTO_OPEN_TOOL;
|
|
2560
|
+
return react.default.createElement("section", { className: "vsm-general-page" }, react.default.createElement("h2", null, "通用"), react.default.createElement("p", null, "配置 DSH 对话中文件链接的打开工具。工具由当前运行时自动扫描。"), unavailable && react.default.createElement("div", { className: "vsm-mcp-error vsm-mcp-banner" }, "设置服务暂不可用,当前使用自动选择。"), error && react.default.createElement("div", { className: "vsm-mcp-error vsm-mcp-banner" }, error), react.default.createElement("label", { className: "vsm-general-row" }, react.default.createElement("span", null, "文件链接使用工具"), react.default.createElement("select", {
|
|
2561
|
+
value: currentOption,
|
|
2562
|
+
disabled: loading || unavailable || notReady || busy || snapshot?.writable === false,
|
|
2563
|
+
onChange: (event) => save(event.target.value)
|
|
2564
|
+
}, options.map((item) => react.default.createElement("option", {
|
|
2565
|
+
key: item.id,
|
|
2566
|
+
value: item.id
|
|
2567
|
+
}, item.label))), loading && react.default.createElement("small", null, "读取中…")));
|
|
2568
|
+
}
|
|
2362
2569
|
/** MCP 管理主面板。 */
|
|
2363
|
-
function McpSettings() {
|
|
2570
|
+
function McpSettings(props) {
|
|
2571
|
+
const openerRegistry = props?.openerRegistry ?? { list: () => [] };
|
|
2364
2572
|
const [servers, setServers] = react.default.useState([]);
|
|
2365
2573
|
const [projects, setProjects] = react.default.useState([]);
|
|
2366
2574
|
const [loading, setLoading] = react.default.useState(true);
|
|
2367
2575
|
const [busy, setBusy] = react.default.useState("");
|
|
2368
2576
|
const [error, setError] = react.default.useState("");
|
|
2369
|
-
const [tab, setTab] = react.default.useState("
|
|
2577
|
+
const [tab, setTab] = react.default.useState("general");
|
|
2370
2578
|
const [draft, setDraft] = react.default.useState(EMPTY);
|
|
2371
2579
|
const [showForm, setShowForm] = react.default.useState(false);
|
|
2372
2580
|
const [projectForm, setProjectForm] = react.default.useState(null);
|
|
@@ -2477,6 +2685,7 @@ window.__ModuleLoader__.load({
|
|
|
2477
2685
|
}) : react.default.createElement("div", { className: "vsm-mcp-empty" }, "请选择项目")) : react.default.createElement("div", { className: "vsm-mcp-empty" }, "还没有项目");
|
|
2478
2686
|
let body;
|
|
2479
2687
|
if (loading) body = react.default.createElement("div", { className: "vsm-mcp-empty" }, "正在读取 MCP 服务…");
|
|
2688
|
+
else if (tab === "general") body = react.default.createElement(GeneralSettings, { registry: openerRegistry });
|
|
2480
2689
|
else if (tab === "mine") body = react.default.createElement("div", null, servers.length ? servers.map((s) => react.default.createElement(ServerCard, {
|
|
2481
2690
|
key: s.id,
|
|
2482
2691
|
server: s,
|
|
@@ -2508,6 +2717,9 @@ window.__ModuleLoader__.load({
|
|
|
2508
2717
|
setShowForm(true);
|
|
2509
2718
|
}
|
|
2510
2719
|
}, "+ 添加全局 MCP")), react.default.createElement("nav", { className: "vsm-mcp-tabs" }, react.default.createElement("button", {
|
|
2720
|
+
className: tab === "general" ? "active" : "",
|
|
2721
|
+
onClick: () => setTab("general")
|
|
2722
|
+
}, "通用"), react.default.createElement("button", {
|
|
2511
2723
|
className: tab === "mine" ? "active" : "",
|
|
2512
2724
|
onClick: () => setTab("mine")
|
|
2513
2725
|
}, "我的 MCP"), react.default.createElement("button", {
|
|
@@ -2542,6 +2754,59 @@ window.__ModuleLoader__.load({
|
|
|
2542
2754
|
}, "保存并连接"))));
|
|
2543
2755
|
}
|
|
2544
2756
|
//#endregion
|
|
2757
|
+
//#region src/client/openPathRouter.ts
|
|
2758
|
+
/**
|
|
2759
|
+
* dsh-vscode-mode client — DSH 对话文件链接的统一打开路由。
|
|
2760
|
+
* @author ddj 2026年08月24号
|
|
2761
|
+
*/
|
|
2762
|
+
/**
|
|
2763
|
+
* 安装可卸载的 workspaces.openPath 路由。
|
|
2764
|
+
* @author ddj 2026年08月24号
|
|
2765
|
+
* @param options 路由依赖
|
|
2766
|
+
* @returns 恢复原方法的 disposer
|
|
2767
|
+
*/
|
|
2768
|
+
function installOpenPathRouter(options) {
|
|
2769
|
+
const original = options.workspaces.openPath;
|
|
2770
|
+
const open = async (path) => {
|
|
2771
|
+
const context = options.context();
|
|
2772
|
+
const opener = selectOpener(options.registry, options.selected());
|
|
2773
|
+
if (!opener || !isAvailable(opener)) return original.call(options.workspaces, path);
|
|
2774
|
+
try {
|
|
2775
|
+
await opener.open(path, context);
|
|
2776
|
+
} catch (error) {
|
|
2777
|
+
options.logger?.("文件打开器 " + opener.id + " 失败,回退系统打开: " + String(error));
|
|
2778
|
+
if (opener.id !== "system") await original.call(options.workspaces, path);
|
|
2779
|
+
else throw error;
|
|
2780
|
+
}
|
|
2781
|
+
};
|
|
2782
|
+
options.workspaces.openPath = open;
|
|
2783
|
+
return () => {
|
|
2784
|
+
options.workspaces.openPath = original;
|
|
2785
|
+
};
|
|
2786
|
+
}
|
|
2787
|
+
/**
|
|
2788
|
+
* 创建 VSCodeMode 内置文件打开器。
|
|
2789
|
+
* @author ddj 2026年08月24号
|
|
2790
|
+
* @returns VSCodeMode 打开器
|
|
2791
|
+
*/
|
|
2792
|
+
function vscodeOpener() {
|
|
2793
|
+
return {
|
|
2794
|
+
id: VSCODE_OPEN_TOOL,
|
|
2795
|
+
label: "VSCodeMode",
|
|
2796
|
+
priority: 100,
|
|
2797
|
+
open: (path) => openEditorView(path)
|
|
2798
|
+
};
|
|
2799
|
+
}
|
|
2800
|
+
/**
|
|
2801
|
+
* 规范化设置中的打开器 id。
|
|
2802
|
+
* @author ddj 2026年08月24号
|
|
2803
|
+
* @param value 原始设置值
|
|
2804
|
+
* @returns 可路由的打开器 id
|
|
2805
|
+
*/
|
|
2806
|
+
function autoValue(value) {
|
|
2807
|
+
return typeof value === "string" && value.trim() ? value.trim() : AUTO_OPEN_TOOL;
|
|
2808
|
+
}
|
|
2809
|
+
//#endregion
|
|
2545
2810
|
//#region src/client/index.ts
|
|
2546
2811
|
/**
|
|
2547
2812
|
* dsh-vscode-mode client — 浏览器半入口:slot 注册 + 装配。
|
|
@@ -2561,7 +2826,11 @@ window.__ModuleLoader__.load({
|
|
|
2561
2826
|
"timer",
|
|
2562
2827
|
"locale",
|
|
2563
2828
|
"connection",
|
|
2564
|
-
"remote"
|
|
2829
|
+
"remote",
|
|
2830
|
+
"workspaces",
|
|
2831
|
+
"sessions",
|
|
2832
|
+
"settingsScope",
|
|
2833
|
+
"webUiSettings"
|
|
2565
2834
|
];
|
|
2566
2835
|
/**
|
|
2567
2836
|
* 装配客户端:注册中央编辑区视图与 header 差异角标。
|
|
@@ -2570,6 +2839,49 @@ window.__ModuleLoader__.load({
|
|
|
2570
2839
|
*/
|
|
2571
2840
|
function apply(ctx) {
|
|
2572
2841
|
const schedule = (fn, ms) => ctx.timeout(fn, ms);
|
|
2842
|
+
const registry = createFileOpenerRegistry();
|
|
2843
|
+
const workspaces = ctx.get("workspaces");
|
|
2844
|
+
const sessions = ctx.get("sessions");
|
|
2845
|
+
const originalOpenPath = workspaces?.openPath;
|
|
2846
|
+
const settings = getSettingsScope(ctx);
|
|
2847
|
+
let selected = autoValue("auto");
|
|
2848
|
+
ctx.provide("fileOpeners", registry);
|
|
2849
|
+
ctx.effect(() => registry.register(vscodeOpener()), "vscode-mode: file opener");
|
|
2850
|
+
ctx.effect(() => registry.register({
|
|
2851
|
+
id: "system",
|
|
2852
|
+
label: "系统默认应用",
|
|
2853
|
+
priority: 0,
|
|
2854
|
+
open: (path) => originalOpenPath.call(workspaces, path)
|
|
2855
|
+
}), "vscode-mode: system file opener");
|
|
2856
|
+
ctx.effect(() => {
|
|
2857
|
+
const sidebar = scanSidebar(ctx);
|
|
2858
|
+
return sidebar ? registry.register(sidebar) : void 0;
|
|
2859
|
+
}, "vscode-mode: sidebar file opener");
|
|
2860
|
+
ctx.effect(() => {
|
|
2861
|
+
if (!settings) return void 0;
|
|
2862
|
+
const sync = () => {
|
|
2863
|
+
const snapshot = settings.getSnapshot();
|
|
2864
|
+
if (snapshot.status === "loading") return;
|
|
2865
|
+
selected = autoValue(snapshot.value?.fileOpenTool);
|
|
2866
|
+
window.dispatchEvent(new CustomEvent("edrv:file-open-tool-change", { detail: { value: selected } }));
|
|
2867
|
+
};
|
|
2868
|
+
sync();
|
|
2869
|
+
return settings.subscribe(sync);
|
|
2870
|
+
}, "vscode-mode: file opener setting sync");
|
|
2871
|
+
if (workspaces?.openPath) ctx.effect(() => installOpenPathRouter({
|
|
2872
|
+
workspaces,
|
|
2873
|
+
registry,
|
|
2874
|
+
selected: () => selected,
|
|
2875
|
+
context: () => {
|
|
2876
|
+
const current = sessions?.list?.getSnapshot?.();
|
|
2877
|
+
const sessionId = current?.current;
|
|
2878
|
+
return {
|
|
2879
|
+
sessionId,
|
|
2880
|
+
cwd: (sessionId ? current?.byId?.[sessionId] : void 0)?.cwd
|
|
2881
|
+
};
|
|
2882
|
+
},
|
|
2883
|
+
logger: (message) => console.warn("[dsh-vscode-mode] " + message)
|
|
2884
|
+
}), "vscode-mode: file link routing");
|
|
2573
2885
|
ctx.slots.inject("conversation.view", () => ctx.slots.register({
|
|
2574
2886
|
name: "conversation.view",
|
|
2575
2887
|
id: "edrv-editor",
|
|
@@ -2588,7 +2900,7 @@ window.__ModuleLoader__.load({
|
|
|
2588
2900
|
id: "vscode-mode",
|
|
2589
2901
|
order: 30,
|
|
2590
2902
|
label: "VSCodeMode"
|
|
2591
|
-
}, () => react.default.createElement(McpSettings)));
|
|
2903
|
+
}, () => react.default.createElement(SettingsContext.Provider, { value: settings }, react.default.createElement(McpSettings, { openerRegistry: registry }))));
|
|
2592
2904
|
}
|
|
2593
2905
|
//#endregion
|
|
2594
2906
|
exports.apply = apply;
|