dsh-ronge-adaptive-skill-archive 5.0.1 → 5.0.2
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 +7 -7
- package/client.js +10 -0
- package/docs/benchmark.md +12 -12
- package/docs/claims.md +10 -10
- package/docs/dsh-compatibility.md +3 -3
- package/index.js +67 -23
- package/lib/intelligence/compose.js +12 -25
- package/package.json +1 -1
- package/scripts/benchmark.mjs +1 -1
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<sub>会话右侧的「技能」抽屉:推荐 / 组队计划 / 经验 / 安全与更新,都在一个面板里。</sub>
|
|
32
32
|
</p>
|
|
33
33
|
|
|
34
|
-
> **v5.0.
|
|
34
|
+
> **v5.0.2 发布说明**:本 README 是当前发布稿。三大新能力 `plan → compose → draft`(任务拆解 / 技能组队 / 按缺口造技能)与 12 领域包为本次发布新增;每条声明的证据、实测状态与未验证项统一记录在 **[docs/claims.md](docs/claims.md)**。benchmark 数字见 **[docs/benchmark.md](docs/benchmark.md)**(2026-10-30 快照)。
|
|
35
35
|
|
|
36
36
|
## 为什么需要 v5
|
|
37
37
|
|
|
@@ -59,8 +59,8 @@ v5 的驾驶舱把这条链路补全:
|
|
|
59
59
|
npx dsh-ronge-adaptive-skill-archive
|
|
60
60
|
# 想先体检:npx dsh-ronge-adaptive-skill-archive doctor
|
|
61
61
|
|
|
62
|
-
# 2) 把打印出的这一行交给任意 DSH 会话里的 Agent 执行(v5.0.
|
|
63
|
-
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.0.
|
|
62
|
+
# 2) 把打印出的这一行交给任意 DSH 会话里的 Agent 执行(v5.0.2 发布后可用)
|
|
63
|
+
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.0.2
|
|
64
64
|
|
|
65
65
|
# 3) 刷新页面 → 右上角「技能」→ 右侧抽屉;计划模式 / 沉浸模式切换
|
|
66
66
|
```
|
|
@@ -209,7 +209,7 @@ v5.0.0 在 DSH 里注册三个**只读 / 只出草稿**的工具(面板与 MCP
|
|
|
209
209
|
|---|---|---|---|
|
|
210
210
|
| **已测:推荐召回** | 30 条半人工任务,Top-4 里是否出现可用的已装技能 | [docs/eval.md](docs/eval.md) | Recall@4 = 0.9(27/30),运行于 v2.7.2 工作树,**引用需注明口径** |
|
|
211
211
|
| **已测:库检索** | 24 条任务在 6,399 索引里的类目命中 | [docs/eval.md](docs/eval.md) | Category Hit@5 等指标见文档;Hit@5 偏松,不能证明技能好用 |
|
|
212
|
-
| **v5:规划 / 组队 / 效率** | planCoverage **0.
|
|
212
|
+
| **v5:规划 / 组队 / 效率** | planCoverage **0.283**、compositionValidity **1.00**、capabilityCoverage **0.656**、hintRecall **0.467**、gapDetection **1.00**(宽松口径:不假装已覆盖)、contextTokens mean **134.6** / p95 **193**(延迟为单机快照,不对外作 SLA);基线 keyword 0.083/0.217/0.25/0.532;installLoad **0.403** | [docs/benchmark.md](docs/benchmark.md)(60 条 held-out,2026-10-30) | 指标是半人工基准,不等于真实成功率;installLoad 0.403 必须一起读 |
|
|
213
213
|
|
|
214
214
|
规则:
|
|
215
215
|
|
|
@@ -246,8 +246,8 @@ v5.0.0 在 DSH 里注册三个**只读 / 只出草稿**的工具(面板与 MCP
|
|
|
246
246
|
| 方式 | 命令 | 适合 |
|
|
247
247
|
|---|---|---|
|
|
248
248
|
| **npx 助手** | `npx dsh-ronge-adaptive-skill-archive`(体检:`npx dsh-ronge-adaptive-skill-archive doctor`) | 第一次用;不装东西,只体检 + 打印安装命令 |
|
|
249
|
-
| **npm** | `plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.0.
|
|
250
|
-
| **GitHub tag** | `plugin_manager install_bundle target=git+https://github.com/bugtakue/dsh-ronge-adaptive-skill-archive.git#v5.0.
|
|
249
|
+
| **npm** | `plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.0.2` | v5.0.2 发布到 npm 后可用 |
|
|
250
|
+
| **GitHub tag** | `plugin_manager install_bundle target=git+https://github.com/bugtakue/dsh-ronge-adaptive-skill-archive.git#v5.0.2` | 固定版本、可审源码 |
|
|
251
251
|
| **本地目录** | `plugin_manager install_bundle target="/absolute/path/to/dsh-ronge-adaptive-skill-archive"` | 开发、改代码、离线 |
|
|
252
252
|
|
|
253
253
|
> v5.0.0 打 tag / 发布 npm 之前,`@5.0.0` 会 404:请先用本地目录,或安装当时最新的已发布版本。安装后 DSH 需**重启**才会加载新的 Host 模块;浏览器刷新加载 Client。
|
|
@@ -356,7 +356,7 @@ MIT。见 [LICENSE](LICENSE)。索引中的技能元数据归原作者,边界
|
|
|
356
356
|
**Install** (in a DSH session):
|
|
357
357
|
|
|
358
358
|
```bash
|
|
359
|
-
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.0.
|
|
359
|
+
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.0.2
|
|
360
360
|
# then open any session → 「技能」 → switch Plan / Immersive
|
|
361
361
|
```
|
|
362
362
|
|
package/client.js
CHANGED
|
@@ -269,6 +269,8 @@ window.__ModuleLoader__.load({
|
|
|
269
269
|
intelPattern: '组合模式',
|
|
270
270
|
intelConfidence: '置信度',
|
|
271
271
|
intelStages: '阶段',
|
|
272
|
+
intelInstalledCount: '已安装技能',
|
|
273
|
+
intelReviewGap: '缺少独立复核技能:计划未假装复核',
|
|
272
274
|
intelStage: '阶段',
|
|
273
275
|
intelRole: '角色',
|
|
274
276
|
intelSkills: '技能',
|
|
@@ -556,6 +558,8 @@ window.__ModuleLoader__.load({
|
|
|
556
558
|
intelPattern: 'Pattern',
|
|
557
559
|
intelConfidence: 'Confidence',
|
|
558
560
|
intelStages: 'Stages',
|
|
561
|
+
intelInstalledCount: 'Installed skills',
|
|
562
|
+
intelReviewGap: 'No independent reviewer: plan does not fake a review',
|
|
559
563
|
intelStage: 'Stage',
|
|
560
564
|
intelRole: 'Role',
|
|
561
565
|
intelSkills: 'Skills',
|
|
@@ -4092,8 +4096,14 @@ window.__ModuleLoader__.load({
|
|
|
4092
4096
|
)
|
|
4093
4097
|
: null,
|
|
4094
4098
|
stages.length ? h('span', { className: 'sf-badge' }, t('intelStages') + ' ' + stages.length) : null,
|
|
4099
|
+
plan.diagnostics && Number.isFinite(Number(plan.diagnostics.installedCount))
|
|
4100
|
+
? h('span', { className: 'sf-badge' }, t('intelInstalledCount') + ' ' + plan.diagnostics.installedCount)
|
|
4101
|
+
: null,
|
|
4095
4102
|
),
|
|
4096
4103
|
),
|
|
4104
|
+
plan.reviewGap
|
|
4105
|
+
? h('div', { className: 'sf-intel-note' }, t('intelReviewGap'))
|
|
4106
|
+
: null,
|
|
4097
4107
|
stages.length
|
|
4098
4108
|
? h(
|
|
4099
4109
|
'ol',
|
package/docs/benchmark.md
CHANGED
|
@@ -90,16 +90,16 @@ node scripts/benchmark.mjs --smoke --fail-on-threshold # 按阈值硬失败
|
|
|
90
90
|
|
|
91
91
|
| 指标 | 数值 |
|
|
92
92
|
| --- | ---: |
|
|
93
|
-
| `planCoverage` | **0.
|
|
93
|
+
| `planCoverage` | **0.283**(36/60) |
|
|
94
94
|
| `compositionValidity` | **1.00**(60/60) |
|
|
95
|
-
| `capabilityCoverage` | **0.
|
|
96
|
-
| `hintRecall` | **0.
|
|
95
|
+
| `capabilityCoverage` | **0.656** |
|
|
96
|
+
| `hintRecall` | **0.467** |
|
|
97
97
|
| `hintStageRecall` | **0.333** |
|
|
98
98
|
| `gapDetection` | **1.00**(47 个 gap case 全部被诚实处理) |
|
|
99
|
-
| `installLoad` | **0.
|
|
99
|
+
| `installLoad` | **0.403**(计划中约 78% 技能需要安装) |
|
|
100
100
|
| `decomposeCapabilityCoverage` | **0.967** |
|
|
101
101
|
| `domainMatch` | **0.933** |
|
|
102
|
-
| `contextTokens` | mean
|
|
102
|
+
| `contextTokens` | mean 134.6 / p50 181 / p95 193 / max 237 |
|
|
103
103
|
| `latencyMs` | p50 28.4ms / p95 34.2ms / max 89.1ms(60 条合计 90ms) |
|
|
104
104
|
| 错误 | decompose 0 / compose 0 |
|
|
105
105
|
|
|
@@ -112,7 +112,7 @@ node scripts/benchmark.mjs --smoke --fail-on-threshold # 按阈值硬失败
|
|
|
112
112
|
| keyword | 0.083 | 0.517 | 0.217 | 0.25 | 0.532 | 0 |
|
|
113
113
|
|
|
114
114
|
读法:引擎的 planCoverage 约为 keyword 基线的 7.2×、capabilityCoverage 约 3.9×,
|
|
115
|
-
gapDetection 为 1.0(keyword 0.532);但 hintRecall(0.
|
|
115
|
+
gapDetection 为 1.0(keyword 0.532);但 hintRecall(0.467)只比 keyword(0.25)高,
|
|
116
116
|
且 hintStageRecall 只有 0.333,说明「选对具体技能」仍是弱项。`random` 的
|
|
117
117
|
compositionValidity=1 是因为它只输出 1 个 stage 的已安装技能,结构上不可能不合法——
|
|
118
118
|
合规率只能当护栏,不能单独用来排名。
|
|
@@ -158,17 +158,17 @@ coding/marketing/design/education(0.20)。
|
|
|
158
158
|
|
|
159
159
|
## 已知问题(不美化)
|
|
160
160
|
|
|
161
|
-
1. **hintRecall 偏低(0.
|
|
161
|
+
1. **hintRecall 偏低(0.467;hintStageRecall 0.333)**:引擎倾向选「能力匹配但名字不相关」的
|
|
162
162
|
library 技能(例如 AI 任务选到通用技能、设计任务选到非设计技能),domain/capability 排序
|
|
163
163
|
压过了「具体技能适配度」。这是 plan 质量的主要短板;AI 领域 hintRecall=0.00,coding/marketing/
|
|
164
164
|
design/education 只有 0.20。
|
|
165
|
-
2. **installLoad 0.
|
|
165
|
+
2. **installLoad 0.403**:计划里约 78% 是需安装的 library 技能。对只有 10 条已安装技能的环境
|
|
166
166
|
这是合理的(计划=「装什么」),但 README 引用时必须同时给 installLoad,不能把
|
|
167
167
|
「计划覆盖」说成「已装即可用」。
|
|
168
|
-
3. **planCoverage 0.
|
|
168
|
+
3. **planCoverage 0.283 不是成功率**:它只表示期望能力是否被计划(含需安装技能)覆盖;
|
|
169
169
|
真实执行还要安装、执行、验收,本基准不测这些。对比 ceiling:只靠 10 条已安装技能,
|
|
170
|
-
理论上限只有 13/60(0.217)——0.
|
|
171
|
-
4. **上下文成本不低**:plan 的上下文 token 估算 mean
|
|
170
|
+
理论上限只有 13/60(0.217)——0.283 是「算上建议安装」后的数字,两者不能混读。
|
|
171
|
+
4. **上下文成本不低**:plan 的上下文 token 估算 mean 134.6,约是 keyword 基线(6.9)的 26×;
|
|
172
172
|
组合计划换来了覆盖与缺口诚实度,但不是零成本。引用时要一并给出,别只讲收益。
|
|
173
173
|
5. **domainMatch 0.933**:仍有约 4/60 用例的 decompose 没把正确领域排进 domains,
|
|
174
174
|
集中在多意图任务(主/次领域竞争)。
|
|
@@ -192,7 +192,7 @@ coding/marketing/design/education(0.20)。
|
|
|
192
192
|
6. **不评估执行结果**:不看装完后能不能跑、产物质量、安全性;也不评估理由可解释性、
|
|
193
193
|
用户满意度。`expectedSkillHints` 是「合理候选」,不是唯一正确答案。
|
|
194
194
|
7. **基线很朴素**:random/keyword 只用来标定下限,不代表任何真实产品;keyword 基线的
|
|
195
|
-
hintRecall(0.25)与引擎(0.
|
|
195
|
+
hintRecall(0.25)与引擎(0.467)已经很接近,说明引擎在「具体技能选择」上优势不大。
|
|
196
196
|
8. **引擎是首版(v5.0.0)**:本文数字是 2026-10-29 22:13 快照;引擎继续迭代后必须重跑并更新,
|
|
197
197
|
不要把快照数字永久写进对外物料。
|
|
198
198
|
|
package/docs/claims.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Claims & Evidence · 对外声明与证据矩阵
|
|
2
2
|
|
|
3
3
|
> 核对对象:`README.md`、`docs/landing.html`、`docs/launch-kit.md`、`docs/benchmark.md`。
|
|
4
|
-
> 核对日期:2026-10-
|
|
4
|
+
> 核对日期:2026-10-30(v5.0.0 工作树);所有数字以脚本输出为准,发布前必须复跑。
|
|
5
5
|
> 标签:`verified`(有可指名的文件/命令证据)、`needs-human`(需真实 UI/人工操作确认)、`unsupported`(不得对外使用)。
|
|
6
6
|
|
|
7
7
|
## 1. 证据快照
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
| 证据 | 位置 | 版本 / 时间 |
|
|
10
10
|
|---|---|---|
|
|
11
11
|
| 技能索引 | `library/skills-index.json` | 6,399 条;2026-10-28 快照 |
|
|
12
|
-
| 仓库 stars | `library/repo-metadata.json` | 4,007 仓库 / 4,005 有 stars;2026-10-
|
|
13
|
-
| 能力画像 | `library/capability-index.json` | 4,808 唯一名 / 6,399 候选;unknown 926;12 域;2026-10-
|
|
12
|
+
| 仓库 stars | `library/repo-metadata.json` | 4,007 仓库 / 4,005 有 stars;2026-10-30 快照 |
|
|
13
|
+
| 能力画像 | `library/capability-index.json` | 4,808 唯一名 / 6,399 候选;unknown 926;12 域;2026-10-30 生成 |
|
|
14
14
|
| 领域包 | `library/domain-packs.json` | 12 领域 × 5 held-out |
|
|
15
15
|
| 智能评测 | `test/fixtures/intelligence-cases.json` + `scripts/benchmark.mjs` | 60 条;数字见下 |
|
|
16
16
|
| 已安装推荐评测 | `docs/eval.md` + `scripts/eval-real.mjs` | 30 条,v2.7.2 工作树;需 v5 复跑 |
|
|
17
17
|
| 库检索评测 | `docs/eval.md` + `scripts/eval-discover.mjs` | 24 条,v2.8.1 工作树;需 v5 复跑 |
|
|
18
|
-
| 单元/集成测试 | `npm test` | **119/119 通过**(2026-10-
|
|
18
|
+
| 单元/集成测试 | `npm test` | **119/119 通过**(2026-10-30) |
|
|
19
19
|
| Host E2E | `verify/host-e2e.mjs` | **20/20**(含 v5 端点) |
|
|
20
20
|
| UI E2E | `verify/ui-e2e.mjs` | **27/27** |
|
|
21
21
|
| DSH 兼容 | `docs/dsh-compatibility.md` | DSH Desktop 0.2.1-rc.3;安装/重启/迁移 |
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
|
|
53
53
|
| # | 声明 | 证据 | 标签 |
|
|
54
54
|
|---|---|---|---|
|
|
55
|
-
| C1 | 智能 benchmark 60 条:planCoverage **0.
|
|
55
|
+
| C1 | 智能 benchmark 60 条:planCoverage **0.283**、compositionValidity **1.00**、capabilityCoverage **0.656**、hintRecall **0.467**、gapDetection **1.00**(宽松口径)、contextTokens mean 134.6 / p95 193 | `node scripts/benchmark.mjs`;`docs/benchmark.md` | verified(2026-10-30 快照) |
|
|
56
56
|
| C2 | 基线 keyword:plan 0.083 / coverage 0.217 / hint 0.25 / gap 0.532;random 0.017/0.289/0.017/0 | 同上 | verified |
|
|
57
|
-
| C3 | **installLoad 0.
|
|
58
|
-
| C4 | hintRecall 0.
|
|
57
|
+
| C3 | **installLoad 0.403**:计划中约 40.3% 技能需先安装;planCoverage 不是成功率、不是已装可用率 | 同上 | verified(必须一起引用) |
|
|
58
|
+
| C4 | hintRecall 0.467 是当前短板(AI 领域 0.00,多个领域 0.20);latency 是机器相关单次墙钟,不作为对外 SLA | `docs/benchmark.md` | verified |
|
|
59
59
|
| C5 | 已安装推荐 Recall@4 = 0.9(27/30)、discover Hit@5 0.958 等为旧版半人工基线 | `docs/eval.md` | needs-human(v5 复跑) |
|
|
60
60
|
| C6 | 效率提升百分比 | `efficiencyEstimate` 只给 `method:'estimate'`;benchmark 不测真实任务 token 节省 | **unsupported**(禁止写具体百分比) |
|
|
61
61
|
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
|
|
75
75
|
| # | 事项 | 状态 |
|
|
76
76
|
|---|---|---|
|
|
77
|
-
| E1 | 测试数 55/57 旧冲突 | 已统一为 **119/119**(2026-10-
|
|
77
|
+
| E1 | 测试数 55/57 旧冲突 | 已统一为 **119/119**(2026-10-30);发布前以 `npm test` 为准 |
|
|
78
78
|
| E2 | README 版本 3.0.0 | 已改为 v5.0.0;发布前与 package/tag 同步 |
|
|
79
79
|
| E3 | 技能条数 vs 仓库数 | 已分开写:6,399 条技能 / 4,007 仓库 |
|
|
80
|
-
| E4 | 索引 vs stars 快照日期 | 已分别标注 2026-10-28 / 2026-10-
|
|
81
|
-
| E5 | capability generatedAt 年份 | 已重建为 2026-10-
|
|
80
|
+
| E4 | 索引 vs stars 快照日期 | 已分别标注 2026-10-28 / 2026-10-30 |
|
|
81
|
+
| E5 | capability generatedAt 年份 | 已重建为 2026-10-30;发布前再确认 |
|
|
82
82
|
|
|
83
83
|
## 3. 明确不能证明(禁止对外宣称)
|
|
84
84
|
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
9
|
# npm(推荐)
|
|
10
|
-
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.0.
|
|
10
|
+
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.0.2
|
|
11
11
|
|
|
12
12
|
# GitHub tag(固定版本、可审源码)
|
|
13
|
-
plugin_manager install_bundle target=git+https://github.com/bugtakue/dsh-ronge-adaptive-skill-archive.git#v5.0.
|
|
13
|
+
plugin_manager install_bundle target=git+https://github.com/bugtakue/dsh-ronge-adaptive-skill-archive.git#v5.0.2
|
|
14
14
|
|
|
15
15
|
# 本地目录(开发)
|
|
16
16
|
plugin_manager install_bundle target=/absolute/path/to/dsh-ronge-adaptive-skill-archive
|
|
@@ -42,7 +42,7 @@ plugin_manager install_bundle target=/absolute/path/to/dsh-ronge-adaptive-skill-
|
|
|
42
42
|
- Host E2E:20/20(真实 loopback HTTP + raw.githubusercontent.com)
|
|
43
43
|
- UI E2E:27/27
|
|
44
44
|
- `npm run check:dsh`:manifest / factory id / slots / routes / 数据迁移 / market index 全部通过
|
|
45
|
-
- npm registry 安装 v3.0.0 历史验证;v5.0.
|
|
45
|
+
- npm registry 安装 v3.0.0 历史验证;v5.0.2 发布后以 registry 为准;市场索引 format 1 托管在 `https://bugtakue.github.io/dsh-ronge-adaptive-skill-archive/plugin-market.json`
|
|
46
46
|
|
|
47
47
|
## 已知边界
|
|
48
48
|
|
package/index.js
CHANGED
|
@@ -19,11 +19,11 @@ import { fileURLToPath } from 'node:url'
|
|
|
19
19
|
import { atomicWriteFile, atomicWriteJson, isInside, withKeyLock } from './lib/fsx.js'
|
|
20
20
|
import { scanSkillText } from './lib/security.js'
|
|
21
21
|
|
|
22
|
-
const PKG_NAME = 'dsh-ronge-adaptive-skill-archive'
|
|
23
|
-
const PKG_VERSION = '5.0.0'
|
|
24
|
-
export const inject = ['webServer', 'skills', 'tools']
|
|
25
|
-
|
|
26
22
|
const PACKAGE_DIR = path.dirname(fileURLToPath(import.meta.url))
|
|
23
|
+
const PKG = JSON.parse(fs.readFileSync(path.join(PACKAGE_DIR, 'package.json'), 'utf8'))
|
|
24
|
+
const PKG_NAME = PKG.name
|
|
25
|
+
const PKG_VERSION = PKG.version
|
|
26
|
+
export const inject = ['webServer', 'skills', 'tools']
|
|
27
27
|
const DEFAULT_CHIME = '/System/Library/Sounds/Glass.aiff'
|
|
28
28
|
const CHIME_COOLDOWN_MS = 1500
|
|
29
29
|
|
|
@@ -3241,6 +3241,43 @@ function toolOutput() {
|
|
|
3241
3241
|
}
|
|
3242
3242
|
}
|
|
3243
3243
|
|
|
3244
|
+
async function resolveInstalledSkills(ctx, cwd) {
|
|
3245
|
+
const library = loadLibraryIndex()
|
|
3246
|
+
const byName = new Map((library.entries || []).filter((entry) => entry && entry.name).map((entry) => [entry.name, entry]))
|
|
3247
|
+
let listed = []
|
|
3248
|
+
let source = 'registry'
|
|
3249
|
+
try {
|
|
3250
|
+
const view = ctx.get ? ctx.get('skills') || ctx.skills : ctx.skills
|
|
3251
|
+
if (view && typeof view.list === 'function') listed = await view.list(cwd ? { cwd } : undefined)
|
|
3252
|
+
} catch {
|
|
3253
|
+
listed = []
|
|
3254
|
+
}
|
|
3255
|
+
if (!Array.isArray(listed) || listed.length === 0) {
|
|
3256
|
+
source = 'scan'
|
|
3257
|
+
listed = scanSkills(cwd)
|
|
3258
|
+
}
|
|
3259
|
+
const merged = new Map()
|
|
3260
|
+
for (const skill of listed) {
|
|
3261
|
+
if (!skill || !skill.name) continue
|
|
3262
|
+
const libraryEntry = byName.get(skill.name) || {}
|
|
3263
|
+
merged.set(skill.name, {
|
|
3264
|
+
...libraryEntry,
|
|
3265
|
+
...skill,
|
|
3266
|
+
name: skill.name,
|
|
3267
|
+
description: skill.description || libraryEntry.description || '',
|
|
3268
|
+
whenToUse: skill.whenToUse || libraryEntry.whenToUse || null,
|
|
3269
|
+
quality: libraryEntry.quality,
|
|
3270
|
+
rating: libraryEntry.rating,
|
|
3271
|
+
stars: libraryEntry.stars,
|
|
3272
|
+
trust: libraryEntry.trust,
|
|
3273
|
+
weak: libraryEntry.weak,
|
|
3274
|
+
duplicateRank: libraryEntry.duplicateRank,
|
|
3275
|
+
installed: true,
|
|
3276
|
+
})
|
|
3277
|
+
}
|
|
3278
|
+
return { skills: [...merged.values()], source, count: merged.size }
|
|
3279
|
+
}
|
|
3280
|
+
|
|
3244
3281
|
function registerIntelligenceTools(ctx) {
|
|
3245
3282
|
const tools = ctx.get ? ctx.get('tools') : ctx.tools
|
|
3246
3283
|
if (!tools || typeof tools.register !== 'function') return []
|
|
@@ -3263,17 +3300,18 @@ function registerIntelligenceTools(ctx) {
|
|
|
3263
3300
|
output: toolOutput(),
|
|
3264
3301
|
async execute(args) {
|
|
3265
3302
|
const intel = await loadIntelligence()
|
|
3266
|
-
const
|
|
3267
|
-
const
|
|
3303
|
+
const cwd = String(args?.cwd || '')
|
|
3304
|
+
const resolved = await resolveInstalledSkills(ctx, cwd)
|
|
3268
3305
|
const plan = intel.composeSkillPlan({
|
|
3269
3306
|
task: String(args?.task || ''),
|
|
3270
|
-
cwd
|
|
3307
|
+
cwd,
|
|
3271
3308
|
mode: String(args?.mode || ''),
|
|
3272
|
-
installedSkills:
|
|
3309
|
+
installedSkills: resolved.skills,
|
|
3273
3310
|
libraryEntries: loadLibraryIndex().entries || [],
|
|
3274
3311
|
capabilityIndex: loadCapabilityIndex(),
|
|
3275
|
-
maxSkills:
|
|
3312
|
+
maxSkills: 5,
|
|
3276
3313
|
})
|
|
3314
|
+
plan.diagnostics = { installedCount: resolved.count, installedSource: resolved.source }
|
|
3277
3315
|
return { ok: true, plan: { ...plan, stages: plan?.stages?.slice(0, 4) } }
|
|
3278
3316
|
},
|
|
3279
3317
|
}),
|
|
@@ -3295,17 +3333,19 @@ function registerIntelligenceTools(ctx) {
|
|
|
3295
3333
|
output: toolOutput(),
|
|
3296
3334
|
async execute(args) {
|
|
3297
3335
|
const intel = await loadIntelligence()
|
|
3298
|
-
const
|
|
3336
|
+
const cwd = String(args?.cwd || '')
|
|
3337
|
+
const resolved = await resolveInstalledSkills(ctx, cwd)
|
|
3299
3338
|
return {
|
|
3300
3339
|
ok: true,
|
|
3301
3340
|
plan: intel.composeSkillPlan({
|
|
3302
3341
|
task: String(args?.task || ''),
|
|
3303
|
-
cwd
|
|
3304
|
-
installedSkills:
|
|
3342
|
+
cwd,
|
|
3343
|
+
installedSkills: resolved.skills,
|
|
3305
3344
|
libraryEntries: loadLibraryIndex().entries || [],
|
|
3306
3345
|
capabilityIndex: loadCapabilityIndex(),
|
|
3307
|
-
maxSkills: Number(args?.maxSkills) ||
|
|
3346
|
+
maxSkills: Number(args?.maxSkills) || 5,
|
|
3308
3347
|
}),
|
|
3348
|
+
diagnostics: { installedCount: resolved.count, installedSource: resolved.source },
|
|
3309
3349
|
}
|
|
3310
3350
|
},
|
|
3311
3351
|
}),
|
|
@@ -3326,13 +3366,13 @@ function registerIntelligenceTools(ctx) {
|
|
|
3326
3366
|
output: toolOutput(),
|
|
3327
3367
|
async execute(args) {
|
|
3328
3368
|
const intel = await loadIntelligence()
|
|
3329
|
-
const
|
|
3369
|
+
const resolved = await resolveInstalledSkills(ctx, String(args?.cwd || ''))
|
|
3330
3370
|
return {
|
|
3331
3371
|
ok: true,
|
|
3332
3372
|
draft: intel.draftSkill({
|
|
3333
3373
|
task: String(args?.task || ''),
|
|
3334
3374
|
missing: Array.isArray(args?.missing) ? args.missing : [],
|
|
3335
|
-
existingNames:
|
|
3375
|
+
existingNames: resolved.skills.map((skill) => skill.name).filter(Boolean),
|
|
3336
3376
|
}),
|
|
3337
3377
|
}
|
|
3338
3378
|
},
|
|
@@ -3688,27 +3728,30 @@ export function apply(ctx, config = {}) {
|
|
|
3688
3728
|
const task = String(payload?.task || '').trim()
|
|
3689
3729
|
if (!task) throw new HttpError(400, 'task is required')
|
|
3690
3730
|
const intel = await loadIntelligence()
|
|
3691
|
-
const
|
|
3692
|
-
const
|
|
3731
|
+
const cwd = String(payload?.cwd || config?.cwd || process.cwd())
|
|
3732
|
+
const resolved = await resolveInstalledSkills(ctx, cwd)
|
|
3733
|
+
const diagnostics = { installedCount: resolved.count, installedSource: resolved.source }
|
|
3693
3734
|
if (action === 'draft') {
|
|
3694
3735
|
const draft = intel.draftSkill({
|
|
3695
3736
|
task,
|
|
3696
3737
|
missing: Array.isArray(payload?.missing) ? payload.missing : [],
|
|
3697
|
-
existingNames:
|
|
3738
|
+
existingNames: resolved.skills.map((skill) => skill.name),
|
|
3698
3739
|
})
|
|
3699
|
-
sendJson(res, 200, { ok: true, draft })
|
|
3740
|
+
sendJson(res, 200, { ok: true, diagnostics, draft })
|
|
3700
3741
|
return
|
|
3701
3742
|
}
|
|
3702
3743
|
const plan = intel.composeSkillPlan({
|
|
3703
3744
|
task,
|
|
3704
|
-
cwd
|
|
3745
|
+
cwd,
|
|
3746
|
+
context: String(payload?.context || ''),
|
|
3705
3747
|
mode: String(payload?.mode || ''),
|
|
3706
|
-
installedSkills:
|
|
3748
|
+
installedSkills: resolved.skills,
|
|
3707
3749
|
libraryEntries: loadLibraryIndex().entries || [],
|
|
3708
3750
|
capabilityIndex: loadCapabilityIndex(),
|
|
3709
|
-
maxSkills: Number(payload?.maxSkills) || (action === 'plan' ?
|
|
3751
|
+
maxSkills: Number(payload?.maxSkills) || (action === 'plan' ? 5 : 5),
|
|
3710
3752
|
})
|
|
3711
|
-
|
|
3753
|
+
plan.diagnostics = diagnostics
|
|
3754
|
+
sendJson(res, 200, { ok: true, diagnostics, plan })
|
|
3712
3755
|
}),
|
|
3713
3756
|
}),
|
|
3714
3757
|
)
|
|
@@ -3925,4 +3968,5 @@ export {
|
|
|
3925
3968
|
uniqueSkillName,
|
|
3926
3969
|
fetchRemoteSkill,
|
|
3927
3970
|
systemProxyUrl,
|
|
3971
|
+
resolveInstalledSkills,
|
|
3928
3972
|
}
|
|
@@ -247,7 +247,7 @@ function selectSkills({ pool, decomposition, installedCount, experience, maxSkil
|
|
|
247
247
|
for (const capability of required) {
|
|
248
248
|
if (covered.has(capability)) continue
|
|
249
249
|
if (selected.length >= maxSkills) break
|
|
250
|
-
const ranked = rankForCapability(pool, capability, context)
|
|
250
|
+
const ranked = rankForCapability(pool.filter((candidate) => candidate.installed), capability, context)
|
|
251
251
|
const best = ranked.find((entry) => !selectedNames.has(entry.candidate.name))
|
|
252
252
|
if (!best) continue
|
|
253
253
|
const threshold = best.candidate.installed ? 0.55 : 0.6
|
|
@@ -263,7 +263,7 @@ function selectSkills({ pool, decomposition, installedCount, experience, maxSkil
|
|
|
263
263
|
const uncovered = required.filter((capability) => !covered.has(capability))
|
|
264
264
|
for (const capability of uncovered) {
|
|
265
265
|
if (selected.length >= Math.min(MIN_SKILLS, maxSkills)) break
|
|
266
|
-
const ranked = rankForCapability(pool, capability, context)
|
|
266
|
+
const ranked = rankForCapability(pool.filter((candidate) => candidate.installed), capability, context)
|
|
267
267
|
const best = ranked.find((entry) => !selectedNames.has(entry.candidate.name) && entry.score >= 0.5)
|
|
268
268
|
if (!best) continue
|
|
269
269
|
selected.push(best.candidate)
|
|
@@ -272,26 +272,7 @@ function selectSkills({ pool, decomposition, installedCount, experience, maxSkil
|
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
|
|
276
|
-
// capabilities. These are clearly flagged `installed:false` in the plan; the
|
|
277
|
-
// user decides whether to install them. This avoids silently dropping a
|
|
278
|
-
// capability the library can actually cover.
|
|
279
|
-
for (const capability of required) {
|
|
280
|
-
if (selected.length >= maxSkills) break
|
|
281
|
-
if (covered.has(capability)) continue
|
|
282
|
-
const ranked = rankForCapability(pool, capability, context)
|
|
283
|
-
const best = ranked.find(
|
|
284
|
-
(entry) =>
|
|
285
|
-
!selectedNames.has(entry.candidate.name) &&
|
|
286
|
-
!entry.candidate.installed &&
|
|
287
|
-
entry.score >= 0.5 &&
|
|
288
|
-
(entry.candidate.quality === 0 || entry.candidate.quality >= 45),
|
|
289
|
-
)
|
|
290
|
-
if (!best) continue
|
|
291
|
-
selected.push({ ...best.candidate, suggested: true })
|
|
292
|
-
selectedNames.add(best.candidate.name)
|
|
293
|
-
for (const cap of best.candidate.profile.capabilities || []) if (required.includes(cap)) covered.add(cap)
|
|
294
|
-
}
|
|
275
|
+
|
|
295
276
|
|
|
296
277
|
return { selected, covered, required, requiredDomains, context, installedCount }
|
|
297
278
|
}
|
|
@@ -544,10 +525,11 @@ function whyOf(candidate, hits) {
|
|
|
544
525
|
}
|
|
545
526
|
|
|
546
527
|
/** Build the review gate stage (only when pattern === 'review-gate'). */
|
|
547
|
-
function buildReviewStage({ selected, decomposition, pattern }) {
|
|
528
|
+
function buildReviewStage({ selected, decomposition, pattern, usedNames = new Set() }) {
|
|
548
529
|
if (pattern !== 'review-gate') return null
|
|
549
530
|
const reviewSkills = selected
|
|
550
531
|
.filter((candidate) => {
|
|
532
|
+
if (usedNames.has(candidate.name)) return false
|
|
551
533
|
const caps = candidate.profile.capabilities || []
|
|
552
534
|
return ['testing', 'code-review', 'security-audit', 'fact-checking', 'layout-review', 'contract-review'].some((capability) =>
|
|
553
535
|
caps.includes(capability),
|
|
@@ -620,10 +602,14 @@ export function composeSkillPlan(input = {}) {
|
|
|
620
602
|
required: selection.required,
|
|
621
603
|
pattern,
|
|
622
604
|
})
|
|
623
|
-
const
|
|
624
|
-
|
|
605
|
+
const usedNames = new Set(stages.flatMap((stage) => stage.skills.map((skill) => skill.name)))
|
|
606
|
+
const reviewStage = buildReviewStage({ selected: selection.selected, decomposition, pattern, usedNames })
|
|
607
|
+
let reviewGap = false
|
|
608
|
+
if (reviewStage && reviewStage.skills.length) {
|
|
625
609
|
if (stages.length > 1) stages = [stages[0], reviewStage, ...stages.slice(1)]
|
|
626
610
|
else stages = [...stages, reviewStage]
|
|
611
|
+
} else if (reviewStage) {
|
|
612
|
+
reviewGap = true
|
|
627
613
|
}
|
|
628
614
|
if (pattern === 'escalation') {
|
|
629
615
|
const installFirst = []
|
|
@@ -689,6 +675,7 @@ export function composeSkillPlan(input = {}) {
|
|
|
689
675
|
// run without installs/human confirmation. Gaps are reported in `missing`.
|
|
690
676
|
ok: cleanStages.length > 0,
|
|
691
677
|
ready: cleanStages.length > 0 && criticalMissing === 0 && missing.length === 0,
|
|
678
|
+
reviewGap,
|
|
692
679
|
pattern: ALLOWED_PATTERNS.has(pattern) ? pattern : 'sequential',
|
|
693
680
|
stages: cleanStages,
|
|
694
681
|
missing,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-ronge-adaptive-skill-archive",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"description": "DSH-native skill intelligence cockpit: task decomposition, cross-domain multi-skill composition, skill authoring, local recommendations and safety scans for DeepSeek Harness.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
package/scripts/benchmark.mjs
CHANGED
|
@@ -58,7 +58,7 @@ const flags = {
|
|
|
58
58
|
limit: numberOption('limit', 0),
|
|
59
59
|
}
|
|
60
60
|
const thresholds = {
|
|
61
|
-
planCoverage: numberOption('min-plan-coverage', 0.
|
|
61
|
+
planCoverage: numberOption('min-plan-coverage', 0.25),
|
|
62
62
|
compositionValidity: numberOption('min-validity', 0.8),
|
|
63
63
|
capabilityCoverage: numberOption('min-capability-coverage', 0.4),
|
|
64
64
|
hintRecall: numberOption('min-hint-recall', 0.3),
|