SKILL.md is the entry point. BROWSER.md supplies the exact referenced cookie section, not an additional execution step.

--- BEGIN FILE "setup-browser-cookies/SKILL.md" (lines 146-206; entrypoint) ---
# Setup Browser Cookies

## 1. Check for Aside

Pick the gstack root first: this checkout, if it has both `BROWSER.md` and `browse/SKILL.md`; otherwise the installed root that has `bin/gstack-skill-start`. Never use a generated host stub. In that root, read the **BROWSER SETUP** section of `browse/SKILL.md` and run its Aside probe.

- **The probe prints `READY`:** stop here. Aside already holds the user's signed-in sessions, so nothing needs importing. Tell the user to work in Aside, or to sign in there.
- **It prints anything else:** carry on with gstack's own headless browser (`$B`).

## 2. Ask every question before touching `$B`

Put all five questions to the user in one go, before you run any `$B` command. Do not guess any answer, and do not read the default Comet browser as consent.

1. **Which browser and which profile?** `--profile` wants the profile's directory (`Default`, `Profile 2`), not the name shown in the browser. If a profile cannot be read, treat it as unknown, not as empty.
2. **Which domains, and which target page?** The target is one URL on a chosen domain that the session should open.
3. **Verify sign-in (`--verify-auth`)?** The default is no. Verification reloads the target and reports **verified** only when the response is successful and same-origin and exactly one visible element, matched by a CSS selector, has whitespace-normalized text equal to the expected identity. If the user says yes, they provide the selector and the expected identity privately.
4. **Clear stale storage (`--clear-storage`)?** The default is no, and it needs the user's explicit approval. It works on Chromium only: it clears localStorage for the target's origin (which all of that origin's tabs share) and sessionStorage for the target tab, and nothing else. Other browser engines refuse the reset but still import. If a reset fails partway, some storage may already be gone, and it is not restored.
5. **Import every cookie in the profile (`--all`)?** The default is no, and it needs explicit consent. It cannot be used together with a domain or with clearing storage.

If the browser, the profile directory or the domains (questions 1-2) are still open, use the picker, which asks for them. If the user has named all three, use direct import.

## 3. Get gstack's browser ready

1. If the user wants verification, ask them to set `GSTACK_COOKIE_AUTH_SELECTOR` and `GSTACK_COOKIE_AUTH_EXPECTED_IDENTITY` privately in the shell that runs `$B`. Never make up these values. The browser daemon reads them only when it starts, so if a gstack daemon is already running, run `$B stop` first.
2. Find `$B` using the **Browser fallback** section of `browse/SKILL.md`, and build it if the check prints `NEEDS_SETUP`.
3. Run `$B status`. `Mode: cdp` means `$B` is attached to the user's real browser and already has their sessions: tell the user no import is needed and stop.
4. Open the target URL from question 2, and do not use that tab for anything else until the import is done:

```bash
$B goto "<url>"
```

## 4. Import

With the picker, run the command below. The user confirms the browser, profile and domains in the picker, ticks verification if they asked for it, and tells you when they are done. The picker link works once and for five minutes; if it expires, run the command again.

```bash
$B cookie-import-browser
```

With direct import, run `$B cookie-import-browser` with the chosen browser name, one `--domain` per run, and `--profile` set to the profile directory (not the display name). Add `--verify-auth` or `--clear-storage` only if the user said yes in step 2.

If the import is rejected because verification settings are missing, nothing has changed yet: tell the user which variable is missing and go back to step 3. For any other error or receipt failure reason, read that same root's `BROWSER.md`, **Choosing a source and checking sign-in**; it holds the error tables, examples, profile labels, supported sources and platform setup.

## 5. Report what actually happened

Base the report on the import receipt, not on raw `$B cookies`, and give exactly three lines:

- `Imported: <count> (<imported|partial|empty|failed>, as the receipt says) from <browser> for <domains>`
- `Storage reset: <done|failed|not requested>`
- `Sign-in: <verified|not verified|not checked>`

**Not checked** means nobody asked for verification. **Not verified** means verification ran and failed. **Verified** requires the identity match. A cookie count, zero imports or an HTTP 200 never proves sign-in. Imported cookies apply to the whole browser context, not to a single tab.

Never ask for or publish cookie values, passwords, identity or profile text, session details, or raw errors in public logs.

## Platform boundaries

Dia runs only on macOS. Approving the Keychain prompt is the user's decision. Database retries are limited; if permission is denied, the user has to act, so do not keep prompting.

On Windows, DPAPI-compatible cookies work, but not all App-Bound Encryption cookies do; native extraction stays off until it is qualified. Closing Chrome does not get around Chrome 136+ default-directory protection, numbered profiles included. There is no TCP fallback and no copying of real profiles. Offer manual sign-in in the headed browser only when a display is available.

--- END FILE "setup-browser-cookies/SKILL.md" ---

--- BEGIN FILE "BROWSER.md" (lines 569-617; section) ---
#### Choosing a source and checking sign-in

Select the source browser and account/profile explicitly. The picker recognizes Chrome, Chromium, Brave, Edge, Windows-only Opera and Opera GX, and macOS-only Comet, Arc, and Dia. It shows current profile names from `Local State`, falling back to Preferences and then the directory name, with directory labels to distinguish duplicate names. `--profile` takes that directory (`Default`, `Profile 2`), not its display name. Without it, only a sole relevant profile is selected; ambiguity or unreadable profiles require a choice. The omitted-browser default remains `comet` for CLI compatibility, not as a recommendation. The picker opening link is one-use and expires after five minutes.

For direct import, first navigate to a page matching `--domain`. Example after choosing Chrome's `Profile 2`:

```bash
$B goto https://example.com
$B cookie-import-browser chrome --domain example.com --profile "Profile 2"
```

**Windows: Opera and Opera GX.** On Windows, Chrome, Edge and Brave increasingly store App-Bound Encryption cookies that gstack cannot decrypt; Opera and Opera GX still use DPAPI-protected cookies that it can. In Git Bash, with `$B` set as in the quick start above (the Windows build is `browse/dist/browse.exe`):

```bash
SITE=app.example.com
DOMAIN=example.com
$B goto "https://$SITE"
$B cookie-import-browser opera-gx --domain "$DOMAIN" --profile Default   # or: opera
$B reload                                                               # view the page; only --verify-auth proves sign-in
```

Run `$B cookie-import-browser` with no flags to see which browsers were detected. `--profile` can be omitted when only one profile has cookies for the domain. If the receipt reports App-Bound Encryption, run `$B handoff`, sign in to the intended account in the window that opens, then `$B resume` (needs a display).

**Receipt failure reasons** (printed after the message as `Failure reasons: key=count`):

| Key | Meaning | Next step |
|---|---|---|
| `unsupported_encryption` | App-Bound Encryption (v20) cookies gstack cannot decrypt | `$B handoff`, sign in, `$B resume` |
| `decryption_failed` | The cookie could not be decrypted with the browser's key | Close the source browser and retry; otherwise sign in manually |
| `native_unrecovered` | Windows native extraction ran but could not recover these cookies | Sign in manually with `$B handoff` |

**Import errors:**

| Code | Meaning | Next step |
|---|---|---|
| `not_installed` | No supported cookie database for that browser or profile; the message lists every path checked and, off-platform, which OS supports the browser | Pick a browser listed as available on this OS, or pass an existing `--profile` |
| `profile_required` | Several profiles qualify, none has cookies for the domain, or a profile could not be read | Retry with `--profile "<dir>"` as the message suggests, or run `$B cookie-import-browser <browser>` to use the picker |
| `native_unsupported_browser` | Internal guard; not expected in normal use | Sign in manually with `$B handoff` |

The picker shows receipt messages verbatim; detailed `not_installed` and `profile_required` explanations appear in CLI output.

`--all` explicitly selects every non-expired cookie in the chosen source profile; it cannot accompany `--domain` or `--clear-storage`. Cookies are applied to the captured browser context, not isolated to a tab. The receipt distinguishes imported, partial, empty, and failed results, plus separate storage-reset and authentication outcomes. Cookies copied with authentication `not_requested` means **not checked**, not logged in. Zero imports, cookie counts, and HTTP 200 alone never prove sign-in.

`--verify-auth` (also an explicit picker checkbox) reloads the captured target. Configure `GSTACK_COOKIE_AUTH_SELECTOR` and `GSTACK_COOKIE_AUTH_EXPECTED_IDENTITY` privately in the **daemon environment before startup**; setting them only on a later CLI call does not reconfigure an existing daemon. Missing configuration rejects before mutation. Verification requires a successful same-origin response and exactly one visible element whose whitespace-normalized text equals the expected identity. A wrong account, login redirect, missing assertion, or changed target is not verified. Do not paste cookie values, passwords, profile/account labels, or expected identity into public logs; report only sanitized outcomes.

Storage stays intact by default. With explicit approval on a Chromium target, `--clear-storage` clears localStorage for the captured origin (exact scheme, host, and port, shared across that origin's tabs in the context) and sessionStorage for the target tab before applying cookies. Reset runs in an isolated world with a native monotonic deadline, so the site's scripts cannot forge its timeout clock. Other target engines reject reset; ordinary imports and authentication checks remain available. It does not clear other origins, other tabs' sessionStorage, IndexedDB, or service workers. Keep the target open and unchanged. A failed reset may have cleared some storage; a later cookie-application failure does not undo it.

**Platform limits:** macOS imports may request Keychain approval; Linux `v11` cookies may require libsecret, while `v10` uses Chromium's fallback key. The Windows Node server needs Node.js 22.13 or newer with built-in SQLite enabled for cookie database reads. DPAPI-compatible cookies remain supported, but native App-Bound Encryption extraction is disabled until the browser/runtime passes qualification. Opera and Opera GX are Windows-only and read from `%APPDATA%\Opera Software\Opera Stable` or `Opera GX Stable`, in `Default` or `Profile N` directories; legacy root-level layouts, Opera side profiles and portable or relocated installs are not detected. Opera has no native extraction, so its App-Bound cookies (if any) need manual sign-in. Chrome 136+ blocks remote debugging of its default user-data directory, including numbered profiles, over both pipe and TCP; closing Chrome does not remove that protection. There is no TCP fallback or real-profile-copy workaround. If import cannot recover the session, sign in manually in gstack's headed browser when a display is available.


--- END FILE "BROWSER.md" ---