kimi-webbridge-dsh 1.4.9 → 1.4.11
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 +30 -141
- package/lib/index.js +48 -11
- package/package.json +3 -3
- package/scripts/fetch-upstream-skill.mjs +3 -3
- package/skill/README.md +1 -1
- package/skill/SKILL.md +10 -6
- package/skill/UPSTREAM.json +7 -7
package/README.md
CHANGED
|
@@ -1,172 +1,61 @@
|
|
|
1
1
|
# kimi-webbridge-dsh
|
|
2
2
|
|
|
3
|
-
Kimi
|
|
3
|
+
把 [Kimi 浏览器扩展](https://www.kimi.com/products/kimi-webbridge)(Kimi Browser Extension,原 Kimi WebBridge)接进 dsh:**供应守护进程 + 注册官方技能包**。插件本身不代理浏览器操作——浏览器能力全部由官方技能文档描述,模型照它驱动本地守护进程。
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
2. **注册官方技能包**:把**原样内置**的上游技能包(`skill/SKILL.md` + `skill/references/**`,与官方 CDN 逐字节一致、按摘要锁定)注册为运行时 skill,并把该目录作为 skill 的 `resourceBase` 暴露给模型 —— 这是 skill 正文里 `references/...` 链接能被解析的前提;
|
|
7
|
-
3. **注册一个瘦工具 `kimi_webbridge`**:只有 `status` 一个动作(守护进程 + 扩展 + 已安装技能副本健康检查),作为其他 skill(如 x-cli 系列)的桥健康锚点。
|
|
8
|
-
|
|
9
|
-
## 架构
|
|
10
|
-
|
|
11
|
-
| 层 | 角色 |
|
|
5
|
+
| 职责 | 说明 |
|
|
12
6
|
|---|---|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
| 运行时增量(`DSH_RUNTIME_SECTION`,本插件追加) | 仅 dsh 特有差异:工具名映射(`read`/`read_image`/`bash`)、`kimi_webbridge` 健康锚点、references 解析方式、不要替 dsh 跑 `install-skill` |
|
|
17
|
-
| 瘦工具 `kimi_webbridge` | 仅 `status` 健康检查(自带守护进程自愈) |
|
|
18
|
-
|
|
19
|
-
**上游文档原样内置 + 末尾追加 dsh 差异**是刻意的分层:升级技能 = 覆盖文件,永远不需要合并散文,也就不会再次出现"文档停在旧版本"的漂移。
|
|
20
|
-
|
|
21
|
-
## 上游文档同步(本插件的核心维护动作)
|
|
22
|
-
|
|
23
|
-
上游把 skill 与守护进程二进制**同版本发布**在同一个 CDN:
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
https://cdn.kimi.com/webbridge/<release>/skills/kimi-webbridge.tar.gz
|
|
27
|
-
https://cdn.kimi.com/webbridge/<release>/skills/kimi-webbridge-windows.tar.gz # 与上面逐字节相同
|
|
28
|
-
```
|
|
7
|
+
| 守护进程供应 | 按官方清单下载对应平台二进制(SHA-256 校验),未运行时自动拉起;落在 `~/.kimi-webbridge/bin/` |
|
|
8
|
+
| 技能注册 | 随包内置官方技能文档(含 `references/`),启动时注册为 `kimi-webbridge` skill |
|
|
9
|
+
| 健康锚点 | 瘦工具 `kimi_webbridge`,只有 `status` 一个动作(守护进程 + 扩展 + 已装技能副本) |
|
|
29
10
|
|
|
30
|
-
|
|
11
|
+
## 安装
|
|
31
12
|
|
|
32
13
|
```bash
|
|
33
|
-
npm run fetch-skill # 拉取 latest,重写 skill/
|
|
34
|
-
node scripts/fetch-upstream-skill.mjs --version v2.0.22 # 或锁定具体版本
|
|
35
|
-
node scripts/fetch-upstream-skill.mjs --check # 只报告上游是否已变动(不写盘)
|
|
36
|
-
node scripts/fetch-upstream-skill.mjs --verify-local # 不联网:校验本地文件与清单一致
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
`skill/UPSTREAM.json` 记录:release、tar 包 SHA-256、每个文件的 SHA-256 与字节数、抓取时间。脚本拒绝安装 frontmatter 版本与 release 不一致的包,也拒绝两个平台变体不一致的情况。
|
|
40
|
-
|
|
41
|
-
## 安装(一次性,零手工配置)
|
|
42
|
-
|
|
43
|
-
```powershell
|
|
44
14
|
dsh plugin --profile web add kimi-webbridge-dsh
|
|
45
15
|
```
|
|
46
16
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
## 用法(模型视角)
|
|
50
|
-
|
|
51
|
-
1. 需要真实浏览器时,加载 `kimi-webbridge` skill(触发词:browser / webpage / open URL / 浏览器 / 网页 / 截图……;"给某个网站做个可复用的 CLI" 也走这个 skill);
|
|
52
|
-
2. 先用 `kimi_webbridge` 工具的 `status` 确认守护进程 + 扩展健康(插件自动补装/拉起二进制);
|
|
53
|
-
3. 按 skill 文档向 `POST http://127.0.0.1:10086/command` 发送 `{action, args, session}`。技能正文里的 `references/...` 路径以 skill 加载时返回的 `resourceBase` 目录为基准,用 `read` 工具读取。
|
|
54
|
-
4. Windows 上必须用临时文件承载 JSON(shell 会破坏非 ASCII 文本),skill 里有完整说明。
|
|
55
|
-
|
|
56
|
-
## 依赖
|
|
57
|
-
|
|
58
|
-
- **浏览器扩展**:需安装并连接 Kimi 浏览器扩展(Kimi Browser Extension,原 Kimi WebBridge)—— 从 [Chrome Web Store](https://chromewebstore.google.com/detail/kimi-webbridge/fldmhceldgbpfpkbgopacenieobmligc) 安装(`kimi_webbridge status` 显示 `extension_connected: true`;扩展版本应与守护进程一致)。
|
|
59
|
-
- **守护进程**:无需预装。插件在守护进程不可达时会自动启动它;二进制缺失时会自动从官方 CDN(cdn.kimi.com,与官方安装器同源)下载安装——全程无需手动运行任何安装命令。
|
|
60
|
-
|
|
61
|
-
### 版本对齐
|
|
62
|
-
|
|
63
|
-
插件按官方 CDN 的 `version.json` 供应守护进程,因此始终与官方发布对齐;下表哈希对应 **v2.0.22**(守护进程与扩展的产品名已更名为 Kimi Browser Extension)。
|
|
64
|
-
|
|
65
|
-
`kimi_webbridge` 的 `status` 会原样透出守护进程的 `update_available`(有更新时)、`version_mismatch`(守护进程与扩展不同步时)、`skills`(守护进程在各 agent 运行时里发现的技能副本)与 `skill_mismatch`(这些副本与扩展不同步时)。按官方约定:出现这些字段时**不要**自动执行 `upgrade` / `stop` / `restart` / `uninstall`(它们会杀掉正在运行的守护进程),而应把字段里的 `command` 原样交给用户执行。
|
|
66
|
-
|
|
67
|
-
> dsh 不在守护进程识别/安装技能的运行时列表内(它只认 Claude Code / Codex / Hermes / OpenClaw / Kimi),所以 `skills` 为空是 dsh 下的正常结果 —— dsh 拿到技能的唯一途径就是本插件。
|
|
68
|
-
|
|
69
|
-
### 上游能力对齐(v2.0.8 → v2.0.22)
|
|
70
|
-
|
|
71
|
-
本插件曾停留在按 v2.0.8 手写的文档上。改为内置上游技能包后,以下上游变化自动跟进(也记录在此便于回顾):
|
|
72
|
-
|
|
73
|
-
| 上游版本 | 新增/变化 |
|
|
74
|
-
|---|---|
|
|
75
|
-
| v2.0.16 | **CDP 焦点仿真**:后台标签页的真实输入需先 `cdp Emulation.setFocusEmulationEnabled {"enabled":true}`;`Page.bringToFront` 语义重写(先开仿真、不抢用户焦点);`Target.activateTarget` 被拒绝 |
|
|
76
|
-
| v2.0.17 | **cli-creator 工作流**(`references/cli-creator/*` 五篇):为网站生成可复用 CLI(勘探协议 → 实现 → 配套 skill);`network` 增加 `bodyError` 语义(`detail` 必须在 `stop` 之前调用) |
|
|
77
|
-
| v2.0.21 | **iframe/frame 读取**:`snapshot` 返回 `frames: [{frame, url, size}]`、`read_page {"frame":"#f1"}`、`wait {"frame":"any"}`;取代旧的"跨域 iframe 请直接导航"限制 |
|
|
78
|
-
| v2.0.9–v2.0.15 / v2.0.18–v2.0.20 / v2.0.22 | 文档无实质变化(v2.0.22 仅改 frontmatter 版本号) |
|
|
79
|
-
|
|
80
|
-
另有早已存在于上游、但旧手写文档遗漏的部分:`ok/data` 回包信封与 `extension_not_connected` 错误码、`find_tab` 按 host 匹配、`status` 的 `skills` / `skill_mismatch`、守护进程 `install-skill` / `upgrade` 子命令、`references/operations.md`。
|
|
81
|
-
|
|
82
|
-
### 兼容性(dsh 版本)
|
|
83
|
-
|
|
84
|
-
插件只 import 宿主提供的 `@deepseek-ai/*` 包,并声明为 `peerDependencies`(不打包自己的副本),所以与 dsh 版本解耦;已在 **dsh 0.1.7-rc.2** 上验证:工具注册、skill 注册(含 `resourceBase` 与 references 解析)、system prompt 注入、`kimi_webbridge status` 健康检查均正常。技能注册走 `ctx.skills.register`(运行时技能),并额外传入 `resourceBase: { kind: "directory", path: <skill 目录> }`——宿主会把该目录作为 skill 的基准目录渲染给模型。
|
|
85
|
-
|
|
86
|
-
| peer | 声明范围 |
|
|
87
|
-
|---|---|
|
|
88
|
-
| `@deepseek-ai/dsh-tools` | `^0.1.0-rc.7 \|\| ^0.1.1-rc.2 \|\| ^0.1.2-rc.1 \|\| ^0.1.5-rc.1 \|\| ^0.1.7-rc.2` |
|
|
89
|
-
| `@deepseek-ai/dsh-llm` | 同上 |
|
|
90
|
-
| `@deepseek-ai/schemastery` | `^3.18.1` |
|
|
17
|
+
自带 bundle patch,无需手改 `cordis.patch.yml`;重启一次 dsh 生效。
|
|
91
18
|
|
|
92
|
-
|
|
19
|
+
## 用法
|
|
93
20
|
|
|
94
|
-
|
|
21
|
+
1. 需要真实浏览器时加载 `kimi-webbridge` skill(触发词:browser / 网页 / 截图 / ……,也包括"给某个网站做个可复用 CLI");
|
|
22
|
+
2. 先调 `kimi_webbridge` 的 `status` 确认守护进程 + 扩展健康(会自动补装 / 拉起);
|
|
23
|
+
3. 按 skill 文档 `POST http://127.0.0.1:10086/command`,请求体 `{action, args, session}`;
|
|
24
|
+
4. Windows 必须用临时文件承载 JSON 请求体(shell 会破坏非 ASCII),skill 里有说明。
|
|
95
25
|
|
|
96
|
-
|
|
26
|
+
工具清单、参数与注意事项一律以 skill 文档为准。
|
|
97
27
|
|
|
98
|
-
|
|
99
|
-
|---|---|---|
|
|
100
|
-
| Windows x64 | `windows-amd64.exe` | `8e9dfc5b…eb338` |
|
|
101
|
-
| macOS arm64 | `darwin-arm64` | `f36dfeba…901f0` |
|
|
102
|
-
| macOS x64 | `darwin-amd64` | `ad9aba7d…8d4ba` |
|
|
103
|
-
| Linux arm64 | `linux-arm64` | `6f083744…5527f` |
|
|
104
|
-
| Linux x64 | `linux-amd64` | `0d1b2bf5…fdcf6` |
|
|
105
|
-
|
|
106
|
-
技能包(两个平台变体逐字节相同)v2.0.22 的 tar 摘要:`4068a646…678ed1`。
|
|
107
|
-
|
|
108
|
-
不支持的平台组合会明确报错并提示手动安装。
|
|
28
|
+
## 配置
|
|
109
29
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
下载到用户目录(与官方安装器路径一致,无需管理员权限;按用户隔离):
|
|
113
|
-
|
|
114
|
-
| 平台 | 最终路径 |
|
|
115
|
-
|---|---|
|
|
116
|
-
| Windows | `%USERPROFILE%\.kimi-webbridge\bin\kimi-webbridge.exe` |
|
|
117
|
-
| macOS / Linux | `~/.kimi-webbridge/bin/kimi-webbridge`(自动 `chmod 755`) |
|
|
118
|
-
|
|
119
|
-
下载流程:先落盘为临时文件(`kimi-webbridge(.exe).tmp-{pid}-{时间戳}`)→ SHA-256 与官方清单核对 → 匹配才重命名为最终路径;不匹配则删除临时文件并中止,任何未验证的二进制都不会留在磁盘。该路径与官方安装器 / `kimi-webbridge upgrade` 命令完全一致,插件、官方工具共用同一份守护进程。
|
|
120
|
-
|
|
121
|
-
## 功能(上游技能承载)
|
|
122
|
-
|
|
123
|
-
以官方文档为准(见 `skill/SKILL.md`),主要能力域:
|
|
124
|
-
|
|
125
|
-
| 能力 | 说明 |
|
|
126
|
-
|---|---|
|
|
127
|
-
| 导航 / 标签 | `navigate`、`find_tab`(按 host 匹配本会话标签页,`active:true` 借用用户正在看的标签页)、`list_tabs`、`close_tab`、`close_session` |
|
|
128
|
-
| 读页面 | `snapshot`(accessibility tree + `@e` 引用,并在有 iframe 时返回 `frames`)、`read_page`(全文文本,可 `{"frame":"#f1"}` 读 frame)、`find` |
|
|
129
|
-
| 点击 / 输入 | `click`、`fill`(含 ProseMirror/Lexical/Slate 等 contenteditable)、`hover`、`drag`、`select_option`、`dialog`、`scroll`、`wait`(支持 `{"frame":"any"}`) |
|
|
130
|
-
| 可信输入 | `mouse_click` / `key_type` / `send_keys`(CDP 真实输入);后台标签页需先用 `cdp` 打开焦点仿真 |
|
|
131
|
-
| JS / CDP | `evaluate`(页面上下文)、`cdp`(chrome.debugger 直通) |
|
|
132
|
-
| 截图 / PDF | `screenshot`、`save_as_pdf`(写文件、返回路径) |
|
|
133
|
-
| 网络 / 上传 | `network`(请求捕获;`detail` 须在 `stop` 前)、`upload` |
|
|
134
|
-
| 会话分组 | 一个任务 = 一个 session = 一个标签页组,可一键清理 |
|
|
135
|
-
| 生成 CLI | `references/cli-creator/*`:为某个网站做可复用 CLI + 配套 skill(勘探 → 实现 → 验证) |
|
|
136
|
-
|
|
137
|
-
## 配置(可选)
|
|
138
|
-
|
|
139
|
-
在 profile 的用户补丁层(`~/.dsh/profiles/web/cordis.patch.yml`)按 id 覆盖配置(替换整份 config,未给出的键取默认值):
|
|
30
|
+
在 `~/.dsh/profiles/web/cordis.patch.yml` 按 id 覆盖(整份替换,未给出的键取默认):
|
|
140
31
|
|
|
141
32
|
```yaml
|
|
142
33
|
- id: kimi-webbridge
|
|
143
34
|
config:
|
|
144
|
-
|
|
145
|
-
daemonVersion: v2.0.22
|
|
35
|
+
daemonVersion: v2.0.23
|
|
146
36
|
```
|
|
147
37
|
|
|
148
|
-
|
|
|
38
|
+
| 键 | 默认 | 说明 |
|
|
149
39
|
|---|---|---|
|
|
150
40
|
| `baseUrl` | `http://127.0.0.1:10086` | 守护进程地址 |
|
|
151
|
-
| `requestTimeoutMs` | `120000` |
|
|
152
|
-
| `autoStartDaemon` | `true` |
|
|
153
|
-
| `autoInstallDaemon` | `true` |
|
|
154
|
-
| `daemonVersion` | `latest` |
|
|
155
|
-
| `registerSkill` | `true` |
|
|
41
|
+
| `requestTimeoutMs` | `120000` | 单次请求超时(ms) |
|
|
42
|
+
| `autoStartDaemon` | `true` | 未运行时自动启动 |
|
|
43
|
+
| `autoInstallDaemon` | `true` | 二进制缺失时自动下载安装 |
|
|
44
|
+
| `daemonVersion` | `latest` | 自动安装的版本,带 `v` 前缀,建议与扩展版本一致 |
|
|
45
|
+
| `registerSkill` | `true` | 注册 `kimi-webbridge` skill |
|
|
156
46
|
|
|
157
|
-
##
|
|
47
|
+
## 要求与提示
|
|
158
48
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
CI:`publish.yml` 在发布前跑 `npm run check`(离线、必须通过)并**报告**上游漂移(不阻断发布);`skill-drift.yml` 每周一跑 `--check`,上游一有变动就让任务失败,避免再次静默落后。
|
|
49
|
+
- **浏览器扩展**:需自行安装并连接([Chrome Web Store](https://chromewebstore.google.com/detail/kimi-webbridge/fldmhceldgbpfpkbgopacenieobmligc));`status` 显示 `extension_connected: true` 即可用。
|
|
50
|
+
- **守护进程**:无需预装,插件自动供应;与官方安装器共用 `~/.kimi-webbridge/bin/`(Windows `%USERPROFILE%\.kimi-webbridge\bin\`)。
|
|
51
|
+
- **dsh 版本**:只 import 宿主提供的 `@deepseek-ai/*`(声明为 peer,不打包副本),已在 **0.2.0-rc.1** 验证,peer 范围覆盖 0.1.0-rc.7 起的整个 0.1.x / 0.2.x。dsh 换代后如果 `kimi_webbridge` 工具、系统提示段落和 skill 一起消失,通常就是插件版本还没覆盖新 dsh——升级本插件再重启即可。
|
|
52
|
+
- **`status` 里的 `version_mismatch` / `update_available` / `skill_mismatch`**:把其中的 `command` 原样交给用户执行;**不要**自行 `upgrade` / `stop` / `restart` / `uninstall`,它们会杀掉正在运行的守护进程。
|
|
53
|
+
- `status.skills` 为空是正常的:守护进程只识别 Claude Code / Codex / Hermes / OpenClaw / Kimi,dsh 拿到技能的唯一途径就是本插件。
|
|
165
54
|
|
|
166
55
|
## 移除
|
|
167
56
|
|
|
168
|
-
```
|
|
57
|
+
```bash
|
|
169
58
|
dsh plugin --profile web remove kimi-webbridge-dsh
|
|
170
59
|
```
|
|
171
60
|
|
|
172
|
-
|
|
61
|
+
重启后生效;skill 随插件注册,移除即消失。
|
package/lib/index.js
CHANGED
|
@@ -102,16 +102,30 @@ const SKILL_DIR = fileURLToPath(new URL("../skill/", import.meta.url));
|
|
|
102
102
|
const SKILL_PATH = join(SKILL_DIR, "SKILL.md");
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
|
-
* Extra routing
|
|
105
|
+
* Extra routing triggers appended to the description upstream ships.
|
|
106
106
|
*
|
|
107
|
-
* The official description is English;
|
|
108
|
-
*
|
|
109
|
-
*
|
|
107
|
+
* The official description is English; the Chinese terms are what the same users type,
|
|
108
|
+
* and the CLI trigger is one upstream only states at the very end of a long paragraph.
|
|
109
|
+
* Keeping them here (rather than rewriting the vendored frontmatter) is what lets
|
|
110
|
+
* `skill/UPSTREAM.json` stay byte-exact against the CDN.
|
|
110
111
|
*/
|
|
111
|
-
const
|
|
112
|
+
const SKILL_EXTRA_TRIGGERS = "Also use to build a reusable CLI or script that automates a specific website. Also use when the user mentions 浏览器 / 网页 / 打开网页 / 截图 / 页面.";
|
|
112
113
|
|
|
113
|
-
/**
|
|
114
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Length of the routing line dsh renders in its model-facing skill catalog.
|
|
116
|
+
*
|
|
117
|
+
* `dsh-tool-skill` builds that line from the description and truncates it at
|
|
118
|
+
* `catalogDescriptionMaxLength` (500 by default), silently dropping the rest — so the
|
|
119
|
+
* registered description has to fit, or the model never sees the triggers above.
|
|
120
|
+
*/
|
|
121
|
+
const CATALOG_DESCRIPTION_LIMIT = 500;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Used only when the vendored SKILL.md frontmatter cannot be parsed; a missing description
|
|
125
|
+
* must never disable the skill. Carries no triggers of its own — {@link composeSkillDescription}
|
|
126
|
+
* appends the shared ones either way.
|
|
127
|
+
*/
|
|
128
|
+
const FALLBACK_SKILL_DESCRIPTION = "Drive the user's real browser through the local kimi-webbridge daemon (127.0.0.1:10086) using their login sessions: navigate, read pages and iframes, click, type, screenshot, evaluate JS, raw CDP, network capture, uploads, PDF export, tabs and sessions. Use whenever a task needs a real browser.";
|
|
115
129
|
|
|
116
130
|
/**
|
|
117
131
|
* The section appended after the vendored upstream instructions.
|
|
@@ -186,6 +200,28 @@ function parseFrontmatter(raw) {
|
|
|
186
200
|
return { description, version, body: raw.slice(match[0].length).trim() };
|
|
187
201
|
}
|
|
188
202
|
|
|
203
|
+
/**
|
|
204
|
+
* Compose the registered routing description inside dsh's catalog budget.
|
|
205
|
+
*
|
|
206
|
+
* Upstream's own words lead — they name the product and the core capability — while the
|
|
207
|
+
* added triggers are reserved their space up front, so the truncation dsh applies can
|
|
208
|
+
* never eat them. When upstream does not fit, it is cut at a sentence boundary rather
|
|
209
|
+
* than mid-word, which is what dsh's own truncation would do to the whole line.
|
|
210
|
+
*
|
|
211
|
+
* @param upstream - the description from the vendored SKILL.md frontmatter.
|
|
212
|
+
* @returns a description of at most {@link CATALOG_DESCRIPTION_LIMIT} characters.
|
|
213
|
+
*/
|
|
214
|
+
function composeSkillDescription(upstream) {
|
|
215
|
+
const triggers = SKILL_EXTRA_TRIGGERS;
|
|
216
|
+
const text = upstream.replace(/\s+/gu, " ").trim();
|
|
217
|
+
const room = CATALOG_DESCRIPTION_LIMIT - triggers.length - 1;
|
|
218
|
+
if (text.length <= room) return `${text} ${triggers}`;
|
|
219
|
+
const visible = text.slice(0, room + 1);
|
|
220
|
+
const sentenceEnd = Math.max(visible.lastIndexOf(". "), visible.lastIndexOf("。"));
|
|
221
|
+
if (sentenceEnd > 0) return `${visible.slice(0, sentenceEnd + 1)} ${triggers}`;
|
|
222
|
+
return `${visible.slice(0, room).replace(/[\s,;:.]+$/u, "")} ${triggers}`;
|
|
223
|
+
}
|
|
224
|
+
|
|
189
225
|
/**
|
|
190
226
|
* Load the vendored upstream skill package.
|
|
191
227
|
*
|
|
@@ -194,11 +230,12 @@ function parseFrontmatter(raw) {
|
|
|
194
230
|
*/
|
|
195
231
|
function readSkillPackage() {
|
|
196
232
|
const { description, version, body } = parseFrontmatter(readFileSync(SKILL_PATH, "utf8"));
|
|
197
|
-
|
|
233
|
+
const fallback = typeof description !== "string" || description.length === 0;
|
|
234
|
+
if (fallback) {
|
|
198
235
|
console.warn(`kimi-webbridge: ${SKILL_PATH} has no frontmatter description; falling back to the built-in routing text`);
|
|
199
236
|
}
|
|
200
237
|
return {
|
|
201
|
-
description:
|
|
238
|
+
description: composeSkillDescription(fallback ? FALLBACK_SKILL_DESCRIPTION : description),
|
|
202
239
|
content: `${body}${dshRuntimeSection(version)}`
|
|
203
240
|
};
|
|
204
241
|
}
|
|
@@ -477,12 +514,12 @@ function apply(ctx, config = {}) {
|
|
|
477
514
|
ctx.systemPrompt.section({
|
|
478
515
|
name: "tool:kimi-webbridge",
|
|
479
516
|
order: 105,
|
|
480
|
-
text: "kimi-webbridge: the local kimi-webbridge daemon (127.0.0.1:10086) bridges to the user's real browser with their login sessions; this plugin provisions the daemon binary, keeps it running, and registers the official upstream skill package (with its references/ directory). The `kimi_webbridge` tool is only the status health check (daemon + extension + installed skill copies). For any browser work — navigation, reading pages and iframes, clicking, typing, form filling, trusted input via CDP focus emulation, screenshots, JS/CDP, network capture, uploads, PDF export, tabs and sessions, and building a reusable CLI for a website — load the kimi-webbridge skill and drive the daemon over HTTP exactly as that skill (and its references) documents."
|
|
517
|
+
text: "kimi-webbridge: the local kimi-webbridge daemon (127.0.0.1:10086) bridges to the user's real browser with their login sessions; this plugin provisions the daemon binary, keeps it running, and registers the official upstream skill package (with its references/ directory). The `kimi_webbridge` tool is only the status health check (daemon + extension + installed skill copies). For any browser work — navigation, reading pages and iframes, clicking, typing, form filling, trusted input via CDP focus emulation, screenshots, JS/CDP, network capture, uploads, PDF export, tabs and sessions, attaching tabs the user already has open, and building a reusable CLI for a website — load the kimi-webbridge skill and drive the daemon over HTTP exactly as that skill (and its references) documents."
|
|
481
518
|
});
|
|
482
519
|
|
|
483
520
|
ctx.tools.register(defineTool({
|
|
484
521
|
name: "kimi_webbridge",
|
|
485
|
-
description: "Health check for the local kimi-webbridge bridge (daemon at " + baseUrl + " and the browser extension). The plugin auto-provisions the daemon: it installs the binary from the official Kimi CDN when missing and starts it, then retries once. Returns daemon version/uptime, extension_connected, plus version (daemon) and extension_version (extension) — a mismatch means the components have drifted (the extension likely auto-updated) — and the upstream notices skills, version_mismatch, update_available and skill_mismatch. This tool does NOT perform browser actions — for navigation, reading pages and iframes, clicking, typing, screenshots, JS/CDP, trusted input, network capture, uploads, PDF export, tabs/sessions, or building a reusable CLI for a website, load the kimi-webbridge skill, which documents the daemon's tool protocol (POST " + baseUrl + "/command) and ships its references/ alongside.",
|
|
522
|
+
description: "Health check for the local kimi-webbridge bridge (daemon at " + baseUrl + " and the browser extension). The plugin auto-provisions the daemon: it installs the binary from the official Kimi CDN when missing and starts it, then retries once. Returns daemon version/uptime, extension_connected, plus version (daemon) and extension_version (extension) — a mismatch means the components have drifted (the extension likely auto-updated) — and the upstream notices skills, version_mismatch, update_available and skill_mismatch. This tool does NOT perform browser actions — for navigation, reading pages and iframes, clicking, typing, screenshots, JS/CDP, trusted input, network capture, uploads, PDF export, tabs/sessions, attaching tabs the user already has open, or building a reusable CLI for a website, load the kimi-webbridge skill, which documents the daemon's tool protocol (POST " + baseUrl + "/command) and ships its references/ alongside.",
|
|
486
523
|
parameters: {
|
|
487
524
|
action: {
|
|
488
525
|
type: "string",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kimi-webbridge-dsh",
|
|
3
3
|
"description": "Infrastructure plugin for dsh: provisions the kimi-webbridge daemon (auto-install with SHA-256 verification, auto-start) and registers the official upstream skill package (SKILL.md + references/, vendored from the CDN and digest-pinned) as a runtime skill. Registers a thin kimi_webbridge tool (status health check only).",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.11",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"fetch-skill": "node scripts/fetch-upstream-skill.mjs"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@deepseek-ai/dsh-tools": "^0.1.0-rc.7 || ^0.1.1-rc.2 || ^0.1.2-rc.1 || ^0.1.5-rc.1 || ^0.1.7-rc.2",
|
|
50
|
-
"@deepseek-ai/dsh-llm": "^0.1.0-rc.7 || ^0.1.1-rc.2 || ^0.1.2-rc.1 || ^0.1.5-rc.1 || ^0.1.7-rc.2",
|
|
49
|
+
"@deepseek-ai/dsh-tools": "^0.1.0-rc.7 || ^0.1.1-rc.2 || ^0.1.2-rc.1 || ^0.1.5-rc.1 || ^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
50
|
+
"@deepseek-ai/dsh-llm": "^0.1.0-rc.7 || ^0.1.1-rc.2 || ^0.1.2-rc.1 || ^0.1.5-rc.1 || ^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
51
51
|
"@deepseek-ai/schemastery": "^3.18.1"
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Usage:
|
|
17
17
|
* node scripts/fetch-upstream-skill.mjs # fetch latest, rewrite skill/
|
|
18
|
-
* node scripts/fetch-upstream-skill.mjs --version v2.0.
|
|
18
|
+
* node scripts/fetch-upstream-skill.mjs --version v2.0.23
|
|
19
19
|
* node scripts/fetch-upstream-skill.mjs --check # fetch and compare, never write
|
|
20
20
|
* node scripts/fetch-upstream-skill.mjs --verify-local # no network: verify vendored files
|
|
21
21
|
*
|
|
@@ -125,7 +125,7 @@ function readManifest() {
|
|
|
125
125
|
* platform-named copy for its installer, and a divergence would mean this plugin is
|
|
126
126
|
* vendoring the wrong variant.
|
|
127
127
|
*
|
|
128
|
-
* @param version - `latest` or a pinned tag such as `v2.0.
|
|
128
|
+
* @param version - `latest` or a pinned tag such as `v2.0.23`.
|
|
129
129
|
* @returns the normalised package.
|
|
130
130
|
*/
|
|
131
131
|
async function fetchPackage(version) {
|
|
@@ -254,7 +254,7 @@ async function main() {
|
|
|
254
254
|
const args = process.argv.slice(2);
|
|
255
255
|
const versionFlag = args.indexOf("--version");
|
|
256
256
|
const requested = versionFlag === -1 ? "latest" : args[versionFlag + 1];
|
|
257
|
-
if (requested === undefined) throw new Error("--version needs a value, e.g. --version v2.0.
|
|
257
|
+
if (requested === undefined) throw new Error("--version needs a value, e.g. --version v2.0.23");
|
|
258
258
|
if (args.includes("--verify-local")) {
|
|
259
259
|
const { manifest, problems } = verifyLocal();
|
|
260
260
|
if (problems.length > 0) {
|
package/skill/README.md
CHANGED
|
@@ -21,7 +21,7 @@ To update:
|
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
npm run fetch-skill # vendor the latest release
|
|
24
|
-
node scripts/fetch-upstream-skill.mjs --version v2.0.
|
|
24
|
+
node scripts/fetch-upstream-skill.mjs --version v2.0.23 # or pin one
|
|
25
25
|
node scripts/fetch-upstream-skill.mjs --check # report upstream drift only
|
|
26
26
|
```
|
|
27
27
|
|
package/skill/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: kimi-webbridge
|
|
|
3
3
|
description: |
|
|
4
4
|
Kimi Browser Extension(Kimi 浏览器扩展,原 Kimi WebBridge)lets AI control the user's real browser — navigate, click, type, read, screenshot, and interact with any website using the user's actual login sessions. Use this skill whenever the user wants to interact with websites, automate browser tasks, scrape web content, or perform any action requiring a real browser. Also use when the user mentions "browser", "webpage", "open URL", "screenshot", asks to read/interact with any website, or wants a reusable CLI tool or script that automates a specific website. Use even for simple-sounding browser requests — the daemon handles all complexity.
|
|
5
5
|
metadata:
|
|
6
|
-
version: "2.0.
|
|
6
|
+
version: "2.0.23"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Kimi Browser Extension (formerly Kimi WebBridge)
|
|
@@ -23,7 +23,7 @@ When the user asks to build a reusable CLI tool or script for a website (rather
|
|
|
23
23
|
|------|------|---------|------|
|
|
24
24
|
| `navigate` | `url`, `newTab`(bool), `group_title` | `{success, url, tabId}` | First call opens a tab — see [Tabs](#tabs-and-the-current-tab). `group_title` sets the group's visible label |
|
|
25
25
|
| `find_tab` | `url`, `active`(bool) | `{success, url, tabId, borrowed}` | Re-select a tab **this session** opened; `active:true` borrows the tab the **user** is viewing — see [Tabs](#tabs-and-the-current-tab) |
|
|
26
|
-
| `snapshot` |
|
|
26
|
+
| `snapshot` | optional `ref`; `format:"aria"` opts into text with optional `max_chars` (1–60000), or `cursor` to continue | Default `{url, title, tree}`; ARIA `{url, title, tree_text}` | **Accessibility tree** (text) — use this to read page content and locate elements |
|
|
27
27
|
| `click` | `selector` (@e ref or CSS) | `{success, tag, text}` | Synthetic `el.click()` |
|
|
28
28
|
| `fill` | `selector`, `value` | `{success, tag, mode}` | Works on `<input>`/`<textarea>` AND `[contenteditable]` (ProseMirror/Lexical/Slate). `mode` is `"value"` or `"contenteditable"` |
|
|
29
29
|
| `evaluate` | `code` (for `await`, wrap it in an async IIFE — top-level `await` is a SyntaxError) | `{type, value}` | |
|
|
@@ -33,16 +33,18 @@ When the user asks to build a reusable CLI tool or script for a website (rather
|
|
|
33
33
|
| `upload` | `selector`, `files`(string[]) | `{success, fileCount}` | |
|
|
34
34
|
| `save_as_pdf` | `paper_format`, `landscape`, `scale`, `print_background`, optional `path` | `{path, sizeBytes, mimeType, pageTitle}` | Render current page → PDF, returns a file path — see [Save as PDF](#save-the-current-page-as-pdf) |
|
|
35
35
|
| `list_tabs` | — | `{success, tabs:[{tabId, url, title, active, groupTitle}]}` | Inspect tabs in the current session |
|
|
36
|
+
| `list_browser_tabs` | — | `{success, tabs:[{tabId, windowId, url, title, active}]}` | Inspect all tabs visible to this WebBridge connection, across windows; does not attach or focus a tab |
|
|
37
|
+
| `attach_tab` | `tabId` | `{success, tabId, url, title, borrowed}` | Attach a specific existing tab to this session without focusing it; borrowed tabs survive `close_session` |
|
|
36
38
|
| `close_tab` | — | `{success, closed: bool}` | Close the current tab in the session |
|
|
37
|
-
| `close_session` | — | `{success, closed: int}` | Close
|
|
39
|
+
| `close_session` | — | `{success, closed: int}` | Close tabs opened by this session; borrowed tabs stay open. `closed` is the count. See [Sessions](#sessions) for when to call |
|
|
38
40
|
|
|
39
41
|
### Tabs and the current tab
|
|
40
42
|
|
|
41
|
-
Single-tab tools (`snapshot`, `click`, `fill`, `screenshot`, `save_as_pdf`) act on the **current tab** — the one you most recently opened with `navigate` or
|
|
43
|
+
Single-tab tools (`snapshot`, `click`, `fill`, `screenshot`, `save_as_pdf`) act on the **current tab** — the one you most recently opened with `navigate`, selected with `find_tab`, or attached with `attach_tab`.
|
|
42
44
|
|
|
43
45
|
- **Opening pages**: use `newTab:true` when pages should coexist (comparing, cross-referencing); omit it to send the current tab to a new URL.
|
|
44
46
|
- **Going back to an earlier tab**: call `find_tab` to make a tab **you opened earlier in this session** the current one again. Pass the tab's URL — take it from `list_tabs` or the earlier `navigate` result. Matching is by host: `kimi.com` also finds a `www.kimi.com` tab, and the path is ignored. By default `find_tab` searches **only this session's own tabs** — it never reaches into the user's other tabs or windows.
|
|
45
|
-
- **Acting on a page the user already has open**:
|
|
47
|
+
- **Acting on a page the user already has open**: call `list_browser_tabs`, choose the tab by its URL/title and `tabId`, then call `attach_tab` with that ID. This also works for tabs in other windows and does not change the user's foreground tab. The attached tab is borrowed and remains open after `close_session`. For the particular tab the user is currently viewing, `find_tab` with `active:true` still works.
|
|
46
48
|
- If `find_tab` errors with "no tab matching … in this session", the page isn't open in this session — `navigate` with `newTab:true` instead.
|
|
47
49
|
|
|
48
50
|
```bash
|
|
@@ -120,7 +122,9 @@ A caller-supplied `path` is honored verbatim (parent dirs created, existing file
|
|
|
120
122
|
|
|
121
123
|
## Prefer snapshot over CSS/JS selectors
|
|
122
124
|
|
|
123
|
-
`snapshot` returns interactive elements with `@e` refs
|
|
125
|
+
`snapshot` returns interactive elements with `@e` refs bound to the observed DOM nodes. Copy refs as opaque strings into click/fill. Re-reading a page preserves refs for the same nodes; a removed node or changed document/connection requires a fresh snapshot. Refs never automatically select a replacement by name.
|
|
126
|
+
|
|
127
|
+
For bounded text reads, call `snapshot` with `format:"aria"` and optionally `max_chars` (default 60000). This bounds `tree_text`, not metadata. If `truncated:true`, pass `next_cursor` back as `cursor` (without `ref`) to continue the same saved observation; `continued:true` identifies subsequent chunks. Concatenate `tree_text` without extra separators: chunks can split long lines, and budgets count UTF-16 code units without splitting surrogate pairs (a budget of 1 errors when the next character needs 2). Cursors expire after five minutes, cache eviction, navigation or connection reset; start a new snapshot on an expired-cursor error. Same-document content edits do not refresh saved text. The cache holds at most eight snapshots / eight million code units; observations above four million fail explicitly, so narrow the read. Alternatively, use `find` with a specific `query` to search the full main-document accessibility tree, then `snapshot` with the chosen match's `ref` to read its subtree. Search results carry ancestor paths to distinguish same-name matches. Scope and budget do not reassign existing refs; iframe content is not included in this search.
|
|
124
128
|
|
|
125
129
|
Fall back to `evaluate` (JS) only when:
|
|
126
130
|
- The target has no `@e` ref in the snapshot
|
package/skill/UPSTREAM.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"note": "Generated by scripts/fetch-upstream-skill.mjs — do not hand-edit. Vendored verbatim from the official CDN.",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"release": "v2.0.
|
|
5
|
-
"tarUrl": "https://cdn.kimi.com/webbridge/v2.0.
|
|
6
|
-
"tarSha256": "
|
|
7
|
-
"fetchedAt": "2026-
|
|
3
|
+
"version": "2.0.23",
|
|
4
|
+
"release": "v2.0.23",
|
|
5
|
+
"tarUrl": "https://cdn.kimi.com/webbridge/v2.0.23/skills/kimi-webbridge.tar.gz",
|
|
6
|
+
"tarSha256": "9a83d372612151f69ac5cd7465e61531d8316e98246ca6e7aa748766d40f1718",
|
|
7
|
+
"fetchedAt": "2026-10-12T13:45:04.953Z",
|
|
8
8
|
"files": [
|
|
9
9
|
{
|
|
10
10
|
"path": "SKILL.md",
|
|
11
|
-
"sha256": "
|
|
12
|
-
"bytes":
|
|
11
|
+
"sha256": "1e7ce8c90bcdc230036ac34a05e381c85e10efbf53d7624eb671f7cbf9e321b1",
|
|
12
|
+
"bytes": 19437
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "references/cli-creator/companion-skill-template.md",
|