dsh-plugin-tool-management 0.8.5 → 0.9.1
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 +275 -206
- package/README.md +71 -69
- package/README_EN.md +65 -65
- 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 +132 -86
- package/lib/agents-md/preset-id.js +1 -1
- package/lib/agents-md/service.js +46 -9
- package/lib/approval-policy.js +1 -1
- package/lib/client.js +867 -146
- package/lib/compat/preset-reach.js +155 -93
- package/lib/context-inject.js +401 -0
- package/lib/hub.js +155 -13
- package/lib/imports/upload.js +34 -14
- package/lib/index.js +1072 -243
- package/lib/mcp/state-section.js +46 -15
- package/lib/rules/archive-engine.js +158 -64
- package/lib/rules/archive.js +41 -1
- package/lib/rules/service.js +424 -162
- package/lib/scene-prompt-sync.js +93 -12
- package/lib/skills/catalog.js +125 -0
- package/lib/skills/core.js +6 -4
- package/lib/skills/service.js +56 -2
- package/lib/subagents/catalog.js +15 -6
- package/lib/subagents/service.js +25 -12
- package/lib/subagents/tools.js +18 -13
- package/package.json +11 -6
- package/screenshots.json +8 -8
- package/docs/images/1/345/234/272/346/231/257.png +0 -0
- package/docs/images/1/345/234/272/346/231/257_en.png +0 -0
- package/docs/images/2MCP.png +0 -0
- package/docs/images/2MCP_en.png +0 -0
- package/docs/images/3/346/212/200/350/203/275.png +0 -0
- package/docs/images/3/346/212/200/350/203/275_en.png +0 -0
- package/docs/images/4/345/255/220/346/231/272/350/203/275/344/275/223.png +0 -0
- package/docs/images/4/345/255/220/346/231/272/350/203/275/344/275/223_en.png +0 -0
- package/docs/images/5/346/217/220/347/244/272/350/257/215.png +0 -0
- package/docs/images/5/346/217/220/347/244/272/350/257/215_en.png +0 -0
- package/docs/images/6/350/256/260/345/277/206.png +0 -0
- package/docs/images/6/350/256/260/345/277/206_en.png +0 -0
- package/docs/images/7/344/274/232/350/257/235.png +0 -0
- package/docs/images/7/344/274/232/350/257/235_en.png +0 -0
- package/docs/images/8/345/205/274/345/256/271.png +0 -0
- package/docs/images/8/345/205/274/345/256/271_en.png +0 -0
- package/lib/prompt-sections.js +0 -148
package/lib/imports/upload.js
CHANGED
|
@@ -166,8 +166,9 @@ const MAX_BUNDLE_ATTACH_TOTAL = 16 * 1024 * 1024;
|
|
|
166
166
|
/**
|
|
167
167
|
* 记忆落点:
|
|
168
168
|
* - 裸 `.md` → 落到 defaultScene(空串 = 全局:任何对话都注入);zip 内带目录 → 目录路径即场景/分组。
|
|
169
|
-
* - zip 内
|
|
170
|
-
* 文件作为附件一并带入(`.md` 不带——bundle
|
|
169
|
+
* - zip 内 `<场景路径>/<名>/<名>.md` → bundle 记忆(目录末段是记忆名,正文文件名与目录名一致,
|
|
170
|
+
* 其余前缀是场景);同层非 `.md` 文件作为附件一并带入(`.md` 不带——bundle 是叶子,塞进去不会被发现,
|
|
171
|
+
* 静默降级反而误导)。旧导出包里正文可能仍叫 `SKILL.md`,也认(只读兼容)。
|
|
171
172
|
* - zip 根层的裸 `SKILL.md` 没有目录名可当记忆名 → 跳过并回报;`SKILL.md` 的大小写变体也跳过
|
|
172
173
|
* (发现层只认精确 `SKILL.md`,NTFS 大小写不敏感下两者不能共存)。
|
|
173
174
|
*/
|
|
@@ -180,18 +181,39 @@ export function planMemoryImport(entries, defaultScene) {
|
|
|
180
181
|
const idx = path.lastIndexOf('/');
|
|
181
182
|
return { dir: idx >= 0 ? path.slice(0, idx) : '', base: path.slice(idx + 1) };
|
|
182
183
|
};
|
|
183
|
-
// pass 1:认 bundle
|
|
184
|
+
// pass 1:认 bundle 目录(`<目录名>.md` 是正文;旧导出包的 `SKILL.md` 也认,只读兼容)。
|
|
184
185
|
const bundleDocs = new Map();
|
|
186
|
+
const consumed = new Set(); // 已被 pass 1 认领(或已回报)的条目路径,pass 3 不再当 flat 处理
|
|
185
187
|
for (const entry of entries) {
|
|
186
188
|
const { dir, base } = split(entry.path);
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if (
|
|
189
|
+
const dirName = dir === '' ? '' : dir.slice(dir.lastIndexOf('/') + 1);
|
|
190
|
+
const isLegacyCaseVariant = base.toLowerCase() === 'skill.md' && base !== 'SKILL.md';
|
|
191
|
+
if (isLegacyCaseVariant) {
|
|
190
192
|
problems.push({ name: entry.path, reason: 'SKILL.md 大小写变体不导入(发现层只认精确 SKILL.md,且与 NTFS 大小写不敏感冲突),已跳过' });
|
|
193
|
+
consumed.add(entry.path);
|
|
191
194
|
continue;
|
|
192
195
|
}
|
|
193
|
-
|
|
196
|
+
// 一级目录恒为场景(与发现层 `discover`/`probeSceneFilesSync` 同口径):`1/1.md` 是
|
|
197
|
+
// 「场景 1 的记忆 1」的 flat 正文,**不是**根层 bundle「1」——bundle 只认目录至少两段
|
|
198
|
+
// (`<场景>/<名>/<名>.md`)。认错会写出发现层根本读不到、且会把整个场景目录吃成叶子的形态。
|
|
199
|
+
const isRootSkill = base === 'SKILL.md' && dir === '';
|
|
200
|
+
if (isRootSkill) {
|
|
201
|
+
// zip 根层的裸 SKILL.md:没有目录名可作记忆名。
|
|
194
202
|
problems.push({ name: entry.path, reason: 'SKILL.md 在 zip 根层,没有目录名可作记忆名,已跳过' });
|
|
203
|
+
consumed.add(entry.path);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
const isLegacyDoc = base === 'SKILL.md' && dir.includes('/');
|
|
207
|
+
const isNamedDoc = dir.includes('/') && base === `${dirName}.md`;
|
|
208
|
+
if (!isLegacyDoc && !isNamedDoc)
|
|
209
|
+
continue;
|
|
210
|
+
consumed.add(entry.path);
|
|
211
|
+
const existing = bundleDocs.get(dir);
|
|
212
|
+
if (existing) {
|
|
213
|
+
// 同一目录里同时出现 `<目录名>.md` 与旧的 `SKILL.md`(少见):`<目录名>.md` 优先。
|
|
214
|
+
const { base: existingBase } = split(existing.path);
|
|
215
|
+
if (isNamedDoc && existingBase !== `${dirName}.md`)
|
|
216
|
+
bundleDocs.set(dir, entry);
|
|
195
217
|
continue;
|
|
196
218
|
}
|
|
197
219
|
bundleDocs.set(dir, entry);
|
|
@@ -206,7 +228,7 @@ export function planMemoryImport(entries, defaultScene) {
|
|
|
206
228
|
if (!bundleDir)
|
|
207
229
|
continue;
|
|
208
230
|
if (dir !== bundleDir) {
|
|
209
|
-
problems.push({ name: entry.path, reason: 'bundle
|
|
231
|
+
problems.push({ name: entry.path, reason: 'bundle 只支持一层附件(正文同层),子目录条目已跳过' });
|
|
210
232
|
continue;
|
|
211
233
|
}
|
|
212
234
|
if (!entry.bytes.length) {
|
|
@@ -231,7 +253,7 @@ export function planMemoryImport(entries, defaultScene) {
|
|
|
231
253
|
list.push({ name, bytes: entry.bytes });
|
|
232
254
|
attachments.set(bundleDir, list);
|
|
233
255
|
}
|
|
234
|
-
// pass 3:先规划 bundle
|
|
256
|
+
// pass 3:先规划 bundle 目标(含正文同层 .md 的明确跳过),再走 flat。
|
|
235
257
|
for (const [dir, doc] of bundleDocs) {
|
|
236
258
|
const segs = dir.split('/');
|
|
237
259
|
const name = segs[segs.length - 1];
|
|
@@ -256,12 +278,10 @@ export function planMemoryImport(entries, defaultScene) {
|
|
|
256
278
|
const { dir, base } = split(entry.path);
|
|
257
279
|
if (!base.toLowerCase().endsWith('.md'))
|
|
258
280
|
continue;
|
|
259
|
-
if (
|
|
260
|
-
continue;
|
|
261
|
-
if (base.toLowerCase() === 'skill.md')
|
|
262
|
-
continue; // pass 1 已回报
|
|
281
|
+
if (consumed.has(entry.path))
|
|
282
|
+
continue; // pass 1 已认领为 bundle 正文,或已回报为大小写变体/根层裸 SKILL.md
|
|
263
283
|
if ([...bundleDocs.keys()].some((d) => dir === d || dir.startsWith(d + '/'))) {
|
|
264
|
-
problems.push({ name: entry.path, reason: 'bundle
|
|
284
|
+
problems.push({ name: entry.path, reason: 'bundle 目录内的非正文 .md 不导入(bundle 是叶子,放进去不会被发现),已跳过' });
|
|
265
285
|
continue;
|
|
266
286
|
}
|
|
267
287
|
const name = base.slice(0, -3); // 去掉 .md
|