@max-null/dsh-skill-mcp-center 0.6.1 → 0.6.3

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/client.js CHANGED
@@ -31,6 +31,17 @@ __export(index_exports, {
31
31
  });
32
32
  module.exports = __toCommonJS(index_exports);
33
33
  var import_react = require("react");
34
+
35
+ // client/skill-key.ts
36
+ var RUNTIME_KEY_PREFIX = "\0runtime:";
37
+ function skillKeyOf(skill) {
38
+ return skill.path === "" ? `${RUNTIME_KEY_PREFIX}${skill.name}` : skill.path;
39
+ }
40
+ function hasSkillFile(skill) {
41
+ return skill.path !== "";
42
+ }
43
+
44
+ // client/index.tsx
34
45
  var import_jsx_runtime = require("react/jsx-runtime");
35
46
  var CSS = `
36
47
  .smc-title { font-size: 18px; font-weight: 600; line-height: 26px; color: var(--dsw-alias-label-primary); }
@@ -212,6 +223,8 @@ var zhDict = {
212
223
  provider: "provider \xB7 {name}",
213
224
  addServer: "\uFF0B \u6DFB\u52A0 server",
214
225
  hotApplied: "\u589E\u5220\u6539\u70ED\u751F\u6548\uFF0C\u514D\u91CD\u542F",
226
+ switchSessionOnly: "\u5F00\u5173\u53EA\u5BF9\u672C\u6B21\u8FD0\u884C\u751F\u6548\uFF0C\u91CD\u542F\u540E\u6062\u590D\uFF08\u8981\u957F\u671F\u7981\u7528\uFF0C\u7ED9\u8BE5\u6761\u76EE\u52A0 disabled: true\uFF09",
227
+ switchReverted: "\u672C\u6B21\u8FD0\u884C\u5DF2\u505C\u7528 \xB7 \u91CD\u542F\u6062\u590D",
215
228
  edit: "\u7F16\u8F91",
216
229
  remove: "\u5220\u9664",
217
230
  disableServer: "\u505C\u7528\uFF08\u65AD\u5F00\u5E76\u91CA\u653E context\uFF09",
@@ -255,6 +268,7 @@ var zhDict = {
255
268
  nsWorkspace: "\u5DE5\u4F5C\u533A",
256
269
  noWorkspace: "\u672A\u9009\u62E9\u5DE5\u4F5C\u533A",
257
270
  viewMd: "\u67E5\u770B SKILL.md",
271
+ noSkillFile: "\u65E0 SKILL.md",
258
272
  hideMd: "\u6536\u8D77",
259
273
  mdLoadFailed: "\u8BFB\u53D6\u5931\u8D25\uFF1A{e}",
260
274
  refOpen: "\u6253\u5F00\u6587\u4EF6\u5F15\u7528",
@@ -276,6 +290,8 @@ var enDict = {
276
290
  provider: "provider \xB7 {name}",
277
291
  addServer: "\uFF0B Add server",
278
292
  hotApplied: "hot-applied, no restart",
293
+ switchSessionOnly: "switch applies to this run only, reverted after restart (to disable for good, add disabled: true to the entry)",
294
+ switchReverted: "disabled for this run \xB7 restored on restart",
279
295
  edit: "Edit",
280
296
  remove: "Remove",
281
297
  disableServer: "Disable (disconnect & free context)",
@@ -319,6 +335,7 @@ var enDict = {
319
335
  nsWorkspace: "Workspace",
320
336
  noWorkspace: "No workspace selected",
321
337
  viewMd: "View SKILL.md",
338
+ noSkillFile: "no SKILL.md",
322
339
  hideMd: "Hide",
323
340
  mdLoadFailed: "Failed to read: {e}",
324
341
  refOpen: "Open file reference",
@@ -470,13 +487,14 @@ function SkillView() {
470
487
  );
471
488
  };
472
489
  const openMd = (s) => {
473
- if (mdPath === s.path) {
490
+ if (!hasSkillFile(s)) return;
491
+ if (mdPath === skillKeyOf(s)) {
474
492
  setMdPath(null);
475
493
  setMdText(null);
476
494
  setMdError(null);
477
495
  return;
478
496
  }
479
- setMdPath(s.path);
497
+ setMdPath(skillKeyOf(s));
480
498
  setMdText(null);
481
499
  setMdError(null);
482
500
  void rpc("readSkill", { path: s.path }).then(
@@ -498,7 +516,7 @@ function SkillView() {
498
516
  else other.push(s);
499
517
  }
500
518
  const renderCard = (s) => {
501
- const open = expanded === s.path;
519
+ const open = expanded === skillKeyOf(s);
502
520
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "smc-card", children: [
503
521
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "smc-card-head", children: [
504
522
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -509,7 +527,7 @@ function SkillView() {
509
527
  "aria-expanded": open,
510
528
  title: t("clickForDetail"),
511
529
  onClick: () => {
512
- setExpanded(open ? null : s.path);
530
+ setExpanded(open ? null : skillKeyOf(s));
513
531
  },
514
532
  children: [
515
533
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "smc-card-name", children: s.name }),
@@ -543,9 +561,9 @@ function SkillView() {
543
561
  !s.modelInvocable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "smc-badge disabled", children: t("modelDisabled") }),
544
562
  !s.writable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "smc-badge disabled", children: t("readOnlyBadge") }),
545
563
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "smc-spacer" }),
546
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "smc-btn", onClick: () => {
564
+ !hasSkillFile(s) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "smc-badge disabled", children: t("noSkillFile") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "smc-btn", onClick: () => {
547
565
  openMd(s);
548
- }, children: mdPath === s.path ? t("hideMd") : t("viewMd") }),
566
+ }, children: mdPath === skillKeyOf(s) ? t("hideMd") : t("viewMd") }),
549
567
  s.writable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
550
568
  "button",
551
569
  {
@@ -562,11 +580,11 @@ function SkillView() {
562
580
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "smc-detail-row", children: [
563
581
  t("detailPath"),
564
582
  "\uFF1A",
565
- s.path
583
+ hasSkillFile(s) ? s.path : t("noSkillFile")
566
584
  ] }),
567
- 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 }) }))
585
+ mdPath === skillKeyOf(s) && (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 }) }))
568
586
  ] })
569
- ] }, s.path);
587
+ ] }, skillKeyOf(s));
570
588
  };
571
589
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
572
590
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "smc-toolbar", children: [
@@ -645,6 +663,7 @@ function McpView() {
645
663
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "smc-spacer" }),
646
664
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "smc-sub", children: t("hotApplied") })
647
665
  ] }),
666
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-sub", style: { marginBottom: 8 }, children: t("switchSessionOnly") }),
648
667
  editing !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ServerForm, { server: editing === "new" ? null : editing, onClose: () => {
649
668
  setEditing(null);
650
669
  }, onSaved: () => {
@@ -676,7 +695,8 @@ function McpView() {
676
695
  }
677
696
  )
678
697
  ] }),
679
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-desc", children: s.transport === "stdio" ? `${s.command ?? ""} ${(s.args ?? []).join(" ")}` : s.url })
698
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-desc", children: s.transport === "stdio" ? `${s.command ?? ""} ${(s.args ?? []).join(" ")}` : s.url }),
699
+ s.disabled && s.sessionToggled === true && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-desc", children: t("switchReverted") })
680
700
  ] }, s.id))
681
701
  ] });
682
702
  }
@@ -906,6 +926,7 @@ function SidebarSkillTab({ visible, cwd }) {
906
926
  );
907
927
  };
908
928
  const openMd = (path) => {
929
+ if (path === "") return;
909
930
  if (mdPath === path) {
910
931
  setMdPath(null);
911
932
  setMdText(null);
@@ -969,7 +990,7 @@ ${s.path}`, children: [
969
990
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "smc-srv-name", children: s.name }),
970
991
  !s.modelInvocable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "smc-badge", children: t("modelDisabled") }),
971
992
  !s.writable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "smc-badge", children: sourceLabel(s.source, true) }),
972
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
993
+ hasSkillFile(s) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
973
994
  "button",
974
995
  {
975
996
  type: "button",
@@ -1012,7 +1033,7 @@ ${s.path}`, children: [
1012
1033
  ] }),
1013
1034
  s.description !== "" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "smc-srv-desc", children: s.description }),
1014
1035
  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 }) }))
1015
- ] }, s.path === "" ? `runtime:${s.name}` : s.path))
1036
+ ] }, skillKeyOf(s)))
1016
1037
  ] }, group.kind)) })
1017
1038
  ] });
1018
1039
  }
package/dist/service.d.ts CHANGED
@@ -42,6 +42,13 @@ export interface McpServer {
42
42
  url?: string;
43
43
  headers?: Record<string, string>;
44
44
  disabled: boolean;
45
+ /**
46
+ * True when the switch was changed during this run. Lets the panel say
47
+ * "reverted on restart" only where that is true — an entry disabled in
48
+ * `cordis.patch.yml` stays disabled across restarts and must not be
49
+ * labelled as session-only.
50
+ */
51
+ sessionToggled: boolean;
45
52
  fiberPhase: string | null;
46
53
  }
47
54
  /** One tool a server contributes, as the management surface lists it. */
@@ -146,6 +153,8 @@ export declare function deleteTargetOf(path: string, roots: readonly string[]):
146
153
  export declare class SkillMcpService extends Service {
147
154
  static inject: string[];
148
155
  private readonly officialSkillDirs;
156
+ /** Ids toggled by the panel during this run (in-memory only, by design: the host does not persist it). */
157
+ private readonly sessionToggled;
149
158
  constructor(ctx: Context, config?: SkillConfig);
150
159
  /**
151
160
  * Skill roots that live **inside loaded plugin packages**.
@@ -207,7 +216,7 @@ export declare class SkillMcpService extends Service {
207
216
  updateMcpServer(id: string, config: McpConfig): Promise<void>;
208
217
  /** Remove one server — disconnects and unregisters its tools. */
209
218
  removeMcpServer(id: string): Promise<void>;
210
- /** Enable/disable one server without deleting its config. */
219
+ /** Enable/disable one server without deleting its config. The host does not persist this. */
211
220
  setMcpServerEnabled(id: string, enabled: boolean): Promise<void>;
212
221
  /** Runtime status per server: upstream `mcpStatus` seam when present, else derived. */
213
222
  mcpStatus(): Promise<McpServerStatus[]>;
package/dist/service.js CHANGED
@@ -232,6 +232,8 @@ export function deleteTargetOf(path, roots) {
232
232
  export class SkillMcpService extends Service {
233
233
  static inject = ['loader', 'tools'];
234
234
  officialSkillDirs;
235
+ /** Ids toggled by the panel during this run (in-memory only, by design: the host does not persist it). */
236
+ sessionToggled = new Set();
235
237
  constructor(ctx, config = {}) {
236
238
  super(ctx, 'skillMcp');
237
239
  this.officialSkillDirs = config.officialSkillDirs ?? [];
@@ -415,6 +417,7 @@ export class SkillMcpService extends Service {
415
417
  url: cfg?.url,
416
418
  headers: cfg?.headers,
417
419
  disabled: entry.disabled,
420
+ sessionToggled: this.sessionToggled.has(entry.id),
418
421
  fiberPhase: entry.fiber === undefined ? null : FIBER_PHASE[entry.fiber.state],
419
422
  });
420
423
  }
@@ -436,9 +439,12 @@ export class SkillMcpService extends Service {
436
439
  async removeMcpServer(id) {
437
440
  await this.ctx.loader.remove(id);
438
441
  }
439
- /** Enable/disable one server without deleting its config. */
442
+ /** Enable/disable one server without deleting its config. The host does not persist this. */
440
443
  async setMcpServerEnabled(id, enabled) {
441
444
  await this.ctx.loader.update(id, { disabled: enabled ? null : true });
445
+ // 记「本次运行改过」:Loader 根树的 write 是 no-op(loader lib/index.js 的 `write() {}`),
446
+ // 所以这里改的只是内存态;面板据此显示“重启后恢复”,而不是假装它是持久设置。
447
+ this.sessionToggled.add(id);
442
448
  }
443
449
  /** Runtime status per server: upstream `mcpStatus` seam when present, else derived. */
444
450
  async mcpStatus() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@max-null/dsh-skill-mcp-center",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
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": {