# Cortaly Surfbar Extension

Runs the Cortaly surfbar without the embedded toolbar/frame. Instead of showing
each site inside an iframe on cortaly.com, the extension navigates a dedicated
browser tab directly to the real URL of the site being surfed — so sites that
block framing (`X-Frame-Options`, `Content-Security-Policy: frame-ancestors`)
still work, because there's no framing involved at all. No login: just enter
your public Cortaly username (the same one in your `cortaly.com/surf/<username>`
link) and press Start. The reward banner keeps showing in a small overlay in
the corner of the surfed tab, and in the extension popup.

**Two ways to start it**: (1) open the extension popup and type your username
— useful if you're not already on cortaly.com; or (2) just navigate to your
own `cortaly.com/surf/<username>` link like normal — `auto-detect.js` (a
content script matching that URL) picks the username straight out of the
address bar and starts automatically, no popup needed. In the second case the
tab you were already on is the one that gets taken over and navigated
straight to the first real site — the go.php page's own iframe-based surfbar
toolbar never really gets a chance to render (the content script calls
`window.stop()` at `document_start`, before the page has drawn anything of
its own or its deferred `surf.js` has run). If a run is already in progress,
landing on a `/surf/...` link again is a no-op — it won't yank the active
session onto a different tab/username underneath you.

## ⚠️ Not yet test-loaded

I wrote this extension but have no tool available in this environment that can
load an unpacked browser extension and click through it. `node --check` passes
on every JS file (syntax-valid), and the API endpoints it calls
(`csrf-token.php`, `surf-next.php`, `surf-banner.php`, etc.) were verified live
against production via `curl`/direct calls — but the extension itself (popup
→ background service worker → tab navigation → content-script overlay →
heartbeat/confirm cycle) has **not been loaded in an actual browser or
click-tested end-to-end**. Please load it as described below and walk through
one full surf cycle (Start → a site opens in a new tab → banner overlay shows
→ it advances to the next site → Stop) before relying on it. If something
breaks, the most likely failure points are: message-passing between
popup.js/background.js, the MV3 service-worker-suspension handling around the
timers, or CORS/cookie behavior that only shows up in a real browser (not
something a syntax check can catch).

## Load in Chrome / Edge (Manifest V3)

1. Open `chrome://extensions` (or `edge://extensions`).
2. Enable **Developer mode** (top-right toggle).
3. Click **Load unpacked** and select this `browser-extension/` folder.
4. Chrome uses `manifest.json` automatically — nothing to rename.
5. Pin the extension, click its icon, enter a Cortaly username, click **Start
   Surfbar**.

## Load in Firefox

Firefox needs the Firefox-specific manifest active as `manifest.json`:

1. Make a copy of this folder (or swap files in place — see note below).
2. Rename `manifest.json` → `manifest.chrome.json` and
   `manifest.firefox.json` → `manifest.json` in that copy.
3. Open `about:debugging#/runtime/this-firefox`.
4. Click **Load Temporary Add-on…** and select the copy's `manifest.json` (or
   any file inside the folder — Firefox will find it).
5. Note: temporary add-ons are removed when Firefox closes; for a persistent
   install it needs to be signed by Mozilla (AMO) or Firefox needs to run in
   Developer/Nightly mode with `xpinstall.signatures.required` disabled.

If you want both browsers loadable from the same folder without manually
swapping files each time, keep both manifests as they are now
(`manifest.json` for Chrome, `manifest.firefox.json` for Firefox) and only
rename a *copy* when loading into Firefox, so the Chrome-ready `manifest.json`
in the main folder is never disturbed.

## Icons

`icons/icon16.png`, `icon32.png`, `icon48.png`, `icon128.png` are placeholder
icons I generated locally (a gold "C" ring on Cortaly's dark background,
matching the site's Exchange Terminal design tokens) — good enough for the
extension to load without a manifest error, but feel free to swap in real
artwork later; the manifests already point at these exact filenames so a
same-name replacement needs no other changes.

## Files

- `manifest.json` / `manifest.firefox.json` — MV3 manifests (Chrome vs. Firefox background style).
- `browser-shim.js` — aliases `browser.*`/`chrome.*` to one `api` object.
- `api-client.js` — thin wrapper around the surf JSON API (`/api/surf-next.php` etc.), including CSRF bootstrap via `/api/csrf-token.php`.
- `background.js` — the surf loop: picks the next site, opens/navigates the dedicated tab, sends heartbeats, confirms, handles pacing/jackpot, persists state to `chrome.storage.local` so it survives service-worker restarts.
- `content-script.js` — injected into the surfed tab; shows the banner overlay (Shadow DOM, sandboxed iframe for HTML banners) with Pause/Skip controls.
- `popup.html` / `popup.css` / `popup.js` — the toolbar popup: username entry + Start, and live stats/banner/controls while running.
- `icons/` — toolbar + store icons.
