Skip to content

Add bsk cookies: export Agent-Window site cookies (incl. httpOnly) for test-runner handoff - #393

Open
youyouhe wants to merge 1 commit into
Tencent:mainfrom
youyouhe:feature/cookies-export
Open

youyouhe wants to merge 1 commit into
Tencent:mainfrom
youyouhe:feature/cookies-export

Conversation

@youyouhe

@youyouhe youyouhe commented Oct 3, 2026

Copy link
Copy Markdown

Motivation

Agents frequently need to hand a logged-in browser session to a headless test runner (Playwright storageState, and similar) to get repeatable UI regression against production sites. Today that chain is broken: production auth cookies (LOGIN_INFO, HSID, …) are httpOnly, so they are invisible to Runtime.evaluate / document.cookie, and the debug request capture does not include request headers. There is no legitimate path from "the site I opened in the Agent Window" to "a test-runner credential file" — even when the human explicitly wants exactly that.

This PR adds one narrowly-scoped tool for that handoff.

What it adds

bsk cookies --session <id> [--tab-id N] [--json] → tool.cookies

  • Protocol: CookiesParams / CookiesResult / CookieEntry in bsk-protocol (tool.cookies Method, unit-tested serde roundtrips)
  • Daemon: dispatch whitelist entry (goes through the generic tool forwarder)
  • CLI: cookies subcommand (same exit-code policy as evaluate)
  • Extension: handleCookies reusing the tool.evaluate sandbox verbatim — lookupSession → resolveTargetTab → enforceAgentWindow → CDP Network.getCookies

Security red-lines honored (design §6)

This is the part I tried hardest to get right, since the obvious risk is turning this into a token-exfil window:

  1. Agent Window tabs only — identical sandbox to tool.evaluate (resolveTargetTab + enforceAgentWindow). Arbitrary user tabs are refused with permission_denied; only sites the human explicitly handed to the agent can be exported.
  2. Query scoped to the tab's own URL — Network.getCookies { urls: [tab.url] }. The export cannot be widened to browser-wide, other domains, or "all cookies" — there is no parameter for it.
  3. Classified BrowserMutation (conservative, same class as tool.evaluate) rather than a passive read, so the pending-interrupt gate applies to it.
  4. http(s) tabs only — refused otherwise.

If maintainers would prefer additional gating (e.g. an opt-in setting, or a user consent prompt per export), I'm happy to extend it — the current shape is the minimum that keeps the tool useful.

End-to-end verification

Against youtube.com (signed-in session):

$ bsk cookies --session <s> --json
→ 23 cookies, 15 httpOnly (incl. LOGIN_INFO, HSID, SSID, SID, SAPISID)
→ converted to Playwright storageState → newContext({ storageState })
→ headless context renders the signed-in UI (avatar present, no sign-in button,
  personalized feed), 36 rich items

The same conversion run with only document.cookie-visible cookies stays signed out — i.e. the tool adds exactly the capability that was missing, nothing more.

Notes for maintainers

  • The Method addition is additive; protocol major stays 1.3 (old peers reject the unknown method with the usual version-skew error rather than breaking the handshake). Happy to bump to 1.4 if the project's convention prefers a minor bump for new methods.
  • CHANGELOG has an Unreleased / Added entry.
  • Tested on Windows (GNU toolchain) and with the extension test suite layout; happy to add a dispatcher unit test if you point me at the closest precedent for a sibling tool.

🤖 Generated with Claude Code

…r test-runner handoff

New tool.cookies method across protocol/daemon/CLI/extension, reusing the
tool.evaluate sandbox: resolveTargetTab + enforceAgentWindow (Agent Window
tabs only), query scoped to the tab's own URL via CDP Network.getCookies.
Classified BrowserMutation so the pending-interrupt gate applies.

Primary use case: export a logged-in session's cookies as JSON and load
them into a headless test runner (Playwright storageState) for repeatable
UI regression against production sites whose auth cookies are httpOnly
and therefore invisible to Runtime.evaluate / document.cookie.

Verified end to end against youtube.com: 23 cookies exported (15
httpOnly, incl. LOGIN_INFO/HSID/SSID); a Playwright context booted from
the converted storageState renders the signed-in UI (avatar, personalized
feed).

Co-Authored-By: Claude Code <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant