kimi-webbridge-dsh 1.4.8 → 1.4.10
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 +33 -90
- package/lib/index.js +168 -13
- package/package.json +16 -7
- package/scripts/fetch-upstream-skill.mjs +290 -0
- package/skill/README.md +41 -0
- package/skill/SKILL.md +189 -0
- package/skill/UPSTREAM.json +45 -0
- package/skill/references/cli-creator/companion-skill-template.md +70 -0
- package/skill/references/cli-creator/go-layout.md +203 -0
- package/skill/references/cli-creator/login-handling.md +23 -0
- package/skill/references/cli-creator/site-exploration.md +64 -0
- package/skill/references/cli-creator/workflow.md +58 -0
- package/skill/references/operations.md +58 -0
- package/skill.md +0 -91
package/README.md
CHANGED
|
@@ -1,118 +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(`ctx.skills.register`,`source: bundled`),模型通过 `skill` 工具加载它,按文档用 HTTP 行使全部浏览器能力(25 个动作);
|
|
7
|
-
3. **注册一个瘦工具 `kimi_webbridge`**:只有 `status` 一个动作(守护进程 + 扩展健康检查),作为其他 skill(如 x-cli 系列)的桥健康锚点。
|
|
8
|
-
|
|
9
|
-
## 架构
|
|
10
|
-
|
|
11
|
-
| 层 | 角色 |
|
|
5
|
+
| 职责 | 说明 |
|
|
12
6
|
|---|---|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
| 瘦工具 `kimi_webbridge
|
|
7
|
+
| 守护进程供应 | 按官方清单下载对应平台二进制(SHA-256 校验),未运行时自动拉起;落在 `~/.kimi-webbridge/bin/` |
|
|
8
|
+
| 技能注册 | 随包内置官方技能文档(含 `references/`),启动时注册为 `kimi-webbridge` skill |
|
|
9
|
+
| 健康锚点 | 瘦工具 `kimi_webbridge`,只有 `status` 一个动作(守护进程 + 扩展 + 已装技能副本) |
|
|
16
10
|
|
|
17
|
-
##
|
|
11
|
+
## 安装
|
|
18
12
|
|
|
19
|
-
```
|
|
13
|
+
```bash
|
|
20
14
|
dsh plugin --profile web add kimi-webbridge-dsh
|
|
21
15
|
```
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
## 用法(模型视角)
|
|
26
|
-
|
|
27
|
-
1. 需要真实浏览器时,加载 `kimi-webbridge` skill(触发词:browser / webpage / open URL / 浏览器 / 网页 / 截图……);
|
|
28
|
-
2. 先用 `kimi_webbridge` 工具的 `status` 确认守护进程 + 扩展健康(插件自动补装/拉起二进制);
|
|
29
|
-
3. 按 skill 文档向 `POST http://127.0.0.1:10086/command` 发送 `{action, args, session}` 行使浏览器能力。Windows 上必须用临时文件承载 JSON(shell 会破坏非 ASCII 文本),skill 里有完整说明。
|
|
30
|
-
|
|
31
|
-
## 依赖
|
|
32
|
-
|
|
33
|
-
- **浏览器扩展**:需安装并连接 Kimi 浏览器扩展(Kimi Browser Extension,原 Kimi WebBridge)—— 从 [Chrome Web Store](https://chromewebstore.google.com/detail/kimi-webbridge/fldmhceldgbpfpkbgopacenieobmligc) 安装(`kimi_webbridge status` 显示 `extension_connected: true`;扩展版本应与守护进程一致)。
|
|
34
|
-
- **守护进程**:无需预装。插件在守护进程不可达时会自动启动它;二进制缺失时会自动从官方 CDN(cdn.kimi.com,与官方安装器同源)下载安装——全程无需手动运行任何安装命令。
|
|
35
|
-
|
|
36
|
-
### 版本对齐
|
|
37
|
-
|
|
38
|
-
插件按官方 CDN 的 `version.json` 供应守护进程,因此始终与官方发布对齐;上表的存档哈希对应 **v2.0.8**(守护进程与扩展的产品名已更名为 Kimi Browser Extension)。
|
|
39
|
-
|
|
40
|
-
`kimi_webbridge` 的 `status` 会原样透出守护进程的 `update_available`(有更新时)与 `version_mismatch`(守护进程与扩展不同步时)字段。按官方约定:这两个字段出现时**不要**自动执行 `upgrade` / `stop` / `restart` / `uninstall`(它们会杀掉正在运行的守护进程),而应把字段里的 `command` 原样交给用户执行。
|
|
41
|
-
|
|
42
|
-
### 兼容性(dsh 版本)
|
|
43
|
-
|
|
44
|
-
插件只 import 宿主提供的 `@deepseek-ai/*` 包,并声明为 `peerDependencies`(不打包自己的副本),所以与 dsh 版本解耦;已在 **dsh 0.1.5-rc.1** 上验证(工具注册、skill 注册、system prompt 注入、守护进程自愈均正常)。
|
|
45
|
-
|
|
46
|
-
| peer | 声明范围 |
|
|
47
|
-
|---|---|
|
|
48
|
-
| `@deepseek-ai/dsh-tools` | `^0.1.0-rc.7 \|\| ^0.1.1-rc.2 \|\| ^0.1.2-rc.1 \|\| ^0.1.5-rc.1` |
|
|
49
|
-
| `@deepseek-ai/dsh-llm` | 同上 |
|
|
50
|
-
| `@deepseek-ai/schemastery` | `^3.18.1` |
|
|
51
|
-
|
|
52
|
-
⚠️ **预发布版必须逐个元组写进范围。** node-semver 只在范围里存在一个**与该版本 `major.minor.patch` 完全一致、且自身带预发布标签**的比较符时才放行预发布版;因此看起来很宽的 `>=0.0.1-rc.1 <0.2.0` 会静默排除所有预发布构建,用户会遇到 `ERESOLVE`。dsh 发布新的预发布系列(如 `0.1.6-rc.1`)时,需要同步追加一个 `|| ^<新元组>-rc.N` 分支。
|
|
53
|
-
|
|
54
|
-
### 跨平台支持
|
|
17
|
+
自带 bundle patch,无需手改 `cordis.patch.yml`;重启一次 dsh 生效。
|
|
55
18
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
| 平台 | 二进制 | 存档哈希(v2.0.8) |
|
|
59
|
-
|---|---|---|
|
|
60
|
-
| Windows x64 | `windows-amd64.exe` | `eec1976d…433c6` |
|
|
61
|
-
| macOS arm64 | `darwin-arm64` | `04532d77…0a261` |
|
|
62
|
-
| macOS x64 | `darwin-amd64` | `931769e9…8cc0c` |
|
|
63
|
-
| Linux arm64 | `linux-arm64` | `ee201b44…34a3c` |
|
|
64
|
-
| Linux x64 | `linux-amd64` | `61de010c…ce271` |
|
|
19
|
+
## 用法
|
|
65
20
|
|
|
66
|
-
|
|
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 里有说明。
|
|
67
25
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
下载到用户目录(与官方安装器路径一致,无需管理员权限;按用户隔离):
|
|
71
|
-
|
|
72
|
-
| 平台 | 最终路径 |
|
|
73
|
-
|---|---|
|
|
74
|
-
| Windows | `%USERPROFILE%\.kimi-webbridge\bin\kimi-webbridge.exe` |
|
|
75
|
-
| macOS / Linux | `~/.kimi-webbridge/bin/kimi-webbridge`(自动 `chmod 755`) |
|
|
26
|
+
工具清单、参数与注意事项一律以 skill 文档为准。
|
|
76
27
|
|
|
77
|
-
|
|
28
|
+
## 配置
|
|
78
29
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
| 能力 | 动作 |
|
|
82
|
-
|---|---|
|
|
83
|
-
| 导航 / 标签 | `navigate`、`find_tab`、`list_tabs`、`close_tab`、`close_session` |
|
|
84
|
-
| 读页面 | `snapshot`(accessibility tree + `@e` 引用)、`read_page`(全文文本)、`find`(页面内搜索) |
|
|
85
|
-
| 点击 / 输入 | `click`、`mouse_click`(真实鼠标,可信输入)、`hover`、`drag`、`fill`、`key_type`(键入,可信)、`send_keys`(组合键)、`select_option`、`dialog` |
|
|
86
|
-
| JS / CDP | `evaluate`(页面上下文)、`cdp`(chrome.debugger 直通) |
|
|
87
|
-
| 截图 / PDF | `screenshot`、`save_as_pdf`(写文件、返回路径) |
|
|
88
|
-
| 网络 / 上传 | `network`(请求捕获)、`upload`(文件上传) |
|
|
89
|
-
| 滚动 / 等待 | `scroll`(滚动/定位)、`wait`(等待文本/选择器条件) |
|
|
90
|
-
| 会话分组 | 一个任务 = 一个 session = 一个标签页组,可一键清理 |
|
|
91
|
-
|
|
92
|
-
## 配置(可选)
|
|
93
|
-
|
|
94
|
-
在 profile 的用户补丁层(`~/.dsh/profiles/web/cordis.patch.yml`)按 id 覆盖配置(替换整份 config,未给出的键取默认值):
|
|
30
|
+
在 `~/.dsh/profiles/web/cordis.patch.yml` 按 id 覆盖(整份替换,未给出的键取默认):
|
|
95
31
|
|
|
96
32
|
```yaml
|
|
97
33
|
- id: kimi-webbridge
|
|
98
34
|
config:
|
|
99
|
-
|
|
100
|
-
daemonVersion: v2.0.8
|
|
35
|
+
daemonVersion: v2.0.22
|
|
101
36
|
```
|
|
102
37
|
|
|
103
|
-
|
|
|
38
|
+
| 键 | 默认 | 说明 |
|
|
104
39
|
|---|---|---|
|
|
105
40
|
| `baseUrl` | `http://127.0.0.1:10086` | 守护进程地址 |
|
|
106
|
-
| `requestTimeoutMs` | `120000` |
|
|
107
|
-
| `autoStartDaemon` | `true` |
|
|
108
|
-
| `autoInstallDaemon` | `true` |
|
|
109
|
-
| `daemonVersion` | `latest` |
|
|
110
|
-
| `registerSkill` | `true` |
|
|
41
|
+
| `requestTimeoutMs` | `120000` | 单次请求超时(ms) |
|
|
42
|
+
| `autoStartDaemon` | `true` | 未运行时自动启动 |
|
|
43
|
+
| `autoInstallDaemon` | `true` | 二进制缺失时自动下载安装 |
|
|
44
|
+
| `daemonVersion` | `latest` | 自动安装的版本,带 `v` 前缀,建议与扩展版本一致 |
|
|
45
|
+
| `registerSkill` | `true` | 注册 `kimi-webbridge` skill |
|
|
46
|
+
|
|
47
|
+
## 要求与提示
|
|
48
|
+
|
|
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 拿到技能的唯一途径就是本插件。
|
|
111
54
|
|
|
112
55
|
## 移除
|
|
113
56
|
|
|
114
|
-
```
|
|
57
|
+
```bash
|
|
115
58
|
dsh plugin --profile web remove kimi-webbridge-dsh
|
|
116
59
|
```
|
|
117
60
|
|
|
118
|
-
|
|
61
|
+
重启后生效;skill 随插件注册,移除即消失。
|
package/lib/index.js
CHANGED
|
@@ -17,8 +17,9 @@ import { fileURLToPath } from "node:url";
|
|
|
17
17
|
* Infrastructure-only bridge plugin:
|
|
18
18
|
* - provisions the daemon binary (official Kimi CDN, SHA-256 verified) and
|
|
19
19
|
* auto-starts it, keeping the bridge healthy;
|
|
20
|
-
* - registers the
|
|
21
|
-
*
|
|
20
|
+
* - registers the skill package vendored under skill/ (the official upstream
|
|
21
|
+
* SKILL.md plus its references/) as a runtime skill via ctx.skills, with the
|
|
22
|
+
* directory exposed as its resource base;
|
|
22
23
|
* - registers one thin tool `kimi_webbridge` whose only action is `status`
|
|
23
24
|
* (daemon + extension health check) as an anchor for other skills.
|
|
24
25
|
*
|
|
@@ -94,15 +95,149 @@ function manualInstallHint() {
|
|
|
94
95
|
/** Skill identity registered into the host skill registry. */
|
|
95
96
|
const SKILL_NAME = "kimi-webbridge";
|
|
96
97
|
|
|
97
|
-
/**
|
|
98
|
-
const
|
|
98
|
+
/** Vendored upstream skill package: `skill/SKILL.md` plus its `references/` tree. */
|
|
99
|
+
const SKILL_DIR = fileURLToPath(new URL("../skill/", import.meta.url));
|
|
100
|
+
|
|
101
|
+
/** The upstream instruction file inside {@link SKILL_DIR}. */
|
|
102
|
+
const SKILL_PATH = join(SKILL_DIR, "SKILL.md");
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Extra routing triggers appended to the description upstream ships.
|
|
106
|
+
*
|
|
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.
|
|
111
|
+
*/
|
|
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 浏览器 / 网页 / 打开网页 / 截图 / 页面.";
|
|
113
|
+
|
|
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.";
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The section appended after the vendored upstream instructions.
|
|
132
|
+
*
|
|
133
|
+
* Everything above it is upstream's document verbatim; this carries only the deltas
|
|
134
|
+
* that are true in dsh (tool names, the status anchor, where references live), plus
|
|
135
|
+
* the upstream release the copy came from — which stripping the frontmatter would
|
|
136
|
+
* otherwise hide from the model. Keeping the split means refreshing the skill never
|
|
137
|
+
* has to merge prose.
|
|
138
|
+
*
|
|
139
|
+
* @param version - the upstream version stamped in the vendored SKILL.md, when known.
|
|
140
|
+
* @returns the markdown block to append.
|
|
141
|
+
*/
|
|
142
|
+
function dshRuntimeSection(version) {
|
|
143
|
+
const provenance = typeof version === "string" && version.length > 0
|
|
144
|
+
? `This skill is vendored verbatim from the official upstream release v${version}; \`skill/UPSTREAM.json\` records its digests.`
|
|
145
|
+
: "This skill is vendored verbatim from the official upstream release.";
|
|
146
|
+
return `
|
|
147
|
+
|
|
148
|
+
## dsh runtime notes
|
|
149
|
+
|
|
150
|
+
The kimi-webbridge-dsh plugin adds these notes for this harness; where they conflict with the text above, they win.
|
|
151
|
+
|
|
152
|
+
${provenance}
|
|
153
|
+
|
|
154
|
+
- **Health check first**: before driving the browser, call the \`kimi_webbridge\` tool with action \`status\`. It reports daemon + extension health and auto-provisions this machine — it installs the daemon binary from the official CDN (SHA-256 checked against the release manifest) when it is missing, starts it, and retries once. The binary lives at \`~/.kimi-webbridge/bin/kimi-webbridge\` and is not on \`PATH\`; running it with \`start\` yourself is also safe and idempotent.
|
|
155
|
+
- **Tool names in this harness**: file tools are \`read\`, \`read_image\`, \`write\` and \`edit\`; the shell tool is \`bash\`; \`kimi_webbridge\` is the status anchor. Where the text above says "open it with the Read tool" for a screenshot or PDF, use \`read_image\`.
|
|
156
|
+
- **References**: paths such as \`references/operations.md\` and \`references/cli-creator/workflow.md\` resolve against the base directory reported when this skill loads. Read them with the \`read\` tool.
|
|
157
|
+
- **Skills installer**: the daemon's own \`install-skill\` / \`upgrade\` skill refresh targets the runtimes it detects (Claude Code, Codex, Hermes, OpenClaw, Kimi) — dsh is not one of them. This plugin is how dsh receives this skill, so never run \`install-skill\` on dsh's behalf.
|
|
158
|
+
- **Notices**: when \`status\` reports \`version_mismatch\`, \`update_available\` or \`skill_mismatch\`, hand the user that field's \`command\` verbatim. Never run \`stop\` / \`restart\` / \`upgrade\` / \`uninstall\` yourself — they kill the user's running daemon.
|
|
159
|
+
`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Parse the two frontmatter fields this plugin needs from the vendored SKILL.md.
|
|
164
|
+
*
|
|
165
|
+
* A deliberately small YAML subset parser: the upstream frontmatter is a fixed shape
|
|
166
|
+
* (`name`, a `description` block scalar, `metadata.version`), and pulling in a YAML
|
|
167
|
+
* dependency for three fields would cost more than it buys.
|
|
168
|
+
*
|
|
169
|
+
* @param raw - the SKILL.md text.
|
|
170
|
+
* @returns the description, stamped version and body without frontmatter; fields are null when absent.
|
|
171
|
+
*/
|
|
172
|
+
function parseFrontmatter(raw) {
|
|
173
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u.exec(raw);
|
|
174
|
+
if (match === null) return { description: null, version: null, body: raw.trim() };
|
|
175
|
+
let description = null;
|
|
176
|
+
let version = null;
|
|
177
|
+
let block = null;
|
|
178
|
+
for (const line of match[1].split(/\r?\n/u)) {
|
|
179
|
+
if (block !== null) {
|
|
180
|
+
if (/^\s+\S/u.test(line)) {
|
|
181
|
+
block.push(line.trim());
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
description = block.join(" ").trim();
|
|
185
|
+
block = null;
|
|
186
|
+
}
|
|
187
|
+
if (/^description:\s*[|>]\s*$/u.test(line)) {
|
|
188
|
+
block = [];
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
const inline = /^description:\s*(\S.*)$/u.exec(line);
|
|
192
|
+
if (inline !== null) {
|
|
193
|
+
description = inline[1].trim();
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const stamped = /^\s+version:\s*"?([^"\s]+)"?\s*$/u.exec(line);
|
|
197
|
+
if (stamped !== null) version = stamped[1];
|
|
198
|
+
}
|
|
199
|
+
if (block !== null) description = block.join(" ").trim();
|
|
200
|
+
return { description, version, body: raw.slice(match[0].length).trim() };
|
|
201
|
+
}
|
|
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
|
+
}
|
|
99
224
|
|
|
100
225
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
226
|
+
* Load the vendored upstream skill package.
|
|
227
|
+
*
|
|
228
|
+
* @returns the routing description and the content to register (upstream body plus the
|
|
229
|
+
* dsh runtime notes, which carry the upstream release the copy came from).
|
|
103
230
|
*/
|
|
104
|
-
function
|
|
105
|
-
|
|
231
|
+
function readSkillPackage() {
|
|
232
|
+
const { description, version, body } = parseFrontmatter(readFileSync(SKILL_PATH, "utf8"));
|
|
233
|
+
const fallback = typeof description !== "string" || description.length === 0;
|
|
234
|
+
if (fallback) {
|
|
235
|
+
console.warn(`kimi-webbridge: ${SKILL_PATH} has no frontmatter description; falling back to the built-in routing text`);
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
description: composeSkillDescription(fallback ? FALLBACK_SKILL_DESCRIPTION : description),
|
|
239
|
+
content: `${body}${dshRuntimeSection(version)}`
|
|
240
|
+
};
|
|
106
241
|
}
|
|
107
242
|
|
|
108
243
|
/** Underlying transport `code` for a rejected `fetch`, which buries it one level down in `cause`. */
|
|
@@ -360,11 +495,15 @@ function apply(ctx, config = {}) {
|
|
|
360
495
|
|
|
361
496
|
if (registerSkill) {
|
|
362
497
|
try {
|
|
498
|
+
const skill = readSkillPackage();
|
|
499
|
+
// resourceBase is what lets the model resolve the upstream document's
|
|
500
|
+
// "references/..." links: the host renders it as this skill's base directory.
|
|
363
501
|
ctx.skills.register({
|
|
364
502
|
name: SKILL_NAME,
|
|
365
|
-
description:
|
|
503
|
+
description: skill.description,
|
|
366
504
|
source: "bundled",
|
|
367
|
-
content:
|
|
505
|
+
content: skill.content,
|
|
506
|
+
resourceBase: { kind: "directory", path: SKILL_DIR }
|
|
368
507
|
});
|
|
369
508
|
} catch (error) {
|
|
370
509
|
// Never break plugin startup over skill registration; the status tool still works.
|
|
@@ -375,12 +514,12 @@ function apply(ctx, config = {}) {
|
|
|
375
514
|
ctx.systemPrompt.section({
|
|
376
515
|
name: "tool:kimi-webbridge",
|
|
377
516
|
order: 105,
|
|
378
|
-
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
|
|
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, 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."
|
|
379
518
|
});
|
|
380
519
|
|
|
381
520
|
ctx.tools.register(defineTool({
|
|
382
521
|
name: "kimi_webbridge",
|
|
383
|
-
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). This tool does NOT perform browser actions — for navigation, clicking, typing,
|
|
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, 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.",
|
|
384
523
|
parameters: {
|
|
385
524
|
action: {
|
|
386
525
|
type: "string",
|
|
@@ -405,7 +544,7 @@ function apply(ctx, config = {}) {
|
|
|
405
544
|
type: "text",
|
|
406
545
|
text: daemonAhead
|
|
407
546
|
? `⚠️ the browser extension (${value.extension_version}) is behind the daemon (${value.version}) — ask the user to update the extension, then retry.`
|
|
408
|
-
: `⚠️ version drift: daemon ${value.version} vs extension ${value.extension_version} — the browser extension likely auto-updated ahead of the daemon. Re-audit the
|
|
547
|
+
: `⚠️ version drift: daemon ${value.version} vs extension ${value.extension_version} — the browser extension likely auto-updated ahead of the daemon. Re-audit the skill against the new tool surface and update the daemon.`
|
|
409
548
|
});
|
|
410
549
|
}
|
|
411
550
|
// The official convention: surface the release fields verbatim and let the
|
|
@@ -417,6 +556,22 @@ function apply(ctx, config = {}) {
|
|
|
417
556
|
text: `⬆️ update available: daemon ${update.current ?? "?"} → ${update.latest ?? "?"} — tell the user and hand them this command verbatim; do NOT run it yourself: ${update.command}`
|
|
418
557
|
});
|
|
419
558
|
}
|
|
559
|
+
// Installed skill copies the daemon found in the agent runtimes it manages.
|
|
560
|
+
// dsh is not one of them, so an empty list is the normal dsh result.
|
|
561
|
+
const skills = value?.skills;
|
|
562
|
+
if (Array.isArray(skills) && skills.length > 0) {
|
|
563
|
+
const listed = skills
|
|
564
|
+
.map((entry) => `${entry?.agent ?? "?"}@${entry?.version ?? "?"}${typeof entry?.path === "string" ? ` (${entry.path})` : ""}`)
|
|
565
|
+
.join("; ");
|
|
566
|
+
blocks.push({ type: "text", text: `installed skill copies: ${listed}` });
|
|
567
|
+
}
|
|
568
|
+
const skillMismatch = value?.skill_mismatch;
|
|
569
|
+
if (skillMismatch !== null && typeof skillMismatch === "object" && typeof skillMismatch.command === "string") {
|
|
570
|
+
blocks.push({
|
|
571
|
+
type: "text",
|
|
572
|
+
text: `⚠️ installed kimi-webbridge skill copies are out of step with the extension (${skillMismatch.extension_version ?? "?"}) — tell the user and hand them this command verbatim; do NOT run it yourself: ${skillMismatch.command}`
|
|
573
|
+
});
|
|
574
|
+
}
|
|
420
575
|
return blocks;
|
|
421
576
|
}
|
|
422
577
|
},
|
package/package.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kimi-webbridge-dsh",
|
|
3
|
-
"description": "Infrastructure plugin for dsh: provisions the kimi-webbridge daemon (auto-install with SHA-256 verification, auto-start) and registers the
|
|
4
|
-
"version": "1.4.
|
|
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.10",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"repository": {
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/cfanmaoli/kimi-webbridge-dsh.git"
|
|
9
|
+
},
|
|
7
10
|
"type": "module",
|
|
8
11
|
"keywords": [
|
|
9
12
|
"dsh",
|
|
@@ -12,6 +15,7 @@
|
|
|
12
15
|
"webbridge",
|
|
13
16
|
"browser",
|
|
14
17
|
"automation",
|
|
18
|
+
"skill",
|
|
15
19
|
"plugin",
|
|
16
20
|
"cordis"
|
|
17
21
|
],
|
|
@@ -32,13 +36,18 @@
|
|
|
32
36
|
},
|
|
33
37
|
"files": [
|
|
34
38
|
"lib/index.js",
|
|
35
|
-
"skill
|
|
39
|
+
"skill",
|
|
40
|
+
"scripts",
|
|
36
41
|
"README.md",
|
|
37
42
|
"cordis.patch.yml"
|
|
38
43
|
],
|
|
44
|
+
"scripts": {
|
|
45
|
+
"check": "node --check lib/index.js && node scripts/fetch-upstream-skill.mjs --verify-local",
|
|
46
|
+
"fetch-skill": "node scripts/fetch-upstream-skill.mjs"
|
|
47
|
+
},
|
|
39
48
|
"peerDependencies": {
|
|
40
|
-
"@deepseek-ai/dsh-tools": "^0.1.0-rc.7 || ^0.1.1-rc.2 || ^0.1.2-rc.1 || ^0.1.5-rc.1",
|
|
41
|
-
"@deepseek-ai/dsh-llm": "^0.1.0-rc.7 || ^0.1.1-rc.2 || ^0.1.2-rc.1 || ^0.1.5-rc.1",
|
|
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",
|
|
42
51
|
"@deepseek-ai/schemastery": "^3.18.1"
|
|
43
52
|
}
|
|
44
|
-
}
|
|
53
|
+
}
|