dsh-mcp-connector 0.2.54 → 0.2.55
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 +7 -0
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/docs/CLI-PROVIDERS.md +5 -1
- package/lib/cli-providers.js +50 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.2.55] - 2026-09-22
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Windows 钉钉 CLI 桥接解析官方 npm 包内原生 `dws.exe`,覆盖全局与 npx 布局,不执行 cmd shim,保持 shell:false;允许带空格的显式绝对路径并提供安装/原生文件缺失诊断(#91)。
|
|
12
|
+
- 精确迁移标准受管钉钉 0.2.48/0.2.49 桥接到 0.2.55,保留自定义命令、参数、环境和授权配置。
|
|
13
|
+
|
|
7
14
|
## [0.2.54] - 2026-09-21
|
|
8
15
|
|
|
9
16
|
### Fixed
|
package/README.en.md
CHANGED
|
@@ -190,7 +190,7 @@ npm run dev:ui
|
|
|
190
190
|
|
|
191
191
|
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.
|
|
192
192
|
|
|
193
|
-
The current public version is [`dsh-mcp-connector@0.2.
|
|
193
|
+
The current public version is [`dsh-mcp-connector@0.2.55`](https://www.npmjs.com/package/dsh-mcp-connector), with [GitHub Release v0.2.55](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.55).
|
|
194
194
|
|
|
195
195
|
See [CHANGELOG.md](CHANGELOG.md) for version history and [docs/DESKTOP-E2E.md](docs/DESKTOP-E2E.md) for the Desktop release checklist.
|
|
196
196
|
|
package/README.md
CHANGED
|
@@ -185,7 +185,7 @@ npm run dev:ui
|
|
|
185
185
|
|
|
186
186
|
公共 Registry 每次合并后会生成 `catalog-stats.json`;本仓库的定时工作流每小时同步中英文介绍和统计快照。npm 页面中的静态正文随版本发布更新,上方动态统计徽标则直接读取 Registry,可在不发布新 npm 版本时保持实时数量一致。
|
|
187
187
|
|
|
188
|
-
当前公开版本为 [`dsh-mcp-connector@0.2.
|
|
188
|
+
当前公开版本为 [`dsh-mcp-connector@0.2.55`](https://www.npmjs.com/package/dsh-mcp-connector),对应 [GitHub Release v0.2.55](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.55)。
|
|
189
189
|
|
|
190
190
|
版本能力与变更记录见 [CHANGELOG.md](CHANGELOG.md)。
|
|
191
191
|
Desktop 发版回归见 [docs/DESKTOP-E2E.md](docs/DESKTOP-E2E.md)。
|
package/docs/CLI-PROVIDERS.md
CHANGED
|
@@ -34,7 +34,7 @@ MCP 连接器原生支持 Streamable HTTP 和 stdio MCP。对于钉钉 `dws` 这
|
|
|
34
34
|
"-y",
|
|
35
35
|
"--legacy-peer-deps",
|
|
36
36
|
"--package",
|
|
37
|
-
"dsh-mcp-connector@0.2.
|
|
37
|
+
"dsh-mcp-connector@0.2.55",
|
|
38
38
|
"--package",
|
|
39
39
|
"dingtalk-workspace-cli@1.0.61",
|
|
40
40
|
"dsh-mcp-cli-bridge",
|
|
@@ -48,6 +48,10 @@ MCP 连接器原生支持 Streamable HTTP 和 stdio MCP。对于钉钉 `dws` 这
|
|
|
48
48
|
|
|
49
49
|
## 首批只读能力
|
|
50
50
|
|
|
51
|
+
Windows 从 DSH 进程 PATH 中的全局 npm 或 npx `.bin` 位置查找官方包,直接运行包内 `vendor/dws.exe`;不执行 `.cmd`/`.bat`/`.ps1`,不启用 shell。也可在启动 DSH 的环境中设置 `DSH_MCP_DINGTALK_DWS_BIN` 为原生 exe 的绝对路径(允许空格),随后重启 DSH。无需复制 exe 到 npm 前缀;复制品可能在 CLI 升级后过期。缺失程序不等于 OAuth 未登录。
|
|
52
|
+
|
|
53
|
+
升级主插件并重启后,标准受管钉钉 0.2.48/0.2.49 桥接参数会在加载时迁移到 0.2.55;自定义命令和参数不自动修改,需自行更新固定桥接版本。授权信息和环境配置保持不变。
|
|
54
|
+
|
|
51
55
|
- 当前用户、通讯录搜索与用户详情
|
|
52
56
|
- 日程列表与日程详情
|
|
53
57
|
- 待办列表与待办详情
|
package/lib/cli-providers.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
+
import { existsSync, readFileSync, realpathSync, statSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
2
4
|
|
|
3
5
|
const MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
4
6
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
@@ -198,8 +200,8 @@ export function listCliProviderTools(providerId) {
|
|
|
198
200
|
|
|
199
201
|
function assertSafeExecutable(executable) {
|
|
200
202
|
const value = String(executable ?? '').trim();
|
|
201
|
-
if (!value || /[\0\r\n]/.test(value) || /\s/.test(value)) {
|
|
202
|
-
throw new Error('CLI executable must be one command name or an absolute path
|
|
203
|
+
if (!value || /[\0\r\n]/.test(value) || (/\s/.test(value) && !path.isAbsolute(value) && !path.win32.isAbsolute(value))) {
|
|
204
|
+
throw new Error('CLI executable must be one command name or an absolute path');
|
|
203
205
|
}
|
|
204
206
|
return value;
|
|
205
207
|
}
|
|
@@ -290,11 +292,48 @@ export function redactCliError(value) {
|
|
|
290
292
|
.trim();
|
|
291
293
|
}
|
|
292
294
|
|
|
295
|
+
// Resolve only the known provider package; never interpret or execute a shell shim.
|
|
296
|
+
export function resolveCliExecutable(command, options = {}) {
|
|
297
|
+
const platform = options.platform ?? process.platform;
|
|
298
|
+
const env = options.env ?? process.env;
|
|
299
|
+
if (platform !== 'win32') return command;
|
|
300
|
+
if (/\.(cmd|bat|ps1)$/i.test(command)) throw new Error('[CLI_SHIM_UNSUPPORTED] 请指定原生 exe,而非 shell 启动脚本');
|
|
301
|
+
if (command !== 'dws') return command; // Explicit override stays authoritative.
|
|
302
|
+
const pathValue = Object.entries(env).find(([key]) => key.toLowerCase() === 'path')?.[1] ?? '';
|
|
303
|
+
let sawShim = false;
|
|
304
|
+
for (const raw of pathValue.split(';')) {
|
|
305
|
+
const dir = raw.replace(/^"(.*)"$/, '$1');
|
|
306
|
+
if (!path.isAbsolute(dir)) continue; // Never search cwd or relative PATH entries.
|
|
307
|
+
const native = path.join(dir, 'dws.exe');
|
|
308
|
+
if (existsSync(native) && statSync(native).isFile()) return native;
|
|
309
|
+
if (existsSync(path.join(dir, 'dws.cmd'))) sawShim = true;
|
|
310
|
+
const roots = path.basename(dir).toLowerCase() === '.bin'
|
|
311
|
+
? [path.join(dir, '..', 'dingtalk-workspace-cli')]
|
|
312
|
+
: [path.join(dir, 'node_modules', 'dingtalk-workspace-cli')];
|
|
313
|
+
for (const root of roots) {
|
|
314
|
+
if (!existsSync(path.join(root, 'package.json'))) continue;
|
|
315
|
+
try {
|
|
316
|
+
const pkg = JSON.parse(readFileSync(path.join(root, 'package.json'), 'utf8'));
|
|
317
|
+
if (pkg.name !== 'dingtalk-workspace-cli' || pkg.bin?.dws !== 'bin/dws.js') continue;
|
|
318
|
+
const realRoot = realpathSync(root);
|
|
319
|
+
const binary = realpathSync(path.join(root, 'vendor', 'dws.exe'));
|
|
320
|
+
const relative = path.relative(realRoot, binary);
|
|
321
|
+
if (relative.startsWith('..') || path.isAbsolute(relative) || !statSync(binary).isFile()) continue;
|
|
322
|
+
return binary;
|
|
323
|
+
} catch { /* Missing/corrupt packages must fail closed, not launch a shim. */ }
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
throw new Error(sawShim
|
|
327
|
+
? '[CLI_NATIVE_MISSING] 已发现 dws npm 启动脚本,但未找到有效的官方原生程序;请检查 CLI 安装,或通过 DSH_MCP_DINGTALK_DWS_BIN 指定 dws.exe'
|
|
328
|
+
: '[CLI_NOT_FOUND] DSH 进程 PATH 中未找到 dws 原生程序或官方 npm 包;请检查安装与 DSH 环境后重启,不代表 OAuth 未登录');
|
|
329
|
+
}
|
|
330
|
+
|
|
293
331
|
export function runCliProcess(command, args, options = {}) {
|
|
294
332
|
const timeoutMs = Number.isInteger(options.timeoutMs) ? options.timeoutMs : DEFAULT_TIMEOUT_MS;
|
|
295
333
|
const maxOutputBytes = Number.isInteger(options.maxOutputBytes) ? options.maxOutputBytes : MAX_OUTPUT_BYTES;
|
|
296
334
|
return new Promise((resolve, reject) => {
|
|
297
|
-
const
|
|
335
|
+
const executable = resolveCliExecutable(command, options);
|
|
336
|
+
const child = spawn(executable, args, {
|
|
298
337
|
shell: false,
|
|
299
338
|
windowsHide: true,
|
|
300
339
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
@@ -399,12 +438,17 @@ export async function ensureCliProviderReady(providerId, options = {}) {
|
|
|
399
438
|
// Upgrade only the exact managed legacy invocation; preserve custom commands,
|
|
400
439
|
// environment, cwd and credentials. Applied on every provision, including restore.
|
|
401
440
|
export function cliBridgeArgs(record) {
|
|
402
|
-
const legacy = ['--yes', '--legacy-peer-deps', '--package',
|
|
441
|
+
const legacy = ['--yes', '--legacy-peer-deps', '--package', argsVersion(record),
|
|
403
442
|
'--package', 'dingtalk-workspace-cli@1.0.61', 'dsh-mcp-cli-bridge', '--provider', 'dingtalk-dws'];
|
|
404
443
|
const args = record.args ?? [];
|
|
405
|
-
if (record.connectorId !== 'dingtalk' || record.command !== 'npx'
|
|
444
|
+
if (!legacy[3] || record.connectorId !== 'dingtalk' || record.command !== 'npx'
|
|
406
445
|
|| JSON.stringify(args) !== JSON.stringify(legacy)) return args;
|
|
407
|
-
return args.map((arg) => arg ===
|
|
446
|
+
return args.map((arg) => arg === legacy[3] ? 'dsh-mcp-connector@0.2.55' : arg);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function argsVersion(record) {
|
|
450
|
+
const value = record.args?.[3];
|
|
451
|
+
return ['dsh-mcp-connector@0.2.48', 'dsh-mcp-connector@0.2.49'].includes(value) ? value : null;
|
|
408
452
|
}
|
|
409
453
|
|
|
410
454
|
export async function handleCliBridgeRequest(message, options = {}) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-mcp-connector",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.55",
|
|
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",
|