Files
2026-07-13 12:22:33 +08:00

173 lines
6.9 KiB
Markdown

---
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)