setup-browser-cookies · git:20261009.553d413 · 2026-10-09 · sha256 2a07a57cacd08fb9
setup-browser-cookies git:20261009.553d413A
Immutable. This exact content never changes and is served at /api/v1/blob/2a07a57cacd08fb9.
---
name: setup-browser-cookies
description: |
Import cookies from your real Chromium browser into the headless browse session to QA authenticated pages.
triggers:
- import browser cookies
- login to test site
- setup authenticated session
allowed-tools:
- Bash
- Read
- AskUserQuestion
---
## When to invoke
Use when asked to "import cookies", "login to the site", or "authenticate the browser".
## Preamble
```bash
eval "$("${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-slug" 2>/dev/null)" 2>/dev/null || SLUG="unknown"
_LEARN_FILE="${VIBESTACK_HOME:-$HOME/.vibestack}/projects/${SLUG:-unknown}/learnings.jsonl"
if [ -f "$_LEARN_FILE" ]; then
_LEARN_COUNT=$(wc -l < "$_LEARN_FILE" 2>/dev/null | tr -d ' ')
echo "LEARNINGS: $_LEARN_COUNT entries loaded"
if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
"${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-learnings-search" --limit 5 2>/dev/null || true
fi
else
echo "LEARNINGS: none yet"
fi
```
{{include lib/snippets/session-host.md}}
{{include lib/snippets/decision-brief.md}}
{{include lib/snippets/working-protocols.md}}
{{include lib/snippets/state-protocols.md}}
# Setup Browser Cookies
Import logged-in sessions from your real Chromium browser into the headless browse session.
## CDP mode check
First, check if browse is already connected to the user's real browser:
```bash
B="${CLAUDE_SKILL_DIR:-$HOME/.claude/skills/setup-browser-cookies}/../browse/bin/vibe-browse"
[ -x "$B" ] || B="$(command -v vibe-browse || true)"
$B status 2>/dev/null | grep -q "Mode: cdp" && echo "CDP_MODE=true" || echo "CDP_MODE=false"
```
If `CDP_MODE=true`: tell the user "Not needed — you're connected to your real browser via CDP. Your cookies and sessions are already available." and stop. No cookie import needed.
## How it works
1. Find the browse binary
2. Run `cookie-import-browser` to detect installed browsers and open the picker UI
3. User selects which cookie domains to import in their browser
4. Cookies are decrypted and loaded into the Playwright session
## Steps
### 1. Find the browse binary
```bash
B="${CLAUDE_SKILL_DIR:-$HOME/.claude/skills/setup-browser-cookies}/../browse/bin/vibe-browse"
[ -x "$B" ] || B="$(command -v vibe-browse || true)"
if [ -n "$B" ] && [ -x "$B" ] && [ "$("$B" status 2>/dev/null)" != "BROWSE_NOT_AVAILABLE" ]; then
echo "READY: $B"
echo "BROWSE_BIN: $B"
else
echo "NEEDS_SETUP"
fi
```
Every Bash call starts a fresh shell, so `$B` is unset in every later block.
A block that runs a browse command starts with `B='<BROWSE_BIN>'`: replace
`<BROWSE_BIN>` with the path printed on the `BROWSE_BIN:` line.
If `NEEDS_SETUP`, stop and tell the user the browse binary could not be found or
could not start — node is missing, or first-run setup was declined.
Cookie import needs the full browse daemon; the stateless fallback shim cannot
decrypt a real browser's cookie store. If any command below answers
`NOT_SUPPORTED:cookie-import-browser`, that is what happened: tell the user the
full daemon is not running in this checkout and stop, rather than reporting a
half-import that never occurred. Point them at `/connect-chrome`, which imports
cookies into the shim from a Chrome started with a remote debugging port.
### 2. Open the cookie picker
```bash
B='<BROWSE_BIN>'
$B cookie-import-browser
```
This auto-detects installed Chromium browsers and opens
an interactive picker UI in your default browser where you can:
- Switch between installed browsers
- Search domains
- Click "+" to import a domain's cookies
- Click trash to remove imported cookies
Tell the user: **"Cookie picker opened — choose the browser, the profile, and the domains you want to import, then tell me when you're done."**
The choice of browser, profile and domains is the user's. Never pick one for
them, and never treat whichever browser the CLI falls back to as consent. A
profile you could not read is unknown, not empty.
### 3. Direct import (alternative)
If the user names a domain directly (e.g., `/setup-browser-cookies github.com`),
skip the UI — but only with a browser the user named. If they did not name one,
ask via AskUserQuestion which browser to import from — this path skips the
picker, so you have no detected list: name the supported ones (Chrome, Chromium,
Arc, Brave, Edge, Comet) and let the user answer; never fill one in yourself. The import is scoped to the page the daemon is on,
so navigate to the domain first:
```bash
B='<BROWSE_BIN>'
$B goto https://github.com
$B cookie-import-browser <browser> --domain github.com
```
`<browser>` is the one the user chose. `--profile` takes a profile directory
(`Default`, `Profile 1`), not a display name; omit it only when the user's
browser has a single relevant profile, otherwise use the picker. `--all` imports
every non-expired cookie from the browser — run it only when the user asked for
exactly that.
### 4. Report honestly
Report what the import itself returned: the receipt line (`Imported N cookies
for <domain> from <browser>`, plus any `failed to decrypt` count) or the picker's
per-domain counts, and say plainly when an import was partial, zero, or errored.
Never run `$B cookies` or `$B storage` to "show what was imported", and never
put a cookie value, token, password, or session detail into the transcript or a
report. Counts and domain names are the whole summary.
Keep three states apart, and name the one you are in:
- **Not checked** — cookies were copied; nobody looked at whether they sign you in.
- **Not verified** — you checked, and the target did not show a signed-in state.
- **Verified** — a page on the target showed positive signed-in evidence (an
account-only page rendered instead of the sign-in wall).
An import count, a zero-error import, or an HTTP 200 never proves a login.
Stop at **Not checked** unless the user asked you to check.
## Notes
- On macOS, the first import per browser may trigger a Keychain dialog — click "Allow" / "Always Allow"
- On Linux, `v11` cookies may require `secret-tool`/libsecret access; `v10` cookies use Chromium's standard fallback key
- Cookie picker is served on the same port as the browse server (no extra process)
- Only domain names and cookie counts are shown in the UI — no cookie values are exposed
- The browse session persists cookies between commands, so imported cookies work immediately