@wenaixi/dsh-superpower 7.0.0 → 7.1.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 +5 -5
- package/lib/catalog.d.ts +98 -0
- package/lib/catalog.d.ts.map +1 -0
- package/lib/catalog.js +295 -0
- package/lib/catalog.js.map +1 -0
- package/lib/document.d.ts +61 -0
- package/lib/document.d.ts.map +1 -0
- package/lib/document.js +268 -0
- package/lib/document.js.map +1 -0
- package/lib/superpowers.d.ts +6 -0
- package/lib/superpowers.d.ts.map +1 -1
- package/lib/superpowers.js +27 -250
- package/lib/superpowers.js.map +1 -1
- package/package.json +2 -2
- package/skills/brainstorming/SKILL.md +1 -1
- package/skills/brainstorming/scripts/server.cjs +6 -14
- package/skills/brainstorming/scripts/start-server.sh +1 -6
- package/skills/brainstorming/spec-document-reviewer-prompt.md +1 -1
- package/skills/brainstorming/visual-companion.md +5 -31
- package/skills/diagnosing-superpowers/SKILL.md +1 -1
- package/skills/diagnosing-superpowers/prompts/request-conflicts.md +1 -1
- package/skills/diagnosing-superpowers/templates/issue.md +1 -1
- package/skills/dispatching-parallel-agents/SKILL.md +4 -4
- package/skills/executing-plans/SKILL.md +5 -5
- package/skills/finishing-a-development-branch/SKILL.md +5 -5
- package/skills/receiving-code-review/SKILL.md +1 -1
- package/skills/requesting-code-review/SKILL.md +1 -1
- package/skills/requesting-code-review/code-reviewer.md +1 -1
- package/skills/subagent-driven-development/SKILL.md +2 -2
- package/skills/subagent-driven-development/implementer-prompt.md +1 -1
- package/skills/subagent-driven-development/re-review-prompt.md +1 -1
- package/skills/subagent-driven-development/scripts/sdd-workspace +2 -2
- package/skills/subagent-driven-development/task-reviewer-prompt.md +1 -1
- package/skills/systematic-debugging/CREATION-LOG.md +2 -2
- package/skills/systematic-debugging/SKILL.md +2 -2
- package/skills/systematic-debugging/condition-based-waiting.md +3 -3
- package/skills/systematic-debugging/defense-in-depth.md +1 -1
- package/skills/systematic-debugging/root-cause-tracing.md +1 -1
- package/skills/systematic-debugging/test-pressure-3.md +1 -1
- package/skills/test-driven-development/SKILL.md +1 -1
- package/skills/test-driven-development/writing-good-tests.md +1 -1
- package/skills/using-git-worktrees/SKILL.md +1 -1
- package/skills/using-superpowers/SKILL.md +4 -10
- package/skills/using-superpowers/references/dsh-tools.md +3 -3
- package/skills/verification-before-completion/SKILL.md +1 -1
- package/skills/writing-plans/SKILL.md +1 -1
- package/skills/writing-skills/SKILL.md +6 -6
- package/skills/writing-skills/testing-skills-with-subagents.md +1 -1
- package/skills/using-superpowers/references/antigravity-tools.md +0 -23
- package/skills/using-superpowers/references/claude-code-tools.md +0 -11
- package/skills/using-superpowers/references/codex-tools.md +0 -108
- package/skills/using-superpowers/references/gemini-tools.md +0 -63
- package/skills/using-superpowers/references/hermes-tools.md +0 -56
- package/skills/using-superpowers/references/muse-tools.md +0 -35
- package/skills/using-superpowers/references/pi-tools.md +0 -16
- package/skills/writing-skills/anthropic-best-practices.md +0 -1146
- package/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -188
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](./LICENSE)
|
|
5
5
|
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
6
6
|
|
|
7
|
-
[obra/superpowers](https://github.com/obra/superpowers) 的 DSH
|
|
7
|
+
[obra/superpowers](https://github.com/obra/superpowers) 的 DSH 专属移植版 — 15 个技能注入 `ctx.skills`,开箱即用,全中文,**仅支持 DSH (DeepSeek Harness) 平台**,不提供其它 AI 宿主适配。
|
|
8
8
|
|
|
9
9
|
## 安装
|
|
10
10
|
|
|
@@ -26,7 +26,7 @@ dsh --profile web --dump-config | grep -A2 "@wenaixi/dsh-superpower"
|
|
|
26
26
|
dsh --profile web # 进会话,技能自动可用
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
> 如需锁定版本,在包名后追加 `@<version>`(如 `@wenaixi/dsh-superpower@7.0.
|
|
29
|
+
> 如需锁定版本,在包名后追加 `@<version>`(如 `@wenaixi/dsh-superpower@7.0.1`)或 `#v7.0.1`(GitHub 形式)。
|
|
30
30
|
>
|
|
31
31
|
> > 旧名 `dsh-superpower`(无 scope)已废弃并 `npm deprecate`,请改用 `@wenaixi/dsh-superpower`。
|
|
32
32
|
|
|
@@ -96,11 +96,11 @@ skills/ # 15 技能(中文化,v7.0.0 起无 superpower- 前缀
|
|
|
96
96
|
lib/ # 已提交,GitHub 直装零构建
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
版本:`v7.0.0` 起技能名回归上游命名(无 `superpower-` 前缀)并整批同步上游 `obra/superpowers v6.4.2`;本插件技能优先级最高(rank 10
|
|
99
|
+
版本:`v7.0.0` 起技能名回归上游命名(无 `superpower-` 前缀)并整批同步上游 `obra/superpowers v6.4.2`;本插件技能优先级最高(rank 10),同名技能本包胜出。`v7.0.0` 起本插件为 **DSH 专属**,已移除全部非 DSH 平台(Claude Code、Codex、Gemini CLI、Hermes、Muse、Pi、Antigravity、Copilot CLI)的参考文档与兼容层;`v7.0.1` 为修复版,重发干净 tarball(npm `7.0.0` 发布于专属化前、已废弃,勿使用)。详见 `CHANGELOG.md`。
|
|
100
100
|
|
|
101
101
|
## 常见问题
|
|
102
102
|
|
|
103
|
-
404/镜像延迟请改用 GitHub
|
|
103
|
+
404/镜像延迟请改用 GitHub 形式或 `--registry https://registry.npmjs.org`(官方源已是最新);白名单不需要;`latest` 可用 `npm view @wenaixi/dsh-superpower --registry https://registry.npmjs.org` 查看。
|
|
104
104
|
|
|
105
105
|
## 协议
|
|
106
106
|
|
|
@@ -113,4 +113,4 @@ MIT,与上游 [obra/superpowers](https://github.com/obra/superpowers) 保持
|
|
|
113
113
|
## 致谢
|
|
114
114
|
|
|
115
115
|
- 上游作者 [Jesse Vincent](https://blog.fsck.com) 与 [Prime Radiant](https://primeradiant.com)
|
|
116
|
-
- [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的 `dsh-skill` 三角色架构
|
|
116
|
+
- [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的 `dsh-skill` 三角色架构
|
package/lib/catalog.d.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @wenaixi/dsh-superpower — SkillCatalog 深度模块
|
|
3
|
+
*
|
|
4
|
+
* 封装技能目录的发现、遍历、健康探测、排重、名称漂移校验与版本化快照索引。
|
|
5
|
+
*
|
|
6
|
+
* 核心设计:
|
|
7
|
+
* - Depth: 将文件系统遍历、mtime 存活检测、去重、状态回写与快照复用隐藏在极简接口之后;
|
|
8
|
+
* - Locality: 集中管理技能目录发现逻辑、缓存一致性与规范合规规则;
|
|
9
|
+
* - Leverage: 同时支撑 SuperpowersProvider 高性能运行时与 verify.mjs 质检治理。
|
|
10
|
+
*/
|
|
11
|
+
import type { SkillCandidate, SkillDefinition } from '@deepseek-ai/dsh-skill';
|
|
12
|
+
import { SkillDocument, type SpecificationTestResult } from './document.js';
|
|
13
|
+
export interface CatalogLogger {
|
|
14
|
+
warn(msg: string): void;
|
|
15
|
+
debug?(msg: string): void;
|
|
16
|
+
info?(msg: string): void;
|
|
17
|
+
}
|
|
18
|
+
export interface CatalogLookupOptions {
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
logger?: CatalogLogger;
|
|
21
|
+
forceScan?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface CatalogEntry {
|
|
24
|
+
directoryName: string;
|
|
25
|
+
skillPath: string;
|
|
26
|
+
document: SkillDocument;
|
|
27
|
+
nameDrift: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface SpecificationReport {
|
|
30
|
+
total: number;
|
|
31
|
+
passed: number;
|
|
32
|
+
failed: number;
|
|
33
|
+
results: SpecificationTestResult[];
|
|
34
|
+
ok: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface CatalogIntegrityReport {
|
|
37
|
+
total: number;
|
|
38
|
+
entries: CatalogEntry[];
|
|
39
|
+
duplicates: string[];
|
|
40
|
+
missingSkillMd: string[];
|
|
41
|
+
errors: {
|
|
42
|
+
path: string;
|
|
43
|
+
error: string;
|
|
44
|
+
}[];
|
|
45
|
+
ok: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare class SkillCatalog {
|
|
48
|
+
readonly skillDir: string;
|
|
49
|
+
private readonly entriesByName;
|
|
50
|
+
private readonly entriesByDir;
|
|
51
|
+
private readonly duplicates;
|
|
52
|
+
private readonly missingSkillMd;
|
|
53
|
+
private readonly loadErrors;
|
|
54
|
+
private cachedCandidates;
|
|
55
|
+
private lastScannedMtimeMs;
|
|
56
|
+
private lastScanProviderName?;
|
|
57
|
+
private lastScanRank?;
|
|
58
|
+
constructor(skillDir: string);
|
|
59
|
+
/**
|
|
60
|
+
* 从指定目录异步扫描并构建已预热的 SkillCatalog 深度实例。
|
|
61
|
+
*/
|
|
62
|
+
static fromDirectory(skillDir: string, options?: CatalogLookupOptions): Promise<SkillCatalog>;
|
|
63
|
+
/**
|
|
64
|
+
* 清空快照与索引,强制下一轮查询重新从磁盘装载。
|
|
65
|
+
*/
|
|
66
|
+
invalidate(): void;
|
|
67
|
+
/**
|
|
68
|
+
* 探测目录是否发生变动。
|
|
69
|
+
*/
|
|
70
|
+
private isDirModified;
|
|
71
|
+
/**
|
|
72
|
+
* 执行全量目录遍历与技能索引构建。
|
|
73
|
+
*/
|
|
74
|
+
scan(options?: CatalogLookupOptions): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* 映射当前有效技能为 DSH SkillCandidate 快照。
|
|
77
|
+
* 自动按 mtime 评估有效性,未变动时直接复用不可变快照,零重复读盘。
|
|
78
|
+
*/
|
|
79
|
+
listCandidates(providerName: string, rank: number, options?: CatalogLookupOptions): Promise<readonly SkillCandidate[]>;
|
|
80
|
+
/**
|
|
81
|
+
* 根据候选技能的 locator 与名称解析出完整 SkillDefinition。
|
|
82
|
+
* 优先命中内存缓存;若发生热重读,自动自愈更新回内存映射,消除状态撕裂缝隙。
|
|
83
|
+
*/
|
|
84
|
+
getDefinition(candidate: SkillCandidate, providerName: string, options?: CatalogLookupOptions): Promise<SkillDefinition | undefined>;
|
|
85
|
+
/**
|
|
86
|
+
* 执行 SkillCatalog 自身边界契约自检(排重与漂移探测)。
|
|
87
|
+
*/
|
|
88
|
+
static selfTest(): Promise<SpecificationTestResult[]>;
|
|
89
|
+
/**
|
|
90
|
+
* 执行完整的核心规范测试套件,返回聚合体检报告(测试表面即接口)。
|
|
91
|
+
*/
|
|
92
|
+
static verifySpecification(): Promise<SpecificationReport>;
|
|
93
|
+
/**
|
|
94
|
+
* 生成目录健康度与一致性完整体检报告(供 verify 脚本与 CI 质量门禁复用)。
|
|
95
|
+
*/
|
|
96
|
+
verifyIntegrity(): CatalogIntegrityReport;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAC7E,OAAO,EAAE,aAAa,EAAE,KAAK,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAE3E,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,KAAK,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,IAAI,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,aAAa,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,uBAAuB,EAAE,CAAA;IAClC,EAAE,EAAE,OAAO,CAAA;CACZ;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACzC,EAAE,EAAE,OAAO,CAAA;CACZ;AAED,qBAAa,YAAY;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAChE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAC/D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAe;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwC;IAGnE,OAAO,CAAC,gBAAgB,CAAyC;IACjE,OAAO,CAAC,kBAAkB,CAAI;IAC9B,OAAO,CAAC,oBAAoB,CAAC,CAAQ;IACrC,OAAO,CAAC,YAAY,CAAC,CAAQ;gBAEjB,QAAQ,EAAE,MAAM;IAI5B;;OAEG;WACU,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC;IAOnG;;OAEG;IACH,UAAU,IAAI,IAAI;IAUlB;;OAEG;YACW,aAAa;IAW3B;;OAEG;IACG,IAAI,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2FzD;;;OAGG;IACG,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC;IAwB5H;;;OAGG;IACG,aAAa,CAAC,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IA2C1I;;OAEG;WACU,QAAQ,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;IAwC3D;;OAEG;WACU,mBAAmB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAiBhE;;OAEG;IACH,eAAe,IAAI,sBAAsB;CAY1C"}
|
package/lib/catalog.js
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @wenaixi/dsh-superpower — SkillCatalog 深度模块
|
|
3
|
+
*
|
|
4
|
+
* 封装技能目录的发现、遍历、健康探测、排重、名称漂移校验与版本化快照索引。
|
|
5
|
+
*
|
|
6
|
+
* 核心设计:
|
|
7
|
+
* - Depth: 将文件系统遍历、mtime 存活检测、去重、状态回写与快照复用隐藏在极简接口之后;
|
|
8
|
+
* - Locality: 集中管理技能目录发现逻辑、缓存一致性与规范合规规则;
|
|
9
|
+
* - Leverage: 同时支撑 SuperpowersProvider 高性能运行时与 verify.mjs 质检治理。
|
|
10
|
+
*/
|
|
11
|
+
import { mkdtemp, mkdir, readdir, rm, stat, writeFile } from 'node:fs/promises';
|
|
12
|
+
import { tmpdir } from 'node:os';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { SkillDocument } from './document.js';
|
|
15
|
+
export class SkillCatalog {
|
|
16
|
+
skillDir;
|
|
17
|
+
entriesByName = new Map();
|
|
18
|
+
entriesByDir = new Map();
|
|
19
|
+
duplicates = [];
|
|
20
|
+
missingSkillMd = [];
|
|
21
|
+
loadErrors = [];
|
|
22
|
+
// 快照缓存与版本探测状态
|
|
23
|
+
cachedCandidates = null;
|
|
24
|
+
lastScannedMtimeMs = 0;
|
|
25
|
+
lastScanProviderName;
|
|
26
|
+
lastScanRank;
|
|
27
|
+
constructor(skillDir) {
|
|
28
|
+
this.skillDir = skillDir;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 从指定目录异步扫描并构建已预热的 SkillCatalog 深度实例。
|
|
32
|
+
*/
|
|
33
|
+
static async fromDirectory(skillDir, options) {
|
|
34
|
+
options?.signal?.throwIfAborted();
|
|
35
|
+
const catalog = new SkillCatalog(skillDir);
|
|
36
|
+
await catalog.scan(options);
|
|
37
|
+
return catalog;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 清空快照与索引,强制下一轮查询重新从磁盘装载。
|
|
41
|
+
*/
|
|
42
|
+
invalidate() {
|
|
43
|
+
this.cachedCandidates = null;
|
|
44
|
+
this.lastScannedMtimeMs = 0;
|
|
45
|
+
this.entriesByName.clear();
|
|
46
|
+
this.entriesByDir.clear();
|
|
47
|
+
this.duplicates.length = 0;
|
|
48
|
+
this.missingSkillMd.length = 0;
|
|
49
|
+
this.loadErrors.length = 0;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 探测目录是否发生变动。
|
|
53
|
+
*/
|
|
54
|
+
async isDirModified(signal) {
|
|
55
|
+
if (this.lastScannedMtimeMs === 0 || this.entriesByName.size === 0)
|
|
56
|
+
return true;
|
|
57
|
+
try {
|
|
58
|
+
signal?.throwIfAborted();
|
|
59
|
+
const dirStat = await stat(this.skillDir);
|
|
60
|
+
return dirStat.mtimeMs > this.lastScannedMtimeMs;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 执行全量目录遍历与技能索引构建。
|
|
68
|
+
*/
|
|
69
|
+
async scan(options) {
|
|
70
|
+
const signal = options?.signal;
|
|
71
|
+
const logger = options?.logger;
|
|
72
|
+
let dirStat;
|
|
73
|
+
try {
|
|
74
|
+
dirStat = await stat(this.skillDir);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const code = err?.code;
|
|
78
|
+
if (code === 'ENOENT' || code === 'ENOTDIR') {
|
|
79
|
+
logger?.warn(`[SkillCatalog] skillDir not found: ${this.skillDir}`);
|
|
80
|
+
this.invalidate();
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
let dirents;
|
|
86
|
+
try {
|
|
87
|
+
dirents = await readdir(this.skillDir, { withFileTypes: true, signal });
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
const code = err?.code;
|
|
91
|
+
if (code === 'ENOENT' || code === 'ENOTDIR') {
|
|
92
|
+
logger?.warn(`[SkillCatalog] skillDir not found: ${this.skillDir}`);
|
|
93
|
+
this.invalidate();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
98
|
+
// 重置内存临时状态
|
|
99
|
+
this.entriesByName.clear();
|
|
100
|
+
this.entriesByDir.clear();
|
|
101
|
+
this.duplicates.length = 0;
|
|
102
|
+
this.missingSkillMd.length = 0;
|
|
103
|
+
this.loadErrors.length = 0;
|
|
104
|
+
this.cachedCandidates = null;
|
|
105
|
+
const sorted = dirents.filter((e) => e.isDirectory() && !e.name.startsWith('.')).sort((a, b) => a.name.localeCompare(b.name));
|
|
106
|
+
for (const entry of sorted) {
|
|
107
|
+
signal?.throwIfAborted();
|
|
108
|
+
const skillPath = join(this.skillDir, entry.name, 'SKILL.md');
|
|
109
|
+
try {
|
|
110
|
+
await stat(skillPath);
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
const code = err?.code;
|
|
114
|
+
logger?.debug?.(`[SkillCatalog] skip ${entry.name}: no SKILL.md (${code ?? String(err)})`);
|
|
115
|
+
this.missingSkillMd.push(entry.name);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
let doc;
|
|
119
|
+
try {
|
|
120
|
+
doc = await SkillDocument.fromFile(skillPath, signal);
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
const msg = String(err?.message ?? err);
|
|
124
|
+
logger?.warn(`[SkillCatalog] skip ${skillPath}: parse failed — ${msg}`);
|
|
125
|
+
this.loadErrors.push({ path: skillPath, error: msg });
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (this.entriesByName.has(doc.name)) {
|
|
129
|
+
logger?.warn(`[SkillCatalog] skip ${skillPath}: duplicate skill name "${doc.name}"`);
|
|
130
|
+
this.duplicates.push(doc.name);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const nameDrift = doc.name !== entry.name;
|
|
134
|
+
if (nameDrift) {
|
|
135
|
+
logger?.warn(`[SkillCatalog] skill name "${doc.name}" != directory "${entry.name}" (using frontmatter)`);
|
|
136
|
+
}
|
|
137
|
+
const catalogEntry = {
|
|
138
|
+
directoryName: entry.name,
|
|
139
|
+
skillPath,
|
|
140
|
+
document: doc,
|
|
141
|
+
nameDrift,
|
|
142
|
+
};
|
|
143
|
+
this.entriesByName.set(doc.name, catalogEntry);
|
|
144
|
+
this.entriesByDir.set(entry.name, catalogEntry);
|
|
145
|
+
}
|
|
146
|
+
this.lastScannedMtimeMs = dirStat.mtimeMs;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* 映射当前有效技能为 DSH SkillCandidate 快照。
|
|
150
|
+
* 自动按 mtime 评估有效性,未变动时直接复用不可变快照,零重复读盘。
|
|
151
|
+
*/
|
|
152
|
+
async listCandidates(providerName, rank, options) {
|
|
153
|
+
options?.signal?.throwIfAborted();
|
|
154
|
+
const needsScan = options?.forceScan ||
|
|
155
|
+
this.cachedCandidates === null ||
|
|
156
|
+
this.lastScanProviderName !== providerName ||
|
|
157
|
+
this.lastScanRank !== rank ||
|
|
158
|
+
(await this.isDirModified(options?.signal));
|
|
159
|
+
if (needsScan) {
|
|
160
|
+
await this.scan(options);
|
|
161
|
+
const list = [];
|
|
162
|
+
for (const entry of this.entriesByName.values()) {
|
|
163
|
+
list.push(entry.document.toCandidate(providerName, rank));
|
|
164
|
+
}
|
|
165
|
+
this.cachedCandidates = Object.freeze(list);
|
|
166
|
+
this.lastScanProviderName = providerName;
|
|
167
|
+
this.lastScanRank = rank;
|
|
168
|
+
}
|
|
169
|
+
return this.cachedCandidates;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 根据候选技能的 locator 与名称解析出完整 SkillDefinition。
|
|
173
|
+
* 优先命中内存缓存;若发生热重读,自动自愈更新回内存映射,消除状态撕裂缝隙。
|
|
174
|
+
*/
|
|
175
|
+
async getDefinition(candidate, providerName, options) {
|
|
176
|
+
options?.signal?.throwIfAborted();
|
|
177
|
+
const locator = candidate.locator;
|
|
178
|
+
if (!locator?.path)
|
|
179
|
+
return undefined;
|
|
180
|
+
// 优先命中内存缓存
|
|
181
|
+
const cached = this.entriesByName.get(candidate.name);
|
|
182
|
+
if (cached && cached.skillPath === locator.path) {
|
|
183
|
+
return cached.document.toDefinition(providerName);
|
|
184
|
+
}
|
|
185
|
+
// 若缓存未命中则重新从文件读取
|
|
186
|
+
let doc;
|
|
187
|
+
try {
|
|
188
|
+
doc = await SkillDocument.fromFile(locator.path, options?.signal);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
if (err?.name === 'AbortError')
|
|
192
|
+
throw err;
|
|
193
|
+
const code = err?.code;
|
|
194
|
+
if (code === 'ENOENT')
|
|
195
|
+
return undefined;
|
|
196
|
+
options?.logger?.warn(`[SkillCatalog] get ${candidate.name}: read failed (${code ?? String(err)})`);
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
if (doc.name !== candidate.name) {
|
|
200
|
+
options?.logger?.warn(`[SkillCatalog] get ${candidate.name}: name drift "${doc.name}" != "${candidate.name}"`);
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
// 自愈回写:将重新读取解析出的文档更新进内部索引,保持状态严格一致
|
|
204
|
+
const dirName = cached?.directoryName ?? candidate.name;
|
|
205
|
+
const updatedEntry = {
|
|
206
|
+
directoryName: dirName,
|
|
207
|
+
skillPath: locator.path,
|
|
208
|
+
document: doc,
|
|
209
|
+
nameDrift: doc.name !== dirName,
|
|
210
|
+
};
|
|
211
|
+
this.entriesByName.set(doc.name, updatedEntry);
|
|
212
|
+
this.entriesByDir.set(dirName, updatedEntry);
|
|
213
|
+
this.cachedCandidates = null; // 快照失效,以便下一轮刷新
|
|
214
|
+
return doc.toDefinition(providerName);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* 执行 SkillCatalog 自身边界契约自检(排重与漂移探测)。
|
|
218
|
+
*/
|
|
219
|
+
static async selfTest() {
|
|
220
|
+
const results = [];
|
|
221
|
+
const runCheck = async (name, fn) => {
|
|
222
|
+
try {
|
|
223
|
+
await fn();
|
|
224
|
+
results.push({ name, ok: true });
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
results.push({ name, ok: false, error: err?.message ?? String(err) });
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
await runCheck('目录排重', async () => {
|
|
231
|
+
const base = await mkdtemp(join(tmpdir(), 'sp-dup-'));
|
|
232
|
+
try {
|
|
233
|
+
const md = '---\nname: same-name\ndescription: d\n---\nbody';
|
|
234
|
+
await mkdir(join(base, 'alpha'));
|
|
235
|
+
await mkdir(join(base, 'bravo'));
|
|
236
|
+
await Promise.all([writeFile(join(base, 'alpha', 'SKILL.md'), md), writeFile(join(base, 'bravo', 'SKILL.md'), md)]);
|
|
237
|
+
const cat = await SkillCatalog.fromDirectory(base);
|
|
238
|
+
if (cat.verifyIntegrity().duplicates.length !== 1)
|
|
239
|
+
throw new Error('duplicates != 1');
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
await rm(base, { recursive: true, force: true }).catch(() => { });
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
await runCheck('name drift', async () => {
|
|
246
|
+
const base = await mkdtemp(join(tmpdir(), 'sp-drift-'));
|
|
247
|
+
try {
|
|
248
|
+
await mkdir(join(base, 'dir-name'));
|
|
249
|
+
await writeFile(join(base, 'dir-name', 'SKILL.md'), '---\nname: other-name\ndescription: d\n---\nbody');
|
|
250
|
+
const cat = await SkillCatalog.fromDirectory(base);
|
|
251
|
+
if (!cat.verifyIntegrity().entries[0]?.nameDrift)
|
|
252
|
+
throw new Error('nameDrift 未生效');
|
|
253
|
+
}
|
|
254
|
+
finally {
|
|
255
|
+
await rm(base, { recursive: true, force: true }).catch(() => { });
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
return results;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* 执行完整的核心规范测试套件,返回聚合体检报告(测试表面即接口)。
|
|
262
|
+
*/
|
|
263
|
+
static async verifySpecification() {
|
|
264
|
+
const [docResults, catResults] = await Promise.all([
|
|
265
|
+
SkillDocument.selfTest(),
|
|
266
|
+
SkillCatalog.selfTest(),
|
|
267
|
+
]);
|
|
268
|
+
const results = [...docResults, ...catResults];
|
|
269
|
+
const passed = results.filter((r) => r.ok).length;
|
|
270
|
+
const failed = results.length - passed;
|
|
271
|
+
return {
|
|
272
|
+
total: results.length,
|
|
273
|
+
passed,
|
|
274
|
+
failed,
|
|
275
|
+
results,
|
|
276
|
+
ok: failed === 0,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* 生成目录健康度与一致性完整体检报告(供 verify 脚本与 CI 质量门禁复用)。
|
|
281
|
+
*/
|
|
282
|
+
verifyIntegrity() {
|
|
283
|
+
const entries = Array.from(this.entriesByName.values());
|
|
284
|
+
const ok = this.duplicates.length === 0 && this.loadErrors.length === 0 && entries.every((e) => !e.nameDrift);
|
|
285
|
+
return {
|
|
286
|
+
total: entries.length,
|
|
287
|
+
entries,
|
|
288
|
+
duplicates: [...this.duplicates],
|
|
289
|
+
missingSkillMd: [...this.missingSkillMd],
|
|
290
|
+
errors: [...this.loadErrors],
|
|
291
|
+
ok,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @wenaixi/dsh-superpower — SkillDocument 深度模块
|
|
3
|
+
*
|
|
4
|
+
* 封装单个技能文档的读取、BOM/CRLF 归一化、YAML frontmatter 解析、
|
|
5
|
+
* 规范字段与调用策略校验,以及向 SkillCandidate 和 SkillDefinition 的契约映射。
|
|
6
|
+
*
|
|
7
|
+
* 核心原则:
|
|
8
|
+
* - Depth: 将大量文件 I/O、边界扫描、YAML 解析与类型收敛封装在紧凑的小接口后;
|
|
9
|
+
* - Locality: 所有 frontmatter 规则与校验逻辑内聚于此;
|
|
10
|
+
* - Test Surface: 对外暴露规范接口,成为运行时与验证脚本的共同测试表面。
|
|
11
|
+
*/
|
|
12
|
+
import type { SkillCandidate, SkillDefinition } from '@deepseek-ai/dsh-skill';
|
|
13
|
+
export interface SkillInvocationPolicy {
|
|
14
|
+
modelInvocable: boolean;
|
|
15
|
+
userInvocable: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface SpecificationTestResult {
|
|
18
|
+
name: string;
|
|
19
|
+
ok: boolean;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface SkillDocumentData {
|
|
23
|
+
name: string;
|
|
24
|
+
description: string;
|
|
25
|
+
whenToUse?: string;
|
|
26
|
+
invocation: SkillInvocationPolicy;
|
|
27
|
+
metadata?: Record<string, unknown>;
|
|
28
|
+
extra: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
export declare class SkillDocument {
|
|
31
|
+
readonly path: string;
|
|
32
|
+
readonly name: string;
|
|
33
|
+
readonly description: string;
|
|
34
|
+
readonly whenToUse?: string;
|
|
35
|
+
readonly invocation: SkillInvocationPolicy;
|
|
36
|
+
readonly metadata?: Record<string, unknown>;
|
|
37
|
+
readonly body: string;
|
|
38
|
+
readonly rawFrontmatterData: Record<string, unknown>;
|
|
39
|
+
private constructor();
|
|
40
|
+
/**
|
|
41
|
+
* 从指定文件路径异步解析 SkillDocument。
|
|
42
|
+
*/
|
|
43
|
+
static fromFile(filePath: string, signal?: AbortSignal): Promise<SkillDocument>;
|
|
44
|
+
/**
|
|
45
|
+
* 从内存中的原始 markdown 字符串直接解析(用于测试或动态构建)。
|
|
46
|
+
*/
|
|
47
|
+
static fromString(raw: string, filePath?: string): SkillDocument;
|
|
48
|
+
/**
|
|
49
|
+
* 执行 SkillDocument 核心边界契约规范自检(接口即测试表面)。
|
|
50
|
+
*/
|
|
51
|
+
static selfTest(): Promise<SpecificationTestResult[]>;
|
|
52
|
+
/**
|
|
53
|
+
* 映射为 DSH SkillCandidate 契约对象。
|
|
54
|
+
*/
|
|
55
|
+
toCandidate(providerName: string, rank: number): SkillCandidate;
|
|
56
|
+
/**
|
|
57
|
+
* 映射为 DSH SkillDefinition 契约对象。
|
|
58
|
+
*/
|
|
59
|
+
toDefinition(providerName: string): SkillDefinition;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAG7E,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,OAAO,CAAA;IACvB,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,OAAO,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,qBAAqB,CAAA;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AA+FD,qBAAa,aAAa;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAA;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAEpD,OAAO;IA6BP;;OAEG;WACU,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;IAWrF;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAa,GAAG,aAAa;IAKpE;;OAEG;WACU,QAAQ,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;IAkD3D;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc;IAiB/D;;OAEG;IACH,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe;CAepD"}
|