dsh-plugin-tool-management 0.14.0 → 0.16.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 (44) hide show
  1. package/CHANGELOG.md +585 -519
  2. package/docs/images/1-EN.png +0 -0
  3. package/docs/images/1.png +0 -0
  4. package/docs/images/2-EN.png +0 -0
  5. package/docs/images/2.png +0 -0
  6. package/docs/images/3-EN.png +0 -0
  7. package/docs/images/3.png +0 -0
  8. package/docs/images/4-EN.png +0 -0
  9. package/docs/images/4.png +0 -0
  10. package/docs/images/5-EN.png +0 -0
  11. package/docs/images/5.png +0 -0
  12. package/docs/images/6-EN.png +0 -0
  13. package/docs/images/6.png +0 -0
  14. package/docs/images/7-EN.png +0 -0
  15. package/docs/images/7.png +0 -0
  16. package/docs/images/8-EN.png +0 -0
  17. package/docs/images/8.png +0 -0
  18. package/docs/update.md +409 -365
  19. package/lib/audit-log.js +157 -0
  20. package/lib/client.js +3915 -2545
  21. package/lib/compat/patch-dialect.js +3 -1
  22. package/lib/compat/preset-reach.js +37 -6
  23. package/lib/compat/probe.js +281 -11
  24. package/lib/context-inject.js +5 -3
  25. package/lib/index.js +236 -30
  26. package/lib/mcp/loader-token.js +53 -28
  27. package/lib/mcp/manager.js +311 -9
  28. package/lib/memories/archive-engine.js +70 -2
  29. package/lib/memories/archive.js +8 -1
  30. package/lib/memories/index-io.js +6 -0
  31. package/lib/memories/service.js +9 -0
  32. package/lib/op-registry.js +18 -4
  33. package/lib/ops/compat.js +121 -35
  34. package/lib/ops/scene-records.js +34 -0
  35. package/lib/ops/scene-sync.js +12 -1
  36. package/lib/ops/sessions.js +23 -8
  37. package/lib/ops/snapshot.js +596 -0
  38. package/lib/scenes/candidates.js +10 -5
  39. package/lib/sessions/bridge.js +5 -0
  40. package/lib/sessions/workspace.js +17 -5
  41. package/lib/skills/core.js +12 -3
  42. package/lib/tools/deps.js +1 -1
  43. package/lib/tools/table.js +5 -1
  44. package/package.json +113 -108
@@ -20,6 +20,8 @@ function reportNativeDeleteAvailable(entry) {
20
20
  kind: "delete",
21
21
  fallback: "inform-only",
22
22
  detail: `宿主已提供原生 ${entry}:本插件仍走自有完整序列(级联子会话 + spill + 记账 + 缓存行),尚未切换到原生入口。`,
23
+ detailKey: "workspace.delete-native",
24
+ params: { entry },
23
25
  });
24
26
  }
25
27
  //#region lib/types/index.js
@@ -697,8 +699,8 @@ var ArchiveWorkspaceRegistry = class {
697
699
  }
698
700
  /**
699
701
  * 列出已归档会话的展示元数据:sessionId / createdAt / cwd / title / archivedAt。
700
- * title 经投影缓存 best-effort 读取(未播种会话用 inheritedEventCount=0);
701
- * 任何一步失败只降级为缺字段,不阻断列表。
702
+ * title 经投影缓存 best-effort 读取(cachedSnapshot 的标题行,旧格式记录退
703
+ * cachedPredecessorTitle);任何一步失败只降级为缺字段,不阻断列表。
702
704
  */
703
705
  async archivedSessionDetails() {
704
706
  await this.reconcileArchiveLedger();
@@ -717,10 +719,19 @@ var ArchiveWorkspaceRegistry = class {
717
719
  entry.cwd = header.cwd;
718
720
  const cache = this.ctx.get("sessionProjectionCache");
719
721
  if (cache !== undefined && typeof cache.cachedSnapshot === "function") {
720
- const snap = cache.cachedSnapshot(header, 0, ["title"]);
722
+ // 官方契约是 cachedSnapshot(meta, keys?) 两参;keys 传数字会在
723
+ // viewCheckpoint 的 new Set 里抛错,被外层 best-effort 吞成"永远没标题"。
724
+ const snap = cache.cachedSnapshot(header, ["title"]);
721
725
  const title = snap?.values?.title;
722
726
  if (typeof title === "string")
723
727
  entry.title = title;
728
+ else if (typeof cache.cachedPredecessorTitle === "function") {
729
+ // 旧格式代际的缓存记录过不了上面的身份校验,官方另有只认标题的提示面。
730
+ const legacy = cache.cachedPredecessorTitle(header);
731
+ const legacyTitle = legacy?.values?.title;
732
+ if (typeof legacyTitle === "string")
733
+ entry.title = legacyTitle;
734
+ }
724
735
  }
725
736
  }
726
737
  catch (error) {
@@ -775,7 +786,8 @@ var ArchiveWorkspaceRegistry = class {
775
786
  return false;
776
787
  try {
777
788
  // 未播种会话的继承事件数恒为零,先查缓存可避免读取完整会话原文。
778
- if (!header.isSeeded && cache.cachedSnapshot(header, 0) !== void 0)
789
+ // keys 缺省 = 任一 wire 行可用即算已有缓存(官方两参契约,勿再传数字)。
790
+ if (!header.isSeeded && cache.cachedSnapshot(header) !== void 0)
779
791
  return false;
780
792
  const stored = await this.readStoredProjectionSource(persistence, header.id);
781
793
  const meta = stored.meta ?? header;
@@ -788,7 +800,7 @@ var ArchiveWorkspaceRegistry = class {
788
800
  this.ctx.logger.warn(`archive-manager: projection repair for unseeded archived session "${header.id}" skipped because its inherited event count is not zero`);
789
801
  return false;
790
802
  }
791
- if (cache.cachedSnapshot(meta, inheritedEventCount) !== void 0)
803
+ if (cache.cachedSnapshot(meta) !== void 0)
792
804
  return false;
793
805
  const restored = projections.restore({}, stored.events, 0, meta, inheritedEventCount);
794
806
  if (restored === void 0 ||
@@ -305,8 +305,13 @@ async function nearestProjectRoot(cwd) {
305
305
  if (!(await fs.stat(start)).isDirectory())
306
306
  return null;
307
307
  }
308
- catch {
309
- return { unavailable: true, cwd };
308
+ catch (error) {
309
+ // 目录不存在(会话还开着、项目已被删)是最常见的一类:带上系统错误码,
310
+ // 调用方对 ENOENT 静默跳过 —— 报警留给真正读不了的目录。
311
+ const code = error && typeof error === "object" && "code" in error
312
+ ? String(error.code)
313
+ : undefined;
314
+ return { unavailable: true, cwd, ...(code ? { code } : {}) };
310
315
  }
311
316
  let current = start;
312
317
  for (;;) {
@@ -344,6 +349,10 @@ export async function projectRoots(projectCwds = [], diagnostics) {
344
349
  for (const cwd of Array.isArray(projectCwds) ? projectCwds : []) {
345
350
  const found = await nearestProjectRoot(cwd);
346
351
  if (!found || !found.root) {
352
+ // 目录不存在(ENOENT)= 会话开着、项目已删:这是常态而不是故障,静默跳过。
353
+ // 报警只留给真实读不了的目录(权限、损坏的链接等)。
354
+ if (found && found.unavailable && found.code === "ENOENT")
355
+ continue;
347
356
  if (found &&
348
357
  found.unavailable &&
349
358
  Array.isArray(diagnostics) &&
@@ -352,7 +361,7 @@ export async function projectRoots(projectCwds = [], diagnostics) {
352
361
  diagnostics.push({
353
362
  code: "warning.project.unavailable",
354
363
  params: { path: cwd },
355
- error: `无法从宿主读取活动工作区,项目技能未显示: ${cwd}`,
364
+ error: `活动会话的项目目录不可访问,项目技能未显示: ${cwd}`,
356
365
  });
357
366
  }
358
367
  continue;
package/lib/tools/deps.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // model 工具(ctx.tools.register + defineTool)各域共用的依赖与 helper。
2
2
  //
3
- // 为什么单独一个文件:五个域的工具都要同一批依赖(defineTool 包装、注册出口、场景锁定
3
+ // 为什么单独一个文件:各注入域的工具都要同一批依赖(defineTool 包装、注册出口、场景锁定
4
4
  // 守卫、注入边界提示),各写一份会漂移。
5
5
  /** 每个工具 output.render 的统一出口:把字符串包成宿主要的 content 数组。 */
6
6
  export function text(value) {
@@ -76,7 +76,11 @@ export const DEFAULT_HIDDEN_TOOLS = Object.freeze([
76
76
  export const DEFAULT_TOOL_TABLE_SETTINGS = { hidden: [...DEFAULT_HIDDEN_TOOLS], presets: [] };
77
77
  /** 方案名上限(与 MCP 备注那类输入同风格:短到能在一行里读,长了也没人看)。 */
78
78
  export const PRESET_NAME_MAX_LENGTH = 40;
79
- /** 存得下的方案数上限 —— 侧车是人手能审的文件,不放开。 */
79
+ /**
80
+ * 场景档案绑定「出厂默认那份」时用的方案名(0.15.0 C1)。
81
+ * 它不是一个可保存的方案名,只在档案里当哨兵用;解析时用户存的同名方案优先。
82
+ */
83
+ export const FACTORY_TOOL_TABLE_PRESET = 'factory-default'; /** 存得下的方案数上限 —— 侧车是人手能审的文件,不放开。 */
80
84
  export const PRESET_MAX_COUNT = 20;
81
85
  const DEFAULT_HIDDEN_SET = new Set(DEFAULT_HIDDEN_TOOLS);
82
86
  /** 夹一份工具名名单(只收非空字符串;重复的只留一份)。 */
package/package.json CHANGED
@@ -1,108 +1,113 @@
1
- {
2
- "name": "dsh-plugin-tool-management",
3
- "version": "0.14.0",
4
- "description": "DSH plugin: one settings panel for MCP servers, skills, scenes, memories, subagent personas and AGENTS.md presets — a scene switches the whole environment, and the model can drive it from chat too.",
5
- "repository": {
6
- "type": "git",
7
- "url": "https://github.com/ouli-1242/dsh-plugin-tool-management"
8
- },
9
- "type": "module",
10
- "main": "lib/index.js",
11
- "exports": {
12
- ".": "./lib/index.js",
13
- "./client": "./lib/client.js",
14
- "./workspace": "./lib/sessions/workspace.js",
15
- "./package.json": "./package.json"
16
- },
17
- "files": [
18
- "lib",
19
- "cordis.patch.yml",
20
- "README.md",
21
- "README_EN.md",
22
- "CHANGELOG.md",
23
- "LICENSE",
24
- "screenshots.json",
25
- "docs"
26
- ],
27
- "engines": {
28
- "node": ">=18"
29
- },
30
- "publishConfig": {
31
- "registry": "https://registry.npmjs.org",
32
- "access": "public"
33
- },
34
- "scripts": {
35
- "build": "tsc -p tsconfig.json && node scripts/sync-client.mjs && node scripts/sync-profile.mjs",
36
- "prepublishOnly": "npm run build && npm run lint && npm run typecheck:client && node --test test/client-exports.test.mjs",
37
- "lint": "node --check lib/client.js && node --check lib/index.js",
38
- "typecheck:client": "node scripts/sync-client.mjs && tsc -p tsconfig.client.json",
39
- "check:i18n": "node scripts/check-i18n.mjs lib/client.js",
40
- "check:host": "node scripts/host-deps.mjs && node scripts/doctor.mjs",
41
- "host-deps": "node scripts/host-deps.mjs --fix",
42
- "doctor": "node scripts/doctor.mjs",
43
- "test": "npm run build && npm run check:i18n && npm run typecheck:client && node --test test/contracts.test.mjs test/client-exports.test.mjs",
44
- "sync:profile": "node scripts/sync-profile.mjs"
45
- },
46
- "keywords": [
47
- "dsh",
48
- "deepseek-harness",
49
- "skill",
50
- "skills",
51
- "mcp",
52
- "mcp-server",
53
- "plugin",
54
- "cordis"
55
- ],
56
- "dsh": {
57
- "bundle": {
58
- "patch": "./cordis.patch.yml"
59
- },
60
- "client": {
61
- "platform": "web",
62
- "inject": [
63
- "@deepseek-ai/dsh-client-locale"
64
- ]
65
- }
66
- },
67
- "peerDependencies": {
68
- "@deepseek-ai/cordis": "^4.0.2",
69
- "@deepseek-ai/dsh-llm": ">=0.1.5-rc.2",
70
- "@deepseek-ai/dsh-session": ">=0.1.5-rc.2",
71
- "@deepseek-ai/dsh-session-projection-cache": ">=0.1.5-rc.2",
72
- "@deepseek-ai/dsh-spill-local": ">=0.1.5-rc.2",
73
- "@deepseek-ai/dsh-storage-domain": ">=0.1.5-rc.2",
74
- "@deepseek-ai/dsh-subagent-fork-in-process": ">=0.1.5-rc.2",
75
- "@deepseek-ai/dsh-subagent-spawn-in-process": ">=0.1.5-rc.2",
76
- "@deepseek-ai/dsh-tools": ">=0.1.5-rc.2",
77
- "@deepseek-ai/dsh-workspace": ">=0.1.5-rc.2",
78
- "react": "^18.2.0"
79
- },
80
- "peerDependenciesMeta": {
81
- "@deepseek-ai/dsh-subagent-fork-in-process": {
82
- "optional": true
83
- },
84
- "@deepseek-ai/dsh-subagent-spawn-in-process": {
85
- "optional": true
86
- }
87
- },
88
- "devDependencies": {
89
- "@deepseek-ai/cordis": "^4.0.1",
90
- "@deepseek-ai/dsh-llm": "^0.1.5-rc.2",
91
- "@deepseek-ai/dsh-session": "^0.1.5-rc.2",
92
- "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-rc.2",
93
- "@deepseek-ai/dsh-spill-local": "^0.1.5-rc.2",
94
- "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.2",
95
- "@deepseek-ai/dsh-subagent-fork-in-process": "^0.1.5-rc.2",
96
- "@deepseek-ai/dsh-subagent-spawn-in-process": "^0.1.5-rc.2",
97
- "@deepseek-ai/dsh-tools": "^0.1.5-rc.2",
98
- "@deepseek-ai/dsh-workspace": "^0.1.5-rc.2",
99
- "@types/js-yaml": "^4.0.9",
100
- "@types/node": "^24.0.0",
101
- "typescript": "^6.0.0"
102
- },
103
- "license": "MIT",
104
- "dependencies": {
105
- "fflate": "^0.8.3",
106
- "js-yaml": "^4.3.2"
107
- }
108
- }
1
+ {
2
+ "name": "dsh-plugin-tool-management",
3
+ "version": "0.16.0",
4
+ "description": "DSH plugin: one settings panel for MCP servers, skills, scenes, memories, subagent personas and AGENTS.md presets — a scene switches the whole environment, and the model can drive it from chat too.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/ouli-1242/dsh-plugin-tool-management"
8
+ },
9
+ "type": "module",
10
+ "main": "lib/index.js",
11
+ "exports": {
12
+ ".": "./lib/index.js",
13
+ "./client": "./lib/client.js",
14
+ "./workspace": "./lib/sessions/workspace.js",
15
+ "./package.json": "./package.json"
16
+ },
17
+ "files": [
18
+ "lib",
19
+ "cordis.patch.yml",
20
+ "README.md",
21
+ "README_EN.md",
22
+ "CHANGELOG.md",
23
+ "LICENSE",
24
+ "screenshots.json",
25
+ "docs"
26
+ ],
27
+ "engines": {
28
+ "node": ">=18"
29
+ },
30
+ "publishConfig": {
31
+ "registry": "https://registry.npmjs.org",
32
+ "access": "public"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc -p tsconfig.json && node scripts/sync-client.mjs && node scripts/sync-profile.mjs",
36
+ "prepublishOnly": "npm run build && npm run lint && npm run typecheck:client && node --test test/client-exports.test.mjs",
37
+ "lint": "node --check lib/client.js && node --check lib/index.js",
38
+ "typecheck:client": "node scripts/sync-client.mjs && tsc -p tsconfig.client.json",
39
+ "check:i18n": "node scripts/check-i18n.mjs lib/client.js",
40
+ "check:host": "node scripts/host-deps.mjs && node scripts/doctor.mjs",
41
+ "host-deps": "node scripts/host-deps.mjs --fix",
42
+ "doctor": "node scripts/doctor.mjs",
43
+ "test": "npm run build && npm run check:i18n && npm run typecheck:client && node --test test/contracts.test.mjs test/client-exports.test.mjs",
44
+ "sync:profile": "node scripts/sync-profile.mjs"
45
+ },
46
+ "keywords": [
47
+ "dsh",
48
+ "deepseek-harness",
49
+ "skill",
50
+ "skills",
51
+ "mcp",
52
+ "mcp-server",
53
+ "plugin",
54
+ "cordis"
55
+ ],
56
+ "dsh": {
57
+ "bundle": {
58
+ "patch": "./cordis.patch.yml"
59
+ },
60
+ "client": {
61
+ "platform": "web",
62
+ "inject": [
63
+ "@deepseek-ai/dsh-client-locale"
64
+ ]
65
+ }
66
+ },
67
+ "peerDependencies": {
68
+ "@deepseek-ai/cordis": "^4.0.2",
69
+ "@deepseek-ai/dsh-agent-preset-registry": ">=0.1.7-rc.2 || >=0.2.0-rc.1",
70
+ "@deepseek-ai/dsh-llm": ">=0.1.7-rc.2 || >=0.2.0-rc.1",
71
+ "@deepseek-ai/dsh-session": ">=0.1.7-rc.2 || >=0.2.0-rc.1",
72
+ "@deepseek-ai/dsh-session-projection-cache": ">=0.1.7-rc.2 || >=0.2.0-rc.1",
73
+ "@deepseek-ai/dsh-settings": ">=0.1.7-rc.2 || >=0.2.0-rc.1",
74
+ "@deepseek-ai/dsh-spill-local": ">=0.1.7-rc.2 || >=0.2.0-rc.1",
75
+ "@deepseek-ai/dsh-storage-domain": ">=0.1.7-rc.2 || >=0.2.0-rc.1",
76
+ "@deepseek-ai/dsh-subagent-fork-in-process": ">=0.1.7-rc.2 || >=0.2.0-rc.1",
77
+ "@deepseek-ai/dsh-subagent-spawn-in-process": ">=0.1.7-rc.2 || >=0.2.0-rc.1",
78
+ "@deepseek-ai/dsh-tools": ">=0.1.7-rc.2 || >=0.2.0-rc.1",
79
+ "@deepseek-ai/dsh-workspace": ">=0.1.7-rc.2 || >=0.2.0-rc.1",
80
+ "react": "^18.2.0"
81
+ },
82
+ "peerDependenciesMeta": {
83
+ "@deepseek-ai/dsh-subagent-fork-in-process": {
84
+ "optional": true
85
+ },
86
+ "@deepseek-ai/dsh-subagent-spawn-in-process": {
87
+ "optional": true
88
+ }
89
+ },
90
+ "devDependencies": {
91
+ "@deepseek-ai/cordis": "^4.0.1",
92
+ "@deepseek-ai/dsh-agent-preset-registry": "^0.2.0-rc.2",
93
+ "@deepseek-ai/dsh-llm": "^0.2.0-rc.2",
94
+ "@deepseek-ai/dsh-session": "^0.2.0-rc.2",
95
+ "@deepseek-ai/dsh-session-projection-cache": "^0.2.0-rc.2",
96
+ "@deepseek-ai/dsh-settings": "^0.2.0-rc.2",
97
+ "@deepseek-ai/dsh-spill-local": "^0.2.0-rc.2",
98
+ "@deepseek-ai/dsh-storage-domain": "^0.2.0-rc.2",
99
+ "@deepseek-ai/dsh-subagent-fork-in-process": "^0.2.0-rc.2",
100
+ "@deepseek-ai/dsh-subagent-spawn-in-process": "^0.2.0-rc.2",
101
+ "@deepseek-ai/dsh-tools": "^0.2.0-rc.2",
102
+ "@deepseek-ai/dsh-workspace": "^0.2.0-rc.2",
103
+ "@types/js-yaml": "^4.0.9",
104
+ "@types/node": "^24.0.0",
105
+ "react": "^18.2.0",
106
+ "typescript": "^6.0.0"
107
+ },
108
+ "license": "MIT",
109
+ "dependencies": {
110
+ "fflate": "^0.8.3",
111
+ "js-yaml": "^4.3.2"
112
+ }
113
+ }