dsh-toolbox-ui 1.6.0 → 1.6.1
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.en.md +2 -2
- package/README.md +2 -2
- package/docs/installation.md +5 -5
- package/lib/client.js +54 -11
- package/lib/whats-new.js +13 -0
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -52,10 +52,10 @@ An **MCP management panel and skills manager** for DeepSeek Harness Web: click t
|
|
|
52
52
|
|
|
53
53
|
```sh
|
|
54
54
|
# Recommended: install from npm — `dsh plugin update` then upgrades within ^1.x automatically
|
|
55
|
-
dsh plugin --profile web add dsh-toolbox-ui@^1.6.
|
|
55
|
+
dsh plugin --profile web add dsh-toolbox-ui@^1.6.1
|
|
56
56
|
|
|
57
57
|
# Or pin a GitHub release tag (no automatic upgrades; re-add with a new tag to upgrade)
|
|
58
|
-
dsh plugin --profile web add github:Imzl-zl/dsh-mcp-manager-ui#v1.6.
|
|
58
|
+
dsh plugin --profile web add github:Imzl-zl/dsh-mcp-manager-ui#v1.6.1
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
Then **restart `dsh web`**. To upgrade:
|
package/README.md
CHANGED
|
@@ -50,10 +50,10 @@ DeepSeek Harness Web 的 **MCP 管理面板 + 技能管理面板**:右下角
|
|
|
50
50
|
|
|
51
51
|
```sh
|
|
52
52
|
# 推荐:npm 安装 —— 之后 `dsh plugin update` 会在 ^1.x 内自动升到最新小版本
|
|
53
|
-
dsh plugin --profile web add dsh-toolbox-ui@^1.6.
|
|
53
|
+
dsh plugin --profile web add dsh-toolbox-ui@^1.6.1
|
|
54
54
|
|
|
55
55
|
# 或固定 GitHub release tag(不会自动跨版本,升级要换 tag 重新 add)
|
|
56
|
-
dsh plugin --profile web add github:Imzl-zl/dsh-mcp-manager-ui#v1.6.
|
|
56
|
+
dsh plugin --profile web add github:Imzl-zl/dsh-mcp-manager-ui#v1.6.1
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
装完**重启 `dsh web`**。升级:
|
package/docs/installation.md
CHANGED
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
推荐用 npm 安装:包里的 `^1.x` 范围让后续 `dsh plugin update` 能自动升级小版本。
|
|
16
16
|
|
|
17
17
|
```sh
|
|
18
|
-
dsh plugin --profile web add dsh-toolbox-ui@^1.6.
|
|
18
|
+
dsh plugin --profile web add dsh-toolbox-ui@^1.6.1
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
也可以固定 GitHub release tag(适合需要锁定某个具体版本时):
|
|
22
22
|
|
|
23
23
|
```sh
|
|
24
24
|
# 固定 release tag
|
|
25
|
-
dsh plugin --profile web add github:Imzl-zl/dsh-mcp-manager-ui#v1.6.
|
|
25
|
+
dsh plugin --profile web add github:Imzl-zl/dsh-mcp-manager-ui#v1.6.1
|
|
26
26
|
|
|
27
27
|
# 或固定某个 commit
|
|
28
28
|
dsh plugin --profile web add github:Imzl-zl/dsh-mcp-manager-ui#<commit>
|
|
@@ -73,7 +73,7 @@ dsh plugin --profile web update dsh-toolbox-ui
|
|
|
73
73
|
|
|
74
74
|
| 安装规格 | `update` 的效果 | 怎么跨版本 |
|
|
75
75
|
|---|---|---|
|
|
76
|
-
| `dsh-toolbox-ui@^1.6.
|
|
76
|
+
| `dsh-toolbox-ui@^1.6.1`(npm,推荐) | 在 `^1.x` 内自动升到最新小版本,不会跨到 2.0.0 | 已是自动;跨大版本显式安装 `@^2` |
|
|
77
77
|
| `github:...#v1.4.0`(tag) | 重新解析同一个 tag,**不会动** | 换成新 tag 重新 `add`:`... #<新 tag>` |
|
|
78
78
|
| `github:...#<commit>` | 同上,固定在 commit | 用新 commit/tag 重新 `add` |
|
|
79
79
|
| `github:...#main`(分支) | 拉取最新 main | 已是自动;但不推荐生产(无 release 门槛) |
|
|
@@ -112,7 +112,7 @@ dsh web # 打开面板点一遍
|
|
|
112
112
|
# 3) 提交并推 tag(CI 会校验 tag 与 version 一致,不一致就拒绝发布)
|
|
113
113
|
git add -A && git commit -m "..."
|
|
114
114
|
git push origin main
|
|
115
|
-
git tag -a v1.6.
|
|
115
|
+
git tag -a v1.6.1 -m "v1.4.2 ..." && git push origin v1.6.1
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
推 tag 后 CI 依次做:校验版本 → `pnpm install --frozen-lockfile` → `npm test` → `npm publish`(trusted publishing,无需 token)→ `gh release create`。
|
|
@@ -131,7 +131,7 @@ git tag -a v1.6.0 -m "v1.4.2 ..." && git push origin v1.6.0
|
|
|
131
131
|
|
|
132
132
|
```sh
|
|
133
133
|
npm publish # 会弹 2FA 挑战;若用 bypass-2FA 的 granular token 则非交互
|
|
134
|
-
gh release create v1.6.
|
|
134
|
+
gh release create v1.6.1 --title "dsh-toolbox-ui v1.6.1" --notes-file <notes>
|
|
135
135
|
```
|
|
136
136
|
|
|
137
137
|
`npm login` 的会话 token 只有 2 小时,超时需要重新登录;classic token 已被 npm 永久吊销,能非交互发布的只剩勾了 **Bypass 2FA** 的 granular access token——但它正在被 npm 收窄(已不能做账号/包管理类操作,且 2027-01 起将失去直接发布能力),所以长期方案是上面的 trusted publishing。
|
package/lib/client.js
CHANGED
|
@@ -3048,7 +3048,11 @@ const McpTab = (props) => {
|
|
|
3048
3048
|
}
|
|
3049
3049
|
const r = res.value || {};
|
|
3050
3050
|
if (r.application === 'failed' || r.application === 'cancelled') {
|
|
3051
|
-
|
|
3051
|
+
// 三个参数:未知错误码时要靠 pnpm 的原文解释失败(见 upgradeFailureText)。
|
|
3052
|
+
setUpgradeState({
|
|
3053
|
+
phase: 'failed',
|
|
3054
|
+
text: upgradeFailureText(r.error, r.packageResult && r.packageResult.exitCode, r.packageResult && r.packageResult.output),
|
|
3055
|
+
});
|
|
3052
3056
|
return;
|
|
3053
3057
|
}
|
|
3054
3058
|
// applied / restart-required / overridden 都算装上了。宿主代码在进程内执行,升级已存在的包
|
|
@@ -3764,13 +3768,13 @@ const McpFooterAction = ({ wide }) => {
|
|
|
3764
3768
|
{
|
|
3765
3769
|
type: 'button',
|
|
3766
3770
|
className: 'dsh-mcp-footer-action' + (wide ? '' : ' rail'),
|
|
3767
|
-
title: '
|
|
3768
|
-
'aria-label': '
|
|
3771
|
+
title: '工具箱面板',
|
|
3772
|
+
'aria-label': '打开工具箱面板',
|
|
3769
3773
|
'aria-expanded': open,
|
|
3770
3774
|
onClick: () => panelVisibility.set(true),
|
|
3771
3775
|
},
|
|
3772
3776
|
h(Icon, { d: ICONS.plug, size: wide ? 16 : 18 }),
|
|
3773
|
-
wide ? h('span', { className: 'dsh-mcp-footer-name' }, '
|
|
3777
|
+
wide ? h('span', { className: 'dsh-mcp-footer-name' }, '工具箱') : null,
|
|
3774
3778
|
);
|
|
3775
3779
|
};
|
|
3776
3780
|
|
|
@@ -3834,17 +3838,50 @@ function upgradePlan({ service, hint, bundle }) {
|
|
|
3834
3838
|
};
|
|
3835
3839
|
}
|
|
3836
3840
|
|
|
3841
|
+
/**
|
|
3842
|
+
* 从官方 `packageResult.output` 里挑出**pnpm 自己说的那句话**。
|
|
3843
|
+
*
|
|
3844
|
+
* 为什么不直接把 output 贴上去:它整段是 pnpm 的完整输出(进度行、`npm notice` 噪声、
|
|
3845
|
+
* 可能还有 ANSI 颜色码),几千字符贴进横幅等于没说话。这里只取"有信息量"的末尾几行。
|
|
3846
|
+
*
|
|
3847
|
+
* 为什么值得做:真机实测过一次失败,面板只显示「错误码 operation-error,pnpm 退出码
|
|
3848
|
+
* 3221226505」(那个退出码是 Windows 上的崩溃码),而 pnpm 原文写得很清楚:
|
|
3849
|
+
* `ERR_PNPM_NO_MATCHING_VERSION … The latest release of <包名> is "1.5.3"`。
|
|
3850
|
+
* 官方早就把这段放在 `packageResult.output` 里回给我们了,之前一直没用。
|
|
3851
|
+
*/
|
|
3852
|
+
function pnpmOutputTail(output, limit = 3) {
|
|
3853
|
+
const text = typeof output === 'string' ? output : '';
|
|
3854
|
+
if (!text) return '';
|
|
3855
|
+
const lines = text
|
|
3856
|
+
// eslint-disable-next-line no-control-regex
|
|
3857
|
+
.replace(/\u001b\[[0-9;]*m/g, '')
|
|
3858
|
+
.split('\n')
|
|
3859
|
+
.map((line) => line.trim())
|
|
3860
|
+
.filter((line) => line && !/^npm (notice|warn)\b/.test(line) && !/^Progress:/.test(line));
|
|
3861
|
+
if (lines.length === 0) return '';
|
|
3862
|
+
// 从**最后一条报错行**起取(含它后面那几行):pnpm 把结论写在报错行的紧后面——
|
|
3863
|
+
// `[ERR_PNPM_NO_MATCHING_VERSION] No matching version found for <包名>@1.6.0` 的下一行就是
|
|
3864
|
+
// `The latest release of <包名> is "1.5.3".`,那句才是用户最需要的。只挑含 error 的行会把它丢掉。
|
|
3865
|
+
// 没有报错行时取末尾几行(pnpm 同样把结论放在最后)。
|
|
3866
|
+
const errorAt = lines.reduce((found, line, index) => (/ERR_|error|Error|failed|ENOENT|ETIMEDOUT|ENOTFOUND|E404|EACCES/.test(line) ? index : found), -1);
|
|
3867
|
+
const picked = errorAt >= 0 ? lines.slice(errorAt, errorAt + limit) : lines.slice(-limit);
|
|
3868
|
+
const joined = picked.join(' ').replace(/\s+/g, ' ').trim();
|
|
3869
|
+
return joined.length > 300 ? joined.slice(0, 297) + '…' : joined;
|
|
3870
|
+
}
|
|
3871
|
+
|
|
3837
3872
|
/**
|
|
3838
3873
|
* 升级失败时给用户看的话。
|
|
3839
3874
|
*
|
|
3840
3875
|
* 为什么不能只写「升级失败」:desktop 直接改当前 profile 且**没有自动回滚**(见
|
|
3841
3876
|
* deepseek-harness 的 desktop-in-place-profile 决策),用户必须知道发生了什么、下一步做什么。
|
|
3842
|
-
* 这些码来自 plugin-manager 的 ManagementError.code
|
|
3877
|
+
* 这些码来自 plugin-manager 的 ManagementError.code,逐个给出可操作的解释;**未知码**则把
|
|
3878
|
+
* 码、退出码和 pnpm 的原文一起带出来——只写一个崩溃码,用户和我们都不无从查起。
|
|
3843
3879
|
* @param {object|null} error - ChangeResult.error({code, diagnostic?})。
|
|
3844
3880
|
* @param {number|null} exitCode - pnpm 退出码。
|
|
3881
|
+
* @param {string|null} output - ChangeResult.packageResult.output(pnpm 的原始输出)。
|
|
3845
3882
|
* @returns {string} 中文说明。
|
|
3846
3883
|
*/
|
|
3847
|
-
function upgradeFailureText(error, exitCode) {
|
|
3884
|
+
function upgradeFailureText(error, exitCode, output) {
|
|
3848
3885
|
const code = error?.code;
|
|
3849
3886
|
const known = {
|
|
3850
3887
|
'incompatible-version': '新版本与当前 DSH 不兼容,未升级。',
|
|
@@ -3863,6 +3900,9 @@ function upgradeFailureText(error, exitCode) {
|
|
|
3863
3900
|
const bits = [];
|
|
3864
3901
|
if (code) bits.push('错误码 ' + code);
|
|
3865
3902
|
if (typeof exitCode === 'number' && exitCode !== 0) bits.push('pnpm 退出码 ' + exitCode);
|
|
3903
|
+
const tail = pnpmOutputTail(output);
|
|
3904
|
+
// 已知码的解释已经说清了原因,就不再拿 pnpm 的输出淹没它;未知码才把原文接上。
|
|
3905
|
+
if (tail) return (bits.length ? '升级失败(' + bits.join(',') + '):' : '升级失败:') + tail;
|
|
3866
3906
|
return bits.length ? '升级失败(' + bits.join(',') + ')。' : '升级失败。';
|
|
3867
3907
|
}
|
|
3868
3908
|
|
|
@@ -4832,8 +4872,8 @@ const McpOverlay = ({ call, callSkills, timer, pluginManager }) => {
|
|
|
4832
4872
|
ref: fabRef,
|
|
4833
4873
|
type: 'button',
|
|
4834
4874
|
className: 'dsh-mcp-fab',
|
|
4835
|
-
title: '
|
|
4836
|
-
'aria-label': '
|
|
4875
|
+
title: '工具箱面板(可拖拽移动)',
|
|
4876
|
+
'aria-label': '打开工具箱面板',
|
|
4837
4877
|
'aria-expanded': false,
|
|
4838
4878
|
style,
|
|
4839
4879
|
onClick: handleClick,
|
|
@@ -5035,7 +5075,7 @@ async function apply(ctx) {
|
|
|
5035
5075
|
if (conflict) {
|
|
5036
5076
|
// 只渲染提示、不注册入口。样式仍要注入,否则提示没有排版。
|
|
5037
5077
|
ctx.slots.inject('shell.overlay', () =>
|
|
5038
|
-
ctx.slots.register({ name: 'shell.overlay', id: 'mcp-handover', order: 1000, label: '
|
|
5078
|
+
ctx.slots.register({ name: 'shell.overlay', id: 'mcp-handover', order: 1000, label: '工具箱' }, () => h(HandoverNotice, { conflict })),
|
|
5039
5079
|
);
|
|
5040
5080
|
return cleanup;
|
|
5041
5081
|
}
|
|
@@ -5043,13 +5083,16 @@ async function apply(ctx) {
|
|
|
5043
5083
|
|| (ctx.remote && ctx.remote[UPGRADE_NAMESPACE])
|
|
5044
5084
|
|| null;
|
|
5045
5085
|
ctx.slots.inject('shell.overlay', () =>
|
|
5046
|
-
ctx.slots.register({ name: 'shell.overlay', id: 'mcp-fab', order: 1000, label: '
|
|
5086
|
+
ctx.slots.register({ name: 'shell.overlay', id: 'mcp-fab', order: 1000, label: '工具箱', inject: () => ({ call, callSkills, timer, pluginManager }) }, McpOverlay),
|
|
5047
5087
|
);
|
|
5048
5088
|
// 官方标准侧栏入口(sidebar.footer.action,0.1.5 起声明):与悬浮按钮共享同一个
|
|
5049
5089
|
// 面板和开关状态。用 inject 而不是直接 register:它声明感知,会等侧边栏把 slot 声明出来
|
|
5050
5090
|
// (插件加载顺序不保证晚于侧边栏)。
|
|
5091
|
+
// ⚠️ label 就是侧栏里**看得见的那几个字**(slot 的 label 由外壳渲染)。这里从 'MCP' 改成
|
|
5092
|
+
// '工具箱':面板早就不是只有 MCP 了(还有技能面与技能市场),而 name/包名是 dsh-toolbox-ui
|
|
5093
|
+
// ——入口上写着 MCP、点开却是 MCP + 技能,用户第一眼就会问"名字怎么还是 MCP"。
|
|
5051
5094
|
ctx.slots.inject('sidebar.footer.action', () =>
|
|
5052
|
-
ctx.slots.register({ name: 'sidebar.footer.action', id: 'mcp-manager', order: 100, label: '
|
|
5095
|
+
ctx.slots.register({ name: 'sidebar.footer.action', id: 'mcp-manager', order: 100, label: '工具箱' }, McpFooterAction),
|
|
5053
5096
|
);
|
|
5054
5097
|
return cleanup;
|
|
5055
5098
|
} catch (error) {
|
package/lib/whats-new.js
CHANGED
|
@@ -171,4 +171,17 @@ export const WHATS_NEW = [
|
|
|
171
171
|
},
|
|
172
172
|
],
|
|
173
173
|
},
|
|
174
|
+
{
|
|
175
|
+
version: '1.6.1',
|
|
176
|
+
items: [
|
|
177
|
+
{
|
|
178
|
+
text: '**入口改名「工具箱」**:侧栏入口与悬浮按钮原来说「MCP」,可点开是 MCP **加**技能两个能力面——名字对不上东西。现在统一叫「工具箱」,能力层枚举里的「MCP / 技能」保持不动(那说的是能力,不是产品名)',
|
|
179
|
+
where: '侧栏入口与右下角悬浮按钮',
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
text: '**安装失败时说清原因**:以前只显示一个错误码(在 Windows 上还可能是个崩溃码),现在把 pnpm 自己的那句话带出来——例如「No matching version found … The latest release is 1.5.3」,装不上时你直接知道是版本、网络还是权限的问题',
|
|
183
|
+
where: '升级/安装失败的那条提示',
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
},
|
|
174
187
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-toolbox-ui",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Responsive MCP management UI and skills manager for DeepSeek Harness Web — floating panel, JSON import, profile-backed Host Remote management, and a skill market with a hard license gate.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|