kimi-webbridge-dsh 1.4.0 → 1.4.5

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.
Files changed (4) hide show
  1. package/README.md +45 -27
  2. package/lib/index.js +75 -62
  3. package/package.json +5 -6
  4. package/skill.md +85 -0
package/README.md CHANGED
@@ -1,21 +1,36 @@
1
1
  # kimi-webbridge-dsh
2
2
 
3
- Kimi WebBridge 的 dsh 插件:通过本机 kimi-webbridge 守护进程(`127.0.0.1:10086`)驱动用户的真实浏览器(保留登录态与 Cookie)。注册一个模型工具 `kimi_webbridge`,覆盖导航、点击、输入、读取页面(accessibility tree + @e 引用)、截图、JS 求值、CDP、网络、上传、PDF 导出、标签页与会话管理。
3
+ Kimi WebBridge 的 dsh 插件(**基础设施 + 技能生成**)。插件本身不代理浏览器操作,而是负责:
4
4
 
5
- ## 功能
5
+ 1. **保障桥完好**:守护进程二进制缺失时自动从官方 CDN 下载(跨平台、SHA-256 校验),守护进程未运行时自动拉起;
6
+ 2. **生成 skill**:启动时把随包内置的 `skill.md` 同步到 `~/.dsh/skills/kimi-webbridge/SKILL.md`,模型通过 `skill` 工具加载它,按文档用 HTTP 行使全部浏览器能力(17 个动作);
7
+ 3. **注册一个瘦工具 `kimi_webbridge`**:只有 `status` 一个动作(守护进程 + 扩展健康检查),作为其他 skill(如 x-cli 系列)的桥健康锚点。
6
8
 
7
- | 能力 | 说明 |
9
+ ## 架构
10
+
11
+ | 层 | 角色 |
8
12
  |---|---|
9
- | 浏览真实页面 | 在用户已登录的浏览器中导航、点击、填表、滚动 |
10
- | 读页面 | `snapshot` 返回 accessibility tree 与 `@e` 元素引用 |
11
- | 截图 / 导出 PDF | 结果写入本地文件,返回路径 |
12
- | JS 求值 / CDP | `evaluate`(页面上下文)、`cdp`(chrome.debugger 直通) |
13
- | 网络 / 上传 | 请求捕获与文件上传 |
14
- | 会话分组 | 一个任务 = 一个 session = 一个标签页组,可一键清理 |
13
+ | 插件(本包) | 守护进程二进制供应 + 自动启动;apply() 时同步 skill 文件 |
14
+ | skill(`~/.dsh/skills/kimi-webbridge/SKILL.md`) | 模型经 `skill` 工具加载,按文档驱动守护进程:navigate / find_tab / snapshot / click / mouse_click / fill / key_type / send_keys / evaluate / cdp / screenshot / network / upload / save_as_pdf / list_tabs / close_tab / close_session |
15
+ | 瘦工具 `kimi_webbridge` | 仅 `status` 健康检查(自带守护进程自愈) |
16
+
17
+ ## 安装(一次性,零手工配置)
18
+
19
+ ```powershell
20
+ dsh plugin --profile web add kimi-webbridge-dsh
21
+ ```
22
+
23
+ 本包声明了 `dsh.bundle.patch`:`dsh plugin add` 会自动把它登记进 profile 的 bundle 层(`dsh.profile.bundles`),**无需手动编辑任何 cordis.patch.yml**。重启一次 `dsh web`:启动时插件同步 skill 文件,新会话的 skill 目录中即出现 `kimi-webbridge`。
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 里有完整说明。
15
30
 
16
31
  ## 依赖
17
32
 
18
- - **浏览器扩展**:需安装并连接 Kimi WebBridge 浏览器扩展 —— 从 [Chrome Web Store](https://chromewebstore.google.com/detail/kimi-webbridge/fldmhceldgbpfpkbgopacenieobmligc) 安装(`kimi-webbridge status` 显示 `extension_connected: true`;扩展版本应与守护进程一致)。
33
+ - **浏览器扩展**:需安装并连接 Kimi WebBridge 浏览器扩展 —— 从 [Chrome Web Store](https://chromewebstore.google.com/detail/kimi-webbridge/fldmhceldgbpfpkbgopacenieobmligc) 安装(`kimi_webbridge status` 显示 `extension_connected: true`;扩展版本应与守护进程一致)。
19
34
  - **守护进程**:无需预装。插件在守护进程不可达时会自动启动它;二进制缺失时会自动从官方 CDN(cdn.kimi.com,与官方安装器同源)下载安装——全程无需手动运行任何安装命令。
20
35
 
21
36
  ### 跨平台支持
@@ -32,26 +47,28 @@ Kimi WebBridge 的 dsh 插件:通过本机 kimi-webbridge 守护进程(`127.
32
47
 
33
48
  不支持的平台组合会明确报错并提示手动安装。
34
49
 
35
- ## 安装(一次性,零手工配置)
36
-
37
- ```powershell
38
- dsh plugin --profile web add kimi-webbridge-dsh
39
- ```
50
+ ### 守护进程二进制位置
40
51
 
41
- 本包声明了 `dsh.bundle.patch`:`dsh plugin add` 会自动把它登记进 profile 的 bundle 层(`dsh.profile.bundles`),**无需手动编辑任何 cordis.patch.yml**。安装后重启一次 dsh web 即生效(bundle 在启动时加载):
52
+ 下载到用户目录(与官方安装器路径一致,无需管理员权限;按用户隔离):
42
53
 
43
- ```powershell
44
- dsh web
45
- ```
54
+ | 平台 | 最终路径 |
55
+ |---|---|
56
+ | Windows | `%USERPROFILE%\.kimi-webbridge\bin\kimi-webbridge.exe` |
57
+ | macOS / Linux | `~/.kimi-webbridge/bin/kimi-webbridge`(自动 `chmod 755`) |
46
58
 
47
- ## 用法
59
+ 下载流程:先落盘为临时文件(`kimi-webbridge(.exe).tmp-{pid}-{时间戳}`)→ SHA-256 与官方清单核对 → 匹配才重命名为最终路径;不匹配则删除临时文件并中止,任何未验证的二进制都不会留在磁盘。该路径与官方安装器 / `kimi-webbridge upgrade` 命令完全一致,插件、官方工具共用同一份守护进程。
48
60
 
49
- 模型在新会话中可直接调用 `kimi_webbridge` 工具。核心规则:
61
+ ## 功能(skill 承载,17 个动作)
50
62
 
51
- - **一个任务 = 一个 session = 一个标签页组**:任务开始时选一个 session 名,之后每次调用都带上(如 `camping-research`)。
52
- - **读页面用 snapshot**:返回 accessibility tree 和 `@e` 引用,点击/输入优先用 `@e` 引用而非手写 CSS。
53
- - **截图返回文件路径**:用 read 工具打开查看。
54
- - **守护进程不可达**:工具会自动启动;二进制缺失时自动从官方 CDN 下载安装。
63
+ | 能力 | 动作 |
64
+ |---|---|
65
+ | 导航 / 标签 | `navigate`、`find_tab`、`list_tabs`、`close_tab`、`close_session` |
66
+ | 读页面 | `snapshot`(accessibility tree + `@e` 引用) |
67
+ | 点击 / 输入 | `click`、`mouse_click`(真实鼠标,可信输入)、`fill`、`key_type`(键入,可信)、`send_keys`(组合键) |
68
+ | JS / CDP | `evaluate`(页面上下文)、`cdp`(chrome.debugger 直通) |
69
+ | 截图 / PDF | `screenshot`、`save_as_pdf`(写文件、返回路径) |
70
+ | 网络 / 上传 | `network`(请求捕获)、`upload`(文件上传) |
71
+ | 会话分组 | 一个任务 = 一个 session = 一个标签页组,可一键清理 |
55
72
 
56
73
  ## 配置(可选)
57
74
 
@@ -69,8 +86,9 @@ dsh web
69
86
  | `baseUrl` | `http://127.0.0.1:10086` | 守护进程地址 |
70
87
  | `requestTimeoutMs` | `120000` | 单次请求超时(毫秒) |
71
88
  | `autoStartDaemon` | `true` | 守护进程未运行时自动启动 |
72
- | `autoInstallDaemon` | `true` | 二进制缺失时自动从官方 CDN 下载安装(关闭后需手动运行 `irm https://cdn.kimi.com/webbridge/install.ps1 | iex`) |
89
+ | `autoInstallDaemon` | `true` | 二进制缺失时自动从官方 CDN 下载安装(关闭后需手动[从官方安装](https://www.kimi.ai/products/kimi-webbridge)) |
73
90
  | `daemonVersion` | `latest` | 自动安装时的版本(可固定如 `0.3.0`) |
91
+ | `generateSkill` | `true` | 启动时同步 `kimi-webbridge` skill 文件(关闭后不生成/更新) |
74
92
 
75
93
  ## 移除
76
94
 
@@ -78,4 +96,4 @@ dsh web
78
96
  dsh plugin --profile web remove kimi-webbridge-dsh
79
97
  ```
80
98
 
81
- 自动从 bundle 层移除(无需手动删补丁行),重启后生效。
99
+ 自动从 bundle 层移除(无需手动删补丁行),重启后生效。skill 文件(`~/.dsh/skills/kimi-webbridge/`)如需一并删除可手动清理。
package/lib/index.js CHANGED
@@ -4,27 +4,26 @@ import { HarnessError } from "@deepseek-ai/dsh-llm";
4
4
  import { spawn } from "node:child_process";
5
5
  import { createHash } from "node:crypto";
6
6
  import { createWriteStream, existsSync } from "node:fs";
7
- import { chmod, mkdir, readFile, rename, rm } from "node:fs/promises";
7
+ import { chmod, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
8
8
  import { request as httpRequest } from "node:http";
9
9
  import { request as httpsRequest } from "node:https";
10
10
  import { homedir } from "node:os";
11
11
  import { dirname, join } from "node:path";
12
+ import { fileURLToPath } from "node:url";
12
13
 
13
14
  /**
14
15
  * Kimi WebBridge plugin for dsh.
15
16
  *
16
- * Registers one model-facing tool `kimi_webbridge` that drives the user's real
17
- * browser (their login sessions) through the local kimi-webbridge daemon at
18
- * `127.0.0.1:10086`.
17
+ * Infrastructure-only bridge plugin:
18
+ * - provisions the daemon binary (official Kimi CDN, SHA-256 verified) and
19
+ * auto-starts it, keeping the bridge healthy;
20
+ * - syncs the packaged skill.md into ~/.dsh/skills/kimi-webbridge/SKILL.md,
21
+ * the model-facing skill that documents the full 17-action HTTP protocol
22
+ * for driving the user's real browser;
23
+ * - registers one thin tool `kimi_webbridge` whose only action is `status`
24
+ * (daemon + extension health check) as an anchor for other skills.
19
25
  *
20
- * The plugin is self-sufficient: if the daemon binary is missing it is
21
- * downloaded from the official Kimi CDN (the same source the official
22
- * installer uses) and started automatically, so no external installer
23
- * command is required. A browser extension must still be connected for
24
- * browser actions to work.
25
- *
26
- * All requests go straight to the daemon over HTTP, so there are none of the
27
- * shell-quoting / non-ASCII corruption issues of curl-based integration.
26
+ * A browser extension must still be connected for browser actions to work.
28
27
  *
29
28
  * @module kimi-webbridge-dsh
30
29
  */
@@ -35,24 +34,8 @@ const name = "kimi-webbridge";
35
34
  /** Services required by this plugin. */
36
35
  const inject = ["tools", "systemPrompt"];
37
36
 
38
- /** Every action the daemon accepts on POST /command, plus local "status". */
39
- const ACTIONS = [
40
- "status",
41
- "navigate",
42
- "find_tab",
43
- "snapshot",
44
- "click",
45
- "fill",
46
- "evaluate",
47
- "cdp",
48
- "screenshot",
49
- "network",
50
- "upload",
51
- "save_as_pdf",
52
- "list_tabs",
53
- "close_tab",
54
- "close_session"
55
- ];
37
+ /** The single action of the thin bridge tool. The full browser protocol lives in the generated skill. */
38
+ const ACTIONS = ["status"];
56
39
 
57
40
  /** Runtime configuration schema for the plugin. */
58
41
  const Config = z.object({
@@ -60,7 +43,8 @@ const Config = z.object({
60
43
  requestTimeoutMs: z.number().step(1).min(1000).default(120000),
61
44
  autoStartDaemon: z.boolean().default(true),
62
45
  autoInstallDaemon: z.boolean().default(true),
63
- daemonVersion: z.string().default("latest")
46
+ daemonVersion: z.string().default("latest"),
47
+ generateSkill: z.boolean().default(true)
64
48
  });
65
49
 
66
50
  /** Official release CDN base. */
@@ -91,6 +75,52 @@ function releasePlatform() {
91
75
  return null;
92
76
  }
93
77
 
78
+ /**
79
+ * Platform-aware manual-install hint shown when auto-install is disabled or fails.
80
+ * Windows users get the PowerShell one-liner; macOS/Linux users get the bash one-liner.
81
+ * @returns a short human-readable install instruction.
82
+ */
83
+ function manualInstallHint() {
84
+ const page = "https://www.kimi.ai/products/kimi-webbridge";
85
+ if (process.platform === "win32") {
86
+ return `run \"irm https://cdn.kimi.com/webbridge/install.ps1 | iex\" in PowerShell (or install from ${page})`;
87
+ }
88
+ return `run \"curl -fsSL https://cdn.kimi.com/webbridge/install.sh | bash\" (or install from ${page})`;
89
+ }
90
+
91
+ /** Directory the DSH skill loader scans for the generated skill. */
92
+ function skillDir() {
93
+ return join(homedir(), ".dsh", "skills", "kimi-webbridge");
94
+ }
95
+
96
+ /**
97
+ * Sync the packaged skill.md into the DSH skills directory so the model can
98
+ * load it with the skill tool. Rewrites only when missing or changed, so
99
+ * restarts stay cheap and updates propagate automatically.
100
+ * @returns true when the file was (re)written.
101
+ */
102
+ async function syncSkill() {
103
+ try {
104
+ const source = join(dirname(fileURLToPath(import.meta.url)), "..", "skill.md");
105
+ const content = await readFile(source, "utf8");
106
+ const dest = join(skillDir(), "SKILL.md");
107
+ let existing = null;
108
+ try {
109
+ existing = await readFile(dest, "utf8");
110
+ } catch {
111
+ // missing — created below
112
+ }
113
+ if (existing === content) return false;
114
+ await mkdir(skillDir(), { recursive: true });
115
+ await writeFile(dest, content, "utf8");
116
+ return true;
117
+ } catch (error) {
118
+ // Never break plugin startup over skill syncing; the health tool still works.
119
+ console.warn(`kimi-webbridge: skill sync failed: ${error?.message ?? error}`);
120
+ return false;
121
+ }
122
+ }
123
+
94
124
  /**
95
125
  * One HTTP JSON round-trip with a timeout and caller-abort support.
96
126
  * @param url - absolute URL.
@@ -287,33 +317,27 @@ function apply(ctx, config = {}) {
287
317
  requestTimeoutMs = 120000,
288
318
  autoStartDaemon = true,
289
319
  autoInstallDaemon = true,
290
- daemonVersion = "latest"
320
+ daemonVersion = "latest",
321
+ generateSkill = true
291
322
  } = config;
292
323
 
324
+ if (generateSkill) void syncSkill();
325
+
293
326
  ctx.systemPrompt.section({
294
327
  name: "tool:kimi-webbridge",
295
328
  order: 105,
296
- text: "kimi_webbridge drives the user's real browser through the local kimi-webbridge daemon. Use it for any web task that needs a real browser: navigation, reading pages (snapshot returns an accessibility tree with @e refs), clicking, filling forms, screenshots, JS evaluation, and PDF export. Keep one session name per task and pass it on every call so tabs group under one label."
329
+ 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 and keeps it running. The `kimi_webbridge` tool is only the status health check (daemon + extension). For any browser automation (navigation, reading pages, clicking, typing, filling forms, screenshots, JS evaluation, CDP, uploads, PDF export, tab management), load the kimi-webbridge skill and drive the daemon over HTTP exactly as that skill documents."
297
330
  });
298
331
 
299
332
  ctx.tools.register(defineTool({
300
333
  name: "kimi_webbridge",
301
- description: "Drive the user's real browser (with their login sessions) via the local kimi-webbridge daemon at " + baseUrl + ". The browser extension must be connected (status shows extension_connected). One task = one session = one tab group: pick a session name at the start of a task and pass it on every call. Actions: status (daemon + extension health); navigate {url, newTab?, group_title?} (first call opens a tab); find_tab {url, active?} (re-select a session tab, or borrow the user's active tab); snapshot (accessibility tree with @e refs — use it to read content and locate elements); click {selector} (@e ref or CSS); fill {selector, value} (inputs, textareas, and contenteditable editors; clear-and-insert); evaluate {code} (async JS in the page realm; wrap re-declarations in an IIFE; return compact JSON); cdp {method, params} (raw chrome.debugger passthrough); screenshot {format?, quality?, selector?, path?} (returns a file path — open it with the read tool to see it); network {cmd, filter?, requestId?}; upload {selector, files}; save_as_pdf {paper_format?, landscape?, scale?, print_background?, path?}; list_tabs; close_tab; close_session (only when the user asks to close the tabs). Prefer @e refs from snapshot over hand-written CSS selectors. When the daemon is unreachable the plugin starts it automatically; if the daemon binary is missing it is downloaded from the official Kimi CDN (config autoInstallDaemon:false disables this). Limits: sites that strictly check event.isTrusted (some banking portals, captchas) ignore click/fill — tell the user the page needs manual interaction; cross-origin iframes are not covered by fill/click/snapshot/evaluate — navigate to the iframe URL directly; if an error says 'Please update the Kimi WebBridge extension', the extension is outdated — ask the user to update it and retry.",
334
+ 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 and extension_connected. This tool does NOT perform browser actions — for navigation, clicking, typing, reading pages, screenshots, JS evaluation, CDP, uploads, PDF export and tab management, load the kimi-webbridge skill, which documents the full 17-action HTTP protocol (POST " + baseUrl + "/command) to drive the user's real browser.",
302
335
  parameters: {
303
336
  action: {
304
337
  type: "string",
305
338
  required: true,
306
339
  enum: ACTIONS,
307
- description: "Which WebBridge action to perform."
308
- },
309
- session: {
310
- type: "string",
311
- description: "Task session name — one session per task, passed on every call so all tabs land in one group (e.g. \"camping-research\"). Defaults to \"default\"."
312
- },
313
- args: {
314
- type: "object",
315
- additionalProperties: true,
316
- description: "Action-specific arguments (see the tool description for each action's fields)."
340
+ description: "The single supported action: status — check daemon and browser-extension health."
317
341
  }
318
342
  },
319
343
  output: {
@@ -329,18 +353,7 @@ function apply(ctx, config = {}) {
329
353
  return false;
330
354
  },
331
355
  async execute(args, exec) {
332
- const action = args.action;
333
- const session = args.session ?? "default";
334
- const actionArgs = args.args ?? {};
335
- const target = action === "status" ? `${baseUrl}/status` : `${baseUrl}/command`;
336
- const attempt = () => action === "status"
337
- ? httpJson(target, { method: "GET", timeoutMs: requestTimeoutMs, signal: exec.signal })
338
- : httpJson(target, {
339
- method: "POST",
340
- body: { action, args: actionArgs, session },
341
- timeoutMs: requestTimeoutMs,
342
- signal: exec.signal
343
- });
356
+ const attempt = () => httpJson(`${baseUrl}/status`, { method: "GET", timeoutMs: requestTimeoutMs, signal: exec.signal });
344
357
  let result;
345
358
  try {
346
359
  result = await attempt();
@@ -355,13 +368,13 @@ function apply(ctx, config = {}) {
355
368
  const notes = [];
356
369
  if (!existsSync(daemonBinPath())) {
357
370
  if (!autoInstallDaemon) {
358
- throw new Error(`kimi-webbridge: daemon binary not found at ${daemonBinPath()} and autoInstallDaemon is disabled. Install it with: irm https://cdn.kimi.com/webbridge/install.ps1 | iex`);
371
+ throw new Error(`kimi-webbridge: daemon binary not found at ${daemonBinPath()} and autoInstallDaemon is disabled. Install it manually: ${manualInstallHint()}`);
359
372
  }
360
373
  try {
361
374
  const { url } = await installDaemonBinary({ version: daemonVersion, timeoutMs: requestTimeoutMs });
362
375
  notes.push(`installed daemon from ${url}`);
363
376
  } catch (installError) {
364
- throw new Error(`kimi-webbridge: daemon binary missing and auto-install failed: ${installError?.message ?? installError}. Install it manually: irm https://cdn.kimi.com/webbridge/install.ps1 | iex`);
377
+ throw new Error(`kimi-webbridge: daemon binary missing and auto-install failed: ${installError?.message ?? installError}. Install it manually: ${manualInstallHint()}`);
365
378
  }
366
379
  }
367
380
  if (autoStartDaemon) {
@@ -370,7 +383,7 @@ function apply(ctx, config = {}) {
370
383
  result = await attempt();
371
384
  } catch (retryError) {
372
385
  const hint = notes.length > 0 ? " " + notes.join("; ") + "." : "";
373
- throw new Error(`kimi-webbridge: daemon at ${baseUrl} still unreachable after starting it.${hint} Check ~/.kimi-webbridge/logs/daemon.log or reinstall: irm https://cdn.kimi.com/webbridge/install.ps1 | iex`);
386
+ throw new Error(`kimi-webbridge: daemon at ${baseUrl} still unreachable after starting it.${hint} Check ~/.kimi-webbridge/logs/daemon.log, or reinstall: ${manualInstallHint()}`);
374
387
  }
375
388
  } else {
376
389
  throw new Error(`kimi-webbridge: daemon at ${baseUrl} is not running and autoStartDaemon is disabled. Start it with: ${daemonBinPath()} start`);
@@ -381,9 +394,9 @@ function apply(ctx, config = {}) {
381
394
  presentCall(callArgs) {
382
395
  return {
383
396
  card: "generic",
384
- title: `kimi_webbridge ${callArgs.action}`,
385
- rawInput: JSON.stringify({ session: callArgs.session ?? "default", args: callArgs.args ?? {} }),
386
- content: [{ type: "text", text: `action: ${callArgs.action}` }]
397
+ title: "kimi_webbridge status",
398
+ rawInput: JSON.stringify({ action: callArgs.action ?? "status" }),
399
+ content: [{ type: "text", text: "checking daemon + extension health" }]
387
400
  };
388
401
  }
389
402
  }));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kimi-webbridge-dsh",
3
- "description": "Kimi WebBridge plugin for dsh: drive the user's real browser (their login sessions) through the local kimi-webbridge daemon at 127.0.0.1:10086. Registers a single kimi_webbridge tool covering navigate, click, fill, snapshot, screenshot, evaluate, cdp, network, upload, save_as_pdf, tab and session management.",
4
- "version": "1.4.0",
3
+ "description": "Infrastructure plugin for dsh: provisions the kimi-webbridge daemon (auto-install with SHA-256 verification, auto-start) and generates the kimi-webbridge skill that documents the full 17-action browser protocol. Registers a thin kimi_webbridge tool (status health check only).",
4
+ "version": "1.4.5",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "keywords": [
@@ -31,14 +31,13 @@
31
31
  },
32
32
  "files": [
33
33
  "lib/index.js",
34
+ "skill.md",
34
35
  "README.md",
35
36
  "cordis.patch.yml"
36
37
  ],
37
38
  "peerDependencies": {
38
- "@deepseek-ai/dsh-tools": ">=0.1.0-rc.7 <0.2.0",
39
- "@deepseek-ai/dsh-llm": ">=0.1.0-rc.7 <0.2.0"
40
- },
41
- "dependencies": {
39
+ "@deepseek-ai/dsh-tools": "^0.1.0-rc.7 || ^0.1.1-rc.2",
40
+ "@deepseek-ai/dsh-llm": "^0.1.0-rc.7 || ^0.1.1-rc.2",
42
41
  "@deepseek-ai/schemastery": "^3.18.1"
43
42
  }
44
43
  }
package/skill.md ADDED
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: kimi-webbridge
3
+ description: |
4
+ Drive the user's real browser (with their login sessions) through the local kimi-webbridge daemon at 127.0.0.1:10086: navigate, click, type, read, screenshot, evaluate JS, raw CDP, network capture, file upload, PDF export, and tab/session management. Use this skill whenever the user wants to interact with websites, automate browser tasks, scrape web content, or do anything that needs a real browser — even simple-sounding requests. Also use when the user mentions "browser", "webpage", "open URL", "screenshot", or asks to read/interact with any website (浏览器 / 网页 / 打开网页 / 截图 / 页面).
5
+ ---
6
+
7
+ # Kimi WebBridge
8
+
9
+ Control the user's real browser (their login sessions) through the local daemon at `http://127.0.0.1:10086`.
10
+
11
+ > This skill file is generated by the `kimi-webbridge-dsh` plugin (plugin v1.4.5 / daemon v1.11.6) and re-synced on plugin updates. Do not hand-edit it.
12
+
13
+ ## Health check first
14
+
15
+ Before driving the browser, call the **`kimi_webbridge` tool with action `status`**. It reports daemon + extension health and auto-provisions the daemon (downloads the binary from the official Kimi CDN when missing and starts it, then retries once). `extension_connected: true` means the browser extension is ready; if false, tell the user to install/connect the Kimi WebBridge extension.
16
+
17
+ ## The 17 actions
18
+
19
+ Every action is one HTTP call: `POST http://127.0.0.1:10086/command` with body `{"action": "<name>", "args": {...}, "session": "<task-name>"}`.
20
+
21
+ | action | args | returns | notes |
22
+ |---|---|---|---|
23
+ | `navigate` | `url` (required), `newTab?`, `group_title?` | `{success, url, tabId}` | first call opens a tab |
24
+ | `find_tab` | `url` (required), `active?` | `{success, url, tabId, borrowed}` | re-select a session tab; `active:true` borrows the tab the user is viewing |
25
+ | `snapshot` | — | `{url, title, tree}` | accessibility tree with `@e` refs — read pages with this |
26
+ | `click` | `selector` (`@e` or CSS) | `{success, tag, text}` | synthetic `el.click()` |
27
+ | `mouse_click` | `selector` (`@e` or CSS) | `{success, x, y, tag, text}` | real mouse click at element center (CDP input) — trusted |
28
+ | `fill` | `selector`, `value` | `{success, tag, mode}` | inputs/textareas/contenteditable; clear-and-insert |
29
+ | `key_type` | `text` | `{success, length}` | types into the focused element (CDP input) — trusted |
30
+ | `send_keys` | `keys`, `repeat?` (1–100) | `{success, dispatched, os}` | named keys/shortcuts, e.g. "Enter", "Mod+A", "Enter Escape" |
31
+ | `evaluate` | `code` (async ok) | `{type, value}` | JS in the page realm |
32
+ | `cdp` | `method`, `params` | raw CDP response | chrome.debugger passthrough |
33
+ | `screenshot` | `format?` png/jpeg, `quality?`, `selector?`, `path?` | `{format, path, sizeBytes, mimeType}` | writes a file, returns the path |
34
+ | `network` | `cmd` start/stop/list/detail, `filter?`, `requestId?` | request/response data | |
35
+ | `upload` | `selector`, `files` (array of local paths) | `{success, fileCount}` | |
36
+ | `save_as_pdf` | `paper_format?` letter/a4/legal/a3/tabloid, `landscape?`, `scale?` 0.1–2.0, `print_background?`, `path?` | `{path, sizeBytes, mimeType, pageTitle}` | |
37
+ | `list_tabs` | — | `{success, tabs:[{tabId,url,title,active,groupTitle}]}` | |
38
+ | `close_tab` | — | `{success, closed}` | |
39
+ | `close_session` | — | `{success, closed}` | close all session tabs — only when the user asks |
40
+
41
+ ## Sending requests (shell-proof)
42
+
43
+ On **Windows (PowerShell)**, inline JSON with non-ASCII text gets corrupted by the shell — **always** send the body via a temp file: write the JSON to a uniquely-named temp file with your file-write tool, then:
44
+
45
+ ```powershell
46
+ curl.exe -s -X POST http://127.0.0.1:10086/command -H "Content-Type: application/json" --data-binary "@$env:TEMP\wb-<random>.json"
47
+ ```
48
+
49
+ then delete the temp file. Always `curl.exe`, never bare `curl` (PowerShell aliases it to Invoke-WebRequest).
50
+
51
+ On **macOS / Linux**, inline `-d '{...}'` is fine; if a call fails with a shell quoting error or HTTP 400, switch to the temp-file form above.
52
+
53
+ ## Sessions
54
+
55
+ One task = one session = one tab group. Pick a task-named session (`camping-research`) and pass it on **every** call, never switching mid-task. `group_title` (in the user's language) on the first `navigate` labels the group. Example body:
56
+
57
+ ```json
58
+ {"action":"navigate","args":{"url":"https://example.com","newTab":true,"group_title":"Research"},"session":"research"}
59
+ ```
60
+
61
+ Call `close_session` only when the user explicitly asks to close the tabs.
62
+
63
+ ## Reading and interacting
64
+
65
+ - Prefer `snapshot` + `@e` refs over hand-written CSS selectors.
66
+ - `find_tab` searches only this session's tabs; pass the exact URL (a bare domain may miss www/subdomain variants). On "no tab matching", `navigate` with `newTab:true`. With `active:true` it borrows the user's currently-viewed tab and operates it in place.
67
+ - `evaluate`: wrap re-declarations in an IIFE; return compact `JSON.stringify` (never pretty-print).
68
+ - `fill` is clear-and-insert; to append, read the current value via `evaluate` first.
69
+ - Trusted input: on sites that reject synthetic events (`event.isTrusted` checks — banking portals, captchas), use `mouse_click` instead of `click` and `key_type`/`send_keys` instead of `fill`. If those still fail, tell the user the page needs manual interaction.
70
+ - `send_keys` keys: Enter/Return, Escape/Esc, Tab, Backspace, Delete, Space, ArrowUp/Down/Left/Right, Home/End, PageUp/PageDown, F1–F12, single letters/digits. Modifiers: Alt/Ctrl/Control/Cmd/Meta/Shift, or `Mod` (Cmd on Mac, Ctrl elsewhere). Join with `+` ("Mod+A", "Shift+Tab"); space-separate several ("Enter Escape").
71
+ - Cross-origin iframes are not covered — navigate to the iframe URL directly.
72
+
73
+ ## Screenshots and PDF
74
+
75
+ `screenshot` and `save_as_pdf` write files and return a path — open it with your read tool. A caller-supplied `path` is honored verbatim (parent dirs created, existing files overwritten). PDF decoded cap is 100 MB; reduce `scale` to shrink.
76
+
77
+ ## Daemon or extension problems
78
+
79
+ - Call the `kimi_webbridge` tool (`status`) — the plugin auto-provisions and starts the daemon. Never run `stop` / `restart` / `uninstall` yourself.
80
+ - If an error mentions "Please update the Kimi WebBridge extension", the extension is outdated — ask the user to update it (https://www.kimi.com/features/webbridge).
81
+ - If the daemon stays unreachable after the status tool's retry, point the user to the help page instead of deep-troubleshooting.
82
+
83
+ ---
84
+
85
+ Protocol and workflow adapted from the Kimi WebBridge community skill (Apache-2.0). Daemon binary and browser extension by Kimi. This file is generated by kimi-webbridge-dsh.