dsh-plugin-tool-management 0.14.0 → 0.15.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.
- package/CHANGELOG.md +560 -519
- package/docs/images/1-EN.png +0 -0
- package/docs/images/1.png +0 -0
- package/docs/images/2-EN.png +0 -0
- package/docs/images/2.png +0 -0
- package/docs/images/3-EN.png +0 -0
- package/docs/images/3.png +0 -0
- package/docs/images/4-EN.png +0 -0
- package/docs/images/4.png +0 -0
- package/docs/images/5-EN.png +0 -0
- package/docs/images/5.png +0 -0
- package/docs/images/6-EN.png +0 -0
- package/docs/images/6.png +0 -0
- package/docs/images/7-EN.png +0 -0
- package/docs/images/7.png +0 -0
- package/docs/images/8-EN.png +0 -0
- package/docs/images/8.png +0 -0
- package/docs/update.md +391 -365
- package/lib/audit-log.js +157 -0
- package/lib/client.js +3800 -2504
- package/lib/compat/patch-dialect.js +3 -1
- package/lib/compat/preset-reach.js +37 -6
- package/lib/compat/probe.js +149 -7
- package/lib/context-inject.js +5 -3
- package/lib/index.js +236 -30
- package/lib/mcp/loader-token.js +53 -28
- package/lib/mcp/manager.js +146 -7
- package/lib/memories/archive-engine.js +70 -2
- package/lib/memories/archive.js +8 -1
- package/lib/memories/index-io.js +6 -0
- package/lib/op-registry.js +18 -4
- package/lib/ops/compat.js +109 -35
- package/lib/ops/scene-records.js +34 -0
- package/lib/ops/scene-sync.js +12 -1
- package/lib/ops/sessions.js +23 -8
- package/lib/ops/snapshot.js +596 -0
- package/lib/scenes/candidates.js +10 -5
- package/lib/sessions/bridge.js +5 -0
- package/lib/sessions/workspace.js +17 -5
- package/lib/skills/core.js +12 -3
- package/lib/tools/deps.js +1 -1
- package/lib/tools/table.js +5 -1
- package/package.json +112 -108
package/lib/ops/scene-records.js
CHANGED
|
@@ -108,6 +108,18 @@ export function buildSceneRecordOps(rc) {
|
|
|
108
108
|
if (name === GLOBAL_SCENE)
|
|
109
109
|
next.label = GLOBAL_SCENE_LABEL;
|
|
110
110
|
index.scenes[name] = next;
|
|
111
|
+
// 模型工具表方案绑定(0.15.0 用户裁定:入口改到「修改场景」表单):绑定存**档案**,
|
|
112
|
+
// 只在真的绑了东西时才建档案存根 —— 不绑就保持「没有档案」的原语义
|
|
113
|
+
//(没有档案与有空档案在进入场景的预览提示上不等价)。
|
|
114
|
+
const toolTablePreset = args && args.toolTablePreset !== undefined ? String(args.toolTablePreset).trim() : '';
|
|
115
|
+
if (toolTablePreset.length > 64) {
|
|
116
|
+
return fail('error.rules.invalidGroup', `工具表方案名过长(≤64 字符)`);
|
|
117
|
+
}
|
|
118
|
+
if (toolTablePreset !== '') {
|
|
119
|
+
if (!index.archives)
|
|
120
|
+
index.archives = {};
|
|
121
|
+
index.archives[name] = { ...(index.archives[name] || {}), toolTablePreset };
|
|
122
|
+
}
|
|
111
123
|
await writeIndex(stateDir, index);
|
|
112
124
|
invalidateSnapshot();
|
|
113
125
|
return { ok: true, scene: sceneRecordOf(name, next), ...(collapsed ? { collapsedActive: true } : {}) };
|
|
@@ -158,6 +170,28 @@ export function buildSceneRecordOps(rc) {
|
|
|
158
170
|
else
|
|
159
171
|
next.prompt = prompt;
|
|
160
172
|
}
|
|
173
|
+
if (args && args.toolTablePreset !== undefined) {
|
|
174
|
+
// 模型工具表方案绑定(0.15.0 用户裁定:入口改到「修改场景」表单):绑定存**档案**,
|
|
175
|
+
// 记录与档案同在一份索引 JSON,这一次读-改-写顺带落掉。''= 解绑(删字段;档案因此
|
|
176
|
+
// 变空时整条删掉,与档案保存「空档案不落条目」的约定一致);不传这个参数 = 完全不碰
|
|
177
|
+
// 这一域(旧调用方兼容)。绑了不存在的方案在这里不硬失败 —— 引擎在进出场景时按
|
|
178
|
+
// stale 丢弃并报告,和档案保存对悬空绑定的处理同口径。
|
|
179
|
+
const toolTablePreset = String(args.toolTablePreset).trim();
|
|
180
|
+
if (toolTablePreset.length > 64) {
|
|
181
|
+
return fail('error.rules.invalidGroup', `工具表方案名过长(≤64 字符)`);
|
|
182
|
+
}
|
|
183
|
+
if (!index.archives)
|
|
184
|
+
index.archives = {};
|
|
185
|
+
const archive = { ...((index.archives && index.archives[name]) || {}) };
|
|
186
|
+
if (toolTablePreset === '')
|
|
187
|
+
delete archive.toolTablePreset;
|
|
188
|
+
else
|
|
189
|
+
archive.toolTablePreset = toolTablePreset;
|
|
190
|
+
if (Object.keys(archive).length > 0)
|
|
191
|
+
index.archives[name] = archive;
|
|
192
|
+
else
|
|
193
|
+
delete index.archives[name];
|
|
194
|
+
}
|
|
161
195
|
if (args && args.label !== undefined && name !== GLOBAL_SCENE) {
|
|
162
196
|
const label = String(args.label).trim();
|
|
163
197
|
if (label === '')
|
package/lib/ops/scene-sync.js
CHANGED
|
@@ -10,7 +10,18 @@ export function buildSceneSyncOps(deps) {
|
|
|
10
10
|
// 的 `agentsMd` 字段(`applied` / `restored` / `unchanged` / `error`)。
|
|
11
11
|
// 组装时放在 memoriesService.ops 的 spread **之后**,显式覆盖同名 op。
|
|
12
12
|
'rules-set-active': async (args) => deps.withAgentsMdSync(await deps.rulesOps['rules-set-active'](args)),
|
|
13
|
-
'rules-update-scene': async (args) =>
|
|
13
|
+
'rules-update-scene': async (args) => {
|
|
14
|
+
const res = await deps.rulesOps['rules-update-scene'](args);
|
|
15
|
+
// 工具表方案绑定改动(0.15.0):改的是**当前启用场景**且这次真的带了这一参数时即时生效;
|
|
16
|
+
// 改名在场景处于模式中时会被拦(rulesUpdateScene 的 sceneInMode),所以这里 args.name 就是生效场景的名字。
|
|
17
|
+
if (res && res.ok !== false && deps.onToolTablePresetChanged && args && args.toolTablePreset !== undefined) {
|
|
18
|
+
try {
|
|
19
|
+
await deps.onToolTablePresetChanged(String(args.name || ''), String(args.toolTablePreset));
|
|
20
|
+
}
|
|
21
|
+
catch { /* 即时生效失败不拦保存;下次进/退场景会对齐 */ }
|
|
22
|
+
}
|
|
23
|
+
return deps.withAgentsMdSync(res);
|
|
24
|
+
},
|
|
14
25
|
'rules-create-scene': async (args) => deps.withAgentsMdSync(await deps.rulesOps['rules-create-scene'](args)),
|
|
15
26
|
'rules-remove-scene': async (args) => deps.withAgentsMdSync(await deps.rulesOps['rules-remove-scene'](args)),
|
|
16
27
|
};
|
package/lib/ops/sessions.js
CHANGED
|
@@ -54,7 +54,27 @@ export function buildSessionOps(deps) {
|
|
|
54
54
|
? (await registry.archivedSessionDetails()).items
|
|
55
55
|
: (await registry.archivedSessionMetadata()).items;
|
|
56
56
|
const archived = new Set(archivedItems.map((i) => i.sessionId));
|
|
57
|
+
// 官方契约(dsh-session-projection-cache 源码):cachedSnapshot(meta, keys?) 两参,
|
|
58
|
+
// keys 缺省 = 全部 wire 键;keys 传非可迭代值会在 viewCheckpoint 里 new Set 抛错。
|
|
59
|
+
// 旧格式代际的缓存记录过不了 cachedSnapshot 的身份校验,官方另有只认标题的
|
|
60
|
+
// cachedPredecessorTitle 提示面(api-session-controller 的列表路径正是两者相或)。
|
|
57
61
|
const cache = deps.host('sessionProjectionCache');
|
|
62
|
+
const titleOf = (header) => {
|
|
63
|
+
if (!cache)
|
|
64
|
+
return undefined;
|
|
65
|
+
try {
|
|
66
|
+
const snap = typeof cache.cachedSnapshot === 'function' ? cache.cachedSnapshot(header, ['title']) : undefined;
|
|
67
|
+
const current = snap && snap.values ? snap.values.title : undefined;
|
|
68
|
+
if (typeof current === 'string')
|
|
69
|
+
return current;
|
|
70
|
+
const legacy = typeof cache.cachedPredecessorTitle === 'function' ? cache.cachedPredecessorTitle(header) : undefined;
|
|
71
|
+
const legacyTitle = legacy && legacy.values ? legacy.values.title : undefined;
|
|
72
|
+
return typeof legacyTitle === 'string' ? legacyTitle : undefined;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
58
78
|
const items = [];
|
|
59
79
|
for (const h of headers) {
|
|
60
80
|
const sessionId = h && typeof h.id === 'string' ? h.id : undefined;
|
|
@@ -71,14 +91,9 @@ export function buildSessionOps(deps) {
|
|
|
71
91
|
item.cwd = h.cwd;
|
|
72
92
|
if (typeof h.createdAt === 'number' && Number.isFinite(h.createdAt))
|
|
73
93
|
item.createdAt = h.createdAt;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (snap && snap.values && typeof snap.values.title === 'string')
|
|
78
|
-
item.title = snap.values.title;
|
|
79
|
-
}
|
|
80
|
-
catch { /* title best-effort */ }
|
|
81
|
-
}
|
|
94
|
+
const title = titleOf(h);
|
|
95
|
+
if (title !== undefined)
|
|
96
|
+
item.title = title;
|
|
82
97
|
// 工作区目录可能已被删除/移动(孤儿会话):best-effort 标记,供导出选择时识别。
|
|
83
98
|
if (item.cwd) {
|
|
84
99
|
try {
|