@daweifu/capability-menu 0.1.0 → 0.1.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/README.md +88 -122
- package/cordis.patch.yml +11 -3
- package/lib/client.d.ts +156 -0
- package/lib/client.d.ts.map +1 -0
- package/lib/client.js +6290 -0
- package/lib/index.js +27 -13
- package/lib/index.js.map +1 -0
- package/lib/invariant.js.map +1 -0
- package/lib/invoke.js +2 -2
- package/lib/invoke.js.map +1 -0
- package/lib/policy.js +4 -4
- package/lib/policy.js.map +1 -0
- package/lib/registry.js +1 -1
- package/lib/registry.js.map +1 -0
- package/lib/search.js +3 -3
- package/lib/search.js.map +1 -0
- package/lib/server/remote.js +111 -0
- package/lib/server/remote.js.map +1 -0
- package/lib/types/index.d.ts +25 -13
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/invariant.d.ts.map +1 -0
- package/lib/types/invoke.d.ts.map +1 -0
- package/lib/types/policy.d.ts +2 -2
- package/lib/types/policy.d.ts.map +1 -0
- package/lib/types/registry.d.ts +3 -3
- package/lib/types/registry.d.ts.map +1 -0
- package/lib/types/search.d.ts.map +1 -0
- package/lib/types/server/remote.d.ts +51 -0
- package/lib/types/server/remote.d.ts.map +1 -0
- package/package.json +56 -24
package/README.md
CHANGED
|
@@ -1,45 +1,76 @@
|
|
|
1
1
|
<h1 align="center">dsh-capability-menu</h1>
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<strong>为 DeepSeek Harness
|
|
5
|
-
海量tools/skills也不会塞满一次请求, 节省token和上下文<br>
|
|
6
|
-
所有能力分为exposed/progressive/blocked三级管理暴露程度和执行方式
|
|
4
|
+
<strong>为 DeepSeek Harness 提供统一的能力菜单管理 Tools 和 Skills 的暴露水平 (上下文占用大小) 和执行方式</strong>
|
|
7
5
|
</p>
|
|
8
6
|
|
|
9
7
|
<p align="center">
|
|
10
|
-
<a href="https://www.npmjs.com/package/@daweifu/capability-menu"><img src="https://img.shields.io/npm/v/@daweifu/capability-menu.svg?style=flat-square&color=
|
|
8
|
+
<a href="https://www.npmjs.com/package/@daweifu/capability-menu"><img src="https://img.shields.io/npm/v/@daweifu/capability-menu.svg?style=flat-square&color=0969DA&labelColor=161b22&logo=npm&logoColor=white" alt="npm version"/></a>
|
|
11
9
|
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-2EA44F?style=flat-square&labelColor=161b22" alt="license"/></a>
|
|
12
10
|
<a href="https://github.com/PKUfudawei/dsh-capability-menu"><img src="https://img.shields.io/github/stars/PKUfudawei/dsh-capability-menu.svg?style=flat-square&color=dbab09&labelColor=161b22&logo=github&logoColor=white" alt="GitHub stars"/></a>
|
|
13
|
-
<a href="https://github.com/
|
|
14
|
-
<a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/
|
|
11
|
+
<a href="https://github.com/cordiverse/cordis"><img src="https://img.shields.io/badge/stack-Cordis%20bundle-7FBDF1.svg?style=flat-square&labelColor=161b22&logo=cardano&logoColor=white" alt="Cordis bundle"/></a>
|
|
12
|
+
<a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/DeepSeek%20Harness-0.1.1--rc.1-4D6BFE.svg?style=flat-square&labelColor=161b22&logo=deepseek&logoColor=white" alt="DeepSeek Harness 0.1.1-rc.1"/></a>
|
|
15
13
|
<a href="https://github.com/PKUfudawei/dsh-capability-menu/actions"><img src="https://img.shields.io/github/actions/workflow/status/PKUfudawei/dsh-capability-menu/ci.yml?branch=master&label=CI&style=flat-square&labelColor=161b22&logo=github&logoColor=white" alt="CI"/></a>
|
|
16
14
|
</p>
|
|
17
15
|
|
|
18
16
|
<br/>
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
## 目录
|
|
19
|
+
|
|
20
|
+
- [能力菜单](#能力菜单)
|
|
21
|
+
- [快速安装](#快速安装)
|
|
22
|
+
- [能力模型](#能力模型)
|
|
23
|
+
- [暴露策略](#暴露策略)
|
|
24
|
+
- [配置文件](#配置文件)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
dsh-capability-menu 是 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的一个 Cordis 插件,为海量 MCP tools / skills 建立统一能力目录(`ctx.capability`),并以**常驻 / 按需 / 禁用**三档管理暴露程度和执行方式——随时调整 agent 的能力边界,避免海量 tools/skills 塞满一次请求、节省 token 和上下文:
|
|
29
|
+
|
|
30
|
+
- **统一能力目录**:编目所有 MCP 工具与 Skill,模型经 `meta_search` 检索、`meta_invoke` 执行。
|
|
31
|
+
- **三档能力策略**:常驻 = 高频能力随叫随到;按需 = 低频能力归档进目录、用到才翻出来;禁用 = 明确禁止。这是你配置的驻留策略,不是按使用次数自动统计的标签。
|
|
32
|
+
- **可视化配置**:「能力菜单」设置 tab(MCP tools / Skills 两栏,分类可点击循环切换),调整即时生效。
|
|
33
|
+
- **零侵入**:不改上游源码,经 Cordis 插件机制与 Harness 组合进同一运行时。
|
|
34
|
+
|
|
35
|
+
## 能力菜单
|
|
36
|
+
|
|
37
|
+
<p align="center">
|
|
38
|
+
<img src="assets/screenshot-mcp-tools.png" alt="MCP tools tab" width="45%"/>
|
|
39
|
+
<img src="assets/screenshot-skills.png" alt="Skills tab" width="45%"/>
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
安装后,「设置 / 通用设置」下出现「能力菜单」tab(位于「模型」与「插件」之间),用于可视化查看和调整暴露策略,改动即时生效、无需重启:
|
|
43
|
+
|
|
44
|
+
- **两栏**:MCP 工具(按 server 分组、可折叠)与 Skills。
|
|
45
|
+
- **三态圆点 + 统计**:每个能力带一个分类圆点(实心 = 常驻、半实心 = 按需、空心 = 禁用),栏顶部显示各档数量统计。
|
|
46
|
+
- **点击循环切换**:点击能力旁的圆点或分类计数即可循环切换分类;MCP 工具还可以点击整行查看模型侧工具定义(name / description / parameters)。
|
|
47
|
+
- **Skills 目录浏览**:展开某个 skill 可浏览其文件目录,点击文件预览 SKILL.md 等正文内容。
|
|
21
48
|
|
|
22
49
|
## 快速安装
|
|
23
50
|
|
|
24
|
-
|
|
51
|
+
前置:已安装 Node.js 与 dsh CLI(`dsh plugin` 内部会转发给 pnpm)。
|
|
25
52
|
|
|
26
|
-
|
|
27
|
-
cd dsh-capability-menu
|
|
28
|
-
npm run build # tsc 产出 lib/(registry/search/invoke/policy/invariant/index)
|
|
29
|
-
pnpm pack # 生成 daweifu-capability-menu-0.1.0.tgz
|
|
30
|
-
```
|
|
53
|
+
### 从 npm 安装(推荐)
|
|
31
54
|
|
|
32
|
-
|
|
55
|
+
单包同时提供服务端插件与前端「能力菜单」tab,装完即可在「设置 / 通用设置」下看到:
|
|
33
56
|
|
|
34
|
-
```
|
|
35
|
-
dsh plugin --profile web add
|
|
57
|
+
```sh
|
|
58
|
+
dsh plugin --profile web add @daweifu/capability-menu
|
|
36
59
|
```
|
|
37
60
|
|
|
38
|
-
|
|
61
|
+
### 从源码安装
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
git clone https://github.com/PKUfudawei/dsh-capability-menu.git
|
|
65
|
+
cd dsh-capability-menu
|
|
66
|
+
pnpm install # prepare 脚本自动构建 lib/(服务端)与 lib/client.js(前端)
|
|
67
|
+
|
|
68
|
+
dsh plugin --profile web add ./dsh-capability-menu
|
|
69
|
+
```
|
|
39
70
|
|
|
40
|
-
|
|
71
|
+
### 验证安装
|
|
41
72
|
|
|
42
|
-
```
|
|
73
|
+
```sh
|
|
43
74
|
dsh --profile web --dump-config | grep -E 'capability-menu'
|
|
44
75
|
```
|
|
45
76
|
|
|
@@ -53,25 +84,25 @@ dsh --profile web --dump-config | grep -E 'capability-menu'
|
|
|
53
84
|
name: '@daweifu/capability-menu/invoke'
|
|
54
85
|
- id: capability-menu-policy
|
|
55
86
|
name: '@daweifu/capability-menu/policy'
|
|
87
|
+
- id: capability-menu
|
|
88
|
+
name: '@daweifu/capability-menu'
|
|
56
89
|
```
|
|
57
90
|
|
|
58
|
-
|
|
91
|
+
### 卸载
|
|
59
92
|
|
|
60
|
-
```
|
|
93
|
+
```sh
|
|
61
94
|
dsh plugin --profile web remove @daweifu/capability-menu
|
|
62
95
|
```
|
|
63
96
|
|
|
64
97
|
## 能力模型
|
|
65
98
|
|
|
66
|
-
Capability
|
|
99
|
+
Capability 是本插件引入的上位概念:Tool / Skill 是不同类型的 capability。
|
|
67
100
|
|
|
68
101
|
| kind | 对 Agent 提供 | action | 备注 |
|
|
69
102
|
| --- | --- | --- | --- |
|
|
70
103
|
| `tool` | 执行一个动作(MCP 工具) | `execute` | 由 `ctx.tools` 索引 |
|
|
71
104
|
| `skill` | 某类任务的方法/流程/知识 | `load` | 由 `ctx.skills` 索引 |
|
|
72
105
|
|
|
73
|
-
> `execute` / `load` 是 capability 对外声明的**规范 action**(`CapabilityAction = 'execute' | 'load'`)。tool 的 `execute` 在底层由 `ctx.tools.execute` 走完整工具管线执行;skill 的 `load` 加载方法/流程正文。当前版本(`0.1.0`)只有这两种 kind 与两种 action。
|
|
74
|
-
|
|
75
106
|
模型获得两个元工具:
|
|
76
107
|
|
|
77
108
|
| 工具 | 作用 | 对应 entry |
|
|
@@ -79,11 +110,7 @@ Capability 是上位概念,Tool / Skill 是不同类型的 capability,不是
|
|
|
79
110
|
| `meta_search` | 检索能力目录(Tool / Skill),list/detail 双模式 | `@daweifu/capability-menu/search` |
|
|
80
111
|
| `meta_invoke` | 统一执行面:Tool 真执行(走完整 `ctx.tools` 管线)+ Skill 加载 | `@daweifu/capability-menu/invoke` |
|
|
81
112
|
|
|
82
|
-
|
|
83
|
-
>
|
|
84
|
-
> 边界:非 `mcp__` 前缀的原生工具(`bash` / `read` / `write` / `edit` / `read_image` / `glob` / `grep` 等)**不进 registry**——不被 `meta_search` 编目、不被 `meta_invoke` 派发、也不在能力管理(`classifyAll`)枚举中。它们只受投影链(`system-prompt/assemble` 对 `assembly.tools` 的裁剪)影响可见性;且因不可 `meta_invoke`,一旦被投影掉就真的不可调用,所以请保留在 `tools.exposed` 保活(见下方配置示例;默认即 Exposed,但若被 `progressive`/`blocked` 通配规则覆盖则不可调用)。
|
|
85
|
-
|
|
86
|
-
## 核心:Exposed / Progressive / Blocked 三档能力策略
|
|
113
|
+
## 暴露策略
|
|
87
114
|
|
|
88
115
|
所有能力(Tool 与 Skill)按 **暴露程度**(模型在上下文中看到什么)与 **执行方式** 分为三档:
|
|
89
116
|
|
|
@@ -91,116 +118,55 @@ Capability 是上位概念,Tool / Skill 是不同类型的 capability,不是
|
|
|
91
118
|
|
|
92
119
|
| 档位 | 能力 | 暴露方式(模型视野) | 发现 | 执行方式 |
|
|
93
120
|
| --- | --- | --- | --- | --- |
|
|
94
|
-
|
|
|
121
|
+
| **常驻** | tool | 完整 schema 进 `assembly.tools` → 模型请求 `tools` payload,每步可见 | 无需发现(已常驻) | 模型直接调用,运行时走完整 `ctx.tools` 管线 |
|
|
95
122
|
| | skill | 名字+描述进 `<available_skills>` 目录(正文不在目录) | 无需发现(已常驻) | `skill` 工具按需加载正文(渐进加载) |
|
|
96
|
-
|
|
|
123
|
+
| **按需** | tool | 不进 payload(零上下文成本) | `meta_search` list 返回 name+summary | `meta_invoke` 执行(走 `ctx.tools.execute`,管线完整);或 detail 拿 schema 后直接调 |
|
|
97
124
|
| | skill | 不进 `<available_skills>` 目录 | `meta_search` 检索(`progressiveSkillCatalog` 条目) | `meta_invoke` 按 `path` 加载 SKILL.md 正文 |
|
|
98
|
-
|
|
|
125
|
+
| **禁用** | tool | 不进 payload | `meta_search` 不返回 | `meta_invoke` 拒绝,直接调用被投影排除 |
|
|
99
126
|
| | skill | 不进目录 | `meta_search` 不返回 | `meta_invoke` 拒绝 |
|
|
100
127
|
|
|
101
|
-
>
|
|
102
|
-
|
|
103
|
-
|
|
128
|
+
> 上表的 tool 档位均指 `mcp__` 编目工具;原生工具不参与三档管理,只能以 `tools.exposed` 保活可见性(见下方配置文件示例)。
|
|
129
|
+
|
|
130
|
+
## 配置文件
|
|
104
131
|
|
|
105
|
-
|
|
132
|
+
规则写在 profile 的 `cordis.patch.yml` 里 `capability-menu-policy` 插件 entry 的 `config` 下(外层 `- insert:` / `id` / `name` 是 Cordis patch 的挂载样板,与规则无关):
|
|
106
133
|
|
|
107
134
|
```yaml
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
- 'mcp__*' # 该规则覆盖所有未显式列出的 MCP 工具
|
|
120
|
-
- 'server:km:*' # 按 server 前缀批量 Progressive
|
|
121
|
-
blocked:
|
|
122
|
-
- 'mcp__secret__*' # 明确禁用(优先级最高,压过 Exposed)
|
|
123
|
-
skills:
|
|
124
|
-
exposed:
|
|
125
|
-
- debugging
|
|
126
|
-
- coding
|
|
127
|
-
progressive:
|
|
128
|
-
- legacy_skill # 显式 Progressive(未列出即默认 Exposed)
|
|
129
|
-
blocked:
|
|
130
|
-
- forbidden_skill
|
|
131
|
-
metaTools:
|
|
132
|
-
- meta_search # 恒 Exposed,不可被 Blocked
|
|
133
|
-
- meta_invoke
|
|
134
|
-
progressiveSkillCatalog: ~/.dsh/progressive-skills.yaml # Progressive skill 的 name+description+path 目录
|
|
135
|
+
config:
|
|
136
|
+
tools:
|
|
137
|
+
exposed: [execute_cmd, get_session_context, search_kb, 'mcp__gongfeng__*'] # 通配:该 server 下全部常驻
|
|
138
|
+
progressive: ['mcp__*', 'server:km:*'] # 通配兜底 + 按 server 前缀批量按需
|
|
139
|
+
blocked: ['mcp__secret__*'] # 禁用优先级最高,压过常驻
|
|
140
|
+
skills:
|
|
141
|
+
exposed: [debugging, coding]
|
|
142
|
+
progressive: [legacy_skill] # 显式按需(未列出即默认常驻)
|
|
143
|
+
blocked: [forbidden_skill]
|
|
144
|
+
metaTools: [meta_search, meta_invoke] # 恒常驻,不可被禁用
|
|
145
|
+
progressiveSkillCatalog: ~/.dsh/progressive-skills.yaml
|
|
135
146
|
```
|
|
136
147
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
> `tools.exposed` 里列原生工具名(`execute_cmd` 等)是**保活**语义:原生工具不进能力管理编目(`classifyAll` 列表里看不到它们),但投影链会裁剪其可见性,列在这里保持模型直接可见可调。不要因为"它不在能力管理里"就把它从 exposed 移除——一旦被 `progressive`/`blocked` 规则覆盖,模型既看不到也调不到。
|
|
140
|
-
|
|
141
|
-
### 默认(不配置 policy)
|
|
142
|
-
|
|
143
|
-
- 不挂 `capability-menu-policy` → 全部工具/技能照旧可见(不投影)。
|
|
144
|
-
- 挂了 policy 但没有任何规则 → 全部能力默认 Exposed(`classify` 兜底),不投影、不隐藏。需要把低频能力归档进目录时,显式配置 `progressive`(或 `blocked`)规则把它们从模型视野中移出。
|
|
145
|
-
|
|
146
|
-
### Progressive skill
|
|
147
|
-
|
|
148
|
-
Progressive skill 的 name + description + path 汇总进独立 YAML(`progressiveSkillCatalog`),由 registry 索引、`meta_search` 检索;完整 SKILL.md 由 `meta_invoke` 按需加载(`ctx.skills` 未注册时按 YAML 的 `path` 读取)。Progressive skill 不进固定上下文。
|
|
149
|
-
|
|
150
|
-
> 关于 `<available_skills>`:Exposed skill 走渐进加载(名字表 → load);Progressive/Blocked skill 不进入 `dsh-tool-skill` 注入的目录。目录级裁剪需要上游 `dsh-tool-skill` 提供 filter 钩子(超出本 bundle 范围);当前 Exposed skill = 会话 registry 中所有 model-invocable skill,Progressive skill = `progressiveSkillCatalog` 条目。
|
|
151
|
-
|
|
152
|
-
## 机制设计
|
|
153
|
-
|
|
154
|
-
**核心第一性原则**:模型可见性(投影)与能力注册(registry 索引 + 执行能力)**必须解耦**。`ctx.tools.restrict` 会把工具从 `view.visible` 移除、连 `execute` 一起挡住(`UNKNOWN_TOOL`),因此本策略**不用 restrict 隐藏 Progressive**,而是在投影链 `system-prompt/assemble` 裁剪 `assembly.tools`,让 Progressive 工具保持全局注册、可检索、可执行。
|
|
155
|
-
|
|
156
|
-
Progressive 的**发现层(catalog)与执行层(`ctx.tools` 管线)分离**:catalog 只存元数据(name + description),完整 schema 从 `ctx.tools` 实时解析;无论哪一档,工具执行都落在 `ctx.tools` 管线上——审批/guard/沙箱/会话日志/取消齐全,不绕过。skill 无"执行",只有正文加载。Blocked 能力保留在 catalog 中(供管理面展示),但 `meta_search` 不返回、`meta_invoke` 拒绝。
|
|
157
|
-
|
|
158
|
-
## 能力管理(server 侧 `ctx.capabilityPolicy`)
|
|
148
|
+
**规则优先级**(命中即停,同级内精确匹配先于通配):`blocked` > `exposed` > `progressive`,未命中任何规则默认 Exposed;`blocked` 是最硬的控制(压过 `exposed`),meta 工具(`meta_search`/`meta_invoke`)恒为 Exposed 且不可被 blocked。`tools.exposed` 里列原生工具名(`execute_cmd` 等)是**保活**:原生工具不进能力编目、只受投影链裁剪可见性,列在这里保持模型可见可调——一旦被 progressive/blocked 覆盖,模型就看不到也调不到。
|
|
159
149
|
|
|
160
|
-
>
|
|
150
|
+
> 「能力菜单」tab 的改动只写入运行时内存、不落盘;要持久化(随 profile 生效、可版本管理/批量声明),编辑 profile 的 `cordis.patch.yml` 即可——这就是持久化入口,无需额外的导入/导出按钮。
|
|
161
151
|
|
|
162
|
-
|
|
152
|
+
### 渐进技能目录(`progressiveSkillCatalog`)
|
|
163
153
|
|
|
164
|
-
|
|
165
|
-
| --- | --- |
|
|
166
|
-
| `getConfig()` / `updateConfig(partial)` | 读取/热更新策略配置(`tools`/`skills`/`metaTools` 等),改动立即重编译规则、无需重启。 |
|
|
167
|
-
| `classifyAll()` | 枚举 `ctx.meta` 目录中每个能力及其当前分类,返回 `{ id, kind, name, server?, class: 'exposed'\|'progressive'\|'blocked', classLabel, mandatory }`;`classLabel` 为「Exposed · 常驻(直接调用)/ Progressive · 按需(目录渐进加载)/ Blocked · 禁用」,供前端只读分类列表展示。 |
|
|
168
|
-
| `classifyTool`/`classifySkill`/`classifyCapability` | 单个能力的分类判定。 |
|
|
169
|
-
| `isExposedTool`/`isExposedSkill`/`isBlockedCapability`/`metaTools`/`toolRules`/`skillRules` | 投影链与执行面消费的判定与规则视图。 |
|
|
154
|
+
按需(Progressive)技能不进固定上下文,也可能根本没注册进 `ctx.skills`。为了让它们仍可被发现,用一份独立 YAML 存 name + description + path,由 registry 索引、`meta_search` 检索;完整 SKILL.md 由 `meta_invoke` 按需加载(`ctx.skills` 未注册时按 YAML 的 `path` 读取):
|
|
170
155
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
├── cordis.patch.yml # insert registry/search/invoke/policy 四个子路径 entry
|
|
179
|
-
├── tsconfig.json / vitest.config.ts
|
|
180
|
-
├── src/
|
|
181
|
-
│ ├── registry.ts # (P0)能力目录 + ctx.meta 服务(不注册工具)
|
|
182
|
-
│ ├── search.ts # (P1)注册 meta_search
|
|
183
|
-
│ ├── invoke.ts # (P2)注册 meta_invoke
|
|
184
|
-
│ ├── policy.ts # (P3)Exposed/Progressive/Blocked 投影策略 + ctx.capabilityPolicy 能力管理
|
|
185
|
-
│ ├── invariant.ts
|
|
186
|
-
│ └── index.ts # re-export 全部
|
|
187
|
-
├── tests/ # registry / search / invoke / policy 四套用例
|
|
188
|
-
└── web/ # 前端「能力菜单」tab(client bundle + host Typert 网关,见 web/README.md)
|
|
156
|
+
```yaml
|
|
157
|
+
# ~/.dsh/progressive-skills.yaml
|
|
158
|
+
skills:
|
|
159
|
+
- name: legacy_skill # 对应 skills.progressive 里的规则名
|
|
160
|
+
description: 旧版迁移技能,低频使用
|
|
161
|
+
whenToUse: 处理旧工程时使用
|
|
162
|
+
path: /path/to/legacy_skill # 含 SKILL.md 的目录
|
|
189
163
|
```
|
|
190
164
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
- `src/` 为 TypeScript 源码,`lib/` 为预构建产物(`npm run build` 产出,本仓库直接分发 `lib/`)。`package.json` 的 `exports` 声明 `/registry` `/search` `/invoke` `/policy` `/invariant` 五个子路径,`cordis.patch.yml` 挂载前四个为 entry。
|
|
194
|
-
- `@deepseek-ai/*` 依赖为 peer 依赖(运行时从 dsh 安装闭包解析);`@deepseek-ai/schemastery` 与 `js-yaml` 为运行时依赖(后者解析 `progressiveSkillCatalog`)。
|
|
195
|
-
- 安装时自动构建:本包 `prepare` 脚本会在支持 lifecycle 的安装路径(git / 打包安装)下自动执行 `npm run build` 产出 `lib/`;前端包 `web/` 的 `prepare` 同样自动执行 `npm run bundle` 产出客户端 bundle(需 dsh-client 环境)。
|
|
196
|
-
- 测试:`pnpm install && npx vitest run`(33 个用例,覆盖 registry / search / invoke / policy,含能力管理面用例)。
|
|
197
|
-
|
|
198
|
-
## 环境前置
|
|
165
|
+
### 默认(不配置 policy)
|
|
199
166
|
|
|
200
|
-
-
|
|
167
|
+
- 不挂 `capability-menu-policy` → 全部工具/技能照旧可见(不投影)。
|
|
168
|
+
- 挂了 policy 但没有任何规则 → 全部能力默认 Exposed(`classify` 兜底),不投影、不隐藏。需要把低频能力归档进目录时,显式配置 `progressive`(或 `blocked`)规则把它们从模型视野中移出。
|
|
201
169
|
|
|
202
170
|
## License
|
|
203
171
|
|
|
204
172
|
本项目遵循 [Apache License 2.0](LICENSE)。
|
|
205
|
-
|
|
206
|
-
> 一个可独立安装的 Cordis 插件,为 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 提供能力发现、按需执行与 Exposed/Progressive/Blocked 投影策略。核心的智能体、模型、工具、会话、Web UI 与插件生态都来自上游项目。
|
package/cordis.patch.yml
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# dsh-capability-menu aggregate bundle patch: mounts the meta plugins in one
|
|
2
2
|
# layer, from a single installable package.
|
|
3
3
|
#
|
|
4
|
-
# One package,
|
|
4
|
+
# One package, five plugin entries — four mount a subpath of
|
|
5
5
|
# `@daweifu/capability-menu` (the loader resolves package subpath exports; see
|
|
6
|
-
# `@deepseek-ai/dsh-web-app/startup` for the same pattern in the harness)
|
|
6
|
+
# `@deepseek-ai/dsh-web-app/startup` for the same pattern in the harness), and
|
|
7
|
+
# the root entry loads the package main to mount the browser-facing gateway
|
|
8
|
+
# (and thereby registers the package itself as a `dsh.client` loader entry):
|
|
7
9
|
#
|
|
8
10
|
# - id: capability-menu-registry
|
|
9
11
|
# name: '@daweifu/capability-menu/registry'
|
|
@@ -34,7 +36,7 @@
|
|
|
34
36
|
# progressiveSkillCatalog: ~/.dsh/progressive-skills.yaml
|
|
35
37
|
#
|
|
36
38
|
# - `capability-menu-registry` (P0): builds/indexes the capability catalog and
|
|
37
|
-
# exposes the `ctx.
|
|
39
|
+
# exposes the `ctx.capability` service (search/get/getDetail/refresh). It registers
|
|
38
40
|
# no model-facing tool itself. Indexes the GLOBAL registry (no visibility
|
|
39
41
|
# filter) and additionally indexes Progressive skills from
|
|
40
42
|
# `progressiveSkillCatalog` (§7.2).
|
|
@@ -85,3 +87,9 @@
|
|
|
85
87
|
- read_image
|
|
86
88
|
- glob
|
|
87
89
|
- grep
|
|
90
|
+
# Root entry: loads the package main, which mounts the Typert gateway that
|
|
91
|
+
# exposes ctx.capabilityPolicy to the browser. Makes this package a loader
|
|
92
|
+
# entry itself so @deepseek-ai/dsh-client-modules discovers its `dsh.client`
|
|
93
|
+
# declaration and serves the 能力菜单 browser bundle (`./client`).
|
|
94
|
+
- id: capability-menu
|
|
95
|
+
name: '@daweifu/capability-menu'
|
package/lib/client.d.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({ id: "@daweifu/capability-menu", factory: (require) => {
|
|
2
|
+
var module = { exports: {} };
|
|
3
|
+
var exports = module.exports;
|
|
4
|
+
|
|
5
|
+
import { ClientContext } from "@deepseek-ai/dsh-client-runtime/client";
|
|
6
|
+
//#region src/client/store.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* ⚠️ VERIFIED AGAINST REAL rc.8 CLIENT API.
|
|
9
|
+
*
|
|
10
|
+
* Types + small helpers for the 能力菜单 (Capability Menu) settings
|
|
11
|
+
* section. The component reads/writes the Host `ctx.capabilityPolicy` through
|
|
12
|
+
* the generated `remote.capabilityPolicy` face (see `./remote.ts`), mirroring
|
|
13
|
+
* how `dsh-client-ui-settings-plugin-inventory` consumes
|
|
14
|
+
* `ctx.remote.pluginInventory`.
|
|
15
|
+
*/
|
|
16
|
+
/** One capability's Exposed/Progressive/Blocked row, as surfaced by the server. */
|
|
17
|
+
interface CapabilityRow {
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly kind: 'tool' | 'skill';
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly server?: string;
|
|
22
|
+
readonly class: 'exposed' | 'progressive' | 'blocked';
|
|
23
|
+
/** Human-friendly display: `Exposed · 常驻(直接调用)` / `Progressive · 按需(目录渐进加载)` / `Blocked · 禁用`. */
|
|
24
|
+
readonly classLabel?: string;
|
|
25
|
+
readonly mandatory: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** Snapshot of the management surface. */
|
|
28
|
+
interface CapabilitySnapshot {
|
|
29
|
+
readonly rows: readonly CapabilityRow[];
|
|
30
|
+
}
|
|
31
|
+
/** One direct child in a skill directory listing. */
|
|
32
|
+
interface SkillFileEntry {
|
|
33
|
+
readonly name: string;
|
|
34
|
+
readonly type: 'file' | 'directory';
|
|
35
|
+
}
|
|
36
|
+
/** Full detail projection of one capability (schema, description, stats). */
|
|
37
|
+
interface ToolDetail {
|
|
38
|
+
readonly id: string;
|
|
39
|
+
readonly kind: 'tool' | 'skill';
|
|
40
|
+
readonly actions: readonly string[];
|
|
41
|
+
readonly name: string;
|
|
42
|
+
readonly description: string;
|
|
43
|
+
readonly whenToUse?: string;
|
|
44
|
+
readonly parameters: Record<string, unknown>;
|
|
45
|
+
readonly output?: Record<string, unknown>;
|
|
46
|
+
readonly origin: {
|
|
47
|
+
readonly provider: string;
|
|
48
|
+
readonly serverName?: string;
|
|
49
|
+
readonly path?: string;
|
|
50
|
+
};
|
|
51
|
+
readonly tags: readonly string[];
|
|
52
|
+
readonly stats: {
|
|
53
|
+
readonly uses: number;
|
|
54
|
+
readonly successes: number;
|
|
55
|
+
readonly failures: number;
|
|
56
|
+
readonly totalMs: number;
|
|
57
|
+
readonly lastUsedAt?: number;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** The Host `capabilityPolicy` remote face (generated contribution). */
|
|
61
|
+
interface CapabilityPolicyRemote {
|
|
62
|
+
getConfig(): Promise<{
|
|
63
|
+
ok: true;
|
|
64
|
+
value: Record<string, unknown>;
|
|
65
|
+
} | {
|
|
66
|
+
ok: false;
|
|
67
|
+
error: {
|
|
68
|
+
code: string;
|
|
69
|
+
message: string;
|
|
70
|
+
};
|
|
71
|
+
}>;
|
|
72
|
+
updateConfig(partial: Record<string, unknown>): Promise<{
|
|
73
|
+
ok: true;
|
|
74
|
+
value: void;
|
|
75
|
+
} | {
|
|
76
|
+
ok: false;
|
|
77
|
+
error: {
|
|
78
|
+
code: string;
|
|
79
|
+
message: string;
|
|
80
|
+
};
|
|
81
|
+
}>;
|
|
82
|
+
classifyAll(): Promise<{
|
|
83
|
+
ok: true;
|
|
84
|
+
value: CapabilityRow[];
|
|
85
|
+
} | {
|
|
86
|
+
ok: false;
|
|
87
|
+
error: {
|
|
88
|
+
code: string;
|
|
89
|
+
message: string;
|
|
90
|
+
};
|
|
91
|
+
}>;
|
|
92
|
+
listSkillDir(id: string, relPath?: string): Promise<{
|
|
93
|
+
ok: true;
|
|
94
|
+
value: SkillFileEntry[] | undefined;
|
|
95
|
+
} | {
|
|
96
|
+
ok: false;
|
|
97
|
+
error: {
|
|
98
|
+
code: string;
|
|
99
|
+
message: string;
|
|
100
|
+
};
|
|
101
|
+
}>;
|
|
102
|
+
readSkillFile(id: string, relPath: string): Promise<{
|
|
103
|
+
ok: true;
|
|
104
|
+
value: string | undefined;
|
|
105
|
+
} | {
|
|
106
|
+
ok: false;
|
|
107
|
+
error: {
|
|
108
|
+
code: string;
|
|
109
|
+
message: string;
|
|
110
|
+
};
|
|
111
|
+
}>;
|
|
112
|
+
getDetail(id: string): Promise<{
|
|
113
|
+
ok: true;
|
|
114
|
+
value: ToolDetail | undefined;
|
|
115
|
+
} | {
|
|
116
|
+
ok: false;
|
|
117
|
+
error: {
|
|
118
|
+
code: string;
|
|
119
|
+
message: string;
|
|
120
|
+
};
|
|
121
|
+
}>;
|
|
122
|
+
}
|
|
123
|
+
//#endregion
|
|
124
|
+
//#region src/client/CapabilitySection.d.ts
|
|
125
|
+
/** Props injected by the settings.section registration (see index.ts). */
|
|
126
|
+
interface CapabilitySectionInjected {
|
|
127
|
+
remote: CapabilityPolicyRemote;
|
|
128
|
+
t(key: CapabilityKey, params?: Record<string, unknown>): string;
|
|
129
|
+
/** Diagnostic: `$mount` failure surfaced instead of crashing the section. */
|
|
130
|
+
mountError?: string;
|
|
131
|
+
/** Diagnostic: namespace methods actually installed on `ctx.remote.capabilityPolicy`. */
|
|
132
|
+
remoteKeys?: string;
|
|
133
|
+
}
|
|
134
|
+
type CapabilitySectionProps = CapabilitySectionInjected;
|
|
135
|
+
type CapabilityKey = 'nav' | 'title' | 'desc' | 'exposed' | 'progressive' | 'blocked' | 'kind' | 'class' | 'tool' | 'skill' | 'mandatory' | 'rules' | 'toolsGroup' | 'skillsGroup' | 'emptyTools' | 'emptySkills' | 'toolCount' | 'exposedShort' | 'progressiveShort' | 'blockedShort' | 'cycleHint' | 'notPreviewable' | 'previewClose' | 'detailNotFound';
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region src/client/index.d.ts
|
|
138
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
139
|
+
interface LocaleNamespaceMap {
|
|
140
|
+
/** 能力菜单 tab copy. */
|
|
141
|
+
'settings.capability': Record<CapabilityKey, string>;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** Required services (cordis fiber inject). `remote.capabilityPolicy` is NOT
|
|
145
|
+
* injected: we mount it in `apply`, so declaring it would deadlock the boot
|
|
146
|
+
* ("waiting for service"). Access it via `ctx.get('remote.capabilityPolicy')`,
|
|
147
|
+
* which resolves the mounted namespace service without the inject gate. */
|
|
148
|
+
declare const inject: string[];
|
|
149
|
+
/** Register the 能力菜单 section once `settings.section` is on the ledger. */
|
|
150
|
+
declare function apply(ctx: ClientContext): Promise<() => void>;
|
|
151
|
+
//#endregion
|
|
152
|
+
export { type CapabilityKey, type CapabilityPolicyRemote, type CapabilityRow, type CapabilitySectionInjected, type CapabilitySectionProps, type CapabilitySnapshot, apply, inject };
|
|
153
|
+
|
|
154
|
+
return module.exports;
|
|
155
|
+
}});
|
|
156
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","names":[],"sources":["../src/client/store.ts","../src/client/CapabilitySection.tsx","../src/client/index.ts"],"mappings":";;;;;;;;;;;;;;;;UAWiB;WACN;WACA;WACA;WACA;WACA;;WAEA;WACA;;;UAIM;WACN,eAAe;;;UAIT;WACN;WACA;;;UAIM;WACN;WACA;WACA;WACA;WACA;WACA;WACA,YAAY;WACZ,SAAS;WACT;aAAmB;aAA2B;aAA8B;;WAC5E;WACA;aACE;aACA;aACA;aACA;aACA;;;;UAKI;EACf,aAAa;IAAU;IAAU,OAAO;;IAA8B;IAAW;MAAS;MAAc;;;EACxG,aAAa,SAAS,0BAA0B;IAAU;IAAU;;IAAkB;IAAW;MAAS;MAAc;;;EACxH,eAAe;IAAU;IAAU,OAAO;;IAAsB;IAAW;MAAS;MAAc;;;EAClG,aAAa,YAAY,mBAAmB;IAAU;IAAU,OAAO;;IAAmC;IAAW;MAAS;MAAc;;;EAC5I,cAAc,YAAY,kBAAkB;IAAU;IAAU;;IAAgC;IAAW;MAAS;MAAc;;;EAClI,UAAU,aAAa;IAAU;IAAU,OAAO;;IAA6B;IAAW;MAAS;MAAc;;;;;;;UCtClG;EACf,QAAQ;EACR,EAAE,KAAK,eAAe,SAAS;;EAE/B;;EAEA;;KAGU,yBAAyB;KAEzB;;;;YCVA;;IAER,uBAAuB,OAAO;;;;;;;cAQrB;;iBAGS,MAAM,KAAK,gBAAgB"}
|