Skip to content
dsh.fish
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

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source