@michengai/dsh-skills-manager 0.1.38 → 0.1.40
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 +6 -0
- package/CHANGELOG.zh-CN.md +6 -0
- package/lib/core.js +37 -48
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,12 @@ The five most recent published versions are listed below.
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 0.1.40 - 2026-09-05
|
|
10
|
+
|
|
11
|
+
- 修复禁用的外部同名技能遮蔽已启用 DSH 技能的问题,统一管理页与运行时的赢家选择。
|
|
12
|
+
- 冲突时为用户和项目级原生赢家提供作用域候选,保留禁用阻断、工作区隔离及来源文件不变性。
|
|
13
|
+
- 显式声明作用域注册表回归所需的开发依赖,确保 CI 干净安装可执行完整检查。
|
|
14
|
+
|
|
9
15
|
## 0.1.38 - 2026-09-03
|
|
10
16
|
|
|
11
17
|
- Added Cursor as a read-only, locally toggleable Skill source at `%USERPROFILE%\.cursor\skills`, with `DSH_CURSOR_HOME` override and state-file migration.
|
package/CHANGELOG.zh-CN.md
CHANGED
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
## 未发布
|
|
8
8
|
|
|
9
|
+
## 0.1.40 - 2026-09-05
|
|
10
|
+
|
|
11
|
+
- 修复禁用的外部同名技能遮蔽已启用 DSH 技能的问题,统一管理页与运行时的赢家选择。
|
|
12
|
+
- 冲突时为用户和项目级原生赢家提供作用域候选,保留禁用阻断、工作区隔离及来源文件不变性。
|
|
13
|
+
- 显式声明作用域注册表回归所需的开发依赖,确保 CI 干净安装可执行完整检查。
|
|
14
|
+
|
|
9
15
|
## 0.1.38 - 2026-09-03
|
|
10
16
|
|
|
11
17
|
- 新增 Cursor 用户级只读技能来源,默认读取 `%USERPROFILE%\.cursor\skills`,支持 `DSH_CURSOR_HOME` 覆盖,并兼容迁移既有状态文件。
|
package/lib/core.js
CHANGED
|
@@ -1382,52 +1382,35 @@ async function listProviderCandidates(options = {}) {
|
|
|
1382
1382
|
const candidates = [];
|
|
1383
1383
|
const user = userRoots();
|
|
1384
1384
|
const userScans = await scanDeduplicatedUserRoots(user);
|
|
1385
|
-
|
|
1386
|
-
const scanned = userScans.get(root.key);
|
|
1387
|
-
for (const entry of scanned.entries) {
|
|
1388
|
-
if (!entry.loadable) continue;
|
|
1389
|
-
const policy = effectiveSkillPolicy(policyResult, root, entry);
|
|
1390
|
-
const needsOverlay = root.key !== "dsh" || policy.override !== void 0 || !entry.invocationPolicyValid || policyResult.writable === false;
|
|
1391
|
-
if (!needsOverlay) continue;
|
|
1392
|
-
candidates.push({
|
|
1393
|
-
name: entry.declaredName,
|
|
1394
|
-
description: entry.description,
|
|
1395
|
-
invocation: { modelInvocable: policy.modelInvocable, userInvocable: policy.userInvocable },
|
|
1396
|
-
provider: "dsh-skills-manager-external",
|
|
1397
|
-
source: root.key === "dsh" ? "user-dsh" : `agent-${root.key}`,
|
|
1398
|
-
rank: root.key === "dsh" ? USER_DSH_POLICY_RANK : entry.providerRank ?? root.rank,
|
|
1399
|
-
locator: { rootKey: root.key, entryName: entry.name, path: entry.docPath, realEntryPath: entry.realEntryPath, realDocPath: entry.realDocPath },
|
|
1400
|
-
resourceBase: { kind: "directory", path: entry.kind === "bundle" ? entry.realEntryPath : root.path },
|
|
1401
|
-
path: entry.docPath,
|
|
1402
|
-
metadata: { dshSkillsManager: { root: root.key, readOnly: !root.mutable, sourceReadOnly: !root.mutable, policyOnly: root.key === "dsh" } }
|
|
1403
|
-
});
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1385
|
+
const items = user.flatMap((root) => userScans.get(root.key).entries.map((entry) => ({ root, entry })));
|
|
1406
1386
|
const cwd = options && typeof options.cwd === "string" ? options.cwd : void 0;
|
|
1407
1387
|
if (cwd) {
|
|
1408
1388
|
const roots = await projectRoots([cwd]);
|
|
1409
1389
|
for (const root of roots) {
|
|
1410
1390
|
const scanned = await scanEntries(root.path);
|
|
1411
|
-
for (const entry of scanned.entries) {
|
|
1412
|
-
if (!entry.loadable) continue;
|
|
1413
|
-
const policy = effectiveSkillPolicy(policyResult, root, entry);
|
|
1414
|
-
const needsOverlay = policy.override !== void 0 || !entry.invocationPolicyValid || policyResult.writable === false;
|
|
1415
|
-
if (!needsOverlay) continue;
|
|
1416
|
-
candidates.push({
|
|
1417
|
-
name: entry.declaredName,
|
|
1418
|
-
description: entry.description,
|
|
1419
|
-
invocation: { modelInvocable: policy.modelInvocable, userInvocable: policy.userInvocable },
|
|
1420
|
-
provider: "dsh-skills-manager-external",
|
|
1421
|
-
source: root.kind,
|
|
1422
|
-
rank: root.rank - 1,
|
|
1423
|
-
locator: { rootKey: root.key, entryName: entry.name, path: entry.docPath, realEntryPath: entry.realEntryPath, realDocPath: entry.realDocPath },
|
|
1424
|
-
resourceBase: { kind: "directory", path: entry.kind === "bundle" ? entry.realEntryPath : root.path },
|
|
1425
|
-
path: entry.docPath,
|
|
1426
|
-
metadata: { dshSkillsManager: { root: root.key, readOnly: !root.mutable, sourceReadOnly: !root.mutable, policyOnly: true } }
|
|
1427
|
-
});
|
|
1428
|
-
}
|
|
1391
|
+
for (const entry of scanned.entries) items.push({ root, entry });
|
|
1429
1392
|
}
|
|
1430
1393
|
}
|
|
1394
|
+
for (const group of groupLoadableSkillsByName(items).values()) {
|
|
1395
|
+
const { root, entry } = group[0];
|
|
1396
|
+
const project = root.scope === "project";
|
|
1397
|
+
const policyOnly = project || root.key === "dsh";
|
|
1398
|
+
const policy = effectiveSkillPolicy(policyResult, root, entry);
|
|
1399
|
+
const needsOverlay = !policyOnly || group.length > 1 || policy.override !== void 0 || !entry.invocationPolicyValid || policyResult.writable === false;
|
|
1400
|
+
if (!needsOverlay) continue;
|
|
1401
|
+
candidates.push({
|
|
1402
|
+
name: entry.declaredName,
|
|
1403
|
+
description: entry.description,
|
|
1404
|
+
invocation: { modelInvocable: policy.modelInvocable, userInvocable: policy.userInvocable },
|
|
1405
|
+
provider: "dsh-skills-manager-external",
|
|
1406
|
+
source: project ? root.kind : root.key === "dsh" ? "user-dsh" : `agent-${root.key}`,
|
|
1407
|
+
rank: project ? root.rank - 1 : root.key === "dsh" ? USER_DSH_POLICY_RANK : entry.providerRank ?? root.rank,
|
|
1408
|
+
locator: { rootKey: root.key, entryName: entry.name, path: entry.docPath, realEntryPath: entry.realEntryPath, realDocPath: entry.realDocPath },
|
|
1409
|
+
resourceBase: { kind: "directory", path: entry.kind === "bundle" ? entry.realEntryPath : root.path },
|
|
1410
|
+
path: entry.docPath,
|
|
1411
|
+
metadata: { dshSkillsManager: { root: root.key, readOnly: !root.mutable, sourceReadOnly: !root.mutable, policyOnly } }
|
|
1412
|
+
});
|
|
1413
|
+
}
|
|
1431
1414
|
return candidates;
|
|
1432
1415
|
}
|
|
1433
1416
|
async function getProviderSkill(candidate, options = {}) {
|
|
@@ -1464,18 +1447,24 @@ async function getProviderSkill(candidate, options = {}) {
|
|
|
1464
1447
|
function canonicalSkillName(item) {
|
|
1465
1448
|
return item.entry.declaredName || item.entry.name;
|
|
1466
1449
|
}
|
|
1467
|
-
function
|
|
1468
|
-
const
|
|
1450
|
+
function groupLoadableSkillsByName(items) {
|
|
1451
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1469
1452
|
for (const item of [...items].sort((a, b) => a.root.rank - b.root.rank)) {
|
|
1470
|
-
const canonicalName = canonicalSkillName(item);
|
|
1471
1453
|
if (!item.entry.loadable) continue;
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
}
|
|
1454
|
+
const name = canonicalSkillName(item);
|
|
1455
|
+
const group = groups.get(name) || [];
|
|
1456
|
+
group.push(item);
|
|
1457
|
+
groups.set(name, group);
|
|
1477
1458
|
}
|
|
1478
|
-
|
|
1459
|
+
return groups;
|
|
1460
|
+
}
|
|
1461
|
+
function markWinners(items, options = {}) {
|
|
1462
|
+
const winners = /* @__PURE__ */ new Map();
|
|
1463
|
+
for (const [canonicalName, [winner, ...shadowed]] of groupLoadableSkillsByName(items)) {
|
|
1464
|
+
winners.set(canonicalName, winner);
|
|
1465
|
+
if (options.markShadowed !== false) {
|
|
1466
|
+
for (const item of shadowed) item.view.shadowedBy = { root: winner.root.key, name: winner.entry.name };
|
|
1467
|
+
}
|
|
1479
1468
|
if (options.markWinner !== false) winner.view.winner = true;
|
|
1480
1469
|
winner.view.enabled = winner.policy.enabled;
|
|
1481
1470
|
winner.view.canonicalName = canonicalName;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michengai/dsh-skills-manager",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.40",
|
|
4
4
|
"description": "NPM-installable DSH Web plugin for safely loading and managing skills across DSH and common local Agents.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -64,11 +64,13 @@
|
|
|
64
64
|
"react": "^18.2.0"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
+
"@deepseek-ai/cordis": "4.0.2",
|
|
67
68
|
"@deepseek-ai/dsh-client-locale": "0.1.2-rc.1",
|
|
68
69
|
"@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1",
|
|
69
70
|
"@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1",
|
|
70
71
|
"@deepseek-ai/dsh-host-webserver": "0.1.2-rc.1",
|
|
71
72
|
"@deepseek-ai/dsh-session": "0.1.2-rc.1",
|
|
73
|
+
"@deepseek-ai/dsh-scope": "0.1.2-rc.1",
|
|
72
74
|
"@deepseek-ai/dsh-skill": "0.1.2-rc.1",
|
|
73
75
|
"@deepseek-ai/dsh-tools": "0.1.2-rc.1",
|
|
74
76
|
"@deepseek-ai/dsh-web-app": "0.1.2-rc.1",
|