Commit Graph
53 Commits
Author SHA1 Message Date
drakezhangandCursor ed92e54dff Bump extension to 0.1.4
The manifest now declares a minimum Chrome version and requests the
`idle` permission, and the runtime gains the WebSocket heartbeat and
wake-driven reconnect. Publishing that update requires a new version.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-22 12:30:46 +08:00
drakezhangandCursor cb11cecdf6 Lock system.heartbeat wire name with a contract test
The extension emits the literal event string "system.heartbeat";
assert the daemon-side serde name serialises to the same value and
round-trips from the exact frame shape the extension sends, so a
future rename cannot silently break keepalive and liveness.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-22 12:30:46 +08:00
drakezhangandCursor ea03f36f3a Widen session.start browser-connect wait for cold reconnects
After a long idle the service worker is only revived on its next
keepalive-alarm tick (up to 30s away), so the previous 5s wait made
the first command after idle fail with `no_browser_connected` even
though the extension was about to reconnect.

- Raise the daemon's `EXTENSION_CONNECT_WAIT` (used by `session.start`)
  to 35s so it comfortably covers one alarm period plus handshake slack.
- Bump the CLI `session start` IPC timeout to that window plus slack so
  it never gives up before the daemon answers, and print a one-line
  "waiting for browser extension to connect…" hint when it actually
  waits.
- Keep `bsk status` / `browsers` on their own short 5s wait so quick
  informational commands are not slowed down.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-22 12:17:15 +08:00
drakezhangandCursor 234e9101ed Keep service worker alive with WS heartbeat and wake reconnect
Harden the extension's connection so the daemon link survives normal
idle periods and OS sleep instead of silently dropping.

- Send a `system.heartbeat` event every 20s while the post-handshake
  link is live. Since Chrome 116 WebSocket activity resets the MV3
  service-worker idle timer, so this keeps the worker (and the socket)
  alive during use rather than relying on the 30s keepalive alarm that
  sits right on the eviction boundary. Declare `minimum_chrome_version:
  "116"` accordingly.
- Reconnect on `runtime.onStartup` and `idle.onStateChanged` ("active"),
  which revive the worker after a browser restart or machine wake and
  let it reconnect immediately instead of waiting for the next alarm
  tick. Add the `idle` permission and document it.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-22 12:17:06 +08:00
drakezhangandCursor 5e91178e03 Add heartbeat event and daemon browser-liveness reaper
Introduce a `system.heartbeat` protocol event and use it as a
liveness signal on the daemon side.

- Track `last_seen` per connected browser, bumped on every inbound
  WS frame (tool response, event, ping/pong, or heartbeat).
- Add a reaper task that drops any browser silent past a 60s window
  and purges its sessions, mirroring the WS disconnect cleanup. This
  releases half-open connections left behind when the OS resumes from
  sleep and kills the service worker without delivering a close frame,
  so the daemon no longer pins a phantom "connected" browser and can
  idle-exit normally.
- Wire the reaper into both the foreground daemon and the test/embed
  entry point, aborting it on shutdown.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-22 12:16:56 +08:00
BB-fat ccf3c32140 Merge pull request #8 from hjxccc/feat/console-network-commands
feat: add bsk network read-only command
2026-07-18 22:53:20 +08:00
BB-fatandCursor 9799b98937 fix: address network command review feedback
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 22:52:53 +08:00
hjxccc 259b4826b7 feat: add bsk network read-only command
Add `bsk network` as a sibling of the `console` command from #7,
reading the buffered network responses / failures for a tab. Fills the
remaining half of the request in #2 (console landed in #7; network did
not).

Mirrors the console command's conventions exactly:

  bsk network --session <id> [--tab-id N] [--since C]
                             [--limit N] [--max-text-chars N]

The extension enables `Network` on attach (best-effort) and buffers
`responseReceived` / `loadingFailed` events per tab with a monotonic
sequence, correlating them to `requestWillBeSent` for method/URL. Reads
are cursor-paginated (`since` -> `next_since`) and bounded (`limit`,
`max_text_chars`) for agent-context safety, same as console. Entries
carry the real HTTP status code (response) or the CDP failure reason
(failure) — things `performance.getEntriesByType('resource')` can't
give.

Classified read-only (pass-through under the pending-interrupt gate);
defaults to the Agent Window's active tab.

Wires bsk-protocol (Method + params/result/entry structs + schema),
bsk-cli (network subcommand + daemon dispatch allow-list) and the
extension (handler + dispatcher route), with unit / parse / IPC tests
paralleling the console command.

Refs #2.
2026-07-18 22:37:57 +08:00
BB-fat 3d6c95c22a Merge pull request #16 from NianJiuZst/codex/fail-closed-tab-borrow
fix(extension): fail closed on borrow confirmation
2026-07-18 22:34:31 +08:00
BB-fatandCursor 11ec51dfb8 fix(extension): dismiss overlay on borrow timeout
Send borrow-cancel when the confirmation timeout denies, and add a
timer fallback so auto-deny does not depend only on CSS transitionend.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 22:31:27 +08:00
BB-fat e16b37aaa0 Merge pull request #22 from NianJiuZst/codex/enforce-session-idle-timeout
fix(daemon): enforce session idle timeout
2026-07-17 16:53:21 +08:00
BB-fat d27ef1f5e0 Merge pull request #23 from NianJiuZst/codex/doctor-fails-nonzero
fix(doctor): exit nonzero on failed checks
2026-07-17 16:50:19 +08:00
BB-fat e55ce8ad99 Merge pull request #29 from klren0312/fixbug/errortips
Correct the incorrect command examples in the error message that does not indicate the mistake.
2026-07-17 16:13:49 +08:00
klkl 7bee906ffb fix(bsk-cli): Correct the incorrect command examples in the error message that does not indicate the mistake. 2026-07-17 15:42:52 +08:00
NianJiuZst bf6c384b2e test: avoid probe race in idle daemon helper 2026-07-10 23:07:43 +08:00
NianJiuZst ec2cde4467 test: bind daemon ports without probe races 2026-07-10 23:06:51 +08:00
NianJiuZst c5e83eac4c test: bind daemon ports without probe races 2026-07-10 23:06:46 +08:00
NianJiuZst 9f82d89788 test: bind daemon ports without probe races 2026-07-10 23:06:02 +08:00
NianJiuZst 2964f6219d ci: retry stalled Rust job 2026-07-10 22:59:01 +08:00
NianJiuZst f8907e5f5a ci: retry stalled Rust job 2026-07-10 22:58:57 +08:00
NianJiuZst d422f655d4 ci: retry stalled Rust job 2026-07-10 22:50:15 +08:00
NianJiuZst d4d4c3beeb ci: retry stalled Rust job 2026-07-10 22:50:01 +08:00
NianJiuZst 3c7a22e7c7 chore(ci): match Biome 2.4 formatting 2026-07-10 22:40:27 +08:00
NianJiuZst dca2b58cbd fix(doctor): exit nonzero on failed checks 2026-07-10 22:39:41 +08:00
NianJiuZst 13279a7f56 fix(daemon): enforce session idle timeout 2026-07-10 22:36:13 +08:00
NianJiuZst ed6d14eab3 fix(extension): fail closed on borrow confirmation 2026-07-10 22:01:46 +08:00
BB-fat 913a3f80a4 Merge pull request #13 from zjxzjw/fix2
config(extension): 配置WebSocket连接URL为构建时变量
2026-07-10 00:30:40 +08:00
BB-fat f60d1e65a7 Merge pull request #12 from NianJiuZst/codex/issue-10-pr-ci
Add PR CI workflow
2026-07-10 00:23:36 +08:00
BB-fat d4a89e89f1 Merge pull request #14 from Tencent/chore/fix-pnpm-lint
Fix pnpm lint formatting
2026-07-10 00:21:36 +08:00
BB-fatandCursor 3c936982a3 Fix Biome and Stylelint formatting so pnpm lint passes.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 00:21:19 +08:00
engineer 37056b3c6e config(extension): 配置WebSocket连接URL为构建时变量
- 移除DEFAULT_DAEMON_PORT常量定义
- 使用__BSK_DAEMON_WS_URL__构建时变量替代硬编码端口
- 在wxt.config.ts和vitest.config.ts中添加环境变量配置
- 为__BSK_DAEMON_WS_URL__添加类型声明和文档注释
- 默认值保持为ws://127.0.0.1:52800,可通过BSK_DAEMON_WS_URL环境变量覆盖
2026-07-09 13:44:48 +08:00
NianJiuZst fa3133a094 Add PR CI workflow 2026-07-09 12:42:42 +08:00
BB-fat d395faa0ab Merge pull request #9 from Tencent/feat/bsk-cli-auto-update
Add bsk CLI auto update support
2026-07-08 14:20:31 +08:00
BB-fatandCursor a7c48275f9 feat: add bsk CLI auto update
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 14:14:00 +08:00
BB-fatandCursor 647ae659b7 feat: add placeholder for bsk CLI auto update
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 17:20:59 +08:00
BB-fatandCursor eda8b22c43 chore: bump CLI to 0.1.7 and extension to 0.1.3
Co-authored-by: Cursor <cursoragent@cursor.com>
cli-v0.1.7 ext-v0.1.3
2026-07-07 17:11:22 +08:00
BB-fat c987e42da9 Merge pull request #7 from Tencent/feat/console-command
feat: add bsk console command
2026-07-07 11:27:09 +08:00
BB-fatandCursor 7f5093d97a feat: add console observation command
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 11:08:12 +08:00
BB-fat ce29ddaa53 Merge pull request #5 from hobostay/fix/borrow-confirmation-tabs-get-fail-open
fix(extension): don't fail-open the borrow gate on a transient tabs.get error
2026-07-06 11:46:39 +08:00
BB-fat 2e7998477d Merge pull request #4 from hobostay/fix/ws-event-ownership
fix(daemon): reject cross-browser session events from non-owners
2026-07-06 11:44:19 +08:00
BB-fat c9e00bb641 Merge pull request #3 from hobostay/fix/tab-return-fallback-into-agent-window
fix(extension): never return a borrowed tab into another session's Agent Window
2026-07-06 11:33:38 +08:00
Test UserandClaude ad2a12e57e fix(extension): don't fail-open the borrow gate on a transient tabs.get error
requestBorrowConfirmation returned `true` (approve the borrow) when
`chrome.tabs.get(tabId)` threw. That fail-open was not one of the
documented fail-open cases in the function's own doc comment (no
candidate window; abort signal; timeout), and the tab was already
fetched successfully moments earlier by the borrow pipeline
(validateBorrowTarget), so a failure here is a transient SW/page hiccup
— not a missing tab. Silently approving a borrow with no confirmation
UI shown defeats the entire human-in-the-loop gate for seizing a user's
logged-in tab.

On a tabs.get failure, fall back to a generic title (the numeric tab id)
and still run the overlay + OS-notification confirmation flow so the
user gets a real chance to approve or deny.

Adds two regression tests (both fail on the unpatched code). Full
extension suite green (361 tests).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 21:02:54 +08:00
Test UserandClaude 61096110c0 fix(daemon): reject cross-browser session events from non-owners
The daemon dispatched inbound `session.window_closed` and
`session.user_interrupt` events using only the payload — the sending
browser's identity was never checked against the session's owner.

Any connected extension could therefore emit window_closed with
another browser's session_id to tear down its session (forgetting it,
dropping its tool queue + interrupt marker), or emit user_interrupt
to cancel every inflight tool of another browser's session and arm
its interrupt marker. This is a cross-tenant integrity/DoS hole that
is exploitable even between two legitimate extensions, independent of
the (separately tracked) WS Origin allow-list gap.

Thread the sender's BrowserId (already in scope as `client.id` in
handle_inbound_text) into both handlers and ignore the event when the
named session is live and owned by a different browser. A session
that is already gone is left to the existing no-op forget path.

Adds four ownership tests (owner honoured / non-owner ignored for each
event); updated two existing tests for the new signature. Full bsk
suite green (165 lib + integration), no new clippy warnings.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 20:47:42 +08:00
Test UserandClaude 8e8dd3840b fix(extension): never return a borrowed tab into another session's Agent Window
When a borrowed tab's original window is gone, tab_return's fallback
picker called getLastFocused({windowTypes:["normal"]}) and only
excluded the *current* session's Agent Window. Agent Windows are
created with type:"normal", so the picker could move a returned user
tab into *another* session's Agent Window. That session could then
write to the tab (it passes enforceAgentWindow), and the tab would be
destroyed when that session stops and closes its window — a
cross-session sandbox break plus silent user-data loss.

Thread an isAgentWindowId predicate (derived from SessionManager in
the production handlers, mirroring the existing filter in
borrow-confirmation's listConfirmationCandidates) through
returnBorrowedTab -> chooseFallbackWindow so every live Agent Window
is skipped as a fallback target.

Adds two regression tests (both fail on the unpatched code).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-02 20:23:02 +08:00
BB-fatandCursor 9c229b2489 chore: bump CLI version to 0.1.6
Co-authored-by: Cursor <cursoragent@cursor.com>
cli-v0.1.6
2026-06-30 18:14:26 +08:00
BB-fatandCursor 26e5f98c16 docs: open extension install page from agent guide
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-25 15:55:20 +08:00
BB-fatandCursor dc8a6d38b3 Fix browser wait during daemon startup
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-23 15:04:20 +08:00
BB-fat ab6aa16dfc feat: add Git Bash PATH support to installer
- Add Add-ToBashProfile helper to append install dir to ~/.bashrc
- Converts Windows paths to Unix-style for Git Bash compatibility
- Integrate into Main install flow alongside Add-ToUserPath
- Update completion message to mention Git Bash
2026-06-23 11:00:47 +08:00
BB-fat 45c85fa64a feat: add PowerShell install script for Windows
- Add install.ps1 mirrored from install.sh patterns
  - Same env var overrides (BSK_REPO, BSK_VERSION, BSK_INSTALL_DIR)
  - Default install dir ~/.local/bin
  - Fetches latest version from version.json via Invoke-RestMethod
  - Downloads, extracts zip, installs bsk.exe
  - Adds to user PATH persistently with idempotent check
  - Supports x64 and ARM64 architecture detection
- Update README.md Windows section with irm | iex one-liner
- Update AGENT_INSTALL.md with Windows PowerShell instructions
2026-06-23 10:45:29 +08:00
BB-fat b8c4be4362 docs: move video link after intro paragraph in both READMEs 2026-06-22 17:55:42 +08:00