# dsh-skill-cockpit 中文文档

规范地址：https://npmcn.com/package/dsh-skill-cockpit/

版本：1\.5\.5
npm 元数据更新时间：2026-11-03T12:16:38.585Z
中文译文更新时间：2026-11-03T13:24:01.091Z
软件包许可：MIT

本文由上游 README 机器翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/dsh-skill-cockpit
原文对照：https://npmcn.com/package/dsh-skill-cockpit/?lang=original
项目主页：https://github.com/huanlin-labs/dsh-skill-cockpit#readme
源码仓库：https://github.com/huanlin-labs/dsh-skill-cockpit

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：946 kB，65 个文件
- 模块格式：ES Module
- TypeScript 类型：未声明
- Node.js 要求：\>=20\.11
- 运行依赖：0 个
- 首次发布：2026-10-14T13:07:14.221Z
- 最新版本发布：2026-11-03T12:16:38.434Z
- 已发布版本数：38（近 12 个月 38 个）

## 中文简介

DSH的技能座舱：在应用级导航（官方侧边栏）中的一页。小组成员座位，顺序5)列出这台机器实际暴露的所有技能（所有六种技能根类型，而不仅仅是~/）。Dsh /skills)，解释了为什么技能是不可见的（删除：\* / missing）

## 安装

```sh
npm install dsh-skill-cockpit
```

也可以使用：`pnpm add dsh-skill-cockpit`、`yarn add dsh-skill-cockpit`、`bun add dsh-skill-cockpit`

## README

# dsh-skill-cockpit

> **v1.5.1 · 已发布 npm [`dsh-skill-cockpit@1.5.1`](https://www.npmjs.com/package/dsh-skill-cockpit)** ｜ `npm test` 19/19 套件全绿 ｜ `npm run verify:install` 13/13（pack → 空目录安装 → 用装机副本启动 → /ping 读回版本）｜ MIT

> **源码 vs npm**：`1.5.1` 已发布，源码与 npm 包一致；改动见 `CHANGELOG.md` 顶部。

> **诚实边界。** 它**不是沙箱**：只管理 DSH 自己暴露的技能根，只写 `~/.dsh/skills` 与 `~/.agents/skills`；管不了别的进程、手工改动，也管不了绕过 DSH 的调用。CLI / doctor / `verify:install` 在本机 Windows 有自动化实测；源码里新加的宿主半守卫要重启 dsh 才生效。2026-10-31 在 1.5.1 真机重启后已实测：左侧「技能」入口与主区 `skill-panel` 槽位 active，面板渲染 76/76 技能、体检 76 条无问题；「新建技能」表单可开可取消、「翻译」一次写入 11 条译文、「自动加载」严格↔标准档位往返生效；`cockpit-doctor --json` 9/9。**未逐按钮全量点完**，其余未单独实测的按钮仍按「未验证」看待、以其单测/接口证据为准。CI 已在 ubuntu / macOS / windows × Node 20/22/24 上跑全量套件与 `verify:install`。 DSH（DeepSeek Harness）**技能面板**：在**左上应用级导航排**加一个「技能」入口， 点开是**主区一整页**，列出本机**全部**技能、**按技能开关**，并接「未安装技能索引」做第二跳。

-   挂载点 = **官方 `slots` 扩展点**的两个座位（不再走第三方 `dsh-better-sidebar`）：
    1.  `sidebar.panellist`（root 作用域的 **list**，即左上应用级导航排）→ 图标行，`order: 5`；
    2.  `main`（root 作用域的 **keyed**）→ 主区整页，`key` 与行 `id` 同名（`skill-panel`）。
-   **顺序严格夹在「插件」(order 0) 与「自动化任务」(order 10) 之间** —— 外壳按 `order` 升序排（`sort((a,b)=>a.order-b.order)`），5 落在唯一的空档里，与加载先后无关。
-   因此本包**不声明任何 `@deepseek-ai/dsh*` peer** ⇒ 不受 DSH 兼容性豁免闸门影响（见工作区 `AGENTS.md` §四 铁律 1/3）
-   纯 ESM JavaScript，无构建链：`lib/*.js` 直接可跑，自测用 `node` 即可复跑

## 自查：`dsh-skill-cockpit-doctor`

```bash
npx dsh-skill-cockpit-doctor                     # 面板没出现？查：状态目录 / 技能根 / 装配 / 译文
npx dsh-skill-cockpit-doctor --json              # 给机器读
npx dsh-skill-cockpit-doctor --home <dir> --fix  # 路径全重定向到临时 home；只补能安全补的
npx dsh-skill-cockpit-doctor --dry-run           # 只说 --fix 会做什么，不落盘
npx dsh-skill-cockpit-doctor --report out.json   # 同一份 JSON 写到文件（只读，不改状态）
```

退出码：`0` 就绪 · `1` 有要修的 · `2` 环境问题。

**平台矩阵**（谁验过、谁没验）：[`docs/platforms.md`](https://npmcn.com/package/dsh-skill-cockpit/docs/platforms.md)。 **交付前自检**（哪条打了勾、证据是什么、哪条还没做）：[`docs/self-check.md`](https://npmcn.com/package/dsh-skill-cockpit/docs/self-check.md)。 **出问题了**（检查项对照表 + 三个常见现象）：[`docs/troubleshooting.md`](https://npmcn.com/package/dsh-skill-cockpit/docs/troubleshooting.md)。 **哪些 backlog 已实现、哪些是真缺**（逐条给证据）：[`docs/status-ledger.md`](https://npmcn.com/package/dsh-skill-cockpit/docs/status-ledger.md)。

## 诚实边界（先看这段，再看下面）

-   **只在 Windows 桌面版 DSH 真机验证过。** 本文所有结论都来自 Windows 11 上的真实 DSH 桌面安装。macOS / Linux 的**语法检查、全量套件与 `verify:install` 已在 CI 里跑过**；也**没有人**在那些平台跑过真实 DSH 会话。
-   **全量自测在 CI 里覆盖 ubuntu + macOS + windows。** CI 通过只是自动化证据，不等于那些平台上的真实 DSH 会话已验证。
-   **翻译用的是免费公开接口**（优先 MyMemory，失败退 Google）。它们会限流、会不打招呼地改；一次批量翻译可能少于请求条数。除这两家之外不发任何数据，而且只在你按下「翻译」时才发。
-   **你让它改，它才改技能文件。** 一键修会重写你点的那份技能的 frontmatter（必先写 `.bak-<时间戳>` 备份），且**不编内容**：只补 entry 名、用该技能自己的正文补缺失/过短的描述、给会破坏 YAML 的冒号加引号。修不了时会明确说原因，不再静默。
-   **它不是沙箱。** 它读 DSH 自己解析的六个技能根（`project-dsh` / `project-agents` / `custom` / `user-dsh` / `user-agents` / `bundled`），只写 `~/.dsh/skills` 与 `~/.agents/skills`；别的 harness 目录一概不碰。
-   **调用次数只是下界。** 数字来自解析会话日志里的 `tool-call`（`name: "skill"`）；更早的日志形状或从别的入口调用的技能会读成 0。

## 安装

三步，每步都有可对照的输出。

**① 装包**

```bash
npm i dsh-skill-cockpit      # 或 pnpm add / yarn add
```

期望：`node_modules/dsh-skill-cockpit/package.json` 里的 `version` 与你装的版本一致。

**② 挂进 profile（这步归 DSH，插件不替你改配置）**

在 `~/.dsh/profiles/<你的 profile>/package.json` 的 `dependencies` 里加 `"dsh-skill-cockpit": "^1.5.0"`（或你装的版本）， 或在 `cordis.patch.yml` 用 `insert:` 挂一行。本机开发可直接写 `"dsh-skill-cockpit": "link:D:/插件/dsh-skill-panel"`。

期望：`node -e "console.log(require('./package.json').dependencies)"` 的输出里能看到这一条。

**③ 重启 DSH，然后自查**

```bash
npx dsh-skill-cockpit-doctor
```

期望：最后一行是「一切就绪」，左侧导航「插件」与「自动化任务」之间出现「技能」。 没出现就看 `--json` 里第一个不是 `ok` 的项：装配那项回第 ② 步；状态目录 / 技能根那项跑 `--fix`。 **同时给 dsh 一个工具**：`skill_panel`（20 个动作，覆盖面板全部能力）—— 基础 11 个：`list` / `read` / `create` / `update` / `delete` / `toggle` / `repair` / `backup` / `trash_list` / `trash_restore` / `trash_purge`； 二期 9 个：后备库 `vault_list` / `vault_put` / `vault_install`、DSH 预设 `preset_list` / `preset_mount` / `preset_unmount`、批量四态 `mode_set`、`usage`、`checkup`。 以后「把某技能停掉」「新建一个技能」「这套技能全关掉」「最近谁在被调用」这类话，模型直接调工具改磁盘，不必点面板；破坏性动作必须显式 `confirm: true`。

## 它解决什么

`~/.dsh/skills` 只是**六类技能根**中的一类。只扫它 → 面板少报技能（本机实测 31 vs 会话可见 39）。 更要紧的是：**frontmatter 写坏 = 运行期静默丢弃**（`dsh-skill-filesystem` 解析失败即 `continue`）， 用户看到的是"这个技能不存在"，而不是"这个技能写坏了"。

本面板：

| 能力 | 说明 |
| --- | --- |
| 六类根全枚举 | `project-dsh(100)` / `project-agents(200)` / `custom(300)` / `user-dsh(400)` / `user-agents(500)` / `bundled(600)`，各带 `source` + `rank` |
| 坏 frontmatter 显式报错 | `dropped:no-frontmatter` / `dropped:unclosed` / `dropped:bad-yaml` / `dropped:missing-fields` / `dropped:bad-name`，每条带原因；**"丢了"就显示"丢了"** |
| 根不存在也算一种状态 | 显示"不存在（正常）"；`bundled` 未挂载时显示 `$DSH_BUNDLED_SKILL_DIR` 未设置，而不是假装有 |
| 每技能开关 | 唯一写盘动作 = **改入口文件名**：`SKILL.md ↔ SKILL.md.disabled`（扁平型 `x.md ↔ x.md.disabled`） |
| 会话作用域 | 面板顶部显示"当前会话 cwd / 项目根"；项目级根**只读**（写工作区 = 绕过"工作区=权限域"边界） |
| 第二跳 | 命中「未安装技能索引」时给信息卡 + 复制按钮，**不下载、不安装** |

## 和同类比（2026-10-08 源码级实查）

生态里做技能面板的不止一家。我们不求「功能最多」，只把三条讲清楚——**都是可验证的机制差异，不是形容词**：

| 维度 | 本插件 | cheshireez/dsh-skill-hub | re-ITRT/dsh-skill-mcp-panel | VDERR/dsh-echocat-skill-panel |
| --- | --- | --- | --- | --- |
| 挂载面 | 左上导航「技能」整页（`sidebar.panellist` order 5） | 设置页「技能中枢」 | 侧栏「技能与 MCP」双 tab | 横栏 + 左栏 + 中栏报告 |
| 启停机制 | **改入口文件名** `SKILL.md ↔ .disabled`（唯一写盘动作） | 改名 + sidecar 对账 | **不碰文件**：写 overlay JSON + overlay provider | 把技能目录**移出**监视目录 |
| 卸载本插件后 | **状态保持**（文件名就是状态） | 保持禁用（启动时对账） | **全部失效**（状态在插件自己的 storage） | 保持禁用 |
| 给模型的接口 | **有：`skill_panel` 20 个动作**（模型可直接改，不必点面板） | 未见模型工具 | 未见模型工具 | 未见模型工具 |
| 依赖与体积 | **零依赖 / 零 peer**，无构建链 | TS 构建 | 无构建链 | 无构建链 |
| 技能根覆盖 | **六类根全扫**，并解释「某技能为何不可见」；项目级只读 | 诊断 + 一键修复（这条它比我们多走一步） | — | — |

> 口径：同类三列来自 2026-10-08 对各自仓库源码的实查；同类插件迭代快，**以它们自己的仓库为准**。 我们**不主张**「独占导航席位」——`@linxin666/dsh-client-ui-skill-explorer` 也挂 `sidebar.panellist`（2026-10-20 实查更正）。

## 开 = 自动加载

**干什么**：每轮对话开始前（`agent/pre-step`），拿你这句话去和各技能的 `description` 做词面匹配； 命中的技能把**正文**直接放进本轮上下文（系统提醒）——模型不用先想起「去读一下技能」，你也不用写规则。

**总开关 + 三档**（工具栏右侧；只有「已开」时三档才有意义）：

| 档 | 相关分阈值 | 描述至少命中几个词 | 单技能正文上限 |
| --- | --- | --- | --- |
| 严格 | ≥ 4.0 | 2 | 4 KB |
| 标准（默认） | ≥ 2.5 | 1 | 8 KB |
| 宽松 | ≥ 1.5 | 1 | 16 KB |

三档共同上限：**单轮最多 3 个技能、总预算 24 KB**。 同一技能同一会话只注入一次；`</system-reminder>` 一律转义；出任何异常只跳过该轮，不影响正常对话。

**每行的「必用」(pin)**：不看相关度，直接排进每轮注入最前（仍受单技能上限与总预算约束）； 技能拨到「关」时 pin 不生效。必用 / 不用名单存在 `~/.dsh/skill-cockpit/autoload.json`（`pinned` / `perSkillOff`）。

**开了的代价（实测，不粉饰）**：

-   **占上下文**：命中即注入正文。pdf 这类 7.9 KB ≈ 2–3k token；宽松档最坏 24 KB ≈ 6–8k token/轮，且每轮都占注意力。
-   **会误注入**：真实技能集实测 **1/10**（10 条本不该命中的查询里 1 条被塞）。
-   **命中不等于执行**：真实集 recall **7/10（70%）**，注入了模型仍可能不照做。
-   **会互相挤**：单轮只装 3 个；pin 多了会把真正相关的技能挤出预算。
-   严格档近乎不触发；宽松档噪音大。

**建议**：默认「标准 + 已开」；只做文档/论文那类活时开；pin 控制在 1–2 个。 关掉后技能仍在，模型需要时仍可自己调用——只是不再自动塞正文。

**为什么不是 100%**：宿主没有公开的「插件往系统提示写入」通道，能做到的上限是"每轮把正文塞进上下文"， 模型仍可能不照做。所以对外口径是**高置信触发**，不是"强制/保证"。工具 `skill_autoload`： `action=on|off` / `tier` / `except` / `pin` / `unpin` / `status` / `probe` / `eval`。

## 四个页面

面板是导航里的一页，顶部四个视图：

| 视图 | 干什么 |
| --- | --- |
| **列表** | 全部技能一处看：名字、来源根标签、功能标签、描述、体积、单技能开关、「看正文」读入口文件 |
| **分组** | 自己摆的看板 —— 从左侧把卡片拖进右边某个组；六个内置功能分组（文档办公 · 代码工程 · 设计视觉 · 写作沟通 · 研究资料 · 元技能）+ 自建组，可改名、可删 |
| **用量** | 从会话日志聚合每个技能的调用次数，看清哪些装了从没用过 |
| **问题** | 「能加载但白占坑」与「某技能为何不在」的诊断，一条一行 |

两个**必须写明的行为**，因为这两处正是同类面板容易撒谎的地方：

-   **组头是一个三态开关。** 全亮 = 整组启用，全灭 = 整组停用，半亮 = 混合。点它逐条改入口文件名；整组停用时整块变灰，不用去读「启用 0」那行字。
-   **分组与归属存在本浏览器（`localStorage`），不落盘。** 摆看板不写任何文件；整个插件唯一的写盘动作仍是入口文件改名。

## 中文摘要（只改显示）

很多第三方技能的 `description` 是英文原文。面板**不会改别人的 SKILL.md**，所以中文摘要放在面板自己这一层：

-   内建 12 条常用英文技能的中文摘要（架构图、论文配图、Git 规范等）。
-   其它英文技能行尾有「补中文」，填一行就存进本机浏览器 `localStorage`（键 `dsh-skill-cockpit-gloss`）；留空即清除。
-   摘要只影响**显示**：技能本体、`description`、注入给模型的内容一律不变。

## 状态即文件名（无第二份状态）

开关状态**每次扫描都从文件名重新读出**，插件里没有 prefs、没有数据库、没有内存副本。 所以面板不可能出现"显示已关、模型照样能加载"的假开关。 （对照：better-sidebar 自带的 `pluginSettings` 管的是"这个 tab 显不显示"，**不是**技能开关。）

## 截图

深色主题、真实 CSS 渲染（900px 宽）：

![体检页：六类问题 + 逐条解法](https://raw.githubusercontent.com/huanlin-labs/dsh-skill-cockpit/main/docs/checkup.png)

![列表页：顶部体检摘要条 + 每行四态](https://raw.githubusercontent.com/huanlin-labs/dsh-skill-cockpit/main/docs/list.png)

## 装配

```bash
npm install dsh-skill-cockpit
```

（现在 npm 上是 **0.2.3**，0.6.7 待发。想直接跑当前源码，用下面的本地 link。）

```jsonc
// ~/.dsh/profiles/<profile>/package.json
"dependencies": { "dsh-skill-cockpit": "link:D:/插件/dsh-skill-panel" }
```

```yaml
# ~/.dsh/profiles/<profile>/cordis.patch.yml
- insert:
    - id: skill-panel
      name: 'dsh-skill-cockpit'
      # 可选配置（全部有默认值）：
      # config:
      #   dshHome: 'C:\\Users\\<你>\\.dsh'          # 默认 $DSH_HOME 或 ~/.dsh
      #   trashRoot / backupRoot 都不得放在技能根内（否则删除 / 备份会把自己搬进自己）
#   backupRoot: 'C:\\Users\\you\\Backups\\skill-panel'   # 默认 <dshHome>/skill-panel/backups
      #   agentsHome: 'C:\\Users\\<你>\\.agents'     # 默认 $DSH_AGENTS_HOME 或 ~/.agents
      #   customSkillDirs: []                       # 额外的技能根
      #   bundledSkillDir: ''                       # 默认 $DSH_BUNDLED_SKILL_DIR
      #   includeDefaultRoots: true
      #   writableSources: ['user-dsh']             # 默认 ['user-dsh','user-agents']
      #   undeclaredIndexPath: 'C:\\Users\\you\\Documents\\skills-index.md'
```

改装配 = **要重启 dsh**（进程红线：重启只由户主执行）。技能开关**不需要**重启。

## HTTP 路由（宿主半，本机同源）

| 方法 | 路径 | 作用 |
| --- | --- | --- |
| GET | `/__dsh-skill-panel/ping` | 插件身份 + 路由清单 + 可写根 |
| GET | `/__dsh-skill-panel/skills?cwd=…` | 全量扫描报告（`cwd` 决定项目级根） |
| GET | `/__dsh-skill-panel/body?path=…&cwd=…` | 读一个入口文件正文（**白名单制**：只认 `/skills` 报告里出现过的入口，带体积上限） |
| GET | `/__dsh-skill-panel/undeclared?q=…` | 搜未安装技能索引（只读） |
| GET | `/__dsh-skill-panel/usage` | 技能调用次数：`{ ok, skills:[{name,count,lastAt}], scanned, skipped, sessions, updatedAt }` |
| GET | `/__dsh-skill-panel/checks?cwd=…` | 四类「能加载但白占坑」诊断：`{ ok, checks:[{kind,skill,detail}], summary, thresholds, note }` |
| POST | `/__dsh-skill-panel/toggle` | `{ filePath, disable, cwd, plan? }` → 改名（唯一写动作） |

`/usage` 只写一个文件：`<dshHome>/dsh-skill-cockpit/usage.json`，内容只有**技能名 / 调用次数 / 时间戳** （不存任何对话内容）；扫描是增量的 —— 会话日志 `(size, mtime)` 没变就跳过，本机 104 个会话的第二次调用 21ms。 `/checks` 是纯计算（不读磁盘），阈值默认「描述 <20 字」「文件 <300 字节（按字节估计，含 frontmatter）」。

### 为什么有些技能禁不了

技能到会话有两条路，只有一条落在文件上：

-   **文件型**（`user-dsh` / `user-agents` / `custom` / 项目根 / 内置目录）：入口是真 `SKILL.md` 或 `x.md`， 面板改入口文件名即可停用。
-   **非文件型（provider 提供）**：宿主的契约是 `ctx.skills.registerProvider(() => provider)`，**只做加法** —— provider 贡献自己的 `list()`，**没有任何钩子能包装 / 过滤 / 排除别人输出的技能**。面板对它无能为力。

这不是漏做，是宿主 API 的形状；所以面板如实标注：这类行在开关位置显示 「本面板无法禁用（属 … provider）」，**不画一个点了也不会有反应的假开关**。

`plan: true` 只算不动 → 面板用它做"确认改名"预告，自测也用它验 dry-run。

### 两条拒绝是所有权的边界（各有负向测试）

面板是本机 web 面，所以路由**不信调用方**：

-   **`/body` 是白名单制**：只回答 `/skills` 报告里**列过**的入口文件。其它路径 —— 任意文件、插件自己的数据文件、 仅仅"存在"的路径 —— 一律 **403 且不回传任何内容**。所以这条路由**不可能被当成任意文件读取器用**。 （0.3.1 之前是"给什么读什么"，这条是复核时发现的，不是事故。）
-   **`/toggle` 只在两个写根内落笔**：目标必须位于 `~/.dsh/skills` 或 `~/.agents/skills` 内；**项目级根只读，哪怕报告里列出了那个文件** （因为由会话 `cwd` 推出来的路径永远不该变成写操作）。

`cwd` 在两条路由上都是**可选的**（0.3.2 起）：这面板同时也是没有会话的全局页。没有 `cwd` 时报告里就没有项目级根， 于是**项目级入口被拒、用户级入口照常工作**；而解析不出来的 `cwd` 按"不存在"处理、不被信任，因此不可能绕过写根门。

其余写路由护栏（任一条不满足即拒绝并给中文原因）：目标必须存在、必须是普通文件（**永不改目录名**）、 必须直接位于可写根内（真实路径比对，防符号链接逃逸）、必须正好是入口文件（`<目录>/SKILL.md` 或 `<根>/x.md`）、 目标名不得已存在（防覆盖）；另有同源栅栏（带外部 `Origin` 的请求一律 403）。

## 后备库（reserve list）

-   默认名单：`<DSH home>/skill-panel/后备库.md`（首次「存进后备库」时自动创建）。
-   想用自己已有的清单：配置 `reserveListPath` 指向那个 markdown 文件（表格列：名字 / 一句话能力 / 来源 / 体积 / 备注）。
-   删除技能时勾「存进后备库」= 照常删进回收站 + 名单追加一行；「恢复」按「来源」下载（git 地址，需本机装 git）或复制（本机目录）。

## 后备技能库（可选）

技能不必「先装才能找」。在 `~/.dsh/skills` 与 `~/.agents/skills` 之外随便找个文件夹放那些 没装的技能目录，再在旁边写一份 markdown 表格 —— 那个文件夹 dsh 不扫描、不加载，既不占上下文也不占 内存，等于冷备：只有面板的搜索能看见它。

表格就是契约，一个技能一行，五列：

| 名字 | 一句话能力 | 来源（仓库·许可） | 体积 | 适用会话/预设 |
| --- | --- | --- | --- | --- |
| `code-review` | 审查改动：正确性、安全、测试覆盖 | my-org/skills · MIT | 42.1 KB | 任意 |

把插件配置 `undeclaredIndexPath` 指向这份文件。之后搜索在已装列表里没命中时，会顺手查这张表， 渲染成只读卡片（名字 / 一句话能力 / 来源与许可 / 体积 / 建议会话）并给一个「复制」按钮 —— 面板自己**不下载、不安装**。

真要用了再「临时装」：点「导入技能」，填备用库里那个目录的路径，面板把它拷进可写根；任务做完删掉， 删除先进回收站，随时能还原，备用库原件不动。

不配、或配了但文件不存在，第二跳直接不出现，不报错。（默认值指的是作者本机那份清单，请改成你自己的。）

## 自测

```bash
node test/run-all.mjs [报告目录]
```

六个套件（全部不需要 GUI / 不需要 dsh）：

| 套件 | 覆盖 |
| --- | --- |
| `run-data-layer.mjs` | 六类根 / `dropped:*` 全可达（合成 fixture）/ `root-missing` / **独立目录遍历比对（不多报、不漏报）** / 字节数与磁盘一致 |
| `run-toggle.mjs` | 在**真实** `~/.dsh/skills` 上对 1 个新建探针做 改名→停用→改回 闭环：sha256 一致、根项数不变、面板仍显示"已停用"、清理后零残留；另含目录/非入口/根外/项目级四类拒绝路径 |
| `run-routes.mjs` | 假 ctx 跑真 `apply()`：**33 条路由**注册、200/400/403/405、ping、`/usage` 落盘到**配置的**路径（自测绝不写真实 `~/.dsh`）且第二次增量跳过、`/checks` 真实命中 |
| `run-client.mjs` | 假 `__ModuleLoader__` + React 桩：bundle 求值、**挂载对（`sidebar.panellist` 行 id/order/label + `main` keyed 页 key 一致）**、`order=5` 夹位断言、**座位未声明时不注册也不抛错**、健康/坏 frontmatter/第二跳/错误态/**无 `useSessions` 降级**、**三个视图（列表/用量/问题）**、用量空态那句、非文件型的「禁不了」标注、主题令牌无死令牌 |
| `run-usage.mjs` | 真 zstd **多帧**文件（每帧独立压缩再拼接）：多帧解码 / 单帧 / 纯文本回退 / 垃圾字节 / `seq` 去重 / 深层嵌套事件筛选 / 增量跳过 / 文件变大不双计 / 落盘结构 / **隐私（落盘不含对话原文）** |
| `run-checks.mjs` | 四类诊断各自正反例：`shadowed` / `short-description`（空、19 字、正好 20 字）/ `dir-name-mismatch`（仅 `dir-bundle`）/ `empty-body`（阈值边界）/ 汇总 / 阈值覆盖 / 畸形输入不抛 / 纯函数不改入参 |

## 边界（有意不做）

-   项目级根**不写**（安全边界：工作区 = 权限域）
-   不安装、不下载技能；**删除 = 先整份复制进插件自己的回收站、二次确认**（`purge` 才永久删）；停用只改入口文件名，正文一字节不动
-   不做"最近被加载"（要动宿主埋点，成本大于收益）
-   **技能开关状态只存在文件名里**（`SKILL.md` ↔ `.md.disabled`）；面板自己只存偏好（自动加载档位、必用/不用、译文缓存），都在 `~/.dsh/skill-cockpit/`

## 未实查项（如实标注）

-   `bundledSkillDir` 的实际取值：本机 `$DSH_BUNDLED_SKILL_DIR` 未设置、profile patch 里也没有该配置项 ⇒ 本插件按"未挂载"如实显示。会话可见 39 条 vs `~/.dsh/skills` 31 条的差额来源**仍未定位** （`app.asar` 内未见 `reviewer-response` 之类的技能文件；`E:\DSH\resources` 下也无）。面板不会替它猜。
-   `@deepseek-ai/dsh-client-*` 原生 Slot 树（设计方案的 H4）**已实查**：本次改挂载面时从**运行中的 `E:\DSH\resources\app.asar`**（0.2.0-rc.2）字节扫描确认 `sidebar.panellist` / `main` 两个座位、`order` 升序语义、以及各占用方（`client-ui-plugin-manager` 0 / `client-ui-schedule` 10 / task-board 20 / ssh 40）。
-   生态惯例与户主指定顺序**不一致**（已如实上报）：`dsh-ssh` 源码注释把 0/10/20/30/40 记为「Plugins / Schedule / board / **skill center 30**」，即生态预留 30 给"技能中心"；本包按户主明确要求取 **5**（夹在 插件 0 与 自动化任务 10 之间）。要改回 30 只需改 `lib/client.js` 的 `PANEL_ORDER` 一个数字。
-   重启后**真实 GUI 渲染**已实查（2026-10-31，1.5.1）：左排「技能」点击打开整页、主区 `skill-panel` 槽位 active、76/76 技能列表与体检摘要正常；`lib/client.js` 由宿主启动时载入。

## 许可

MIT。

## 给 dsh 的工具接口（1.0.0）

面板是给人看的；平时更常用的是**让 dsh 直接改技能**。插件因此注册了一个工具 `skill_panel`（与任务板同一套路，不需要 SKILL.md），模型可以自己调：

| action | 作用 |
| --- | --- |
| `list` | 列出全部技能（名字 / 来源 / 启用状态 / 路径） |
| `read` | 读一个技能（简介 + 正文） |
| `create` | 新建技能（写 SKILL.md） |
| `update` | 改简介 / 正文 / 适用场景（旧文件自动备份） |
| `delete` | 删除，整份进回收站（需 `confirm: true`） |
| `toggle` | 启用 / 停用（只改入口文件名，`plan: true` 可预览） |
| `repair` | 修结构问题（缺 frontmatter、名字不合法等） |
| `backup` | 备份单个或全部技能 |
| `trash_list` / `trash_restore` / `trash_purge` | 回收站：列出 / 还原 / 彻底删除（后者需 `confirm: true`） |
| `vault_list` / `vault_put` / `vault_install` | 后备库：看名单 / 存进去（= 本机删除 + 名单记一行，需 `confirm: true`）/ 按名单装回来 |
| `preset_list` / `preset_mount` / `preset_unmount` | DSH 预设：列预设 / 把技能以 junction 挂进去 / 摘掉（挂载改动重启 dsh 生效） |
| `mode_set` | 批量切四态（`on` / `user-only` / `model-only` / `off`）；`scope: exclusive` 当白名单，清单外全关；不带 `confirm: true` 只返回预演 |
| `usage` | 从会话日志统计每个技能被调多少次（默认复用索引，`refresh: true` 重扫） |
| `checkup` | 体检：描述过短 / 目录名不符 / 正文疑似为空 / 同名被遮蔽 |

边界与面板一致：只写用户级技能根（`~/.dsh/skills`、`~/.agents/skills`），项目级技能只读；删除一律先整份复制进回收站，绝不半删。

## 常见问题

### dsh-skill-cockpit 是什么？

DSH的技能座舱：在应用级导航（官方侧边栏）中的一页。小组成员座位，顺序5\)列出这台机器实际暴露的所有技能（所有六种技能根类型，而不仅仅是~/）。Dsh /skills\)，解释了为什么技能是不可见的（删除：\* / missing）

### 如何安装 dsh-skill-cockpit？

在项目目录运行 npm install dsh-skill-cockpit，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 dsh-skill-cockpit-doctor，可以用 npx dsh-skill-cockpit-doctor 直接运行。

### dsh-skill-cockpit 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/dsh-skill-cockpit 是否存在。

### dsh-skill-cockpit 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### dsh-skill-cockpit 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=20\.11。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### dsh-skill-cockpit 可以商用吗？

dsh-skill-cockpit 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### dsh-skill-cockpit 还在维护吗？

最新版本 1\.5\.5 发布于 2026/11/03（今天）；至今共发布 38 个版本，其中过去 12 个月发布了 38 个；首次发布于 2026/10/14。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

