# @liaozhi/dsh-comfyui-based-tools 中文文档

规范地址：https://npmcn.com/package/%40liaozhi/dsh-comfyui-based-tools/

版本：0\.9\.0
npm 元数据更新时间：2026-11-01T16:48:06.307Z
中文译文更新时间：2026-11-01T17:32:35.498Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40liaozhi/dsh-comfyui-based-tools
原文对照：https://npmcn.com/package/%40liaozhi/dsh-comfyui-based-tools/?lang=original

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

- 包体积（解压后）：6.4 MB，62 个文件
- 模块格式：ES Module
- TypeScript 类型：未声明
- Node.js 要求：\>=22
- 运行依赖：5 个
- peer 依赖：@deepseek-ai/cordis ^4\.0\.5，@deepseek-ai/dsh-llm ^0\.2\.1-rc\.1，@deepseek-ai/dsh-tools ^0\.2\.1-rc\.1，@deepseek-ai/dsh-session ^0\.2\.1-rc\.1，@deepseek-ai/schemastery ^3\.18\.5，@deepseek-ai/dsh-settings ^0\.2\.1-rc\.1，@deepseek-ai/dsh-attachment ^0\.2\.1-rc\.1，@deepseek-ai/dsh-util-values ^0\.2\.1-rc\.1，@deepseek-ai/dsh-client-locale ^0\.2\.1-rc\.1，@deepseek-ai/dsh-system-prompt ^0\.2\.1-rc\.1，@deepseek-ai/dsh-client-ui-chat ^0\.2\.1-rc\.1，@deepseek-ai/dsh-client-ui-tool ^0\.2\.1-rc\.1，@deepseek-ai/dsh-host-webserver ^0\.2\.1-rc\.1，@deepseek-ai/dsh-client-ui-slots ^0\.2\.1-rc\.1，@deepseek-ai/dsh-typert-protocol ^0\.2\.1-rc\.1，@deepseek-ai/dsh-typert-registry ^0\.2\.1-rc\.1，@deepseek-ai/dsh-client-ui-layout ^0\.2\.1-rc\.1，@deepseek-ai/dsh-client-connection ^0\.2\.1-rc\.1，@deepseek-ai/dsh-client-ui-plugin-manager ^0\.2\.1-rc\.1
- 首次发布：2026-09-13T22:03:39.470Z
- 最新版本发布：2026-11-01T16:48:06.113Z
- 已发布版本数：20（近 12 个月 20 个）

## 中文简介

DeepSeek利用插件:把DSH工具接到用户自备的ComfyUI实例(实例管理+工具分配+极大极小H3视频/ Qwen-Image图像工具)。

## 安装

```sh
npm install @liaozhi/dsh-comfyui-based-tools
```

也可以使用：`pnpm add @liaozhi/dsh-comfyui-based-tools`、`yarn add @liaozhi/dsh-comfyui-based-tools`、`bun add @liaozhi/dsh-comfyui-based-tools`

## README

# dsh-comfyui-based-tools

> **支持范围：本插件仅适配 DeepSeek 桌面版（desktop profile）的 Harness runtime。** **当前支持的 DeepSeek 桌面版版本：`0.2.1-rc.1` ~ `0.2.1-rc.5`**（版本门禁 `[MIN_HARNESS_VERSION, MAX_HARNESS_VERSION]` = `[0.2.1-rc.1, 0.2.1-rc.5]`， 见 `src/version-gate.ts`；桌面版应用与 runtime 锁步同版发版， 插件 peer 声明 `^0.2.1-rc.1`）——**高于上限**时插件启动即软禁用， 设置里不再有本插件分区，改在「插件」页本插件详情页出现「已停用」说明面板 并给出版本指引，不影响 DSH 启动与其他插件。 `dsh web`、自定义 profile、SDK/headless 等形态一律不支持——启动时 profile 门禁 （`src/profile-gate.ts`）会自动软禁用本插件。下文沿用的 `dsh web` 开发流示例是 插件模板的历史写法，实际部署与运行请以桌面版为准。

[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 插件：**双端（host + client）**结构，开发完成后可**直接发布到 npm** 或**推到 GitHub** 供用户安装。

模板自带三个可删改的示例功能，覆盖两端与端间调用：

-   **Host half**（`src/index.ts`）：注册模型可调用的 `greet` 工具，演示 `inject` / `Config` schema / 事件监听；
-   **Client half**（`src/client/index.ts`）：在「插件」页本插件详情页注册配置面板（`plugins.bundle.config` 槽位），演示 slot 组合、locale 词典（zh/en 双语键集）、CSS Modules 样式与浏览器原地热替换；
-   **Host↔Client 调用**（`src/remote.ts` + `src/client/api.ts`）：面板上的"调用 host"按钮经 Typert Gateway 调用 host 半的 `comfyui-tools/ping` 端点，演示第三方插件的远程调用形态（为什么是手写描述符而非官方 `@Remote` 装饰器，见 `src/remote.ts` 头注释）。

## 使用本模板

通过 GitHub 的 "Use this template" **创建新的插件仓库**（仓库名随意），**克隆到本地**后， 先**改名**。改名前搞懂插件身份由**三样东西**组成，它们互相派生：

| 概念 | 本模板取值 | 怎么派生 |
| --- | --- | --- |
| **短插件 id** | `dsh-comfyui-based-tools` | \= **仓库名**（use-this-template 建库时你起的名字；克隆到本地即根文件夹名） |
| **npm 包名**（scoped） | `@liaozhi/dsh-comfyui-based-tools` | `@<scope>/` + 短 id；`@scope` = 你的 npm 用户名 |
| **环境前缀** | `DSH_COMFYUI_BASED_TOOLS` | 短 id 全大写、`-`/`.` 转 `_` |

`@scope` 即 npm 用户名（`npm whoami` 可查，未登录先 `npm login`）——本插件取 `@liaozhi`， 故包名为 `@liaozhi/dsh-comfyui-based-tools`。

改名 = 换这三样东西，各有固定落点。**漏改不报错**——这些标识只是注册 key，构建/加载 都不校验一致性，漏改只会让对应功能静默失效（面板不出现、RPC 404）， 所以必须逐表核对。建议执行顺序：**先全局换短 id（包名里的短 id 会一并变）→ 再换 3 处 scope → 再换前缀 → 最后核对顺手项**。

### ① npm 包名（scoped）—— 只 3 处

| 位置 | 改成 |
| --- | --- |
| `package.json` 的 `name` | `@<新scope>/<新短id>` |
| `cordis.patch.yml` 的 `name:` | `"@<新scope>/<新短id>"`（**必须加引号**，YAML 里 `@` 是保留指示符；按它解析到包 `exports['.']`） |
| `tsdown.config.ts` banner 的 `__ModuleLoader__` id | 同上（client 按包名发现） |

### ② 短插件 id —— 其余 15+ 处

| 位置 | 改成 |
| --- | --- |
| `cordis.patch.yml` 的 `id:` | `<新短id>` |
| `src/index.ts` 的 `export const name` + Typert `package:` 字段 | 同上（cordis 插件名） |
| `src/client/index.ts` 的 `export const name` + 两处 slot `id` | 同上 |
| `src/remote.ts` 的端点描述符 `id`（`<短id>#…`） | 同上（Typert 关联） |
| `tsdown.config.ts` 的 CSS 虚拟模块前缀 + 插件名 | 同上 |

### ③ 环境前缀 —— 2 处 + 各文件错误/日志前缀

| 位置 | 改成 |
| --- | --- |
| `src/version-gate.ts` 错误前缀、`DSH_<前缀>_STRICT` 变量名 | `<新前缀>` + `_STRICT` |
| `src/shared/disabled-flag.ts` 的 `__DSH_<前缀>_DISABLED__` 变量名 | `__<新前缀>_DISABLED__` |
| `src/update-state.ts` 的错误/日志前缀（`dsh-comfyui-based-tools:` / `[dsh-comfyui-based-tools]`） | 换成新短 id（包名/版本本身从自身 package.json 读，无需改） |

### ④ 顺手项

| 位置 | 改成 |
| --- | --- |
| `src/client/locales.ts` 的 `title`（配置页标题；插件页条目名与导航 label 由插件页按包清单自带，无需 locale key） | 你的 UI 标识（如 "Meme 生成"） |
| `src/shared/update-contract.ts` 端点 namespace（`'comfyui-tools/…'`）与 `src/remote.ts` 的 `namespace` / `serviceKey` / `service` | 与 Typert 服务名同源，改服务名时一并改 |
| `LICENSE` 版权行 | 你的名字 |
| `README.md` / `AGENTS.md` / 示例文案里出现的旧短 id | 同上 |

### 验证

1.  `pnpm install`（自动跑 `prepare` 完成首次构建）
2.  `pnpm typecheck && pnpm build` 通过
3.  `git grep <旧短id>` 与 `git grep <旧包名>`，全仓应无残留
4.  若该目录此前已装进 profile：重跑 `dsh plugin --profile web add`

## 开发与生效

**唯一生效路径 = 构建后重启/重装 DeepSeek Harness**（本插件不接热加载开发流）：

```sh
pnpm install      # 首次（prepare 自动构建）
pnpm build        # 之后的每次改动
```

然后**重启 DeepSeek Harness**（或到「插件」页卸载本插件后重装）即可看到变更。 离线守护不依赖实例与费用：`node scripts/smoke-offline.mjs`。

## 发版纪律（version bump）

**改 `package.json` 的 `version` 后跑一次构建**：`scripts/gen-version.mjs` 处在 build 链首步，负责重生成 `locale/{zh,en}.json` 的**包显示元数据**（插件页卡片的 title 与 兼容窗口描述）——漏跑会让卡片上的版本窗口停在旧值。卡片 title 取自词典的 **`pluginName`（插件身份名）**，不是面板标题 `title`——改面板标题不会、也不该 改掉插件名。

-   **bump 走生命周期**：`pnpm version patch --no-git-tag-version`（或 `minor` / `major`）， 再 `git commit -am "chore(release): x.y.z"`。`package.json` 的 `"version"` 生命周期 脚本会自动跑 `gen-version` 并 `git add locale/`，让新版本号与重生成的元数据落在同一次 提交里。**三个实测边界**：① `<patch|minor|major>` 是 **`pnpm version` 命令**的参数， `"version"` 脚本自身**不收任何参数**（脚本内 `npm_package_version` 已是 bump 后的新值）； ② 脏工作树直接被拒（`ERR_PNPM_UNCLEAN_WORKING_TREE`——git-ignored 的 `lib/`、 `extracted-workflows/` 不算脏）；③ **别用 `pnpm run version`**——那只是直跑脚本、 **不 bump**。想去掉 `--no-git-tag-version` 让 pnpm 自动提交并打 `vX.Y.Z` tag 的话， 配 `-m "chore(release): %s"`；
-   发版前的完整守护是 `node scripts/smoke-offline.mjs`（**0g 节**守护 locale 元数据与 `src/version-gate.ts` 的窗口一致；另需 git-ignored 的 `extracted-workflows/` 取证缓存）。

**【0.2.1 起】原先还有一层"版本烧录 + 提交期闸门"**（`src/client/build-version.ts` 的 `BUILD_VERSION`、`scripts/check-version-sync.mjs`、`.githooks/pre-commit`）——那是为 **陈旧代码检测**服务的。该检测已随上游修复整体拆除（卸载→重装不重启由 harness 自行 驱逐旧模块，2026-10-19 真机确认），闸门与生成步骤一并删除，**不要再加回来**：取证与 回退记录见 `docs/harness-defect-workarounds.md` 的历史防护回退块。

## 本地版本 bump 测试（Verdaccio）

「版本提示」弹窗（available）与\*\*「卸载重装免重启生效」\*\*的端到端验证台，两种模式：

```sh
pnpm test-version-bump                                     # 交互式：先选模式（缺省 bump）
pnpm test-version-bump --mode bump                         # bump 模式（工作区当前版本 → patch+1）
pnpm test-version-bump --mode commit --a <ref> --b <ref>   # commit 模式（commit a 旧版本 / commit b 新版本）
```

**两种模式的差别只在「两个被测版本从哪来」**：bump 模式把工作区当前版本作为版本 A、 A 的 patch+1 作为版本 B（同一个工作区构建两次，适合改完 UI 立刻验证）；commit 模式把 commit a、b 的代码树各自 checkout 到临时 git worktree 里构建（**工作区不被触碰，未提交 改动不进入构建**，适合验证某个已提交的 UI 改动）。

**commit 模式的「版本相同」陷阱**：本仓库 `chore(release)` 与 `feat` 提交分离，提交 UI 改动时 package.json 的 version 往往还没抬——a、b 版本相同就构不成 bump 对比。此时**只有 commit b 恰为当前最新提交（HEAD）才能测**：脚本在 b 的 worktree 里把版本临时 patch+1 作为 新版本（只改工作文件、不提交，随临时 worktree 一起丢弃）；**b 不是最新提交则不做任何改动、 输出警告并直接退出（exit 2）**——请先 `git checkout <commit b>`（或把 b 合并/rebase 到当前 分支）让 b 成为 HEAD，或改用 bump 模式。两版 version 本来就不同时直接用各自版本。

脚本按阶段自动/交互执行，**dsh 内一律通过 Verdaccio npm 源安装被测包，文件夹形式安装 的副本不参与测试**（脚本会清理链接残留）：

1.  **准备**：你在 dsh 插件页卸载本插件 → **重启 dsh**；脚本清理桌面 profile 里 文件夹安装的残留副本（`<user_home>/.dsh/profiles/desktop/node_modules/<包名>`， 链接安装只删链接不进工作区）；
2.  **基线（版本 A）**：候选源首位注入本地 Verdaccio → 构建 → 打包 → 发布 → 你在插件添加页选**自定义 npm 源**（`127.0.0.1:4873`）安装版本 A——这是**新装插件， 不用重启 dsh**（bump 模式 = 工作区当前版本；commit 模式 = commit a 的代码在临时 worktree 里构建）；
3.  **新版本（版本 B）**：bump 模式 = version patch+1 → 重新构建（locale 显示元数据跟随 新版本；dsh 内副本是 verdaccio 安装的复制品，不受 workspace 构建影响）； commit 模式 = 从 commit b 的代码树构建（版本相同时先临时 patch+1）→ 打包 → 发布；
4.  **验证**：先到「插件」页本插件详情页点一次\*\*「检查更新」按钮\*\*（配置面板标题行右侧） → available 更新弹窗；再到插件详情页**卸载**本插件、然后安装版本 B（**不重启**）→ **0.2.1 起 harness 会在重装时驱逐旧模块**：插件立刻以新版本运行，且**不弹任何 "陈旧代码"对话框**（旧防护已拆除，见 `docs/harness-defect-workarounds.md`）—— 这既是版本更新闭环的验证，也是"上游修复"的回归断言；
5.  **还原**：候选源回官方两源 + **版本号回滚**（bump 模式；package.json 回 bump 前值， 依据 `.verdaccio-storage/version-bump-state.json`——本次 bump 仅为测试造数）
    -   **删除临时 worktree**（commit 模式；工作区自始至终未被改动）+ 重建（bump 模式）
    -   停 Verdaccio。

所有测试资产（verdaccio 配置 / htpasswd / 发布凭据 / tgz / 包数据 / 日志 / bump 状态 / 临时 worktree）都集中在 git-ignored 的 `.verdaccio-storage/`——整删即净，仓库无残留。 还原是脚本的默认行为：无论正常结束、出错还是 Ctrl+C，退出前都会自动执行（候选源回官方 两源 + 版本号回滚 + 删临时 worktree + 重建），无需任何额外命令。

## 依赖版本与追新

harness 处于 0.1 rc 快速迭代期，要点：

-   **peer 与 dev 写同一个 `^<已实测的最低版本>`**：dev = 编译所用版本（typecheck 类型面），peer = 运行时声明。窗口内没有"下限/上限/并集"之分——**不要用范围去"夹"多条 harness 线**（预发布线内跨版本 API 破坏频繁，范围放宽救不了，取证见 `docs/dsh-0.1.5-rc.1-upgrade-report.md` 与 `docs/compat-plan-0.1.7-rc.1.md`）。caret 在预发布线上只覆盖同一 `major.minor.patch` 的更高预发布号，所以 `^0.2.1-rc.1` 覆盖 0.2.1 线内更高预发布号（含 rc.2…rc.5，**pnpm 默认解析语义**下同样成立）——**同 tuple 内追新（如 rc.2→rc.5）默认不需要改依赖，只抬 MAX**；**tuple 变化（如 0.2.0→0.2.1）或跨 minor 迁移（0.1.7→0.2.0）时 caret 取不到新线**（实测 `^0.2.0-rc.1` 对 0.2.1-rc.2 在默认解析下为 false → pnpm 装不到新线的类型面），**MIN/MAX 一并上移 + 依赖下限同步改写**（peer precheck 按 satisfies(includePrerelease) 校验，旧 caret 对新线 runtime 直接 false → 插件被声明面禁用）；**只有同 tuple 内的 MIN 上移**（旧 MIN 从未通过运行时验证 / 已不可安装；dist-tag 被接任本身不构成理由——0.1.5-rc.2 先例已实测旧 MIN 在被接任后仍保留窗口内；本轮 MIN 上移属 **tuple 变化** + 用户指定纳入）时才把依赖下限同步改写到新 MIN。
-   **harness 版本门禁**：模板自带 `src/version-gate.ts`，要求 harness 版本落在 `[MIN_HARNESS_VERSION, MAX_HARNESS_VERSION]` 双边界窗口内（main 当前 `[0.2.1-rc.1, 0.2.1-rc.5]`——rc.5 为当前基线（本机桌面版内置版本），rc.1 为**用户指定纳入**的同 tuple 相邻预发布：取证覆盖、非单独实机验收，见 `docs/compat-plan-0.2.1-rc.2.md`；rc.2→rc.5 为只抬 MAX 的同 tuple 追新，见 `docs/compat-plan-0.2.1-rc.5.md`。**行为地图**：低于 MIN 的宿主由 harness 声明面在组合期拦截（静默跳过、插件无机会出面板）；窗口内正常加载；**高于 MAX 由本插件门禁软禁用并给出可执行的更新/降级指引**）。另有 `src/profile-gate.ts`：无 profile 启动（SDK 嵌入等）或非 desktop profile 时插件软禁用——本插件仅支持 DeepSeek 桌面版（desktop-only 收敛，取证见该文件头注释）。0.1.7 起 harness 自身也做插件兼容性检查（peer 依赖 semver satisfies(includePrerelease) 校验，不满足的插件行在启动组装期直接 disabled；0.2.1 起若声明 `engines.dsh` 则它**单独决定、peers 被忽略**，且三个执行点全在 import 之前——本插件**刻意不用**，理由与激活条件见 `docs/harness-defect-workarounds.md`），插件自身的精细窗口门禁仍在 apply 时执行，两者分工见 version-gate.ts 头注释。**版本源 = runtime 内 `@deepseek-ai/dsh` 包 version**（桌面版应用与 runtime 锁步同版发版，语义与 `dsh --version` 一致）；【不能】读 `@deepseek-ai/dsh-tools` 等内嵌依赖当 harness 版本：caret 语义下实装版本可能高于 CLI 本体（实测 `@deepseek-ai/dsh@0.1.5-rc.1` 内嵌的 dsh-tools 已解析到 0.1.5-rc.2，读它会误判软禁用）。解析锚点 = **桌面单锚**：桌面版 host 子进程由 Electron spawn，`process.argv[2]` = runtimeDir（launcher 硬契约，apps/desktop/src/host-process.ts），读 `<argv[2]>/node_modules/@deepseek-ai/dsh/package.json` 并校验 name。落在窗口外默认**软禁用**：醒目错误日志 + 插件不注册任何业务能力，不影响 DSH 启动；`DSH_COMFYUI_BASED_TOOLS_STRICT=1` 恢复抛错 fail-loud。软禁用时 host 半经 `webserver/index-inject` 向页面注入 `__DSH_COMFYUI_BASED_TOOLS_DISABLED__` 标记（fiber-bound，卸载即撤、无残留），client 半读到后改挂"已停用"说明面板并展示支持版本窗口（`src/shared/disabled-flag.ts` 是两侧共享的标记契约）。

**追新流程（手动，无脚本）**：

版本抬升刻意做成显式手改——目标线选择、破坏面评估、门禁窗口三件事本来就该人工过目（实测教训：`0.1.x` 线内 `0.1.1 → 0.1.2` 这种带破坏性变更的跨 patch 追新会被脚本静默扫进来）。追新的每一步都值得慢下来看一眼：

```sh
# ① 查目标线的最新版本（各 @deepseek-ai/dsh-* 与 harness 同步发版）：
pnpm view @deepseek-ai/dsh versions --json

# ② 手改 package.json：全部 @deepseek-ai/dsh-* 的 peer 与 dev 改为同一个 ^<目标版本>
#    （窗口内没有并集写法；新线才有、只 import type 的包只进 dev）
#    同 tuple 内追新（如 rc.2→rc.5）caret 已覆盖，默认无需改依赖，直接跳到 ④；
#    仅当 MIN 也要上移（旧 MIN 从未实测 / 已不可安装 / tuple 变化）时才同步改写依赖下限

# ③ 同步与验证：
pnpm install
pnpm typecheck && pnpm build        # 红 = 上游破坏性变更，按升级报告的取证清单修

# ④ 实测通过后手动上调 src/version-gate.ts 的 MAX_HARNESS_VERSION
#    （MIN 保持已实测（或用户指定纳入）的最低版本；窗口保持双边界结构）

# ⑤ 同一轮同步指引：AGENTS.md / README.md / version-gate.ts 头注释里的版本表述
#    ——留旧窗口 = 让后续 agent 照旧窗口写代码。
```

-   不用 `pnpm update`：它会剥掉 rc 包的 `^`（实测），且不碰 peer 侧。
-   **窗口 = 已验证承诺**：抬 MAX 等于宣布「插件已在那个版本上验证过」，没实测过的版本不要抬；MIN 保持已实测（或用户指定纳入）的最低版本（main 当前 `[0.2.1-rc.1, 0.2.1-rc.5]`；rc.1 属**用户指定纳入**、取证覆盖而非单独实机验收，已在 `AGENTS.md` 与 `docs/compat-plan-0.2.1-rc.2.md` 如实标注；rc.5 的抬升依据见 `docs/compat-plan-0.2.1-rc.5.md`）。MIN 上移 = 收缩承诺面：**tuple 变化 / 跨 minor 迁移必做**（caret 取不到新线；双窗口需 OR 范围夹线、被禁止）；同 tuple 内只在旧 MIN **从未通过运行时验证**或**已不可安装**（从 npm versions 移除）时做，且须同轮把依赖 caret 下限改写到新 MIN（0.1.7-rc.2 先例即此情形）——**dist-tag 被接任本身不构成理由**（0.1.5-rc.2 先例：已实测旧 MIN 被接任后仍保留窗口）。
-   锁文件会钉住首次安装版本：想每次克隆都最新就删掉它，否则按上面流程主动追新。
-   注意 caret 语义会匹配同 tuple 的更高预发布（`^0.2.1-rc.1` 会解析到 0.2.1 线内更高的 rc/正式版——`0.2.1-rc.2` 在**默认解析**与 satisfies(includePrerelease) 下都命中）——这正是同 tuple 追新无需改依赖的理由：与门禁窗口重合。**tuple 变化即失效**：`^0.2.0-rc.1` 对 0.2.1-rc.2 在默认解析下为 **false**、`^0.1.7-rc.2` 对 0.2.0-rc.1 runtime 为 false（均实测），故 tuple 变化/跨 minor 迁移必须改写依赖下限。

**多线兼容（默认不做）**：

双线/多线支持（peer 并集 + dev 钉线 + 特征探测回退）是 0.1.1→0.1.2 时代的做法，本插件已收敛为单条线（main = 0.2.1 线；compat/0.2.0-rc.1 与 compat/0.1.7-rc.2 分支为冻结的历史发布线；0.1.5 线已随 desktop-only 收敛放弃），不再维护。历史方法论仅存档于 `docs/compat-guide-0.1.1-to-0.1.2.md`（已加归档标注），仅在确需重新引入多线时参考，并须在 `AGENTS.md` 与迁移计划里明确标注为多线。

## 版本更新提示

插件**不自更新**（0.8.0 起安装通道整体删除——进程内安装只会制造「新 UI + 旧内核」错配）：发现新版本只弹窗提示用户「到插件页卸载本插件后重新安装」。**0.2.1 起该两步免重启即生效**（harness 会停掉旧 bundle、丢弃其模块映射后再装新版本；2026-10-19 真机复核确认）；第三方插件仍**没有**「一键更新」——那只对按需官方插件开放（harness 文案：「其他插件请先卸载再安装新版」）。

-   **版本检查**（host 半 `src/update-state.ts` 状态机，client 半面板更新条轮询投影，经 `comfyui-tools/checkUpdate` / `comfyui-tools/getUpdateState` RPC）：当前版本 vs npm registry `/<pkg>/latest`（严格 semver 比较，含预发布规则）；候选源固定官方兜底计划（npm → npmmirror，逐源降级）；apply 启动静默查一次 + 面板「检查更新」手动触发，离线不打扰、手动可重试；
-   **新版本弹窗**（client 半 `GlobalNotice.tsx`，shell.overlay 槽位条目 comfy-update-notice）：`available` 相位弹 NoticeModal（复制的 Modal 本体，neutral）提示卸载后重装；弹窗与配置页更新条均内嵌**可复制的安装 spec 命令片**（`插件包名@最新版本`，复制后粘进「插件」页安装输入框）；「我知道了」仅关闭本次窗口（内存态、零持久化）——下次启动 DSH 若仍未更新则重新弹出（浏览器刷新同样重弹）；
-   **前提**：插件必须已发布到 npm。GitHub-only 分发（未发 npm）时 registry 检查失败——面板静默/手动重试，属预期行为；
-   **软禁用态没有提示 UI**：版本门禁软禁用时 client 半只挂停用面板（不注册版本提醒条目、host 半无 RPC），停用面板自带版本自查与修复引导。

**历史（0.2.1 起已拆除）**：原有一个"陈旧代码"检测（client 半 `StaleBanner.tsx` + 构建期烧录的 `BUILD_VERSION` + 与快照 `currentVersion` 严格不等比较，danger 对话框、共提醒两次），兜底「卸载重装不重启时 host 半继续跑旧代码」这一 harness 缺陷。该缺陷已被上游修复并经 2026-10-19 真机确认，故整个检测连同 `scripts/check-version-sync.mjs`、`.githooks/pre-commit`、smoke 0d 节一并拆除（**不要再加回来**）。**残留在案的已知限制**：`link:` 本地链接 + 手工 build 而不经过插件页操作时，host 半仍持进程内旧模块而浏览器端取到新 bundle —— 开发期照旧「改码/改版本后重启 DeepSeek Harness」。取证与回退记录见 `docs/harness-defect-workarounds.md` 的历史防护回退块。

## 给其它插件用的状态服务

本插件在 host 半 `ctx.provide('comfy-status', ...)` 一个**只读状态服务**，供把本插件作为依赖的其它插件查询身份与当前可用的工具集（同步、零 IO、进程内直调，不走 RPC）。

**依赖方不需要 import 本包任何东西**——服务键是纯字符串约定，`ctx.get('comfy-status')` 一句就判得出"本插件装好了没有"（`undefined` = 没装 / 未启用 / 软禁用），拿到对象再读 `status()`：

```ts
// 依赖方（另一个 DSH 插件）的 host 半
const comfy = ctx.get('comfy-status')       // undefined = 本插件不可用，走回退路径
if (comfy !== undefined) {
  const status = comfy.status()
  // {
  //   name: 'dsh-comfyui-based-tools',        // 插件短 id（不是 npm 包名）
  //   version: '0.8.9' | null,                // 运行中模块自报版本（包损坏时 null）
  //   all_tools_provided: [...7 个工具 ID],   // 本插件提供的全部工具（与配置无关）
  //   ready_tools: [...],                     // 本会话已注册 = 此刻真能调用的子集
  // }
}
```

口径要点：

-   **`ready_tools` 才是"能不能调"的答案**——它是门控真正注册进会话的集合（与面板绿点同一份快照），不是"配置层面就绪"；实例离线时该工具不在其中；
-   每次调用现算、返回副本；两个数组都按 `TOOL_IDS` 声明顺序排列；
-   **服务键刻意与面板 RPC 服务键 `'comfyui-tools'` 分开**：后者是"浏览器 ↔ host"，前者是"插件 ↔ 插件"，互不影响；
-   **契约常量不从插件入口导出**（入口只导出 Loader 约定项 `name`/`Config`/`inject`/`apply`）：依赖方用字符串键 + `ctx.get` 即可，不必把本包加进自己的依赖树；要对照返回形状就看 `src/shared/status-contract.ts`（本包也不产出 `.d.ts`）。

## 发布到 npm

```sh
npm login          # 首次
pnpm publish       # prepack 会自动完成构建
```

`files` 白名单只带运行必需的产物（`lib/index.js`、`lib/client.js`、`cordis.patch.yml`、`icon.svg`、`locale/*.json`），发布前建议 `pnpm pack` 检查内容。用户安装：

```sh
dsh plugin --profile web add dsh-comfyui-based-tools
```

## 上传到 GitHub

直接 push 源码即可（**不要**提交 `lib/`，它在 .gitignore 里）。本模板带了 `prepare` 脚本：用户从 git 安装时 pnpm 会用它现场构建产物（自包含，只依赖 npm 上的公开包）。

用户侧安装分两步（pnpm ≥10 的构建许可要求）：

```sh
# 1. 首次 add 会被 pnpm 拒绝构建脚本，按提示把包名加进 profile 的
#    pnpm-workspace.yaml（~/.dsh/profiles/<profile>/pnpm-workspace.yaml）：
#    allowBuilds:
#      dsh-comfyui-based-tools: true
# 2. 重新执行
dsh plugin --profile web add github:<owner>/dsh-comfyui-based-tools#<commit-sha>
```

> 构建许可 = 允许安装时执行该包的代码，提醒你的用户只对他们信任的包开启，并建议 pin commit。 不想让用户配许可的话，也可以发 npm 或提供 `pnpm pack` 产物（tarball 安装不跑构建）。

## 原理速记

-   **一切都是 Cordis 插件**；通过 `ctx` 注册的都是可逆 effect，卸载自动清理。
-   **分发形态即开发形态**：`exports['.']` 恒指向 `lib/index.js`，npm 包、git 安装、本地开发走同一条加载路径，没有"源码能跑、装上就挂"的落差。
-   **依赖规则**：`@deepseek-ai/*` 一律进 `peerDependencies`（运行时由 harness 安装环境提供；dsh profile 的 pnpm 工作区是 `autoInstallPeers: false` + 安装目录兜底解析，不会为你的 peer 链去 npm 拉包），普通第三方库进 `dependencies`，构建工具进 `devDependencies`。不要把 `@deepseek-ai/*` 放进 `dependencies`。**type-only / 构建期用的基座可同时进 `devDependencies`**（本仓库：`cordis` / `cosmokit` / `schemastery`，以及 `cordis@4.0.5` 的自动补齐 peer `cordis-plugin-include`/`cordis-plugin-group`——dev 只服务本仓库编译与解析一致性，不进发布包；取证 `docs/compat-plan-0.2.1-rc.2.md` §5）。
-   `dsh.client` 声明是包元数据，扫描缓存永不过期：改它要重启 harness。

## 文件清单

```
├── src/index.ts                      # host half 入口（版本门禁 + greet 工具示例 + Typert 端点注册）
├── src/profile-gate.ts               # profile 启动门禁（profileContext 判空；无 profile 启动软禁用）
├── src/version-gate.ts               # harness 版本门禁（软禁用语义 + 桌面单锚 + semver 比较）
├── src/update-state.ts               # 版本提示状态机 host 半（registry latest 检查 + 快照恒填运行中自报版本）
├── src/client/GlobalNotice.tsx       # 更新提示（shell.overlay 槽位条目：NoticeModal 提示卸载后重装）
├── scripts/gen-version.mjs           # 包显示元数据生成（build 链首步：locale/{zh,en}.json 的 title + 兼容窗口）
├── src/shared/disabled-flag.ts       # host→client 的软禁用标记契约（全局变量名 + 载荷形状）
├── src/shared/update-contract.ts     # 版本提示 RPC 契约（端点名 + 请求/结果类型，两端共用）
├── src/remote.ts                     # host 半 Typert 远程端点（comfyui-tools/*，表驱动描述符 + 第三方安全形态）
├── src/css-modules.d.ts              # CSS Modules 导入声明（*.module.css）
├── src/client/index.ts               # client half 入口（词典/槽位注册组装 + 停用标记分支，无 JSX）
├── src/client/locales.ts             # zh/en 词典（所有 UI 文案走 locale key）
├── src/client/api.ts                 # 浏览器 → host 的 RPC 调用（OpResult 统一错误面）
├── src/client/ComfySection.tsx         # 配置页组件（plugins.bundle.config 面板 + 插件更新条）
├── src/client/ComfyDisabledSection.tsx # 版本不兼容"已停用"说明面板
├── src/client/ComfySection.module.css  # 配置页样式（CSS Modules + --dsw 设计令牌）
├── docs/compat-guide-0.1.1-to-0.1.2.md     # 0.1.1↔0.1.2 兼容手册（两线差异取证 + 带代码方案）
├── docs/compat-plan-TEMPLATE.md            # 兼容迁移执行记录骨架（每次追新 cp 一份填写）
├── docs/compat-plan-0.1.7-rc.1.md          # 0.1.5-rc.3→0.1.7-rc.1 兼容迁移执行记录
├── docs/compat-plan-0.1.7-rc.2.md          # 0.1.7-rc.1→0.1.7-rc.2 同线追新执行记录（main 窗口）
├── docs/compat-plan-0.2.0-rc.1.md          # 0.1.7-rc.2→0.2.0-rc.1 跨 minor 迁移执行记录
├── docs/compat-plan-0.2.0-rc.2.md          # 0.2.0-rc.1→0.2.0-rc.2 同线追新执行记录
├── docs/compat-plan-0.2.1-rc.2.md          # 0.2.0-rc.2→0.2.1-rc.2 新线迁移执行记录
├── docs/compat-plan-0.2.1-rc.5.md          # 0.2.1-rc.2→0.2.1-rc.5 同 tuple 追新执行记录（当前窗口）
├── tsdown.config.ts                  # client bundle 构建（CJS 工厂 + 基线外部化 + CSS Modules 内联自注入）
├── tsconfig.json                     # 全量类型检查（pnpm typecheck）
├── tsconfig.build.json               # host 半构建（lib/index.js）
├── cordis.patch.yml                  # bundle 层：安装时插入插件行
└── package.json                      # dsh.bundle + dsh.client 双清单，prepare/prepack 构建
```

## 常见问题

### @liaozhi/dsh-comfyui-based-tools 是什么？

DeepSeek利用插件:把DSH工具接到用户自备的ComfyUI实例\(实例管理\+工具分配\+极大极小H3视频/ Qwen-Image图像工具\)。

### 如何安装 @liaozhi/dsh-comfyui-based-tools？

在项目目录运行 npm install @liaozhi/dsh-comfyui-based-tools，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@deepseek-ai/cordis（^4\.0\.5）、@deepseek-ai/dsh-llm（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-tools（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-session（^0\.2\.1-rc\.1）、@deepseek-ai/schemastery（^3\.18\.5）、@deepseek-ai/dsh-settings（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-attachment（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-util-values（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-client-locale（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-system-prompt（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-client-ui-chat（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-client-ui-tool（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-host-webserver（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-client-ui-slots（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-typert-protocol（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-typert-registry（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-client-ui-layout（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-client-connection（^0\.2\.1-rc\.1）、@deepseek-ai/dsh-client-ui-plugin-manager（^0\.2\.1-rc\.1）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @liaozhi/dsh-comfyui-based-tools 支持 TypeScript 吗？

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

### @liaozhi/dsh-comfyui-based-tools 支持 ESM 还是 CommonJS？

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

### @liaozhi/dsh-comfyui-based-tools 需要什么版本的 Node\.js？

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

### @liaozhi/dsh-comfyui-based-tools 可以商用吗？

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

### @liaozhi/dsh-comfyui-based-tools 还在维护吗？

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

