dsh-plugin-tool-management 0.5.0 → 0.6.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/README.md +300 -236
- package/README_EN.md +300 -290
- package/cordis.patch.yml +9 -55
- package/docs/Changelog.md +108 -435
- 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/docs/update.md +54 -0
- package/lib/agents-md/preset-id.js +49 -0
- package/lib/agents-md/service.js +138 -56
- package/lib/client.js +4142 -3489
- package/lib/compat/probe.js +665 -0
- package/lib/history/bridge.js +293 -0
- package/lib/history/workspace.js +498 -52
- package/lib/http-fence.js +73 -0
- package/lib/index.js +511 -126
- package/lib/rules/provider.js +3 -3
- package/lib/rules/service.js +264 -30
- package/lib/scene-prompt-sync.js +112 -0
- package/lib/skills/core.js +112 -35
- package/lib/skills/service.js +6 -1
- package/package.json +5 -3
- package/screenshots.json +8 -7
- package/docs/images/MCP.png +0 -0
- package/docs/images//344/274/232/350/257/235.png +0 -0
- package/docs/images//345/234/272/346/231/257.png +0 -0
- package/docs/images//345/255/220/346/231/272/350/203/275/344/275/223.png +0 -0
- package/docs/images//346/212/200/350/203/275.png +0 -0
- package/docs/images//346/217/220/347/244/272/350/257/215.png +0 -0
- package/docs/images//350/256/260/345/277/206.png +0 -0
package/lib/skills/core.js
CHANGED
|
@@ -67,6 +67,10 @@ export function userRoots() {
|
|
|
67
67
|
path: join(resolveDshHome(), "skills"),
|
|
68
68
|
label: "DSH 技能",
|
|
69
69
|
mutable: true,
|
|
70
|
+
// 默认来源:路径不可移除、不可停用(必须读取),但里面的技能可删(见 isDefaultSkillSource)。
|
|
71
|
+
deletable: true,
|
|
72
|
+
// 注意:`toggleable` 指的是「这个来源里的**单个技能**能否启停」,与来源开关无关 ——
|
|
73
|
+
// 来源层的启停/移除由 isDefaultSkillSource 判定,两者别混。
|
|
70
74
|
toggleable: true,
|
|
71
75
|
native: true,
|
|
72
76
|
rank: 400,
|
|
@@ -77,12 +81,13 @@ export function userRoots() {
|
|
|
77
81
|
// 官方 ~/.dsh/skills/ 仍作为可切换来源列出(不搬走、不删)。
|
|
78
82
|
//
|
|
79
83
|
// 界面名「导入技能」:它是插件导入/新建技能的落点,不是"管理器自己的一类技能"。
|
|
80
|
-
//
|
|
84
|
+
// 与 dsh 同为默认来源:路径必须读取(不可移除、不可停用),里面的技能可删。
|
|
81
85
|
key: "hub",
|
|
82
86
|
path: join(resolveDshHome(), "tool-management", "skills"),
|
|
83
87
|
label: "导入技能",
|
|
84
88
|
localeKey: "hub",
|
|
85
89
|
mutable: true,
|
|
90
|
+
deletable: true,
|
|
86
91
|
toggleable: true,
|
|
87
92
|
native: false,
|
|
88
93
|
rank: 350,
|
|
@@ -116,6 +121,27 @@ export function userRoots() {
|
|
|
116
121
|
},
|
|
117
122
|
];
|
|
118
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* 默认来源:插件自己的读写根 —— `dsh`(官方技能目录)与 `hub`(新建/导入落点)。
|
|
126
|
+
*
|
|
127
|
+
* 用户裁定的是**不对称**语义,两个方向必须成对记住,只改一半就是漏改:
|
|
128
|
+
*
|
|
129
|
+
* - 来源**路径**:必须读取。既不能「移除来源」(连目录都不扫),也不能「停用来源」
|
|
130
|
+
* (仍然扫描但仍算不读取的策略位)—— 界面上没有来源开关,服务端也拒绝这两个写操作。
|
|
131
|
+
* 因为它们是插件自己的读写根:移除会让创建/导入无处落脚。
|
|
132
|
+
* - 路径**里面的技能**:可以删除(`deletable: true`,移入插件回收站,可恢复)。
|
|
133
|
+
*
|
|
134
|
+
* 其余来源(外部 Agent / 自定义绝对路径 / 项目级)恰好相反:来源可以停用或移除
|
|
135
|
+
* (「不再读取这个文件夹」),但目录里的技能只读、不可删除。
|
|
136
|
+
*
|
|
137
|
+
* 一句话记法:**`mutable` 与 `deletable` 同向,`removable` 与 `mutable` 反向。**
|
|
138
|
+
*/
|
|
139
|
+
const DEFAULT_SOURCE_KEYS = Object.freeze(["dsh", "hub"]);
|
|
140
|
+
/** 是否为默认来源。接受 root 对象或 key 字符串;`dsh` / `hub` 的所有特判都走这里。 */
|
|
141
|
+
export function isDefaultSkillSource(rootOrKey) {
|
|
142
|
+
const key = rootOrKey && typeof rootOrKey === "object" ? rootOrKey.key : rootOrKey;
|
|
143
|
+
return DEFAULT_SOURCE_KEYS.includes(key);
|
|
144
|
+
}
|
|
119
145
|
function projectIdentity(path) {
|
|
120
146
|
const canonical = pathIdentity(path);
|
|
121
147
|
return createHash("sha256").update(canonical).digest("hex").slice(0, 16);
|
|
@@ -333,8 +359,8 @@ export async function projectRoots(projectCwds = [], diagnostics) {
|
|
|
333
359
|
const id = projectIdentity(project.root);
|
|
334
360
|
const common = {
|
|
335
361
|
mutable: false,
|
|
336
|
-
//
|
|
337
|
-
//
|
|
362
|
+
// 未知/只读来源(外部 Agent 与自定义绝对路径)一律不可删;用户级 dsh / hub
|
|
363
|
+
// 与本仓库的项目级 .dsh/skills 都是可删的(见上方两处 `deletable: true`)。
|
|
338
364
|
deletable: false,
|
|
339
365
|
toggleable: false,
|
|
340
366
|
native: true,
|
|
@@ -504,16 +530,38 @@ function readonlyError(action) {
|
|
|
504
530
|
};
|
|
505
531
|
}
|
|
506
532
|
/**
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
533
|
+
* 来源可写但**没有删除权**时的拒绝结果 —— 防御性分支。
|
|
534
|
+
*
|
|
535
|
+
* 来源表里可写的三种根(dsh / hub / 项目级 `.dsh/skills`)现在都带 `deletable: true`,
|
|
536
|
+
* 正常路径走不到这里。它守的是「以后新增可写来源时忘了标 deletable」:那种情况下
|
|
537
|
+
* 必须拒绝删除,而不是照搬一个用户目录进回收站。
|
|
510
538
|
*/
|
|
511
539
|
function notDeletableError(definition) {
|
|
512
540
|
return {
|
|
513
541
|
ok: false,
|
|
514
542
|
code: "error.skill.notDeletable",
|
|
515
543
|
params: { root: definition && definition.key ? definition.key : "" },
|
|
516
|
-
error: "
|
|
544
|
+
error: "该来源没有开启删除(可写来源需要显式标记 deletable: true 才提供删除)",
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* 默认来源(dsh / hub)被要求「停用」或「移除」时的拒绝结果。
|
|
549
|
+
*
|
|
550
|
+
* 这两种来源是插件自己的读写根,**必须读取**:停用会让它退化成"读出来但不可调用",
|
|
551
|
+
* 移除则连目录都不扫,两者都与「路径不能不读取」冲突。
|
|
552
|
+
*
|
|
553
|
+
* 被拒的只有**来源层**操作 —— 来源**里面的技能**照常可以删除(那是 `deletable`,
|
|
554
|
+
* 与来源的 removable / 停用无关),提示里要写清这一点,否则用户会以为整个来源被锁死。
|
|
555
|
+
*/
|
|
556
|
+
function reservedSourceError(root) {
|
|
557
|
+
const key = root && root.key ? root.key : "";
|
|
558
|
+
return {
|
|
559
|
+
ok: false,
|
|
560
|
+
code: "error.source.reserved",
|
|
561
|
+
params: { root: key },
|
|
562
|
+
error: key === "dsh"
|
|
563
|
+
? "DSH 技能目录是默认来源,必须读取:不能停用或移除(里面的技能可以删除)"
|
|
564
|
+
: "导入技能目录是默认来源、插件新建/导入的落点,必须读取:不能停用或移除(里面的技能可以删除)",
|
|
517
565
|
};
|
|
518
566
|
}
|
|
519
567
|
function rootDefinition(root) {
|
|
@@ -1089,7 +1137,9 @@ function defaultManagerState() {
|
|
|
1089
1137
|
const disabledSkills = Object.create(null);
|
|
1090
1138
|
const enabledSkills = Object.create(null);
|
|
1091
1139
|
for (const root of userRoots()) {
|
|
1092
|
-
|
|
1140
|
+
// 默认来源(dsh / hub)没有来源开关,所以不落进 sources 表 —— 它们永远「读取」。
|
|
1141
|
+
// 旧版本可能往这里写过 hub 的 false,normalizeManagerState 会顺手丢掉。
|
|
1142
|
+
if (!isDefaultSkillSource(root.key))
|
|
1093
1143
|
sources[root.key] = true;
|
|
1094
1144
|
disabledSkills[root.key] = [];
|
|
1095
1145
|
enabledSkills[root.key] = [];
|
|
@@ -1178,7 +1228,7 @@ function validManagerStateDocument(value) {
|
|
|
1178
1228
|
return false;
|
|
1179
1229
|
}
|
|
1180
1230
|
for (const root of userRoots()) {
|
|
1181
|
-
if (root.key
|
|
1231
|
+
if (isDefaultSkillSource(root.key))
|
|
1182
1232
|
continue;
|
|
1183
1233
|
if (typeof value.sources[root.key] !== "boolean")
|
|
1184
1234
|
return false;
|
|
@@ -1205,7 +1255,9 @@ function normalizeManagerState(value) {
|
|
|
1205
1255
|
normalized.customRoots = normalizeCustomRoots(value.customRoots);
|
|
1206
1256
|
const customKeys = new Set(normalized.customRoots.map((root) => root.key));
|
|
1207
1257
|
for (const root of userRoots()) {
|
|
1208
|
-
|
|
1258
|
+
// 默认来源不接收 sources 标志:旧版本写过的 `sources.hub = false` 在这里被丢弃,
|
|
1259
|
+
// 于是「曾经把 hub 停用掉」的用户升级后自动回到必须读取的状态(技能不丢,只是策略位作废)。
|
|
1260
|
+
if (!isDefaultSkillSource(root.key) &&
|
|
1209
1261
|
value.sources &&
|
|
1210
1262
|
typeof value.sources[root.key] === "boolean")
|
|
1211
1263
|
normalized.sources[root.key] = value.sources[root.key];
|
|
@@ -1264,8 +1316,7 @@ function normalizeManagerState(value) {
|
|
|
1264
1316
|
normalized.removedSources = [
|
|
1265
1317
|
...new Set(raw.filter((key) => typeof key === "string" &&
|
|
1266
1318
|
known.has(key) &&
|
|
1267
|
-
key
|
|
1268
|
-
key !== "hub")),
|
|
1319
|
+
!isDefaultSkillSource(key))),
|
|
1269
1320
|
].sort();
|
|
1270
1321
|
}
|
|
1271
1322
|
return normalized;
|
|
@@ -1393,7 +1444,7 @@ function managerSkillOverride(policy, rootKey, name, policyAliases = []) {
|
|
|
1393
1444
|
}
|
|
1394
1445
|
function effectiveSkillPolicy(policyResult, root, entry) {
|
|
1395
1446
|
const override = managerSkillOverride(policyResult.state, root.key, entry.name, entry.policyAliases);
|
|
1396
|
-
const sourceEnabled = root
|
|
1447
|
+
const sourceEnabled = isDefaultSkillSource(root) ||
|
|
1397
1448
|
root.scope === "project" ||
|
|
1398
1449
|
policyResult.state.sources[root.key] !== false;
|
|
1399
1450
|
if (policyResult.writable === false || !sourceEnabled || override === false) {
|
|
@@ -1432,13 +1483,21 @@ function invalidManagerStateWrite() {
|
|
|
1432
1483
|
error: `技能管理器状态文件不可读,已拒绝覆盖: ${managerStatePath()}`,
|
|
1433
1484
|
};
|
|
1434
1485
|
}
|
|
1486
|
+
/**
|
|
1487
|
+
* 停用 / 启用一个来源(仍然扫描目录、仍然列出技能,只是不可调用)。
|
|
1488
|
+
*
|
|
1489
|
+
* 默认来源(dsh / hub)不允许停用 —— 停用等于「不读取」,而它们必须读取。
|
|
1490
|
+
* 其余来源(外部 Agent、自定义绝对路径)随来源开关。
|
|
1491
|
+
*/
|
|
1435
1492
|
export async function setSourceEnabled(rootOrKey, enabled, log) {
|
|
1436
1493
|
// 支持传 key(静态来源)或 definition 对象(自定义来源由 service 层从状态文件生成)。
|
|
1437
1494
|
const root = rootOrKey && typeof rootOrKey === "object" && typeof rootOrKey.key === "string"
|
|
1438
1495
|
? rootOrKey
|
|
1439
1496
|
: rootByKey(rootOrKey);
|
|
1440
|
-
if (!root ||
|
|
1497
|
+
if (!root || !root.toggleable)
|
|
1441
1498
|
return readonlyError("toggle");
|
|
1499
|
+
if (isDefaultSkillSource(root))
|
|
1500
|
+
return reservedSourceError(root);
|
|
1442
1501
|
const current = await readManagerState();
|
|
1443
1502
|
if (current.writable === false)
|
|
1444
1503
|
return invalidManagerStateWrite();
|
|
@@ -1457,7 +1516,7 @@ export async function setSourceEnabled(rootOrKey, enabled, log) {
|
|
|
1457
1516
|
*
|
|
1458
1517
|
* 与 `setSourceEnabled(false)` 的区别:停用仍然读目录、仍然列出技能(只是不可调用);
|
|
1459
1518
|
* 移除是"当它不存在"。`dsh`(官方技能目录)与 `hub`(导入技能落点)不允许移除 ——
|
|
1460
|
-
*
|
|
1519
|
+
* 它们是插件自身的读写根,移除会让创建/导入无处落脚(见 isDefaultSkillSource)。
|
|
1461
1520
|
*/
|
|
1462
1521
|
export async function setSourceRemoved(rootOrKey, removed, log) {
|
|
1463
1522
|
const root = rootOrKey && typeof rootOrKey === "object" && typeof rootOrKey.key === "string"
|
|
@@ -1465,15 +1524,8 @@ export async function setSourceRemoved(rootOrKey, removed, log) {
|
|
|
1465
1524
|
: rootByKey(rootOrKey);
|
|
1466
1525
|
if (!root)
|
|
1467
1526
|
return readonlyError(removed === true ? "remove" : "restore");
|
|
1468
|
-
if (root
|
|
1469
|
-
return
|
|
1470
|
-
ok: false,
|
|
1471
|
-
code: "error.source.reserved",
|
|
1472
|
-
params: { root: root.key },
|
|
1473
|
-
error: root.key === "dsh"
|
|
1474
|
-
? "DSH 技能目录是官方来源,不能从管理器移除"
|
|
1475
|
-
: "导入技能目录是插件自身的读写落点,不能移除",
|
|
1476
|
-
};
|
|
1527
|
+
if (isDefaultSkillSource(root))
|
|
1528
|
+
return reservedSourceError(root);
|
|
1477
1529
|
if (root.scope === "project")
|
|
1478
1530
|
return readonlyError("remove");
|
|
1479
1531
|
const current = await readManagerState();
|
|
@@ -1718,9 +1770,16 @@ async function publishTrashStage(stage, finalPath, metadata, renameOptions) {
|
|
|
1718
1770
|
}
|
|
1719
1771
|
return { fallback: true, cleanupError };
|
|
1720
1772
|
}
|
|
1773
|
+
/**
|
|
1774
|
+
* 回收站条目的来源元数据 —— 恢复时靠它把技能放回原处。
|
|
1775
|
+
*
|
|
1776
|
+
* 用户级可写来源不止 dsh 一个(hub 也是,而且它是「导入技能」页删除的主战场),
|
|
1777
|
+
* 所以这里必须按 scope 分岔:早先只特判 `dsh`,hub 会被记成项目级、`projectRoot`
|
|
1778
|
+
* 为 undefined,恢复时被判「原项目当前不在活动工作区中」—— 删除进去就再也拿不回来。
|
|
1779
|
+
*/
|
|
1721
1780
|
function trashRootMetadata(definition) {
|
|
1722
|
-
if (definition.
|
|
1723
|
-
return { key:
|
|
1781
|
+
if (definition.scope !== "project")
|
|
1782
|
+
return { key: definition.key, scope: "user", label: definition.label };
|
|
1724
1783
|
return {
|
|
1725
1784
|
key: definition.key,
|
|
1726
1785
|
scope: "project",
|
|
@@ -1734,8 +1793,10 @@ async function restoreRootDefinition(metadata, options = {}) {
|
|
|
1734
1793
|
// version 1 entries predate scoped Trash and always belong to $DSH_HOME/skills.
|
|
1735
1794
|
if (!metadata.root)
|
|
1736
1795
|
return rootByKey("dsh");
|
|
1737
|
-
|
|
1738
|
-
|
|
1796
|
+
// 用户级来源按 key 重新解析:路径来自 userRoots(),不信元数据里记住的 path
|
|
1797
|
+
// (DSH_HOME 换过之后,旧路径可能已经不在读取范围内了)。
|
|
1798
|
+
if (metadata.root.scope === "user")
|
|
1799
|
+
return rootByKey(metadata.root.key);
|
|
1739
1800
|
if (metadata.root.scope !== "project" ||
|
|
1740
1801
|
metadata.root.kind !== "project-dsh" ||
|
|
1741
1802
|
typeof metadata.root.key !== "string" ||
|
|
@@ -1769,8 +1830,8 @@ export async function deleteSkill(root, name, log, options = {}) {
|
|
|
1769
1830
|
return definition;
|
|
1770
1831
|
if (!definition)
|
|
1771
1832
|
return readonlyError("delete");
|
|
1772
|
-
//
|
|
1773
|
-
//
|
|
1833
|
+
// 删除只对插件可管理的来源开放(用户级 dsh / hub、项目级 .dsh/skills);外部 Agent
|
|
1834
|
+
// 目录与自定义绝对路径来源只读,返回明确错误而不是"假装删了"。
|
|
1774
1835
|
if (definition.deletable !== true)
|
|
1775
1836
|
return notDeletableError(definition);
|
|
1776
1837
|
const resolved = await resolveEntry(definition, name);
|
|
@@ -2486,8 +2547,19 @@ export async function createSkill(input, log, options = {}) {
|
|
|
2486
2547
|
const definition = await checkedWritableRootDefinition(requestedRoot);
|
|
2487
2548
|
if (definition && definition.ok === false)
|
|
2488
2549
|
return definition;
|
|
2489
|
-
if (!definition)
|
|
2550
|
+
if (!definition) {
|
|
2551
|
+
// 区分「来源根本不存在」与「来源存在但只读」:旧实现两种都回
|
|
2552
|
+
// 「该技能来源不允许启用或停用」,创建失败时这条提示既指错动作又指错原因。
|
|
2553
|
+
if (!rootDefinition(requestedRoot)) {
|
|
2554
|
+
return {
|
|
2555
|
+
ok: false,
|
|
2556
|
+
code: "error.root.unknown",
|
|
2557
|
+
params: { root: String(requestedRoot == null ? "" : requestedRoot) },
|
|
2558
|
+
error: `技能来源不存在:${requestedRoot == null || requestedRoot === "" ? "(空)" : requestedRoot}`,
|
|
2559
|
+
};
|
|
2560
|
+
}
|
|
2490
2561
|
return readonlyError("create");
|
|
2562
|
+
}
|
|
2491
2563
|
const root = definition.path;
|
|
2492
2564
|
const requestedName = String((input && input.name) || "").trim();
|
|
2493
2565
|
const name = toKebab(requestedName);
|
|
@@ -2831,7 +2903,9 @@ export async function state(options = {}) {
|
|
|
2831
2903
|
label: root.label,
|
|
2832
2904
|
mutable: root.mutable,
|
|
2833
2905
|
deletable: root.deletable === true,
|
|
2834
|
-
removable: root
|
|
2906
|
+
removable: !isDefaultSkillSource(root) && root.scope !== "project",
|
|
2907
|
+
// 默认来源(dsh / hub):界面据此隐藏来源开关、只显示「可管理」标记。
|
|
2908
|
+
defaultSource: isDefaultSkillSource(root),
|
|
2835
2909
|
toggleable: root.toggleable,
|
|
2836
2910
|
native: root.native,
|
|
2837
2911
|
rank: root.rank,
|
|
@@ -2891,7 +2965,8 @@ export async function state(options = {}) {
|
|
|
2891
2965
|
path: root.path,
|
|
2892
2966
|
label: root.label,
|
|
2893
2967
|
mutable: root.mutable,
|
|
2894
|
-
//
|
|
2968
|
+
// 是否提供「删除」:dsh / hub / 项目级 .dsh/skills 为 true;
|
|
2969
|
+
// 外部 Agent 与自定义绝对路径来源为 false(只读)。
|
|
2895
2970
|
deletable: root.deletable === true,
|
|
2896
2971
|
toggleable: root.toggleable,
|
|
2897
2972
|
native: root.native,
|
|
@@ -2907,11 +2982,13 @@ export async function state(options = {}) {
|
|
|
2907
2982
|
exists,
|
|
2908
2983
|
truncated: truncated === true,
|
|
2909
2984
|
// 界面用:能否从管理器「移除」(不再读取)。dsh / hub / 项目级不可移除。
|
|
2910
|
-
removable: root
|
|
2985
|
+
removable: !isDefaultSkillSource(root) && root.scope !== "project",
|
|
2986
|
+
// 默认来源(dsh / hub):界面据此隐藏来源开关(它们不能停用),换成「可管理」标记。
|
|
2987
|
+
defaultSource: isDefaultSkillSource(root),
|
|
2911
2988
|
removed: false,
|
|
2912
2989
|
enabled: policyResult.writable !== false &&
|
|
2913
2990
|
(root.scope === "project" ||
|
|
2914
|
-
root
|
|
2991
|
+
isDefaultSkillSource(root) ||
|
|
2915
2992
|
policyResult.state.sources[root.key] !== false),
|
|
2916
2993
|
skills,
|
|
2917
2994
|
});
|
package/lib/skills/service.js
CHANGED
|
@@ -424,7 +424,12 @@ export function createSkillsService(ctx) {
|
|
|
424
424
|
// 创建 / 导入 / 删除 / 回收站
|
|
425
425
|
// 创建默认落 hub(`tool-management/skills/`):UI 不传 root 时走这里;
|
|
426
426
|
// core.js 的 createSkill 默认值是第二道保险(同口径)。官方 `~/.dsh/skills/` 仍作为来源列出。
|
|
427
|
-
'skill-create': wrap((args) => write(async () =>
|
|
427
|
+
'skill-create': wrap((args) => write(async () => {
|
|
428
|
+
// requestRoot 未命中时回传原始 key,让 core 的 error.root.unknown 带上来源名
|
|
429
|
+
// (否则传了不存在的 root 会收到「技能来源不存在:(空)」这种指错方向的提示)。
|
|
430
|
+
const key = String(args.root || 'hub');
|
|
431
|
+
return createSkill({ name: args.name, description: args.description, body: args.body }, log, { root: (await requestRoot(key)) || key });
|
|
432
|
+
}), afterWrite),
|
|
428
433
|
'skill-import': wrap((args) => write(() => importSkill(String(args.source || ''), log, {
|
|
429
434
|
conflict: args.conflict === 'overwrite' ? 'overwrite' : 'skip',
|
|
430
435
|
dryRun: args.dryRun === true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-tool-management",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "DSH plugin: one settings panel for MCP servers, Skills, AGENTS.md presets, archived sessions and scene memories — plus scene memory injected into the system prompt and one-shot persona subagents. Settings UI + HTTP API + 14 model tools (skill_mcp_manager_*, skill_manager_*, agentsmd_*, rule_manager_*, subagent_*). Install with one command: dsh plugin --profile web add dsh-plugin-tool-management@latest",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,7 +37,10 @@
|
|
|
37
37
|
"prepublishOnly": "npm run build",
|
|
38
38
|
"lint": "node --check lib/client.js && node --check lib/index.js",
|
|
39
39
|
"check:i18n": "node scripts/check-i18n.mjs src/client.js",
|
|
40
|
-
"
|
|
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 && node --test test/archive.test.mjs test/import.test.mjs test/approval-policy.test.mjs test/subagent-scene.test.mjs test/subagent-persona.test.mjs test/hub-layout.test.mjs test/skills-state.test.mjs test/skills-delete.test.mjs test/skills-source-remove.test.mjs test/client-exports.test.mjs test/client-render.test.mjs test/compat-probe.test.mjs test/compat-fallback.test.mjs"
|
|
41
44
|
},
|
|
42
45
|
"keywords": [
|
|
43
46
|
"dsh",
|
|
@@ -56,7 +59,6 @@
|
|
|
56
59
|
"client": {
|
|
57
60
|
"platform": "web",
|
|
58
61
|
"inject": [
|
|
59
|
-
"@deepseek-ai/dsh-client-ui-slots",
|
|
60
62
|
"@deepseek-ai/dsh-client-locale"
|
|
61
63
|
]
|
|
62
64
|
}
|
package/screenshots.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
-
"docs/images/
|
|
3
|
-
"docs/images
|
|
4
|
-
"docs/images
|
|
5
|
-
"docs/images
|
|
6
|
-
"docs/images
|
|
7
|
-
"docs/images
|
|
8
|
-
"docs/images
|
|
2
|
+
"docs/images/1场景.png",
|
|
3
|
+
"docs/images/2MCP.png",
|
|
4
|
+
"docs/images/3技能.png",
|
|
5
|
+
"docs/images/4子智能体.png",
|
|
6
|
+
"docs/images/5提示词.png",
|
|
7
|
+
"docs/images/6记忆.png",
|
|
8
|
+
"docs/images/7会话.png",
|
|
9
|
+
"docs/images/8兼容.png"
|
|
9
10
|
]
|
package/docs/images/MCP.png
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|