@max-null/dsh-skill-mcp-center 0.4.0 → 0.4.2

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 CHANGED
@@ -1,5 +1,9 @@
1
1
  # dsh-skill-mcp-center
2
2
 
3
+ 本插件属于 **`@max-null/*` 插件系列**——这一系列共同构成 **[SSID(思灵 · Seek Soul in Darkness)](https://github.com/Max-Null/seek-soul-in-darkness)** 桌面体验。SSID 是整合它们的盒:`dsh-capture` · `dsh-chat-rail` · `dsh-chinese-thinking` · `dsh-draft-polish` · `dsh-guardian` · `dsh-habit` · `dsh-header-unify` · `dsh-memory` · `dsh-node-appearance` · `dsh-plugin-center` · `dsh-skill-mcp-center` · `dsh-ssid-panels` · `dsh-ssid-zh-ui`。
4
+
5
+ This plugin belongs to the **`@max-null/*` family** — a set of plugins that together form the **[SSID (思灵 · Seek Soul in Darkness)](https://github.com/Max-Null/seek-soul-in-darkness)** desktop experience.
6
+
3
7
  Skill & MCP management center for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`) — manage skills and MCP servers in Settings, with live MCP status in the sidebar.
4
8
 
5
9
  Skill 与 MCP 管理中心:在设置里管理 skills 与 MCP 服务器,右侧边栏查看 MCP 实时状态。
@@ -34,6 +38,3 @@ pnpm build # tsc (host) + esbuild (browser bundle)
34
38
 
35
39
  ## SSID 系列
36
40
 
37
- 本插件属于 **`@max-null/*` 插件系列**——这一系列共同构成 **[SSID(思灵 · Seek Soul in Darkness)](https://github.com/Max-Null/seek-soul-in-darkness)** 桌面体验。SSID 是整合它们的盒:`dsh-chat-rail` · `dsh-chinese-thinking` · `dsh-draft-polish` · `dsh-guardian` · `dsh-habit` · `dsh-header-unify` · `dsh-memory` · `dsh-node-appearance` · `dsh-plugin-center` · `dsh-skill-mcp-center` · `dsh-ssid-panels` · `dsh-ssid-zh-ui`。
38
-
39
- This plugin belongs to the **`@max-null/*` family** — a set of plugins that together form the **[SSID (思灵 · Seek Soul in Darkness)](https://github.com/Max-Null/seek-soul-in-darkness)** desktop experience.
package/client.js CHANGED
@@ -40,33 +40,33 @@ var CSS = `
40
40
  .smc-tab:hover { color: var(--dsw-alias-label-secondary); }
41
41
  .smc-tab.active { color: var(--dsw-alias-label-primary); border-bottom-color: var(--dsw-alias-state-business-primary); }
42
42
 
43
- .smc-card { border: 1px solid var(--dsw-alias-border-l2); border-radius: 10px; margin-bottom: 10px; background: var(--dsw-alias-bg-layer-1); min-width: 0; overflow: hidden; }
43
+ .smc-card { border: 1px solid var(--dsw-alias-border-l2); border-radius: 12px; margin-bottom: 10px; background: var(--dsw-alias-bg-layer-3); min-width: 0; overflow: hidden; transition: border-color .16s, background .16s; }
44
44
  .smc-card-pad { padding: 14px 16px; }
45
- .smc-card:hover { background: var(--dsw-alias-interactive-bg-hover); }
45
+ .smc-card:hover { border-color: var(--dsw-alias-label-dimmed); }
46
46
  .smc-card-head { display: flex; align-items: center; }
47
- .smc-card-title { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; padding: 12px 8px 12px 16px; background: none; border: none; cursor: pointer; text-align: left; font-family: inherit; }
47
+ .smc-card-title { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; padding: 14px 16px; background: none; border: none; cursor: pointer; text-align: left; font-family: inherit; }
48
48
  .smc-card-title:hover .smc-card-name { color: var(--dsw-alias-state-business-primary); }
49
- .smc-card-name { font-size: 14px; font-weight: 600; color: var(--dsw-alias-label-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
50
- .smc-card-desc { font-size: 12px; color: var(--dsw-alias-label-tertiary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
49
+ .smc-card-name { font-size: 15px; font-weight: 600; line-height: 1.4; color: var(--dsw-alias-label-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
50
+ .smc-card-desc { font-size: 13px; line-height: 1.5; color: var(--dsw-alias-label-tertiary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
51
51
  .smc-chevron { flex: none; width: 8px; height: 8px; border-right: 1.5px solid var(--dsw-alias-label-caption); border-bottom: 1.5px solid var(--dsw-alias-label-caption); transform: rotate(45deg); transition: transform .15s; margin: 0 14px 0 4px; }
52
52
  .smc-chevron.open { transform: rotate(-135deg); }
53
- .smc-card .smc-detail { margin: 0; padding: 10px 16px 14px; border-top: 1px solid var(--dsw-alias-border-l1); }
53
+ .smc-card .smc-detail { margin: 0; padding: 10px 16px 14px; border-top: 1px solid var(--dsw-alias-border-l2); }
54
54
  .smc-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
55
55
  .smc-name { font-weight: 600; color: var(--dsw-alias-label-primary); }
56
56
  .smc-desc { color: var(--dsw-alias-label-secondary); font-size: 13px; margin-top: 4px; }
57
57
  .smc-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
58
58
  .smc-spacer { flex: 1; }
59
59
 
60
- .smc-badge { display: inline-flex; align-items: center; height: 20px; padding: 0 8px; border-radius: 6px; font-size: 12px; line-height: 1; background: var(--dsw-alias-bg-module-platform); color: var(--dsw-alias-label-secondary); }
60
+ .smc-badge { display: inline-flex; align-items: center; padding: 1px 8px; border-radius: 999px; font-size: 11px; font-weight: 500; line-height: 17px; white-space: nowrap; background: var(--dsw-alias-bg-module-platform); color: var(--dsw-alias-label-secondary); }
61
61
  .smc-badge.user { background: var(--dsw-alias-state-business-tertiary); color: var(--dsw-alias-state-business-primary); }
62
62
  .smc-badge.workspace { background: var(--dsw-alias-state-success-tertiary); color: var(--dsw-alias-state-success-primary); }
63
63
  .smc-badge.bundled { background: var(--dsw-alias-bg-module-platform); color: var(--dsw-alias-label-tertiary); }
64
64
  .smc-badge.runtime { background: var(--dsw-alias-state-warn-tertiary); color: var(--dsw-alias-state-warn-primary); }
65
65
  .smc-badge.disabled { background: var(--dsw-alias-bg-module-platform); color: var(--dsw-alias-label-caption); }
66
66
 
67
- .smc-btn { height: 26px; padding: 0 10px; border-radius: 8px; border: 1px solid var(--dsw-alias-border-l2); background: var(--dsw-alias-bg-module-platform); color: var(--dsw-alias-label-primary); font-size: 12px; cursor: pointer; font-family: inherit; }
67
+ .smc-btn { padding: 5px 14px; border-radius: 8px; border: 1px solid var(--dsw-alias-border-l2); background: transparent; color: var(--dsw-alias-label-primary); font-size: 13px; line-height: 1.5; cursor: pointer; font-family: inherit; }
68
68
  .smc-btn:hover { background: var(--dsw-alias-interactive-bg-hover); }
69
- .smc-btn.primary { border: none; background: var(--dsw-alias-button-primary-fill); color: var(--dsw-alias-bg-base); }
69
+ .smc-btn.primary { border: none; background: var(--dsw-alias-button-primary-fill); color: var(--dsw-alias-label-primary-foreground); }
70
70
  .smc-btn.primary:hover { background: var(--dsw-alias-button-primary-hover); }
71
71
  .smc-btn.danger { border-color: var(--dsw-alias-state-error-primary); color: var(--dsw-alias-state-error-primary); background: none; }
72
72
  .smc-btn.danger:hover { background: var(--dsw-alias-interactive-bg-hover); }
@@ -76,16 +76,16 @@ var CSS = `
76
76
  .smc-dot.idle { background: var(--dsw-alias-label-caption); }
77
77
  .smc-dot.failed { background: var(--dsw-alias-state-error-primary); }
78
78
 
79
- .smc-toggle { position: relative; width: 34px; height: 20px; border-radius: 10px; border: none; cursor: pointer; background: var(--dsw-alias-bg-module-platform); transition: background .15s; }
80
- .smc-toggle.on { background: var(--dsw-alias-state-success-primary); }
81
- .smc-toggle::after { content: ''; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--dsw-alias-bg-base); transition: left .15s; }
82
- .smc-toggle.on::after { left: 16px; }
79
+ .smc-toggle { position: relative; flex: none; width: 40px; height: 22px; border-radius: 11px; border: none; cursor: pointer; background: var(--dsw-alias-border-l4, rgba(0,0,0,.16)); transition: background .15s; padding: 0; }
80
+ .smc-toggle.on { background: var(--dsw-alias-state-business-primary, #4FC3F7); }
81
+ .smc-toggle::after { content: ''; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; transition: left .15s; }
82
+ .smc-toggle.on::after { left: 21px; }
83
83
  .smc-toggle:disabled { opacity: 0.4; cursor: default; }
84
84
 
85
- .smc-input { height: 28px; padding: 0 10px; border-radius: 8px; border: 1px solid var(--dsw-alias-border-l2); background: var(--dsw-alias-bg-base); color: var(--dsw-alias-label-primary); font-size: 13px; outline: none; font-family: inherit; }
86
- .smc-input:focus { border-color: var(--dsw-alias-state-business-primary); }
87
- .smc-select { height: 28px; padding: 0 8px; border-radius: 8px; border: 1px solid var(--dsw-alias-border-l2); background: var(--dsw-alias-bg-base); color: var(--dsw-alias-label-secondary); font-size: 13px; cursor: pointer; font-family: inherit; }
88
- .smc-form { border: 1px solid var(--dsw-alias-border-l2); border-radius: 10px; padding: 16px; margin-bottom: 14px; background: var(--dsw-alias-bg-layer-2); }
85
+ .smc-input { height: 34px; padding: 0 12px; border-radius: 8px; border: 1px solid var(--dsw-alias-border-l2); background: var(--dsw-alias-bg-layer-3); color: var(--dsw-alias-label-primary); font-size: 13px; line-height: 1.5; outline: none; font-family: inherit; }
86
+ .smc-input:focus { border-color: var(--dsw-alias-brand-primary); }
87
+ .smc-select { height: 34px; padding: 0 12px; border-radius: 8px; border: 1px solid var(--dsw-alias-border-l2); background: var(--dsw-alias-bg-layer-3); color: var(--dsw-alias-label-secondary); font-size: 13px; line-height: 1.5; cursor: pointer; font-family: inherit; }
88
+ .smc-form { border: 1px solid var(--dsw-alias-border-l2); border-radius: 12px; padding: 16px; margin-bottom: 14px; background: var(--dsw-alias-bg-layer-3); }
89
89
  .smc-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
90
90
  .smc-label { font-size: 12px; color: var(--dsw-alias-label-tertiary); }
91
91
  .smc-error { font-size: 12px; color: var(--dsw-alias-state-error-primary); }
@@ -6,16 +6,18 @@
6
6
  import { load } from 'js-yaml';
7
7
  /** Toggle `disable-model-invocation` in SKILL.md text; creates frontmatter if absent. */
8
8
  export function setDisableModelInvocation(text, disabled) {
9
+ const eol = text.includes('\r\n') ? '\r\n' : '\n';
9
10
  const match = /^---\r?\n([\s\S]*?)\r?\n---/.exec(text);
10
11
  if (match === null) {
11
- return `---\ndisable-model-invocation: ${disabled}\n---\n\n${text}`;
12
+ return `---${eol}disable-model-invocation: ${disabled}${eol}---${eol}${eol}${text}`;
12
13
  }
13
14
  const full = match[0];
14
15
  const body = match[1];
15
16
  const line = /^(\s*)disable-model-invocation\s*:.*$/m;
16
17
  const next = line.test(body)
17
18
  ? body.replace(line, `$1disable-model-invocation: ${disabled}`)
18
- : body.replace(/\s*$/, `\ndisable-model-invocation: ${disabled}`);
19
+ // 追加分支沿用文件现有行尾(CRLF 文件不混入 LF,防止混合行尾扩散)。
20
+ : body.replace(/\s*$/, `${eol}disable-model-invocation: ${disabled}`);
19
21
  return text.replace(full, full.replace(body, next));
20
22
  }
21
23
  /** Parse a SKILL.md frontmatter block; null when absent or missing a name. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@max-null/dsh-skill-mcp-center",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Skill & MCP management center for DeepSeek Harness — manage skills and MCP servers in Settings, live MCP status in the sidebar",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -56,7 +56,8 @@
56
56
  },
57
57
  "scripts": {
58
58
  "build": "tsc -p tsconfig.json && node build-client.mjs",
59
- "typecheck": "tsc --noEmit -p tsconfig.json"
59
+ "typecheck": "tsc --noEmit -p tsconfig.json",
60
+ "test": "vitest run"
60
61
  },
61
62
  "dependencies": {
62
63
  "js-yaml": "^4.1.0"
@@ -81,6 +82,7 @@
81
82
  "@types/react": "~18.3.1",
82
83
  "esbuild": "^0.24.0",
83
84
  "react": "^18.2.0",
84
- "typescript": "^5.5.0"
85
+ "typescript": "^5.5.0",
86
+ "vitest": "^4.1.11"
85
87
  }
86
88
  }