# Context Extractor Status: active. Capture console logs, network activity, JS errors, and clean markdown content from a webpage, formatted as an AI-ready prompt. Ships three ways from one shared core: [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) Captures console, network, errors, and clean markdown for agents and debugging. Public mirror: [github.com/Gitilia/context-extractor](https://github.com/Gitilia/context-extractor). - `extension/`: browser extension (Manifest V3) for interactive use. - `automation/`: Python package for scripted/headless use with Playwright or [Camoufox](https://camoufox.com). - `automation-js/`: Node/TS twin of `automation/` for Playwright (`playwright-core`) or [camoufox-js](https://www.npmjs.com/package/camoufox-js) automation that's already JS, so it can `import` the session directly instead of shelling out to Python. ``` context-extractor/ ├── extension/ browser extension (Chrome + Brave, unpacked) │ ├── core/dom.js ← shared: selector + markdown extraction │ ├── core/prompt.js ← shared: AI-prompt formatter │ ├── page-patcher.js MAIN-world console/fetch/XHR/error capture │ ├── content.js ISOLATED-world store, picker, messaging │ ├── background.js │ └── popup.html / popup.js ├── automation/ Python package for Playwright / Camoufox │ ├── context_extractor/ session + CLI │ │ └── js/ symlinks → extension/core/*.js │ └── tests/ pytest + fixture page ├── automation-js/ Node/TS package for Playwright / camoufox-js │ ├── src/session.ts ← ExtractorSession (async, one class) │ │ └── js/ symlinks → extension/core/*.js │ └── tests/ vitest + real Chromium, shared fixture ├── scripts/package_extension.py optional zip for distribution ├── .gitea/workflows/ci.yml Gitea Actions: JS lint + pytest + package smoke ├── CURSOR_PROMPT.md paste into other Cursor chats └── Makefile make test / make lint / make package ``` `extension/core/dom.js` and `extension/core/prompt.js` are the single source of truth for DOM/markdown/prompt logic, the extension loads them directly as content-script files, and **both** automation packages read the exact same files (via symlinks) and run them with `page.evaluate()`. There's only one place to fix a markdown-formatting bug, and the Python/JS test suites both run against the same fixture page (`automation/tests/fixtures/sample.html`) so a regression can't silently diverge between the two. ## Versioning The extension (`extension/manifest.json`), the Python package (`automation/pyproject.toml`), and the Node package (`automation-js/package.json`) share **one product version** and are bumped together, they ship the same `core/*.js`, so a version like `1.4.0` means the same extraction behavior in all three. ## Use from another Cursor project Copy the block in [`CURSOR_PROMPT.md`](CURSOR_PROMPT.md) into that project's chat (or drop it in `.cursor/rules/`). ## Tests ```bash make install # once make ci # lint + pytest + vitest + package smoke (same checks as Gitea Actions) ``` Or manually: ```bash cd automation python3 -m venv .venv && source .venv/bin/activate pip install -e ".[dev]" playwright install chromium pytest -q ``` ## 1. Browser extension (Chrome and Brave) Brave is Chromium under the hood and loads unpacked Manifest V3 extensions exactly like Chrome does, there is no separate "Brave build." Same steps in both: 1. Go to `chrome://extensions` (or `brave://extensions`). 2. Enable **Developer Mode**. 3. **Load unpacked** → select the `extension/` folder. 4. Reload any tab you want to capture from (content scripts only attach to pages loaded/reloaded after install). Click the toolbar icon to see captured console/network/errors, extract markdown from the whole page or a CSS selector (use **Pick** to click an element), and **Copy** to put a ready-to-paste prompt on the clipboard. ### What changed vs. a typical extension implementation The original console/fetch/XHR patcher was injected as an inline `