---
summary: "Windsurf provider data sources: browser localStorage session import, local SQLite cache, and GetPlanStatus protobuf API."
read_when:
  - Debugging Windsurf usage fetch
  - Updating Windsurf web session import or API handling
  - Adjusting Windsurf provider UI/menu behavior
---

# Windsurf provider

Windsurf supports two data sources: a web API backed by the current website session, and a local SQLite cache.

## Data sources + fallback order

Usage source picker:
- Preferences → Providers → Windsurf → Usage source (Auto / Web API / Local).

### Auto mode (default)
1) **Web API** (preferred) — real-time data from windsurf.com.
2) **Local SQLite cache** (fallback) — reads from Windsurf's `state.vscdb`.

### Web API fetch order
1) **Manual session bundle** (when Cookie source = Manual).
2) **Browser localStorage import** — extracts complete `devin_*` session bundles from Chromium browsers, checking
   `app.devin.ai` before the legacy `windsurf.com` origin.

### Local SQLite cache
- File: `~/Library/Application Support/Windsurf/User/globalStorage/state.vscdb`.
- Key: `windsurf.settings.cachedPlanInfo` in `ItemTable`.
- Newer cache shapes may omit `quotaUsage` but include `usage` counters. In that case CodexBar derives
  usage windows from `usedMessages/messages` and `usedFlowActions/flowActions`.
- Limitation: only updates when Windsurf is launched; can be significantly stale.

## Cookie source settings

Preferences → Providers → Windsurf → Cookie source:

- **Automatic** (default): imports the active Windsurf session bundle from Chromium browser localStorage.
- **Manual**: paste a JSON bundle with `devin_session_token`, `devin_auth1_token`, `devin_account_id`, and `devin_primary_org_id`.
- **Off**: disables web API access entirely; only local SQLite cache is used.

### How to get a manual session bundle

1. Open [windsurf.com/profile](https://windsurf.com/profile) in Chrome or Edge and sign in.
2. Open Developer Tools (`F12` or `Cmd+Option+I`).
3. Go to the **Console** tab.
4. Paste the following JavaScript and press Enter:

```javascript
(() => {
  const keys = [
    "devin_session_token",
    "devin_auth1_token",
    "devin_account_id",
    "devin_primary_org_id",
  ];

  const read = (key) => {
    const value = localStorage.getItem(key);
    if (!value) return null;
    try {
      return JSON.parse(value);
    } catch {
      return value;
    }
  };

  const payload = Object.fromEntries(keys.map((key) => [key, read(key)]));
  const missing = keys.filter((key) => !payload[key]);

  if (missing.length > 0) {
    console.log("Missing Windsurf session keys:", missing.join(", "));
    return;
  }

  const json = JSON.stringify(payload, null, 2);
  console.log(json);
  if (typeof copy === "function") {
    copy(json);
    console.log("Copied Windsurf session bundle to clipboard.");
  }
})();
```

5. Copy the JSON output.
6. In CodexBar: Providers → Windsurf → Cookie source → Manual → paste the JSON bundle.

## Authentication flow (Automatic mode)

```text
Browser localStorage (leveldb on disk)
    ↓ extract devin_session_token / devin_auth1_token / devin_account_id / devin_primary_org_id
POST https://windsurf.com/_backend/.../GetPlanStatus
    ↓ headers: x-auth-token + x-devin-*
    ↓ protobuf body: { auth_token, include_top_up_status: true }
UsageSnapshot (daily/weekly quota %)
```

## Browser session extraction

- **Browsers scanned**: Chrome, Edge, Brave, Arc, Vivaldi, Chromium, and compatible Chromium forks.
- **Local storage path**: `~/Library/Application Support/<Browser>/<Profile>/Local Storage/leveldb/`
- **Origins**: `https://app.devin.ai`, then legacy `https://windsurf.com`
- Values from different structured origins are never combined. A partial app-origin bundle cannot contaminate a
  complete legacy-origin fallback.
- **Required keys**:
  - `devin_session_token`
  - `devin_auth1_token`
  - `devin_account_id`
  - `devin_primary_org_id`

## API endpoint

### GetPlanStatus (ConnectRPC over protobuf)
- `POST https://windsurf.com/_backend/exa.seat_management_pb.SeatManagementService/GetPlanStatus`
- Headers:
  - `Content-Type: application/proto`
  - `Connect-Protocol-Version: 1`
  - `Origin: https://windsurf.com`
  - `Referer: https://windsurf.com/profile`
  - `x-auth-token: <devin_session_token>`
  - `x-devin-session-token: <devin_session_token>`
  - `x-devin-auth1-token: <devin_auth1_token>`
  - `x-devin-account-id: <devin_account_id>`
  - `x-devin-primary-org-id: <devin_primary_org_id>`
- Protobuf request fields:
  - `1 auth_token: string`
  - `2 include_top_up_status: bool`
- Parsed response fields used by CodexBar:
  - `plan_status.plan_info.plan_name`
  - `plan_status.plan_end`
  - `plan_status.daily_quota_remaining_percent`
  - `plan_status.weekly_quota_remaining_percent`
  - `plan_status.daily_quota_reset_at_unix`
  - `plan_status.weekly_quota_reset_at_unix`

## Snapshot mapping
- Web primary: daily usage percent (`100 - daily_quota_remaining_percent`).
- Web secondary: weekly usage percent (`100 - weekly_quota_remaining_percent`).
- Local primary: daily quota percent when present; otherwise message usage (`usedMessages/messages`).
- Local secondary: weekly quota percent when present; otherwise flow-action usage (`usedFlowActions/flowActions`).
- Reset: daily/weekly reset timestamps (Unix seconds), when available.
- Plan: `plan_status.plan_info.plan_name`.
- Expiry: `plan_status.plan_end`.

## Troubleshooting

### "No Windsurf web session found in Chromium localStorage"
- Sign in to [app.devin.ai](https://app.devin.ai) or [windsurf.com](https://windsurf.com) in Chrome, Edge, or another
  Chromium browser.
- Grant Full Disk Access to CodexBar (System Settings → Privacy & Security → Full Disk Access).
- Try Manual mode and paste the JSON session bundle directly.

### "Invalid Windsurf session payload"
- The manual value must include all four keys: `devin_session_token`, `devin_auth1_token`, `devin_account_id`, and `devin_primary_org_id`.
- Re-run the console snippet on a logged-in `windsurf.com` page.

### "Windsurf API call failed: HTTP 401"
- The imported browser session is stale or invalid.
- Refresh the Windsurf page in your browser and try again.
- If using Manual mode, paste a fresh JSON bundle.

### Stale data with Local mode
- The local SQLite cache only updates when Windsurf is launched. Switch to Auto or Web API mode for real-time data.

## Key files
- `Sources/CodexBarCore/Providers/Windsurf/WindsurfStatusProbe.swift` (local SQLite)
- `Sources/CodexBarCore/Providers/Windsurf/WindsurfDevinSessionImporter.swift` (Chromium localStorage extraction)
- `Sources/CodexBarCore/Providers/Windsurf/WindsurfWebFetcher.swift` (protobuf request + response parsing)
- `Sources/CodexBarCore/Providers/Windsurf/WindsurfProviderDescriptor.swift` (fetch strategies)
- `Sources/CodexBar/Providers/Windsurf/WindsurfProviderImplementation.swift` (settings UI)
- `Sources/CodexBar/Providers/Windsurf/WindsurfSettingsStore.swift` (settings persistence)
