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

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.
Files changed (3) hide show
  1. package/README.md +6 -0
  2. package/client.js +61 -4
  3. package/package.json +9 -9
package/README.md CHANGED
@@ -31,3 +31,9 @@ pnpm build # tsc (host) + esbuild (browser bundle)
31
31
  ## License / 许可
32
32
 
33
33
  [MIT](./LICENSE)
34
+
35
+ ## SSID 系列
36
+
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
@@ -111,6 +111,8 @@ var CSS = `
111
111
  .smc-ns-btn:hover { background: var(--dsw-alias-interactive-bg-hover); }
112
112
  .smc-ns-btn.active { color: var(--dsw-alias-state-business-primary); border-color: var(--dsw-alias-state-business-primary); }
113
113
  .smc-md { margin: 6px 0 2px; padding: 8px 10px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; background: var(--dsw-alias-bg-base); font-size: 11px; line-height: 1.6; color: var(--dsw-alias-label-secondary); white-space: pre-wrap; word-break: break-all; max-height: 240px; overflow-y: auto; font-family: ui-monospace, 'Cascadia Code', Consolas, monospace; }
114
+ .smc-ref { display: inline; padding: 0 3px; border-radius: 4px; background: var(--dsw-alias-state-business-tertiary); color: var(--dsw-alias-state-business-primary); cursor: pointer; text-decoration: underline dotted; }
115
+ .smc-ref:hover { background: var(--dsw-alias-state-business-primary); color: var(--dsw-alias-bg-base); }
114
116
  .smc-md-err { margin: 6px 0 2px; font-size: 11px; color: var(--dsw-alias-state-error-primary); }
115
117
  .smc-detail .smc-md { margin-top: 8px; }
116
118
  .smc-search { position: sticky; top: 0; z-index: 1; height: 30px; padding: 0 12px; border-radius: 18px; 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; width: 240px; font-family: inherit; }
@@ -239,7 +241,8 @@ var zhDict = {
239
241
  noWorkspace: "\u672A\u9009\u62E9\u5DE5\u4F5C\u533A",
240
242
  viewMd: "\u67E5\u770B SKILL.md",
241
243
  hideMd: "\u6536\u8D77",
242
- mdLoadFailed: "\u8BFB\u53D6\u5931\u8D25\uFF1A{e}"
244
+ mdLoadFailed: "\u8BFB\u53D6\u5931\u8D25\uFF1A{e}",
245
+ refOpen: "\u6253\u5F00\u6587\u4EF6\u5F15\u7528"
243
246
  };
244
247
  var enDict = {
245
248
  loading: "Loading\u2026",
@@ -293,11 +296,60 @@ var enDict = {
293
296
  noWorkspace: "No workspace selected",
294
297
  viewMd: "View SKILL.md",
295
298
  hideMd: "Hide",
296
- mdLoadFailed: "Failed to read: {e}"
299
+ mdLoadFailed: "Failed to read: {e}",
300
+ refOpen: "Open file reference"
297
301
  };
298
302
  var rpc = async () => {
299
303
  throw new Error("skill-mcp-center: rpc not wired");
300
304
  };
305
+ var openFileRef = null;
306
+ var FILE_REF_RE = /@("([^"]+)"|([^\s"@]+))/g;
307
+ function looksLikePath(path) {
308
+ if (path.includes("\\")) return true;
309
+ if (path.startsWith("./") || path.startsWith("../") || path.startsWith("/") || path.startsWith("~/")) return true;
310
+ if (path.includes("/")) {
311
+ return path.includes(".");
312
+ }
313
+ const m = /\.([A-Za-z0-9]{1,6})$/.exec(path);
314
+ if (m === null) return false;
315
+ const ext = m[1].toLowerCase();
316
+ const COMMON_EXTS = /* @__PURE__ */ new Set(["md", "txt", "ts", "tsx", "js", "mjs", "cjs", "json", "yml", "yaml", "toml", "png", "jpg", "jpeg", "gif", "webp", "svg", "ico", "css", "scss", "html", "py", "rs", "go", "java", "c", "h", "cpp", "sh", "ps1", "bat", "exe", "zip", "tar", "gz", "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "log", "env", "lock", "csv", "xml", "sql", "db", "wasm"]);
317
+ return COMMON_EXTS.has(ext);
318
+ }
319
+ function splitFileRefs(text) {
320
+ const parts = [];
321
+ let last = 0;
322
+ let m;
323
+ FILE_REF_RE.lastIndex = 0;
324
+ while ((m = FILE_REF_RE.exec(text)) !== null) {
325
+ if (m.index > last) parts.push({ kind: "text", text: text.slice(last, m.index) });
326
+ const path = m[2] ?? m[3];
327
+ if (m[2] !== void 0 || looksLikePath(path)) {
328
+ parts.push({ kind: "ref", ref: { raw: m[0], path } });
329
+ } else {
330
+ parts.push({ kind: "text", text: m[0] });
331
+ }
332
+ last = m.index + m[0].length;
333
+ }
334
+ if (last < text.length) parts.push({ kind: "text", text: text.slice(last) });
335
+ return parts;
336
+ }
337
+ function MdWithRefs({ text }) {
338
+ const parts = splitFileRefs(text);
339
+ if (parts.every((p) => p.kind === "text")) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: text });
340
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: parts.map((p, i) => p.kind === "text" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: p.text }, i) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
341
+ "span",
342
+ {
343
+ className: "smc-ref",
344
+ title: t("refOpen"),
345
+ onClick: () => {
346
+ openFileRef?.(p.ref.path, p.ref.path);
347
+ },
348
+ children: p.ref.raw
349
+ },
350
+ i
351
+ )) });
352
+ }
301
353
  var toastState = null;
302
354
  var toastListeners = /* @__PURE__ */ new Set();
303
355
  function showToast(message, kind = "ok") {
@@ -457,7 +509,7 @@ function SkillView() {
457
509
  "\uFF1A",
458
510
  s.path
459
511
  ] }),
460
- mdPath === s.path && (mdError !== null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md-err", children: t("mdLoadFailed", { e: mdError }) }) : mdText === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md", children: t("loading") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md", children: mdText }))
512
+ mdPath === s.path && (mdError !== null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md-err", children: t("mdLoadFailed", { e: mdError }) }) : mdText === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md", children: t("loading") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MdWithRefs, { text: mdText }) }))
461
513
  ] })
462
514
  ] }, s.path);
463
515
  };
@@ -819,7 +871,7 @@ ${s.path}`, children: [
819
871
  )
820
872
  ] }),
821
873
  s.description !== "" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-srv-desc", children: s.description }),
822
- mdPath === s.path && (mdError !== null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md-err", children: t("mdLoadFailed", { e: mdError }) }) : mdText === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md", children: t("loading") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md", children: mdText }))
874
+ mdPath === s.path && (mdError !== null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md-err", children: t("mdLoadFailed", { e: mdError }) }) : mdText === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md", children: t("loading") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-md", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MdWithRefs, { text: mdText }) }))
823
875
  ] }, s.path)) })
824
876
  ] });
825
877
  }
@@ -854,6 +906,11 @@ function apply(ctx) {
854
906
  ctx.inject(["betterSidebar"], (sidebarCtx) => {
855
907
  const service = sidebarCtx.betterSidebar;
856
908
  if (service === void 0) return;
909
+ if (typeof service.openFile === "function") {
910
+ openFileRef = (path, title) => {
911
+ service.openFile?.({}, path, title);
912
+ };
913
+ }
857
914
  sidebarCtx.effect(() => service.registerTab({
858
915
  id: "@max-null/dsh-skill-mcp-center:mcp",
859
916
  title: () => "MCP",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@max-null/dsh-skill-mcp-center",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
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": {
@@ -64,18 +64,18 @@
64
64
  "peerDependencies": {
65
65
  "@deepseek-ai/cordis": "^4.0.1",
66
66
  "@deepseek-ai/cordis-plugin-loader": "^1.0.2",
67
- "@deepseek-ai/dsh-client-connection": ">=0.0.1-rc.5",
68
- "@deepseek-ai/dsh-host-apiproxy": ">=0.0.1-rc.5",
69
- "@deepseek-ai/dsh-skill": "^0.1.0-rc.7",
70
- "@deepseek-ai/dsh-tools": "^0.1.0-rc.7"
67
+ "@deepseek-ai/dsh-client-connection": "^0.1.1-rc.1",
68
+ "@deepseek-ai/dsh-host-apiproxy": "^0.1.1-rc.1",
69
+ "@deepseek-ai/dsh-skill": "^0.1.1-rc.1",
70
+ "@deepseek-ai/dsh-tools": "^0.1.1-rc.1"
71
71
  },
72
72
  "devDependencies": {
73
73
  "@deepseek-ai/cordis": "^4.0.1",
74
74
  "@deepseek-ai/cordis-plugin-loader": "^1.0.2",
75
- "@deepseek-ai/dsh-client-connection": ">=0.0.1-rc.5",
76
- "@deepseek-ai/dsh-host-apiproxy": ">=0.0.1-rc.5",
77
- "@deepseek-ai/dsh-skill": "^0.1.0-rc.7",
78
- "@deepseek-ai/dsh-tools": "^0.1.0-rc.7",
75
+ "@deepseek-ai/dsh-client-connection": "^0.1.1-rc.1",
76
+ "@deepseek-ai/dsh-host-apiproxy": "^0.1.1-rc.1",
77
+ "@deepseek-ai/dsh-skill": "^0.1.1-rc.1",
78
+ "@deepseek-ai/dsh-tools": "^0.1.1-rc.1",
79
79
  "@types/js-yaml": "^4.0.9",
80
80
  "@types/node": "^26.2.0",
81
81
  "@types/react": "~18.3.1",