Bundle
dsh-htmlrun
Publish local single-file HTML to shareable html.run links as a DeepSeek Harness model tool (wraps the zero-dependency htmlrun.cjs CLI).
- Source
- iwker
- License
- MIT
- Updated
- Updated 5 days ago
Readme
# dsh-htmlrun
把 [html.run](https://html.run) 的 HTML 发布能力从 **agent skill** 封装成 **DeepSeek Harness(DSH)插件**,让 DSH 会话内的模型可以直接把本地 HTML 发布成可分享链接。
> GitHub 仓库名与 npm 包名均为 **`dsh-htmlrun`**;harness 插件列表显示时会剥离 `dsh-` 前缀 → **htmlrun**;工具名、插件 `name` 均为 `htmlrun`。
```
用户:"帮我把这个页面发布一下,发给我看看"
↓
DSH 模型调用动态工具 htmlrun (action=publish, file=...)
↓
插件通过 ctx.subprocess 调用 skill 自带 CLI(scripts/htmlrun.cjs)
↓
返回链接、版本、敏感词、指引等信息,由模型原样转达给用户
```
## 目录结构
```
dsh-htmlrun/
├── README.md # 本文件
├── package.json # 组合包(bundle)manifest:包名 dsh-htmlrun,声明 dsh.bundle
├── cordis.patch.yml # 组合包 patch:条目 id=htmlrun,name=dsh-htmlrun
├── lib/
│ └── index.js # 插件真实模块入口(ESM,import defineTool + ctx.tools.register)
├── plugin/
│ └── htmlrun-publish/
│ └── host.js # 动态插件形态(code.host,会话内 cordis_define 用,免安装)
└── skill/ # 原始 htmlrun skill(v2.0.1,MIT,原样拷贝,随项目分发)
├── SKILL.md # skill 说明文档
├── scripts/htmlrun.cjs # 零依赖 CLI(Node >= 16),插件的实际执行体
└── references/api.md # html.run 服务端接口参考
```
两种形态共享同一套执行逻辑(子进程调 CLI、token 存 `~/.htmlrun/config`):
- **动态插件**(`plugin/htmlrun-publish/host.js`):会话内 `cordis_define` 加载,免安装、进程内临时;
- **组合包**(仓库根:`package.json` + `cordis.patch.yml` + `lib/index.js`):可安装进 profile 的正式形态,用于发布到社区。
## 原理
- **不重写 HTTP 层**:插件的 `execute` 用 `ctx.subprocess` 把 `node scripts/htmlrun.cjs <动作>` 作为子进程跑起来,输出原样透传给模型转达——行为与 skill 里 CLI 逐字节一致,包括激活二维码、敏感词、`⚠ 已被限制访问`、`说明:`/`指引:` 等字段。
- **凭据互通**:CLI 的 token 存在 `~/.htmlrun/config`,插件与终端里手工使用 CLI 是同一份凭据,无需重复激活。
- **为什么不直接用网络服务**:DSH 动态插件沙箱禁用了 `fetch`/`require`,而 `ctx.web.fetch` 只支持无头 GET(无法发 POST + Authorization),调不了 html.run 的发布接口;`ctx.fs` 写 `~` 会被 workspace-write 沙箱拒绝。`ctx.subprocess` 是本地未加沙箱的子进程服务(`dsh-bash-local` 同样用它),是唯一能完整跑 CLI 的路径。
## 快速开始(动态插件,会话级)
1. 确认本机有 Node(`node --version`,需 >= 16),并保证 `skill/scripts/htmlrun.cjs` 可用(本仓库自带)。
2. 在 DSH 会话中加载插件(把 `plugin/htmlrun-publish/host.js` 的内容作为 `code.host`):
- **cordis_define**(新插件):`plugin.kind = "new"`、`idPrefix = "hpub"`、`code.host = host.js 全文`;
- **cordis_run**:激活后即向当前会话注册模型工具 `htmlrun`。
3. 之后直接对模型说"发布 xx.html / 更新一下链接"即可,模型会调用 `htmlrun` 工具。
### CLI 路径解析
插件按以下顺序确定 `htmlrun.cjs` 的位置:
1. 调用时显式传 `cliPath` 参数(绝对路径);
2. 当前 workspace 下的 `skill/scripts/htmlrun.cjs`(把本仓库作为 DSH workspace 时自动命中);
3. 两者都找不到时返回明确错误,提示用户传 `cliPath` 或把仓库作为 workspace。
## 工具参数
| 参数 | 说明 |
|---|---|
| `action` | 必填。`check`(检查/发起激活)· `publish`(发布或更新)· `bind`(配对码换 token)· `login`(手工配置 token)· `logout`(清除 token)· `whoami`(查看状态) |
| `file` | `publish` 用:HTML 文件绝对路径或相对 workspace 路径 |
| `note` | `publish` 用:本次发布/更新的简短说明(可选) |
| `forceNew` | `publish` 用:强制新建工件拿全新链接(慎用;默认同路径自动更新原链接,版本 +1) |
| `noInline` | `publish` 用:不内联本地资源(默认自动内联,只内联 HTML 所在目录内的文件) |
| `code` | `bind` 用:管理端「绑定设备」给的 8 位配对码 |
| `token` | `login` 用:手工配置的 publish token(`h_` 开头) |
| `cliPath` | 可选:覆盖 htmlrun.cjs 的位置 |
## 常见流程
- **首次使用**:`action=check`——未激活时返回激活链接与二维码,转达用户,等用户确认后再 `check` 一次;已激活则静默通过。
- **发布**:`action=publish, file=...`;成功后把输出里的 `链接:` 原样给用户,出现 `敏感词(N)`/`⚠ 已被限制访问`/`说明:`/`指引:` 时原样转达,不要说"发布成功"糊弄过去。
- **更新**:改完内容后对**同一文件路径**再次 `publish`(不加 `forceNew`),链接不变、版本 +1。
- **token 纪律**:token 明文不要出现在对话回复或日志里;`login` 只把 `h_` 开头的值传给工具,之后不要复述。
## 发布到插件社区
DeepSeek Harness 目前**没有官方的中心化插件商店**;官方推荐的插件分发方式是把插件打包成**组合包(bundle)**发布到 npm 或 GitHub,并在仓库打上 `dsh-plugin` 话题便于社区发现(官方 [CONTRIBUTING](https://github.com/deepseek-ai/deepseek-harness/blob/HEAD/CONTRIBUTING.md) 明确推荐,官方仓库暂不接受外部 PR)。本仓库根目录已经是标准 bundle 结构。
### 分发渠道(三选一)
**1. GitHub(推荐,零构建门槛)**
本插件是纯 JavaScript,无需构建,git 安装**不需要** `prepare` 脚本授权:
```sh
# 推送到 GitHub 后,用户安装(仓库名 dsh-htmlrun):
dsh plugin --profile <name> add github:iwker/dsh-htmlrun#<commit-sha>
```
建议锁定 commit(`#<sha>`),防止仓库后续推送悄悄改变实际运行的代码。仓库创建后到 Settings → Topics 添加 `dsh-plugin` 话题。
**2. npm 注册表**
```sh
pnpm publish # 或 npm publish(需先登录;包名 dsh-htmlrun,npm 上尚无人占用)
# 用户安装:
dsh plugin --profile <name> add dsh-htmlrun
```
发布到 npm 的内容由 `package.json` 的 `files` 字段控制(`lib/`、`skill/scripts/`、`cordis.patch.yml`、`README.md`),用户拿到的是预构建代码。安装后 harness 插件列表显示的标题是 **htmlrun**(`dsh-` 前缀由界面自动剥离)。
**3. tarball(自建分发)**
```sh
pnpm pack # 生成 dsh-htmlrun-0.1.1.tgz
# 用户安装:
dsh plugin --profile <name> add ./dsh-htmlrun-0.1.1.tgz
```
### 安装后验证
```sh
dsh --profile <name> --dump-config # 应出现 "# == dsh-htmlrun" 层
dsh --profile <name> # 启动,然后在对话里让模型发布 HTML
```
### 社区发现渠道
- GitHub 话题 [`dsh-plugin`](https://github.com/topics/dsh-plugin)(官方推荐)
- [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin)(社区清单,PR 收录)
- [awesome-deepseek-harness](https://github.com/Dominic789654/awesome-deepseek-harness)(社区清单,PR 收录)
- [dshfind](https://github.com/hikariming/dshfind)(社区插件市场)
### 与配置 key 的关系
本插件不需要为 DSH 配置任何 key:html.run 的 publish token 由 CLI 自行管理(`~/.htmlrun/config`)。若插件自身需要接入 DSH 的密钥体系(比如调用别的服务),官方做法是用 `ctx.credentials` 服务(见 host.js 里的说明),配置里只存环境变量名,值放 `$DSH_HOME/.credentials.yaml` 或启动环境变量。
## 已知边界
- 只支持单文件静态 HTML(CSS/JS 需内嵌或用本地相对引用;本地图片等资源由 CLI 自动内联)。
- 不支持需要构建、需要后端的完整项目;不支持自定义域名等 html.run 未提供的能力。
- 动态插件是进程内临时的,DSH 进程重启后需重新加载(`@hpub-1` 引用或重新 cordis_define)。
- `token` 保存在 `~/.htmlrun/config`(0600),换机器/换路径发布会被视为新工件(`path` 参与工件匹配)。
## 许可与来源
- 仓库根 bundle(`package.json`、`cordis.patch.yml`、`lib/index.js`)与 `plugin/htmlrun-publish/host.js`:本仓库作者编写,MIT。
- `skill/`:原样拷贝自 html.run 官方发布的 htmlrun skill v2.0.1(MIT),随项目分发;升级请替换整个 `skill/` 目录,不要单独改 `scripts/htmlrun.cjs`(其内部与服务端逐字节对齐,禁止私自分叉)。bundle 通过 `lib/index.js` 的 `import.meta.url` 相对引用 `skill/scripts/htmlrun.cjs`,保持单一来源。
Install
dsh plugin --profile web add github:iwker/dsh-htmlrun
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-htmlrun from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.