Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ __pycache__/
*.py[cod]
.venv/
logs/
dist/
*.egg-info/
.pytest_cache/
64 changes: 58 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,34 @@ FocusSight-AI/
│ ├── __init__.py
│ ├── tracker.py # Real-time webcam tracking, CLI, session loop
│ ├── summary.py # Session analytics, history, streaks, heatmap, notes
│ └── ops_report.py # Cognitive operations report builder and renderer
│ ├── ops_report.py # Cognitive operations report builder and renderer
│ └── server.py # Phase 13: local REST / WebSocket API server
├── tests/ # Automated test suite (78 tests)
├── extension/ # Phase 14: Manifest V3 browser extension
│ ├── manifest.json # Chrome / Firefox extension manifest
│ ├── background.js # Service worker – polls /status, updates badge
│ ├── popup.html / popup.js # Toolbar popup (live stats panel)
│ ├── options.html / options.js # Settings page (server URL, notifications)
│ ├── icons/ # Extension icons (16/32/48/128 px)
│ ├── generate_icons.py # Script to regenerate placeholder icons
│ ├── package_extension.py # Script to produce .zip / .xpi packages
│ └── README.md # Extension usage & loading instructions
├── tests/ # Automated test suite (90 tests)
│ ├── test_tracker.py
│ ├── test_summary.py
│ └── test_ops_report.py
│ ├── test_ops_report.py
│ └── test_server.py # Phase 13 API / state tests
├── docs/
│ ├── ROADMAP.md # Phase-by-phase development plan
│ ├── ROADMAP.md # Phase-by-phase development plan (all 14 complete)
│ └── CHANGELOG.md # Release history
├── eye_test.py # Backward-compatible tracker launcher
├── session_summary.py # Backward-compatible summary launcher
├── ops_report.py # Backward-compatible report launcher
├── pyproject.toml # Phase 12: pip-installable package metadata
├── haarcascade_frontalface_default.xml # Frontal face cascade (auto-downloaded if missing)
├── haarcascade_eye.xml # Eye cascade (auto-downloaded if missing)
├── haarcascade_profileface.xml # Profile face cascade (auto-downloaded if missing)
Expand Down Expand Up @@ -507,6 +520,31 @@ python eye_test.py --autolog --note "Exam prep – third coffee, library was lou
| `--dashboard-interval F` | float | Seconds between dashboard prints (default: 5) |
| `--streak-goal F` | float | Personal focused-streak goal in seconds |
| `--note TEXT` | str | Annotation saved alongside the session log |
| `--serve` | flag | Start local API server on port 8765 alongside the tracker |
| `--serve-port N` | int | Port for local API server (default: 8765) |

### Local API Server (`python -m focussight.server`)

Phase 13 — install `pip install "focussight-ai[server]"` first.

| Endpoint | Method | Description |
|---|---|---|
| `/status` | GET | Current focus state as JSON |
| `/report` | GET | Ops report JSON for the active session log |
| `/health` | GET | Liveness probe — always returns `{"ok": true}` |
| `/events` | WebSocket | Streams a state event every second |

Start standalone (no webcam):

```bash
python -m focussight.server --host 127.0.0.1 --port 8765
```

Start alongside the tracker:

```bash
python eye_test.py --autolog --serve
```

### Ops Report (`ops_report.py` / `python -m focussight.ops_report`)

Expand Down Expand Up @@ -558,17 +596,31 @@ python ops_report.py --distraction-heatmap
python -m pytest tests/ -v
```

The test suite covers tracker logic, signal quality, calibration, profile I/O, reminder policies, analytics, streak records, distraction heatmap, session notes, daily reports, HTML rendering, and the adaptive threshold learner — **78 tests** in total.
The test suite covers tracker logic, signal quality, calibration, profile I/O, reminder policies, analytics, streak records, distraction heatmap, session notes, daily reports, HTML rendering, adaptive threshold learner, and the Phase 13 API server — **90 tests** in total.

---

## Project Documentation

- [`docs/ROADMAP.md`](docs/ROADMAP.md) — full phase-by-phase development plan (Phases 1–11 complete)
- [`docs/ROADMAP.md`](docs/ROADMAP.md) — full phase-by-phase development plan (all 14 phases complete)
- [`docs/CHANGELOG.md`](docs/CHANGELOG.md) — detailed change history per release

---

## Upcoming Phases

All 14 planned phases are now complete. FocusSight AI has reached its full-featured milestone — including the browser extension.

| Phase | Name | Status |
|---|---|---|
| 12 | Packaging & Distribution | ✅ Complete |
| 13 | REST API / WebSocket Server | ✅ Complete |
| 14 | Browser Extension | ✅ Complete |

See [`docs/ROADMAP.md`](docs/ROADMAP.md) and [`extension/README.md`](extension/README.md) for full details.

---

## Notes & Troubleshooting

| Issue | Fix |
Expand Down
18 changes: 18 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## 2026-04-16 (Phases 12–14 implementation)

- **Phase 12 – Packaging & Distribution**: added `pyproject.toml` (PEP 517/518) with package metadata, entry-point scripts (`focussight-track`, `focussight-report`), dependency declarations, and `[server]` / `[dev]` optional extras. The package can now be installed with `pip install focussight-ai` or `pip install -e .`.
- **Phase 13 – REST API / WebSocket Server**: added `focussight/server.py` with a FastAPI application exposing `GET /status` (live focus state JSON), `GET /report` (ops report JSON), `GET /health` (liveness probe), and `WS /events` (1-second streaming). `FocusState` dataclass and thread-safe `update_live_state()` / `get_live_state()` helpers allow the tracker loop to push state with zero overhead. The tracker now calls `update_live_state()` every frame when the server is running.
- Added `--serve` and `--serve-port` CLI flags to `eye_test.py` / tracker `main()`; starts a `uvicorn` daemon thread before the webcam loop begins.
- CORS is open for all origins by default so the browser extension can connect from any `localhost` port.
- Added `tests/test_server.py` with 12 tests covering `FocusState` dataclass, shared-state thread-safety, and FastAPI endpoint contracts (`/status`, `/report`, `/health`, CORS headers).
- **Phase 14 – Browser Extension**: added `extension/` folder with a complete Manifest V3 Chrome / Firefox extension:
- `manifest.json` — MV3 manifest with `storage` and `notifications` permissions.
- `background.js` — service worker that polls `GET /status` every second via `chrome.alarms`, updates the badge colour (green/red/amber/grey) and fires desktop notifications when distraction streak exceeds the configured threshold.
- `popup.html` / `popup.js` — styled live-stats panel showing state badge, focus %, distracted %, streak, elapsed time, and signal status; polls every second while open.
- `options.html` / `options.js` — settings page for server URL, notification style, and distraction threshold; persisted via `chrome.storage.sync`.
- `icons/` — placeholder 16/32/48/128 px green PNG icons generated by `generate_icons.py`.
- `package_extension.py` — packages the extension as `dist/focussight-extension.zip` (Chrome Web Store) and `dist/focussight-extension.xpi` (Firefox).
- `extension/README.md` — loading instructions for Chrome (unpacked) and Firefox (temporary), options reference, and badge colour legend.
- Updated `README.md`: folder structure now shows `focussight/server.py`, `extension/`, and `tests/test_server.py`; CLI flags table extended with `--serve` / `--serve-port`; new Local API Server endpoint table; test count updated to 90; Upcoming Phases section now shows all phases complete.
- Updated `docs/ROADMAP.md`: Phases 12, 13, and 14 marked **completed**; removed orphaned `---` separator between Phase 11 and Phase 12.

## 2026-04-12 (Phase 9–11)

- Added Phase 9 focus streak goals in `focussight/summary.py`: `compute_streak_records()` scans all session logs for the all-time best focused run; `check_streak_milestone()` returns achievement strings for round milestones (30s, 1 min, 2 min, 5 min, 10 min, 15 min, 30 min), user-defined streak goals, and personal bests.
Expand Down
42 changes: 37 additions & 5 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,42 @@ Deliverables:
- Session note included in `render_ops_report()` text output and HTML report when present
- `build_ops_report()` always includes a `note` key (empty string when no note file exists)

## Phase 12: Packaging & Distribution (completed)

Goal: make FocusSight AI trivially installable as a proper Python package so users can `pip install` it and run it anywhere without manually cloning the repo.

1. Complete Phase 2 fallback labels and reliability metrics.
2. Validate with tests and update docs/changelog.
3. Release and collect sample logs with weighted scoring.
4. Build Phase 3 aggregation on top of richer session logs.
5. Add coaching logic only after metric confidence is acceptable.
Deliverables:

- Add `pyproject.toml` (PEP 517/518) with package metadata, entry-point scripts (`focussight-track`, `focussight-report`), and dependency declarations
- Publish to PyPI (or provide a local `pip install -e .` workflow for development)
- Ensure cascade XML files are bundled as package data so they are always available after install
- Update `README.md` installation section with `pip install focussight-ai` quick-start
- Add a `Makefile` (or `tox.ini`) for one-command test, lint, and build targets

## Phase 13: REST API / WebSocket Server (completed)

Goal: expose FocusSight's real-time tracking data over a local HTTP/WebSocket interface so external clients (browser extensions, dashboards, integrations) can consume focus state without any Python knowledge.

Deliverables:

- Lightweight FastAPI server (`focussight/server.py`) that runs the tracker loop in a background thread
- `/status` GET endpoint – returns current focus state, score, streak, signal quality, and session elapsed time as JSON
- `/events` WebSocket endpoint – streams a focus-state event every second to connected clients
- `/report` GET endpoint – returns the latest session ops-report JSON on demand
- `--serve` CLI flag on the tracker to start the API alongside the webcam loop
- CORS enabled by default for `localhost` origins so the browser extension can connect without extra config
- Add tests for server endpoint contracts using `httpx` / `pytest-asyncio`

## Phase 14: Browser Extension (completed)

Goal: ship a lightweight Chrome/Firefox browser extension that reads focus state from the Phase 13 API and surfaces non-intrusive in-browser nudges — bringing FocusSight into the user's actual work environment.

Deliverables:

- Manifest V3 extension with a popup showing live focus score, state badge, and session streak
- Background service-worker that polls `/status` (or subscribes to `/events` WebSocket) every second
- Non-intrusive banner/toast notification when a distraction streak exceeds the user's alert threshold
- Options page: server URL (default `http://localhost:8765`), notification style (banner / silent / none), distraction threshold override
- Extension icon badge colour changes with state: green (FOCUSED), amber (LOW_CONFIDENCE), red (DISTRACTED)
- Packaged as a `.zip` ready for Chrome Web Store submission and as an unsigned `.xpi` for Firefox
- Developer docs explaining how to load the extension unpacked for local testing
103 changes: 103 additions & 0 deletions extension/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# FocusSight AI – Browser Extension (Phase 14)

A Manifest V3 Chrome / Firefox browser extension that reads live focus state
from the **Phase 13 local API server** and surfaces non-intrusive in-browser
nudges — no cloud, no subscription.

---

## Prerequisites

1. The Python tracker is running **with the `--serve` flag**:

```bash
python eye_test.py --autolog --serve
```

This starts the FocusSight webcam tracker **and** the local API server on
`http://127.0.0.1:8765`.

2. Install the server dependencies if you haven't already:

```bash
pip install "focussight-ai[server]"
# or: pip install fastapi uvicorn[standard] websockets
```

---

## Loading the extension (Chrome / Edge — unpacked)

1. Open `chrome://extensions` in your browser.
2. Enable **Developer mode** (top-right toggle).
3. Click **Load unpacked** and select this `extension/` folder.
4. The FocusSight badge appears in the toolbar.

---

## Loading the extension (Firefox — temporary)

1. Open `about:debugging#/runtime/this-firefox`.
2. Click **Load Temporary Add-on**.
3. Select `extension/manifest.json`.

---

## Icon assets

The extension references PNG icons at:

```
icons/icon16.png
icons/icon32.png
icons/icon48.png
icons/icon128.png
```

Placeholder 1 × 1 transparent PNGs are included so the extension loads
without errors. Replace them with real artwork before publishing to a
browser store.

A helper script is provided to regenerate placeholders:

```bash
python generate_icons.py
```

---

## Packaging for distribution

Run the helper script from the repo root:

```bash
python extension/package_extension.py
```

This produces:
- `dist/focussight-extension.zip` — ready for Chrome Web Store submission
- `dist/focussight-extension.xpi` — unsigned Firefox add-on

---

## Options

Click **Options** in the popup or open the extensions page and click
"Extension options" to configure:

| Setting | Default | Description |
|---|---|---|
| API Server URL | `http://127.0.0.1:8765` | URL of the local FocusSight server |
| Notification Style | Banner | `banner`, `silent` (badge only), or `none` |
| Distraction Threshold | 5 s | Seconds of distraction before a notification fires |

---

## Badge colours

| Colour | Meaning |
|---|---|
| 🟢 Green | FOCUSED |
| 🔴 Red | DISTRACTED |
| 🟡 Amber | Server reachable but state is UNKNOWN / degraded signal |
| ⚫ Grey | Server not reachable |
Loading