Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENT_INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ For CLI harnesses, start with `bsk session start --no-focus --json`, retain the
returned session ID, then navigate and observe using `--session <id>`. Stop that
session with `bsk session stop <id>` on success or failure. With multiple browsers,
use `bsk browsers` and add `--browser <id>` when starting the session.
For dsh, use its injected `browser_*` tools instead.
For dsh, use its injected `bsk_*` tools instead.

For the WorkBuddy/CodeBuddy or child-reaping-host workflow, use separate tool
calls for startup, status, session creation, navigation/observation and final
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,22 @@ Starting from 0.2.0, CLI / Extension / DSH Plugin share the same version number.

## [Unreleased]

### Changed

- **Breaking — DSH Plugin:** replace `browser_session`, `browser_page`,
`browser_inspect`, `browser_interact`, `browser_tabs`, and `browser_assist` with
the corresponding `bsk_*` names to coexist with other browser plugins.
Actions, arguments, results, and the `browser-skill` skill name are unchanged.
Update hardcoded calls and tool policies, restart the host, and reload the skill
in existing conversations. See the [migration guide](packages/dsh-plugin-browserskill/README.md#breaking-tool-api-migration-unreleased).

### Fixed

- DSH Plugin: roll back incomplete tool registration, surface activation failures,
and retry at skill/session lifecycle boundaries without leaving a partial suite.
Include tool schemas in the first `/browser-skill` request, and keep failure and
recovery notices synchronized with model skill results
([#444](https://github.com/Tencent/BrowserSkill/issues/444)).
- Extension: input to a background Agent Window tab no longer keeps failing with
`input_not_ready` after Chrome drops the session's focus override without a detach
([#355](https://github.com/Tencent/BrowserSkill/issues/355)). The session's
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ In WorkBuddy/CodeBuddy, or hosts that reap command children, the agent should re

## DeepSeek Harness plugin

The [DSH plugin](packages/dsh-plugin-browserskill/README.md) adds native `browser_*` tools, browser task previews, and screenshot results to the DeepSeek Harness Web UI. It uses the same `bsk` CLI and extension and includes its own BrowserSkill skill.
The [DSH plugin](packages/dsh-plugin-browserskill/README.md) adds native `bsk_*` tools, browser task previews, and screenshot results to the DeepSeek Harness Web UI. It uses the same `bsk` CLI and extension and includes its own BrowserSkill skill.

With DeepSeek Harness, pnpm, and `bsk` installed and the extension connected, add the plugin to your profile:

Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ bsk session stop <id>

## DeepSeek Harness 插件

[DSH 插件](packages/dsh-plugin-browserskill/README.md) 在 DeepSeek Harness Web UI 中提供原生 `browser_*` 工具、浏览器任务预览和截图结果。它使用同一套 `bsk` CLI 与扩展,并自带 BrowserSkill skill。
[DSH 插件](packages/dsh-plugin-browserskill/README.md) 在 DeepSeek Harness Web UI 中提供原生 `bsk_*` 工具、浏览器任务预览和截图结果。它使用同一套 `bsk` CLI 与扩展,并自带 BrowserSkill skill。

安装好 DeepSeek Harness、pnpm 和 `bsk`,连接扩展后,将插件加入你的 profile:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe("profile instructions", () => {
const text = vi.mocked(navigator.clipboard.writeText).mock.calls[0]?.[0];
expect(text).toContain('browser "Work" (instance ID: a1234567)');
expect(text).toContain("bsk session start --browser a1234567 --json");
expect(text).toContain('browser_session({ action: "start", browser: "a1234567" })');
expect(text).toContain('bsk_session({ action: "start", browser: "a1234567" })');
expect(text).toContain("use the tool call instead of running the CLI command separately");
expect(text).toContain("every new session for this task");
expect(text).toContain("Do not omit --browser / browser or switch to another instance");
Expand Down Expand Up @@ -70,7 +70,7 @@ describe("profile instructions", () => {
"bsk session start --browser b1234567 --json",
);
expect(vi.mocked(navigator.clipboard.writeText).mock.calls[1]?.[0]).toContain(
'browser_session({ action: "start", browser: "b1234567" })',
'bsk_session({ action: "start", browser: "b1234567" })',
);
});
it("reports clipboard failure and allows retry without claiming success", async () => {
Expand All @@ -90,7 +90,7 @@ describe("profile instructions", () => {
const text = vi.mocked(navigator.clipboard.writeText).mock.calls[0]?.[0];
expect(text).toContain(JSON.stringify(label));
expect(text).toContain("CLI: bsk session start --browser a1234567 --json");
expect(text).toContain('browser_session({ action: "start", browser: "a1234567" })');
expect(text).toContain('bsk_session({ action: "start", browser: "a1234567" })');
expect(await screen.findByRole("button", { name: "Copied" })).toBeTruthy();
});
it("discards pending feedback when the saved name changes and copies the new name", async () => {
Expand Down Expand Up @@ -153,7 +153,7 @@ describe("profile instructions", () => {
"bsk session start --browser a1234567 --json",
);
expect(vi.mocked(navigator.clipboard.writeText).mock.calls[0]?.[0]).toContain(
'browser_session({ action: "start", browser: "a1234567" })',
'bsk_session({ action: "start", browser: "a1234567" })',
);
expect(vi.mocked(navigator.clipboard.writeText).mock.calls[0]?.[0]).toContain(
"--browser / browser",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function ProfileInstructions({
name: JSON.stringify(label || t("popup.profile.unnamed")),
instanceId,
command: `bsk session start --browser ${instanceId} --json`,
toolCall: `browser_session({ action: "start", browser: ${JSON.stringify(instanceId)} })`,
toolCall: `bsk_session({ action: "start", browser: ${JSON.stringify(instanceId)} })`,
});

useEffect(() => {
Expand Down
16 changes: 8 additions & 8 deletions apps/extension/src/video/capture.browser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -730,20 +730,20 @@ describe.skipIf(!process.env.BSK_VIDEO_CHROME || !process.env.BSK_VIDEO_BSK)(
// navigation and exports after its owned session is gone.
const dsh = await createDshVideoFixture(executable, env, path.join(directory, "dsh"));
try {
const task = await dsh.call<{ sessionId: string }>("browser_session", {
const task = await dsh.call<{ sessionId: string }>("bsk_session", {
action: "start",
});
const started = await dsh.call<{
recording: { recording_id: string; state: string; tab_id: number };
}>("browser_inspect", {
}>("bsk_inspect", {
action: "video",
videoAction: "start",
session: task.sessionId,
durationMs: 30000,
});
expect(started.recording.state).toBe("recording");
const recordingId = started.recording.recording_id;
await dsh.call("browser_page", {
await dsh.call("bsk_page", {
action: "navigate",
session: task.sessionId,
url: `http://127.0.0.1:${address.port}/red`,
Expand All @@ -764,28 +764,28 @@ describe.skipIf(!process.env.BSK_VIDEO_CHROME || !process.env.BSK_VIDEO_BSK)(
await new Promise((resolve) => setTimeout(resolve, 1200));
const finished = await dsh.call<{
recording: { state: string; completeness: string; byte_size: number };
}>("browser_inspect", { action: "video", videoAction: "stop", recordingId });
}>("bsk_inspect", { action: "video", videoAction: "stop", recordingId });
expect(finished.recording.state).toBe("ready");
expect(finished.recording.completeness).toBe("complete");
await dsh.call("browser_session", { action: "stop", session: task.sessionId });
await dsh.call("bsk_session", { action: "stop", session: task.sessionId });
const output = path.join(directory, "dsh.mp4");
await dsh.call("browser_inspect", {
await dsh.call("bsk_inspect", {
action: "video",
videoAction: "save",
recordingId,
output,
});
expect((await stat(output)).size).toBe(finished.recording.byte_size);
await expect(
dsh.call("browser_inspect", {
dsh.call("bsk_inspect", {
action: "video",
videoAction: "save",
recordingId,
output,
}),
).rejects.toThrow(/Output exists/);
const list = await dsh.call<{ recordings: { recording_id: string }[] }>(
"browser_inspect",
"bsk_inspect",
{ action: "video", videoAction: "list" },
);
expect(list.recordings.map((value) => value.recording_id)).toEqual([recordingId]);
Expand Down
2 changes: 1 addition & 1 deletion docs/browser-profiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ routing identifiers, not independent proof of a filesystem path.
Use the verified popup instance ID in the plugin's session tool:

```text
browser_session({ action: "start", browser: "<verified-instance-id>" })
bsk_session({ action: "start", browser: "<verified-instance-id>" })
```

**Copy instructions** includes this tool call alongside the CLI command.
Expand Down
4 changes: 2 additions & 2 deletions docs/scroll-to.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ distance or scroll direction. Use [wheel](wheel.md) for native directional wheel
| --- | --- |
| CLI | `bsk scroll-to` |
| Wire protocol | `tool.scroll_to` |
| DeepSeek Harness | `browser_interact` with `action: "scroll-to"` |
| DeepSeek Harness | `bsk_interact` with `action: "scroll-to"` |

## CLI

Expand Down Expand Up @@ -97,7 +97,7 @@ The plugin exposes the same action with its usual camelCase parameters:
}
```

Call this through `browser_interact` using a plugin-owned session. Its result
Call this through `bsk_interact` using a plugin-owned session. Its result
contains `session`, `tabId`, `x`, `y`, `width` and `height` with the same bounds
semantics. Omitted `session` uses the plugin's current session.

Expand Down
12 changes: 6 additions & 6 deletions docs/structured-extraction.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,12 @@ allows a consumer to detect a mismatched pair.

## DSH plugin

The existing **browser_inspect** tool gains **action: "extract"**:
The existing **bsk_inspect** tool gains **action: "extract"**:

~~~text
browser_inspect({ action: "extract", session: "<id>", extractKind: "discover" })
browser_inspect({ action: "extract", session: "<id>", extractKind: "table", extractTarget: "<target_id>" })
browser_inspect({ action: "extract", session: "<id>", extractKind: "table", selector: "#orders",
bsk_inspect({ action: "extract", session: "<id>", extractKind: "discover" })
bsk_inspect({ action: "extract", session: "<id>", extractKind: "table", extractTarget: "<target_id>" })
bsk_inspect({ action: "extract", session: "<id>", extractKind: "table", selector: "#orders",
extractFormat: "csv", output: "/absolute/path/orders.csv", csvSafe: true })
~~~

Expand All @@ -203,8 +203,8 @@ requires an output path so the plugin always receives structured JSON. The plugi
normal session registry, runner and queue; it does not introduce arbitrary
page-script evaluation. Output paths are on the CLI host; relative paths resolve
against that process's working directory. Prefer absolute paths in harness calls.
Extraction shares browser_inspect's output parameter with debug export and video
save. Its model guidance lives in the browser_inspect description and parameter
Extraction shares bsk_inspect's output parameter with debug export and video
save. Its model guidance lives in the bsk_inspect description and parameter
schema rather than a separate DSH skill reference, keeping the DSH skill entry
within its 4,500-byte budget in both LF and CRLF checkouts.

Expand Down
8 changes: 4 additions & 4 deletions docs/video-recording.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ BSK_VIDEO_CHROME=/path/to/chrome BSK_VIDEO_BSK=../../target/debug/bsk \
```

The extension's minimum Chrome version remains 125. Codec support is validated at
runtime. DSH uses `browser_inspect(action=video)` with `videoAction` set to start, status,
runtime. DSH uses `bsk_inspect(action=video)` with `videoAction` set to start, status,
stop, save, list, or discard. Its six public tool schemas are retained. Start
follows the session queue; artifact operations bypass that queue so status/stop
remain available during human help. A plugin-local allowlist of returned recording
Expand All @@ -190,11 +190,11 @@ this allowlist; the extension library remains available for recovery. CLI partia
stop/save errors retain their recording metadata and saved path in the tool error.

```text
browser_inspect({ action: "video", videoAction: "start", session: "<task>", durationMs: 60000 })
bsk_inspect({ action: "video", videoAction: "start", session: "<task>", durationMs: 60000 })
// Execute task operations after state=recording.
browser_inspect({ action: "video", videoAction: "stop", recordingId: "<recording_id>" })
bsk_inspect({ action: "video", videoAction: "stop", recordingId: "<recording_id>" })
// End the task. Preview and Save As remain available in the extension.
browser_inspect({ action: "video", videoAction: "save", recordingId: "<recording_id>", output: "<explicit-path.mp4>" })
bsk_inspect({ action: "video", videoAction: "save", recordingId: "<recording_id>", output: "<explicit-path.mp4>" })
```


Expand Down
4 changes: 2 additions & 2 deletions docs/website-debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Follow `next_offset` while present. Offsets count UTF-16 code units, matching th
extension. RFC 6901 `--pointer` works only on a complete retained JSON body and is
applied after redaction. No network request is repeated by these reads.

DSH uses `browser_inspect` with `action: "debug"`, `debugAction` matching the CLI
DSH uses `bsk_inspect` with `action: "debug"`, `debugAction` matching the CLI
subcommand, and camelCase options (`runId`, `tabId`, `maxChars`). The six public
tools, existing session ownership, cancellation and queue remain unchanged.
The wire endpoint is `tool.debug`; schemas are in `crates/bsk-protocol/schema`.
Expand Down Expand Up @@ -420,7 +420,7 @@ bsk debug replay <request-id> --session <id> --replay-file replay.json
```

`--rule` and `--replay` also accept inline JSON. DSH exposes these as JSON-string
`rule` / `replay` parameters on `browser_inspect(action: "debug")`, with the same
`rule` / `replay` parameters on `bsk_inspect(action: "debug")`, with the same
`debugAction` values. File input avoids putting large bodies in command arguments.

Replay sends a **new** request and may change server data. It uses a dedicated
Expand Down
2 changes: 1 addition & 1 deletion docs/wheel.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ when the goal is simply to bring an existing element into view.
| --- | --- |
| CLI | `bsk wheel` |
| Wire protocol | `tool.wheel` |
| DeepSeek Harness | `browser_interact` with `action: "wheel"` |
| DeepSeek Harness | `bsk_interact` with `action: "wheel"` |

## Usage

Expand Down
Loading
Loading