browser-assistant 2.8.1 → 2.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +121 -119
- package/extension/answer-requests.js +7 -3
- package/extension/manifest.json +44 -44
- package/extension/popup.html +61 -61
- package/extension/styles.css +572 -572
- package/package.json +2 -1
- package/server/.env.example +19 -19
- package/server/journal_prompt.md +424 -424
- package/server/journal_syllabus.json +80 -80
- package/server/main.py +1822 -1764
- package/server/vision_images.py +88 -20
package/README.md
CHANGED
|
@@ -1,119 +1,121 @@
|
|
|
1
|
-
# Browser Assistant
|
|
2
|
-
|
|
3
|
-
A Chrome Manifest V3 extension with a local Python backend for exploring multiple-choice questions and coding exercises on webpages. Built for learners reviewing answers and developers experimenting with automation on pages they own or have permission to operate.
|
|
4
|
-
|
|
5
|
-
## What it does
|
|
6
|
-
|
|
7
|
-
- Extracts page text and requests answers from Groq, with Ollama fallback for text requests.
|
|
8
|
-
- Captures the visible browser tab for Groq vision analysis.
|
|
9
|
-
- Detects requested programming languages and validates generated code syntax; model review does not prove correctness.
|
|
10
|
-
- Displays results in an in-page panel, offers code copying, and saves successful scans in local SQLite history.
|
|
11
|
-
- Includes a local practice page and automation for selecting answers, filling editors, and submitting supported forms after starting a run.
|
|
12
|
-
- Resumes CCBP practice from an already submitted answer through its submitted-question Next control, without generating or submitting that answer again. Delayed Submit controls are awaited for up to 15 seconds while the question and selected answer remain unchanged.
|
|
13
|
-
- Press **Alt + Shift + A** on the webpage to start automation, then press it again to pause or resume. It also works with the code editor focused and opens QA Control. Journal automation uses the same toggle; its existing **Alt + Shift + J** shortcut remains available.
|
|
14
|
-
|
|
15
|
-
AI answers can be wrong. Automation can change or submit page content: use it only where authorized, review results, and avoid restricted assessments. Site detection is heuristic; custom controls, frames, editors, and navigation can fail. The policy includes a general HTTP/HTTPS fallback, so it is not a strict site allowlist.
|
|
16
|
-
|
|
17
|
-
## First run
|
|
18
|
-
|
|
19
|
-
### Continuous coding batch
|
|
20
|
-
|
|
21
|
-
On CCBP `/problems-set`, start on page 1 and keep both **Not Attempted** and
|
|
22
|
-
**In Progress** visible in the status filters. Choose **QA Control → Start automation**.
|
|
23
|
-
The batch skips Solved rows, opens an eligible question, reads its language and
|
|
24
|
-
existing code, generates and submits a solution, and returns to the list only after
|
|
25
|
-
a confirmed passing result. It follows numbered pages within the selected filters.
|
|
26
|
-
Keep the browser tab and local AI server open; Pause/Resume and Stop are available.
|
|
27
|
-
Failed tests, unsupported layouts, or unconfirmed results stop the batch with a reason.
|
|
28
|
-
Reloading during solving/submission stops rather than submitting twice. Starting on
|
|
29
|
-
a single question still solves just that question. Batch behavior has fixture tests;
|
|
30
|
-
completion on the live portal has not been verified.
|
|
31
|
-
|
|
32
|
-
Use Chrome, Python **3.11+**, and either a Groq key or an installed Ollama model for text scans. Building from source or running contributor tests requires Node.js **22.18+**. Chrome internal pages cannot run content scripts; other Chromium browsers are not verified here. Firefox is not supported by this manifest.
|
|
33
|
-
|
|
34
|
-
### Install and update with npm
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
1. Open `chrome://extensions`, enable **Developer mode**, choose **Load unpacked**, and select `node_modules/browser-assistant/extension` inside your folder.
|
|
39
|
-
2. Create and activate a Python 3.11+ virtual environment in your folder. Install the backend dependencies with `python -m pip install --require-hashes -r node_modules/browser-assistant/server/requirements.lock.txt`.
|
|
40
|
-
3. Copy `node_modules/browser-assistant/server/.env.example` to `.env` in your folder. Set `HISTORY_DB_PATH=./scan_history.db` in that copy and configure a provider as described below. Keep this file and the database beside `node_modules` so they persist across upgrades.
|
|
41
|
-
4. From your folder, start the backend with `python -m uvicorn --app-dir node_modules/browser-assistant/server --env-file .env --host 127.0.0.1 --port 8000 main:app`. Check `http://127.0.0.1:8000/health`.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
For
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
The
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
[
|
|
118
|
-
|
|
119
|
-
|
|
1
|
+
# Browser Assistant
|
|
2
|
+
|
|
3
|
+
A Chrome Manifest V3 extension with a local Python backend for exploring multiple-choice questions and coding exercises on webpages. Built for learners reviewing answers and developers experimenting with automation on pages they own or have permission to operate.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
- Extracts page text and requests answers from Groq, with Ollama fallback for text requests.
|
|
8
|
+
- Captures the visible browser tab for Groq vision analysis.
|
|
9
|
+
- Detects requested programming languages and validates generated code syntax; model review does not prove correctness.
|
|
10
|
+
- Displays results in an in-page panel, offers code copying, and saves successful scans in local SQLite history.
|
|
11
|
+
- Includes a local practice page and automation for selecting answers, filling editors, and submitting supported forms after starting a run.
|
|
12
|
+
- Resumes CCBP practice from an already submitted answer through its submitted-question Next control, without generating or submitting that answer again. Delayed Submit controls are awaited for up to 15 seconds while the question and selected answer remain unchanged.
|
|
13
|
+
- Press **Alt + Shift + A** on the webpage to start automation, then press it again to pause or resume. It also works with the code editor focused and opens QA Control. Journal automation uses the same toggle; its existing **Alt + Shift + J** shortcut remains available.
|
|
14
|
+
|
|
15
|
+
AI answers can be wrong. Automation can change or submit page content: use it only where authorized, review results, and avoid restricted assessments. Site detection is heuristic; custom controls, frames, editors, and navigation can fail. The policy includes a general HTTP/HTTPS fallback, so it is not a strict site allowlist.
|
|
16
|
+
|
|
17
|
+
## First run
|
|
18
|
+
|
|
19
|
+
### Continuous coding batch
|
|
20
|
+
|
|
21
|
+
On CCBP `/problems-set`, start on page 1 and keep both **Not Attempted** and
|
|
22
|
+
**In Progress** visible in the status filters. Choose **QA Control → Start automation**.
|
|
23
|
+
The batch skips Solved rows, opens an eligible question, reads its language and
|
|
24
|
+
existing code, generates and submits a solution, and returns to the list only after
|
|
25
|
+
a confirmed passing result. It follows numbered pages within the selected filters.
|
|
26
|
+
Keep the browser tab and local AI server open; Pause/Resume and Stop are available.
|
|
27
|
+
Failed tests, unsupported layouts, or unconfirmed results stop the batch with a reason.
|
|
28
|
+
Reloading during solving/submission stops rather than submitting twice. Starting on
|
|
29
|
+
a single question still solves just that question. Batch behavior has fixture tests;
|
|
30
|
+
completion on the live portal has not been verified.
|
|
31
|
+
|
|
32
|
+
Use Chrome, Python **3.11+**, and either a Groq key or an installed Ollama model for text scans. Building from source or running contributor tests requires Node.js **22.18+**. Chrome internal pages cannot run content scripts; other Chromium browsers are not verified here. Firefox is not supported by this manifest.
|
|
33
|
+
|
|
34
|
+
### Install and update with npm
|
|
35
|
+
|
|
36
|
+
In a dedicated folder, run `npm init -y` and then `npm install browser-assistant`. The package includes the compiled Chrome extension and the local Python backend.
|
|
37
|
+
|
|
38
|
+
1. Open `chrome://extensions`, enable **Developer mode**, choose **Load unpacked**, and select `node_modules/browser-assistant/extension` inside your folder.
|
|
39
|
+
2. Create and activate a Python 3.11+ virtual environment in your folder. Install the backend dependencies with `python -m pip install --require-hashes -r node_modules/browser-assistant/server/requirements.lock.txt`.
|
|
40
|
+
3. Copy `node_modules/browser-assistant/server/.env.example` to `.env` in your folder. Set `HISTORY_DB_PATH=./scan_history.db` in that copy and configure a provider as described below. Keep this file and the database beside `node_modules` so they persist across upgrades.
|
|
41
|
+
4. From your folder, start the backend with `python -m uvicorn --app-dir node_modules/browser-assistant/server --env-file .env --host 127.0.0.1 --port 8000 main:app`. Check `http://127.0.0.1:8000/health`.
|
|
42
|
+
|
|
43
|
+
If you're moving from a ZIP install, copy your existing `server/.env` and `server/scan_history.db`, if present, into the new folder to keep your provider settings and scan history.
|
|
44
|
+
|
|
45
|
+
To upgrade, stop the backend and run `npm install browser-assistant@latest` from the same folder. Rerun the Python dependency install, restart the backend, and click **Reload** on the extension card in `chrome://extensions`. Refresh any open tabs where you use the extension.
|
|
46
|
+
|
|
47
|
+
### Install from GitHub
|
|
48
|
+
|
|
49
|
+
Download the backend ZIP or clone this repository, then open a terminal in the extracted backend folder or repository root. Versioned extension, backend, and source ZIPs with SHA-256 checksums are available on the [GitHub Releases page](https://github.com/JaswanthCodeHub/browser-assistant/releases).
|
|
50
|
+
|
|
51
|
+
### Windows PowerShell
|
|
52
|
+
|
|
53
|
+
```powershell
|
|
54
|
+
py -3.11 -m venv .venv
|
|
55
|
+
.\.venv\Scripts\python.exe -m pip install --require-hashes -r server\requirements.lock.txt
|
|
56
|
+
Copy-Item server\.env.example server\.env
|
|
57
|
+
# Edit server\.env as described below, then:
|
|
58
|
+
Set-Location server
|
|
59
|
+
..\.venv\Scripts\python.exe main.py
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### macOS / Linux
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
python3.11 -m venv .venv
|
|
66
|
+
.venv/bin/python -m pip install --require-hashes -r server/requirements.lock.txt
|
|
67
|
+
cp server/.env.example server/.env
|
|
68
|
+
# Edit server/.env as described below, then:
|
|
69
|
+
cd server
|
|
70
|
+
../.venv/bin/python main.py
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Python 3.12 or 3.14 can replace 3.11. Pillow 13 security fixes require Python 3.11+, so Python 3.10 is no longer in the secure installation matrix. Existing users on 3.11+ keep their runtime. These commands avoid shell activation requirements. Do not overwrite an existing `.env` or environment when updating a local installation.
|
|
74
|
+
|
|
75
|
+
### Configure a provider
|
|
76
|
+
|
|
77
|
+
For cloud inference, set `GROQ_API_KEY` in your `.env` to your own key from [Groq Console](https://console.groq.com/). Text and vision model IDs are configurable; provider availability and account access can change. The example matches implementation defaults, not a guarantee that a model is available to your account.
|
|
78
|
+
|
|
79
|
+
For local text inference, install [Ollama](https://github.com/ollama/ollama), run `ollama pull llama3`, and ensure its service is running. Leave all Groq key fields empty to keep text inference on Ollama; when a Groq key is present, Groq is tried first. Set `OLLAMA_MODEL` to an installed model name. Vision scans require Groq and have no Ollama fallback. See [configuration and troubleshooting](docs/SETUP.md).
|
|
80
|
+
|
|
81
|
+
### Install and try the extension
|
|
82
|
+
|
|
83
|
+
1. Extract the extension ZIP from Releases. If using a clone or the source ZIP, run `npm ci` and `npm run build` from its root to prepare the `extension` folder.
|
|
84
|
+
2. Open `chrome://extensions`, enable **Developer mode**, choose **Load unpacked**, and select the prepared folder containing `manifest.json`.
|
|
85
|
+
3. Open `http://127.0.0.1:8000/health`. A JSON `status: "ok"` confirms the backend is running; it does not test model access.
|
|
86
|
+
4. Open `http://127.0.0.1:8000/practice`, then use the floating panel's Text Scan. Review the answer before trying automation with Start.
|
|
87
|
+
5. After changing extension files, reload it in the extensions page and refresh the practice tab.
|
|
88
|
+
|
|
89
|
+
The toolbar popup reports backend status. In-page shortcuts are backtick (open), `]` (close), `\` (vision scan), and `[` (minimal mode). They are hardcoded page listeners, not configurable Chrome extension commands.
|
|
90
|
+
|
|
91
|
+
## Data and permissions
|
|
92
|
+
|
|
93
|
+
The backend binds to `127.0.0.1:8000` by default and has **no authentication**. Keep it local. Its address is fixed in the extension.
|
|
94
|
+
|
|
95
|
+
The manifest requests `activeTab`, `tabs`, `scripting`, and `clipboardWrite`, plus access to all URLs and localhost. Content scripts run on matching pages; scripting bridges supported page editors, tabs support capture and messaging, and clipboard access supports code copying. These are broad permissions; install only if you accept page access.
|
|
96
|
+
|
|
97
|
+
Text scans send extracted text and the current URL to the backend. Groq receives model prompts containing question text; vision scans capture the entire visible tab, compress the image, and send it to Groq. Sensitive content visible in a tab may therefore leave your machine. There is no screenshot redaction step. The application does not explicitly save raw screenshots to disk; request data exists in memory, and providers have their own retention policies.
|
|
98
|
+
|
|
99
|
+
Successful scans are saved by the extension through `/history`: URL, timestamp, scan type, provider, language, and answer JSON are kept in `server/scan_history.db`, capped at 100 entries. Clear History deletes rows, not a forensic secure erase. Stop the backend and remove the database and its `-wal`/`-shm` companions for file-level removal; backups may still contain data. Panel position uses the page's localStorage, and automation resume state uses its sessionStorage. Clear site data to remove those settings. Minimal/stealth controls change presentation; they do not guarantee invisibility or privacy.
|
|
100
|
+
|
|
101
|
+
## Development and Docker
|
|
102
|
+
|
|
103
|
+
From the repository root:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm ci
|
|
107
|
+
npm test
|
|
108
|
+
python scripts/check_repo.py
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Edit the TypeScript sources in `extension/src/`. Run `npm run build` to regenerate the JavaScript used by Chrome before reloading the unpacked extension. `npm test` builds and type-checks the extension before running its tests.
|
|
112
|
+
|
|
113
|
+
Use your environment's Python for the last command. Backend checks and Docker instructions are in [CONTRIBUTING.md](CONTRIBUTING.md) and [SETUP.md](docs/SETUP.md). `server/requirements.lock.txt` pins the full dependency graph with package hashes; `requirements.txt` records the direct dependencies. Use the lockfile for installation. The [repair report](docs/REPAIR_REPORT.md) distinguishes automated checks from unverified live integrations.
|
|
114
|
+
|
|
115
|
+
## Get involved
|
|
116
|
+
|
|
117
|
+
Small, focused contributions are welcome. Start with the [contribution guide](CONTRIBUTING.md) and [roadmap](docs/ROADMAP.md). Read the [code of conduct](CODE_OF_CONDUCT.md) and [security policy](SECURITY.md) before reporting problems.
|
|
118
|
+
|
|
119
|
+
[API](docs/API.md) · [Architecture](docs/ARCHITECTURE.md) · [Changelog](CHANGELOG.md) · [Launch checklist](docs/LAUNCH.md)
|
|
120
|
+
|
|
121
|
+
Licensed under the [MIT license](LICENSE). The existing attribution is preserved; the repository owner must confirm rights to publish before launch.
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
message = String(message).replace(/gsk_[\w]+|sk-[\w-]+/g, '[redacted]').slice(0, 900);
|
|
11
11
|
const error = new Error(`${response?.status ? `HTTP ${response.status}: ` : ''}${message}`);
|
|
12
12
|
error.status = response?.status;
|
|
13
|
+
const seconds = detail?.retry_after_seconds;
|
|
14
|
+
if (error.status === 429 && Number.isFinite(seconds) && seconds > 0) {
|
|
15
|
+
error.retryAfterMs = seconds * 1000;
|
|
16
|
+
}
|
|
13
17
|
return error;
|
|
14
18
|
}
|
|
15
19
|
function temporary(error) {
|
|
@@ -40,16 +44,16 @@
|
|
|
40
44
|
catch (error) {
|
|
41
45
|
if (!active())
|
|
42
46
|
return null;
|
|
43
|
-
if (attempt === attempts || !temporary(error))
|
|
47
|
+
if (attempt === attempts || !temporary(error) || error.retryAfterMs > 60_000)
|
|
44
48
|
throw error;
|
|
45
49
|
onRetry({ attempt: attempt + 1, attempts, message: error.message });
|
|
46
50
|
// Short waits keep Stop/Pause responsive. Revalidate before the
|
|
47
51
|
// next request so an old answer cannot target a new question.
|
|
48
|
-
const delay = attempt === 1 ? 1000 : 2500;
|
|
52
|
+
const delay = error.retryAfterMs ?? (attempt === 1 ? 1000 : 2500);
|
|
49
53
|
for (let elapsed = 0; elapsed < delay; elapsed += 100) {
|
|
50
54
|
if (!active())
|
|
51
55
|
return null;
|
|
52
|
-
await sleep(100);
|
|
56
|
+
await sleep(Math.min(100, delay - elapsed));
|
|
53
57
|
}
|
|
54
58
|
}
|
|
55
59
|
}
|
package/extension/manifest.json
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
{
|
|
2
|
-
"manifest_version": 3,
|
|
3
|
-
"name": "Browser Assistant",
|
|
4
|
-
"version": "2.8.
|
|
5
|
-
"description": "Scans webpages for MCQs and coding problems. Powered by Groq (cloud) and Ollama (local fallback).",
|
|
6
|
-
"permissions": [
|
|
7
|
-
"activeTab",
|
|
8
|
-
"scripting",
|
|
9
|
-
"tabs",
|
|
10
|
-
"clipboardWrite",
|
|
11
|
-
"alarms"
|
|
12
|
-
],
|
|
13
|
-
"background": {
|
|
14
|
-
"service_worker": "background.js"
|
|
15
|
-
},
|
|
16
|
-
"action": {
|
|
17
|
-
"default_popup": "popup.html"
|
|
18
|
-
},
|
|
19
|
-
"content_scripts": [
|
|
20
|
-
{
|
|
21
|
-
"matches": [
|
|
22
|
-
"<all_urls>"
|
|
23
|
-
],
|
|
24
|
-
"js": [
|
|
25
|
-
"automation-policy.js",
|
|
26
|
-
"editor-bridge.js",
|
|
27
|
-
"question-visuals.js",
|
|
28
|
-
"answer-requests.js",
|
|
29
|
-
"coding-automation.js",
|
|
30
|
-
"coding-batch.js",
|
|
31
|
-
"content.js",
|
|
32
|
-
"journal-automation.js"
|
|
33
|
-
],
|
|
34
|
-
"css": [
|
|
35
|
-
"styles.css"
|
|
36
|
-
]
|
|
37
|
-
}
|
|
38
|
-
],
|
|
39
|
-
"host_permissions": [
|
|
40
|
-
"http://localhost:8000/*",
|
|
41
|
-
"http://127.0.0.1:8000/*",
|
|
42
|
-
"<all_urls>"
|
|
43
|
-
]
|
|
44
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"manifest_version": 3,
|
|
3
|
+
"name": "Browser Assistant",
|
|
4
|
+
"version": "2.8.3",
|
|
5
|
+
"description": "Scans webpages for MCQs and coding problems. Powered by Groq (cloud) and Ollama (local fallback).",
|
|
6
|
+
"permissions": [
|
|
7
|
+
"activeTab",
|
|
8
|
+
"scripting",
|
|
9
|
+
"tabs",
|
|
10
|
+
"clipboardWrite",
|
|
11
|
+
"alarms"
|
|
12
|
+
],
|
|
13
|
+
"background": {
|
|
14
|
+
"service_worker": "background.js"
|
|
15
|
+
},
|
|
16
|
+
"action": {
|
|
17
|
+
"default_popup": "popup.html"
|
|
18
|
+
},
|
|
19
|
+
"content_scripts": [
|
|
20
|
+
{
|
|
21
|
+
"matches": [
|
|
22
|
+
"<all_urls>"
|
|
23
|
+
],
|
|
24
|
+
"js": [
|
|
25
|
+
"automation-policy.js",
|
|
26
|
+
"editor-bridge.js",
|
|
27
|
+
"question-visuals.js",
|
|
28
|
+
"answer-requests.js",
|
|
29
|
+
"coding-automation.js",
|
|
30
|
+
"coding-batch.js",
|
|
31
|
+
"content.js",
|
|
32
|
+
"journal-automation.js"
|
|
33
|
+
],
|
|
34
|
+
"css": [
|
|
35
|
+
"styles.css"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"host_permissions": [
|
|
40
|
+
"http://localhost:8000/*",
|
|
41
|
+
"http://127.0.0.1:8000/*",
|
|
42
|
+
"<all_urls>"
|
|
43
|
+
]
|
|
44
|
+
}
|
package/extension/popup.html
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Browser Assistant</title>
|
|
7
|
-
<style>
|
|
8
|
-
body {
|
|
9
|
-
width: 220px;
|
|
10
|
-
padding: 12px 14px;
|
|
11
|
-
font-family: 'Inter', system-ui, sans-serif;
|
|
12
|
-
background: #0f0f0f;
|
|
13
|
-
color: #eee;
|
|
14
|
-
margin: 0;
|
|
15
|
-
}
|
|
16
|
-
.logo {
|
|
17
|
-
display: flex;
|
|
18
|
-
align-items: center;
|
|
19
|
-
gap: 8px;
|
|
20
|
-
margin-bottom: 10px;
|
|
21
|
-
}
|
|
22
|
-
.logo-dot {
|
|
23
|
-
width: 10px;
|
|
24
|
-
height: 10px;
|
|
25
|
-
border-radius: 50%;
|
|
26
|
-
background: #6e8efb;
|
|
27
|
-
box-shadow: 0 0 6px #6e8efb;
|
|
28
|
-
}
|
|
29
|
-
h3 { margin: 0; font-size: 14px; color: #fff; }
|
|
30
|
-
p { font-size: 11px; color: #888; margin: 0 0 10px; line-height: 1.5; }
|
|
31
|
-
.status { font-size: 11px; color: #555; }
|
|
32
|
-
.status span { color: #10b981; font-weight: 600; }
|
|
33
|
-
.shortcuts { margin-top: 10px; border-top: 1px solid #222; padding-top: 8px; }
|
|
34
|
-
.shortcut-row { display: flex; justify-content: space-between; font-size: 10px; color: #666; margin-bottom: 4px; }
|
|
35
|
-
kbd {
|
|
36
|
-
background: #222; border: 1px solid #444; border-radius: 3px;
|
|
37
|
-
padding: 1px 5px; font-size: 10px; color: #bbb;
|
|
38
|
-
}
|
|
39
|
-
#server-status { color: #f59e0b; }
|
|
40
|
-
#server-status.online { color: #10b981; }
|
|
41
|
-
#server-status.offline { color: #ef4444; }
|
|
42
|
-
</style>
|
|
43
|
-
</head>
|
|
44
|
-
<body>
|
|
45
|
-
<div class="logo">
|
|
46
|
-
<div class="logo-dot"></div>
|
|
47
|
-
<h3>Browser Assistant</h3>
|
|
48
|
-
</div>
|
|
49
|
-
<p>Extension active. The floating panel appears on every page.</p>
|
|
50
|
-
<div class="status">Server: <span id="server-status">checking...</span></div>
|
|
51
|
-
<div class="shortcuts">
|
|
52
|
-
<div class="shortcut-row"><span>Open panel</span> <kbd>`</kbd></div>
|
|
53
|
-
<div class="shortcut-row"><span>Close panel</span> <kbd>]</kbd></div>
|
|
54
|
-
<div class="shortcut-row"><span>Vision scan</span> <kbd>\</kbd></div>
|
|
55
|
-
<div class="shortcut-row"><span>Minimal mode</span> <kbd>[</kbd></div>
|
|
56
|
-
<div class="shortcut-row"><span>Journal fill & submit</span> <kbd>Alt+Shift+J</kbd></div>
|
|
57
|
-
<div class="shortcut-row"><span>Automation start / pause / resume</span> <kbd>Alt+Shift+A</kbd></div>
|
|
58
|
-
</div>
|
|
59
|
-
<script src="popup.js"></script>
|
|
60
|
-
</body>
|
|
61
|
-
</html>
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Browser Assistant</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
width: 220px;
|
|
10
|
+
padding: 12px 14px;
|
|
11
|
+
font-family: 'Inter', system-ui, sans-serif;
|
|
12
|
+
background: #0f0f0f;
|
|
13
|
+
color: #eee;
|
|
14
|
+
margin: 0;
|
|
15
|
+
}
|
|
16
|
+
.logo {
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
gap: 8px;
|
|
20
|
+
margin-bottom: 10px;
|
|
21
|
+
}
|
|
22
|
+
.logo-dot {
|
|
23
|
+
width: 10px;
|
|
24
|
+
height: 10px;
|
|
25
|
+
border-radius: 50%;
|
|
26
|
+
background: #6e8efb;
|
|
27
|
+
box-shadow: 0 0 6px #6e8efb;
|
|
28
|
+
}
|
|
29
|
+
h3 { margin: 0; font-size: 14px; color: #fff; }
|
|
30
|
+
p { font-size: 11px; color: #888; margin: 0 0 10px; line-height: 1.5; }
|
|
31
|
+
.status { font-size: 11px; color: #555; }
|
|
32
|
+
.status span { color: #10b981; font-weight: 600; }
|
|
33
|
+
.shortcuts { margin-top: 10px; border-top: 1px solid #222; padding-top: 8px; }
|
|
34
|
+
.shortcut-row { display: flex; justify-content: space-between; font-size: 10px; color: #666; margin-bottom: 4px; }
|
|
35
|
+
kbd {
|
|
36
|
+
background: #222; border: 1px solid #444; border-radius: 3px;
|
|
37
|
+
padding: 1px 5px; font-size: 10px; color: #bbb;
|
|
38
|
+
}
|
|
39
|
+
#server-status { color: #f59e0b; }
|
|
40
|
+
#server-status.online { color: #10b981; }
|
|
41
|
+
#server-status.offline { color: #ef4444; }
|
|
42
|
+
</style>
|
|
43
|
+
</head>
|
|
44
|
+
<body>
|
|
45
|
+
<div class="logo">
|
|
46
|
+
<div class="logo-dot"></div>
|
|
47
|
+
<h3>Browser Assistant</h3>
|
|
48
|
+
</div>
|
|
49
|
+
<p>Extension active. The floating panel appears on every page.</p>
|
|
50
|
+
<div class="status">Server: <span id="server-status">checking...</span></div>
|
|
51
|
+
<div class="shortcuts">
|
|
52
|
+
<div class="shortcut-row"><span>Open panel</span> <kbd>`</kbd></div>
|
|
53
|
+
<div class="shortcut-row"><span>Close panel</span> <kbd>]</kbd></div>
|
|
54
|
+
<div class="shortcut-row"><span>Vision scan</span> <kbd>\</kbd></div>
|
|
55
|
+
<div class="shortcut-row"><span>Minimal mode</span> <kbd>[</kbd></div>
|
|
56
|
+
<div class="shortcut-row"><span>Journal fill & submit</span> <kbd>Alt+Shift+J</kbd></div>
|
|
57
|
+
<div class="shortcut-row"><span>Automation start / pause / resume</span> <kbd>Alt+Shift+A</kbd></div>
|
|
58
|
+
</div>
|
|
59
|
+
<script src="popup.js"></script>
|
|
60
|
+
</body>
|
|
61
|
+
</html>
|