@sunshaobei/dsh-mcp-manager 3.0.8 → 3.0.9

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/lib/index.js CHANGED
@@ -69,8 +69,11 @@ function mcpManagerHome() {
69
69
  function mcpManagerFile(fileName) {
70
70
  return join3(mcpManagerHome(), fileName);
71
71
  }
72
+ function legacyGlobalConfigFile() {
73
+ return join3(dshHome(), ".dsh", EFFECTIVE_CONFIG_FILE_NAME);
74
+ }
72
75
  function configFile() {
73
- return join3(dshHome(), EFFECTIVE_CONFIG_FILE_NAME);
76
+ return mcpManagerFile(EFFECTIVE_CONFIG_FILE_NAME);
74
77
  }
75
78
  function userStatePath() {
76
79
  return mcpManagerFile(USER_STATE_FILE_NAME);
@@ -93,9 +96,12 @@ function sourcePrefsPath() {
93
96
  function versionFile() {
94
97
  return mcpManagerFile(VERSION_FILE_NAME);
95
98
  }
96
- function projectConfigFile(projectRoot) {
99
+ function legacyProjectEffectiveConfigFile(projectRoot) {
97
100
  return join3(projectRoot, PROJECT_CONFIG_DIR_NAME, EFFECTIVE_CONFIG_FILE_NAME);
98
101
  }
102
+ function projectConfigFile(projectRoot) {
103
+ return join3(projectRoot, PROJECT_CONFIG_DIR_NAME, PACKAGE_DIR, EFFECTIVE_CONFIG_FILE_NAME);
104
+ }
99
105
  function legacyProjectConfigFile(projectRoot) {
100
106
  return join3(projectRoot, PROJECT_CONFIG_DIR_NAME, PACKAGE_DIR, PROJECT_CONFIG_FILE_NAME);
101
107
  }
@@ -103,7 +109,9 @@ function legacyFile(fileName) {
103
109
  return join3(dshHome(), fileName);
104
110
  }
105
111
  function isProjectConfigFile(path) {
106
- return basename(path) === EFFECTIVE_CONFIG_FILE_NAME && basename(dirname(path)) === PROJECT_CONFIG_DIR_NAME;
112
+ const parent = basename(dirname(path));
113
+ return basename(path) === EFFECTIVE_CONFIG_FILE_NAME && // 旧布局:父目录即 .dsh;包分区布局:父目录是 .dsh/dsh-mcp-manager。
114
+ (parent === PROJECT_CONFIG_DIR_NAME || parent === PACKAGE_DIR);
107
115
  }
108
116
  function fileMode(file) {
109
117
  const entry = FILE_MODES.find((candidate) => candidate.matches(file));
@@ -146,6 +154,7 @@ var init_paths2 = __esm({
146
154
  };
147
155
  FILE_MODES = [
148
156
  { matches: (path) => path === configFile(), mode: 384 },
157
+ { matches: (path) => path === legacyGlobalConfigFile(), mode: 384 },
149
158
  { matches: (path) => path === userStatePath(), mode: 420 },
150
159
  { matches: (path) => dirname(path) === catalogDir(), mode: 420 },
151
160
  { matches: (path) => path === catalogSummaryFile(), mode: 420 },
@@ -381,6 +390,7 @@ __export(interface_exports, {
381
390
  OFFICIAL_MCP_CLIENT_LOG_NAME: () => OFFICIAL_MCP_CLIENT_LOG_NAME,
382
391
  OFFICIAL_MCP_CLIENT_SPECIFIER: () => OFFICIAL_MCP_CLIENT_SPECIFIER,
383
392
  OFFICIAL_SERVER_NAME_PATTERN: () => OFFICIAL_SERVER_NAME_PATTERN,
393
+ PACKAGE_DIR: () => PACKAGE_DIR,
384
394
  PACKAGE_DIR_MODE: () => PACKAGE_DIR_MODE,
385
395
  SERVER_NAME_PATTERN: () => SERVER_NAME_PATTERN,
386
396
  STATS_FILE_NAME: () => STATS_FILE_NAME,
@@ -396,7 +406,9 @@ __export(interface_exports, {
396
406
  ensureDir: () => ensureDir,
397
407
  fileMode: () => fileMode,
398
408
  legacyFile: () => legacyFile,
409
+ legacyGlobalConfigFile: () => legacyGlobalConfigFile,
399
410
  legacyProjectConfigFile: () => legacyProjectConfigFile,
411
+ legacyProjectEffectiveConfigFile: () => legacyProjectEffectiveConfigFile,
400
412
  mcpManagerHome: () => mcpManagerHome,
401
413
  projectConfigFile: () => projectConfigFile,
402
414
  publicToolName: () => publicToolName,
@@ -517,8 +529,9 @@ function sourcePath(id, projectRoot) {
517
529
  return join4(homedir2(), ".dsh", "mcp.json");
518
530
  if (projectRoot === void 0 || projectRoot === "")
519
531
  return null;
520
- const dir = id === "project-agents" ? ".agents" : ".dsh";
521
- return join4(projectRoot, dir, "mcp.json");
532
+ if (id === "project-agents")
533
+ return join4(projectRoot, ".agents", "mcp.json");
534
+ return join4(projectRoot, ".dsh", PACKAGE_DIR, "mcp.json");
522
535
  }
523
536
  function readSourceFile(path) {
524
537
  return existsSync(path) ? readFileSync(path, "utf8") : null;
@@ -575,6 +588,7 @@ var init_sources = __esm({
575
588
  "lib/server/config/sources.js"() {
576
589
  "use strict";
577
590
  init_import();
591
+ init_interface();
578
592
  SOURCE_IDS = [
579
593
  "global-dsh",
580
594
  "global-agents",
@@ -9237,6 +9251,22 @@ function archive(source) {
9237
9251
  throw new Error(`dsh-mcp-manager: 旧存储文件改名失败:${source}`, { cause });
9238
9252
  }
9239
9253
  }
9254
+ async function relocateEffectiveConfigs(deps) {
9255
+ if (deps.storePath !== "")
9256
+ return;
9257
+ const legacy = legacyGlobalConfigFile();
9258
+ if (!existsSync10(legacy))
9259
+ return;
9260
+ const target = configFile();
9261
+ const seededEmpty = existsSync10(target) && readFileSync4(target, "utf8") === EMPTY_CONFIG;
9262
+ if (existsSync10(target) && !seededEmpty) {
9263
+ warnIfDowngraded(legacy, target, deps);
9264
+ archive(legacy);
9265
+ return;
9266
+ }
9267
+ await writeFileAtomic(target, readSource(legacy));
9268
+ archive(legacy);
9269
+ }
9240
9270
 
9241
9271
  // lib/server/upgrade/impl/steps/index.js
9242
9272
  var STEPS = [
@@ -9248,7 +9278,9 @@ var STEPS = [
9248
9278
  // 0.2.7 → 0.2.8 为空步(dsh 0.2.0-rc.2 适配 + 导出面收窄,均不落盘):run 指共享空函数。
9249
9279
  { fromVersion: "0.2.7", targetVersion: "0.2.8", run: tickUpgradeVersion },
9250
9280
  // 0.2.8 → 0.2.9 为空步(本版无 MCP 管理器 home 级存储形态变化):run 指共享空函数。
9251
- { fromVersion: "0.2.8", targetVersion: "0.2.9", run: tickUpgradeVersion }
9281
+ { fromVersion: "0.2.8", targetVersion: "0.2.9", run: tickUpgradeVersion },
9282
+ // 0.2.9 → 0.2.10:生效配置 .config 归位进包分区目录(全局 + 项目级 JIT)。
9283
+ { fromVersion: "0.2.9", targetVersion: "0.2.10", run: relocateEffectiveConfigs }
9252
9284
  ];
9253
9285
 
9254
9286
  // lib/server/upgrade/impl/version/index.js
@@ -9286,12 +9318,13 @@ var upgradeRunner = createUpgradeRunner("dsh-mcp-manager", runUpgradeChain2);
9286
9318
  // lib/server/upgrade/impl/steps/project-layout.js
9287
9319
  init_interface();
9288
9320
  function settleProjectConfig(root, logger) {
9289
- return settleOne(legacyProjectConfigFile(root), projectConfigFile(root), null, {
9321
+ const deps = {
9290
9322
  logger,
9291
9323
  // settle 路径只用 logger:`storePath` 传空串——takenOver 是 LAYOUT 层的概念,
9292
9324
  // 与项目级无关。
9293
9325
  storePath: ""
9294
- });
9326
+ };
9327
+ return settleOne(legacyProjectConfigFile(root), projectConfigFile(root), null, deps).then(() => settleOne(legacyProjectEffectiveConfigFile(root), projectConfigFile(root), null, deps));
9295
9328
  }
9296
9329
  function withSettledProjectConfig(root, logger, useSettled) {
9297
9330
  return settleProjectConfig(root, logger).then(() => useSettled(projectConfigFile(root)));
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 四个声明来源,默认全部读取:
5
5
  * - 全局:~/.agents/mcp.json 与 ~/.dsh/mcp.json
6
- * - 项目:<项目根>/.agents/mcp.json 与 <项目根>/.dsh/mcp.json
6
+ * - 项目:<项目根>/.agents/mcp.json 与 <项目根>/.dsh/dsh-mcp-manager/mcp.json
7
7
  *
8
8
  * 同名互斥原则:同一个服务器名在多个来源出现时,**只允许一个生效**——
9
9
  * 生效者进入对应 scope 的 store 并连接;落选者不落盘(若其 scope store
@@ -11,4 +11,4 @@ export type { DomainSpec } from "./compose.js";
11
11
  export type { AgentFace, AttachmentsPort, EventsPort, ExposePort, HostContextPort, HostFaces, LoaderPort, LogRecord, LoggerPort, LogsPort, ModelAttachmentRef, ModelContentBlock, ModelInfoPort, MountedPlugin, OfficialPluginModule, PromptPort, RegisterPort, SaveImageInput, ToolsPort, } from "./host-faces.js";
12
12
  export { CONNECT_TIMEOUT_MS, DEFAULT_ANNOUNCE_CATALOG, DEFAULT_CATALOG_MAX_ENTRIES, DEFAULT_TOOL_CALL_TIMEOUT_MS, DISCOVERY_TIMEOUT_MS, LIST_DEFAULT_TOOLS_PER_SERVER, OFFICIAL_MCP_CLIENT_LOG_NAME, OFFICIAL_MCP_CLIENT_SPECIFIER, OFFICIAL_SERVER_NAME_PATTERN, SERVER_NAME_PATTERN, } from "./constants.js";
13
13
  export { publicToolName } from "./tool-names.js";
14
- export { CATALOG_DIR_NAME, CATALOG_SUMMARY_FILE_NAME, CONFIG_FILE_NAME, LEGACY_LAYOUT, PACKAGE_DIR_MODE, STATS_FILE_NAME, USER_STATE_FILE_NAME, VERSION_FILE_NAME, catalogDir, catalogFile, catalogSummaryFile, configFile, directoryMode, fileMode, legacyFile, legacyProjectConfigFile, mcpManagerHome, projectConfigFile, statsFile, userStatePath, sourcePrefsPath, versionFile, } from "./paths.js";
14
+ export { CATALOG_DIR_NAME, CATALOG_SUMMARY_FILE_NAME, CONFIG_FILE_NAME, LEGACY_LAYOUT, PACKAGE_DIR_MODE, STATS_FILE_NAME, USER_STATE_FILE_NAME, VERSION_FILE_NAME, catalogDir, catalogFile, catalogSummaryFile, configFile, directoryMode, fileMode, legacyFile, PACKAGE_DIR, legacyProjectConfigFile, legacyProjectEffectiveConfigFile, legacyGlobalConfigFile, mcpManagerHome, projectConfigFile, statsFile, userStatePath, sourcePrefsPath, versionFile, } from "./paths.js";
@@ -1,3 +1,5 @@
1
+ /** 本插件在 DSH home 下的私有目录:按 npm 包名分区,不与其它插件争用根目录。 */
2
+ export declare const PACKAGE_DIR = "dsh-mcp-manager";
1
3
  /** 私有目录权限:同机其它用户不得列举本插件的落盘面(与 mcp.json 的 0o600 同族)。 */
2
4
  export declare const PACKAGE_DIR_MODE = 448;
3
5
  /** 目标布局的文件名(迁移契约)。 */
@@ -22,7 +24,9 @@ export declare const LEGACY_LAYOUT: {
22
24
  };
23
25
  /** 本插件私有目录。 */
24
26
  export declare function mcpManagerHome(): string;
25
- /** 全局生效配置:`<DSH_HOME>/.dsh/dsh-mcp-manager.config`(互斥同步唯一写面,
27
+ /** 旧版全局生效配置(迁移**读面**,新代码不得回写):`<DSH_HOME>/.dsh/dsh-mcp-manager.config`。 */
28
+ export declare function legacyGlobalConfigFile(): string;
29
+ /** 全局生效配置:`<DSH_HOME>/dsh-mcp-manager/dsh-mcp-manager.config`(互斥同步唯一写面,
26
30
  * 含 env 引用与凭据字段,0600)。四个声明来源 mcp.json 不会直接被运行面读取。 */
27
31
  export declare function configFile(): string;
28
32
  /**
@@ -44,7 +48,9 @@ export declare function statsFile(): string;
44
48
  export declare function sourcePrefsPath(): string;
45
49
  /** 存储版本刻度(升级链走到哪一版,不是插件版本——后者读 package.json)。 */
46
50
  export declare function versionFile(): string;
47
- /** 项目级生效配置:`<项目根>/.dsh/dsh-mcp-manager.config`(互斥同步唯一写面)。 */
51
+ /** 旧版项目级生效配置(迁移**读面**,新代码不得回写):`<项目根>/.dsh/dsh-mcp-manager.config`。 */
52
+ export declare function legacyProjectEffectiveConfigFile(projectRoot: string): string;
53
+ /** 项目级生效配置:`<项目根>/.dsh/dsh-mcp-manager/dsh-mcp-manager.config`(互斥同步唯一写面)。 */
48
54
  export declare function projectConfigFile(projectRoot: string): string;
49
55
  /**
50
56
  * 旧目录形态(迁移**读面**,新代码不得回写):`<项目根>/.dsh/dsh-mcp-manager/mcp.json`。
@@ -15,3 +15,12 @@ export declare function migrateStorageLayout(deps: UpgradeDeps): Promise<void>;
15
15
  * 项目级 just-in-time 迁移(`./project-layout.ts`)复用本函数:同文件内的 `settleOne` 即同一语义。
16
16
  */
17
17
  export declare function settleOne(source: string, target: string, initial: string | null, deps: UpgradeDeps): Promise<void>;
18
+ /**
19
+ * 0.2.9 → 0.2.10:生效配置 .config 归位进包分区目录——
20
+ * 全局 `<DSH_HOME>/.dsh/dsh-mcp-manager.config` → `<DSH_HOME>/dsh-mcp-manager/`。
21
+ *
22
+ * 不能直接复用 `settleOne`:0.2.5 的迁移可能已在目标落过**版本化空形占位**——那不是用户数据。
23
+ * 目标是空占位而源在场时,以源为准覆盖;目标已有真实内容才走「归档源、保目标」的常规语义。
24
+ * 用户接管 store(`storePath` 非空)时整项不动。
25
+ */
26
+ export declare function relocateEffectiveConfigs(deps: UpgradeDeps): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sunshaobei/dsh-mcp-manager",
3
- "version": "3.0.8",
3
+ "version": "3.0.9",
4
4
  "description": "Manage MCP servers (stdio / streamable-http) for dsh web; tools are reached only through four middleware tools. DSH MCP 管理器:Web 侧边栏「MCP」入口,面板按状态分级展示 MCP 服务器(运行中/连接中/已配置/失败),支持快速接入(stdio / streamable-http 表单)与粘贴 mcpServers JSON 导入。已连接服务器的工具一律经中间层工具(ws_mcp_search / ws_mcp_detail / ws_mcp_call / ws_mcp_list)访问:宿主注册名 mcp__<id>__<tool> 是内部标识(id 按 (工作空间, 服务器名) 分配、不可由服务器名推导),不对模型可见,禁止直呼。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",