# Maxy LinkedIn Ingest — Chrome Extension

Unpacked-extension dev build. No Chrome Web Store publication.

## Install

1. `chrome://extensions`
2. Enable **Developer mode** (top right).
3. **Load unpacked** → select this `extension/` directory.
4. Click the new puzzle icon → open **Maxy LinkedIn Ingest** options.
5. Paste your admin host (e.g. `https://your-tunnel.example.com`) and your admin **session key** (the value of `session_key` on the cookie or query in your admin browser). Save.

## Use

- Open any `https://www.linkedin.com/in/<slug>/` profile or `https://www.linkedin.com/messaging/thread/<id>/` thread.
- Click the **Add to Maxy** pill at the top of the page.
- The pill turns green and writes one `:KnowledgeDocument` plus the entities the body assertively states.

If the pill turns amber and shows **Sign in to Maxy**, your session key has expired — open the options page and paste a fresh one.

## File layout

| File | Role |
|---|---|
| `manifest.json` | MV3 manifest. Declares profile + thread content scripts. |
| `content/extractors.js` | Pure DOM extractor functions. Loaded first into each content-script context. |
| `content/profile.js` | Profile pill + click handler. |
| `content/thread.js` | Thread pill + click handler. |
| `background/sw.js` | Service worker. POSTs envelopes to the admin route. |
| `options/options.html` + `options/options.js` | Admin host + session-key entry. |
| `assets/pill.css` | Pill styling. |
| `__tests__/` | jsdom unit tests for the extractors, run via vitest from `platform/ui`. |

## How the wire works

The extension does no extraction or graph-write logic — those live in `platform/plugins/memory/skills/document-ingest/`. Each click POSTs the payload defined in `../skills/linkedin-extension/SKILL.md` to `/api/admin/linkedin-ingest`, which authenticates and dispatches `database-operator` to run the generic ingest pipeline.

## Updating selectors

LinkedIn ships DOM changes from time to time. When the pill misses a field:

1. Save the current page as `__tests__/fixtures/<kind>.html` (overwrite).
2. Update the primary selector in `content/extractors.js`; keep the prior one as fallback if older clients may still serve it.
3. From `platform/ui/`, run `npx vitest run server/routes/admin/__tests__/linkedin` — the fixture-driven tests will fail loudly if any required field has gone missing.
