Skip to content

Commit 8c4d2cc

Browse files
committed
feat(shared): add shared package with grouping logic and models
- Created a new shared package with package.json and TypeScript configuration. - Implemented domain grouping and purity calculation functions in grouping.ts. - Defined various data models using Zod schemas in models.ts. - Added TypeScript build configuration for the shared package. test(e2e): add end-to-end tests for extension functionality - Implemented tests for real extension popup authentication and session saving. - Created full workflow tests to validate API interactions and session management. - Added grouping tests to ensure correct domain grouping logic. - Included integration tests for server API endpoints and security checks. test(unit): add unit tests for grouping logic and schemas - Added unit tests for domain grouping and purity functions. - Implemented schema validation tests for session schema using Zod. chore: add uploads for testing file upload functionality - Added sample files for testing file upload and download features. chore: update tsconfig for multi-package workspace - Configured root tsconfig.json to reference shared and server packages.
0 parents  commit 8c4d2cc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+9595
-0
lines changed

.env.example

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Environment configuration for Groupem
2+
# Copy to .env and adjust values as needed.
3+
4+
# Server listening port (auto-increments if busy)
5+
PORT=8080
6+
7+
# JWT signing secret (change in production!)
8+
JWT_SECRET=change-me-dev-secret
9+
10+
# SQLite database URL for Prisma
11+
DATABASE_URL="file:./dev.db"
12+
13+
# External ML service base URL (FastAPI service). If unreachable, server/extension fallbacks kick in.
14+
ML_URL=http://localhost:8000

.github/workflows/ci.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
branches: [ main, master ]
8+
9+
jobs:
10+
build-test:
11+
runs-on: ubuntu-latest
12+
services:
13+
ml:
14+
image: python:3.11
15+
env: {}
16+
ports:
17+
- 8000:8000
18+
options: >-
19+
--health-cmd "curl -f http://localhost:8000/health || exit 1" --health-interval 10s --health-retries 5 --health-timeout 5s
20+
command: ["bash", "-c", "pip install fastapi uvicorn scikit-learn numpy sentence-transformers hdbscan bs4 cachetools && uvicorn app.main:app --host 0.0.0.0 --port 8000 --app-dir ml-service/app"]
21+
steps:
22+
- uses: actions/checkout@v4
23+
- name: Setup Node
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: '20'
27+
cache: 'npm'
28+
- name: Setup Python
29+
uses: actions/setup-python@v5
30+
with:
31+
python-version: '3.11'
32+
- name: Install node deps
33+
run: npm install
34+
- name: Install python deps (for local ml usage)
35+
run: |
36+
python -m pip install --upgrade pip
37+
pip install -r ml-service/requirements.txt || true
38+
- name: Build packages
39+
run: npm run build
40+
- name: Run tests
41+
run: npm test
42+
- name: Playwright Browsers
43+
run: npx playwright install --with-deps chromium
44+
- name: Run E2E (headless)
45+
env:
46+
ML_URL: http://localhost:8000
47+
run: npx playwright test --project=chromium || true

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
node_modules/
2+
dist/
3+
build/
4+
.env
5+
*.log
6+
.prisma/
7+
coverage/
8+
.playwright-cache/
9+
playwright-report/
10+
ml-service/.venv/
11+
ml-service/__pycache__/
12+
ml-service/.mypy_cache/

CONTRIBUTING.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Contributing to Groupem
2+
3+
## Development Environment
4+
1. Clone repo and install dependencies:
5+
```powershell
6+
npm install
7+
```
8+
2. Generate Prisma client:
9+
```powershell
10+
cd mcp-server
11+
npx prisma generate
12+
cd ..
13+
```
14+
3. Copy `.env.example` to `.env` and adjust.
15+
4. (Optional) Start ML service:
16+
```powershell
17+
cd ml-service
18+
python -m venv .venv
19+
. .venv/Scripts/Activate.ps1
20+
pip install -r requirements.txt
21+
uvicorn app.main:app --port 8000
22+
```
23+
5. Run server + ML concurrently:
24+
```powershell
25+
npm run dev
26+
```
27+
6. Build extension:
28+
```powershell
29+
npm -w extension run build
30+
```
31+
32+
## Scripts Overview
33+
- `npm run dev:mcp` – MCP server (ts-node-dev)
34+
- `npm run dev:ml` – FastAPI ML service
35+
- `npm run dev` – Concurrent server + ML
36+
- `npm run build` – Build shared libs, server, extension
37+
- `npm test` – Unit/integration tests
38+
- `npm run test:e2e` – Playwright tests
39+
40+
## Code Style
41+
- TypeScript strictness maintained; avoid unnecessary any.
42+
- Keep functions small and purposeful.
43+
- Do not commit generated `dist/` except for packaged extension release branches.
44+
45+
## Security & Secrets
46+
- Never commit real secrets. `.env` is ignored.
47+
- Rotate `JWT_SECRET` for production deployments.
48+
49+
## Pull Requests
50+
- Include description & rationale.
51+
- Ensure `npm test` passes locally.
52+
- Run `npm -w shared run build` if modifying shared models.
53+
54+
## Commit Messages
55+
Follow conventional style (recommended):
56+
- `feat: add X`
57+
- `fix: correct Y`
58+
- `docs: update README`
59+
- `refactor: simplify Z`
60+
61+
## Testing Guidance
62+
- Add unit tests for new utilities.
63+
- Extend Playwright E2E if UI flows change.
64+
65+
## Issue Reporting
66+
Include reproduction steps, expected vs actual behavior, and environment (OS, Node, Python versions).
67+
68+
Happy hacking!

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Groupem Contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Groupem
2+
3+
Cross-browser tab grouping extension with secure MCP server and optional ML microservice.
4+
5+
## Components
6+
- Extension (Chrome/Firefox) in `extension/`
7+
- MCP Server (Node/TypeScript + Prisma + SQLite) in `mcp-server/`
8+
- ML Service (FastAPI) in `ml-service/`
9+
- Shared models in `shared/`
10+
11+
## Quick Start (PowerShell)
12+
```powershell
13+
# Install root deps
14+
npm install
15+
16+
# Generate Prisma client
17+
setx DATABASE_URL "file:./dev.db"
18+
cd mcp-server; npx prisma generate; cd ..
19+
20+
# Run server (port 8080 default; will auto-increment if busy)
21+
# Optionally set explicit port
22+
$env:PORT=8080; npm run dev:mcp
23+
24+
# Run extension build (dev)
25+
cd extension; npm run dev
26+
```
27+
28+
## ML Service
29+
```powershell
30+
cd ml-service
31+
python -m venv .venv
32+
. .venv/Scripts/Activate.ps1
33+
pip install -r requirements.txt
34+
uvicorn app.main:app --reload --port 8000
35+
36+
### Health
37+
MCP server exposes `GET /ml/health` reflecting reachability of `ML_URL` (default `http://localhost:8000`).
38+
Set a custom ML URL:
39+
```powershell
40+
$env:ML_URL="http://localhost:9000"; npm run dev:mcp
41+
```
42+
If unreachable, embeddings in extension fall back to:
43+
1. (Future) Local ONNX model (placeholder)
44+
2. Server-side TF-IDF stub
45+
Check server logs for: `ML service unreachable at ...`.
46+
47+
### Ports
48+
Server attempts desired `$env:PORT` (default 8080) then increments up to 10 times if occupied.
49+
Use `/` root route for basic health and `/ml/health` for ML status.
50+
51+
## Environment Variables
52+
See `.env.example` for documented defaults:
53+
- `PORT` – MCP server port (auto-increment fallback)
54+
- `JWT_SECRET` – Signing key (change for production)
55+
- `DATABASE_URL` – Prisma SQLite path
56+
- `ML_URL` – Base URL for ML microservice
57+
58+
## CI
59+
GitHub Actions workflow (`.github/workflows/ci.yml`) installs dependencies, builds all packages, runs tests, and executes a Chromium Playwright project (soft-fail for E2E).
60+
61+
## Contributing
62+
See `CONTRIBUTING.md` for guidelines, scripts, and commit style.
63+
64+
## Release Checklist
65+
- Update version numbers (extension + server) if public release.
66+
- Run `npm run build` and `npm test`.
67+
- Tag release: `git tag -a vX.Y.Z -m "Release vX.Y.Z"; git push --tags`.
68+
- Upload packaged extension (zip `extension/dist`).
69+
```
70+
71+
## Tests
72+
```powershell
73+
# (After installing deps) build shared & server
74+
npm -w shared run build
75+
npm -w mcp-server run build
76+
npm test
77+
```
78+
79+
## Security Notes
80+
- Argon2id used for password hashing.
81+
- AES-GCM encryption of sessions and storage with per-user random key unwrapped at login (kept in-memory only).
82+
- TOTP enrollment and verification endpoints provided.
83+
- Simplified WebAuthn (mock) endpoints included; not production secure.
84+
- Registration now supports optional `phone` and automatic TOTP secret provisioning (returned in `totpSecret`). Store it in an authenticator app to use during login.
85+
86+
## Embeddings
87+
Current implementation uses a simple TF-IDF style embedding in the server; ML service provides higher quality embeddings & clustering if integrated via future enhancement.
88+
89+
## Disclaimer
90+
This repository is a functional baseline but additional hardening, full WebAuthn ceremony, and production deployment considerations (HTTPS, key management) are required before production use.

extension/flattenHtml.mjs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { promises as fs } from 'fs';
2+
import { resolve } from 'path';
3+
4+
async function run() {
5+
const dist = resolve('./dist/src');
6+
const root = resolve('./dist');
7+
for (const name of ['popup.html', 'options.html']) {
8+
const from = resolve(dist, name);
9+
try {
10+
await fs.access(from);
11+
const to = resolve(root, name);
12+
await fs.copyFile(from, to);
13+
console.log('Copied', from, '->', to);
14+
} catch {
15+
// ignore if not exists
16+
}
17+
}
18+
}
19+
run();

extension/groupem-extension.zip

5.08 MB
Binary file not shown.

extension/package.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "groupem-extension",
3+
"version": "1.0.0",
4+
"private": true,
5+
"scripts": {
6+
"build": "vite build && node ./flattenHtml.mjs",
7+
"dev": "vite",
8+
"pack": "npm run build && powershell -NoLogo -Command Compress-Archive -Path dist/* -DestinationPath groupem-extension.zip -Force",
9+
"test": "echo 'No extension tests yet'"
10+
},
11+
"dependencies": {
12+
"react": "18.2.0",
13+
"react-dom": "18.2.0",
14+
"webextension-polyfill": "^0.10.0",
15+
"onnxruntime-web": "^1.18.0"
16+
},
17+
"devDependencies": {
18+
"typescript": "^5.4.5",
19+
"@types/react": "^18.2.21",
20+
"@types/react-dom": "^18.2.7",
21+
"vite": "^5.2.0",
22+
"@vitejs/plugin-react": "^4.2.1"
23+
}
24+
}

extension/src/activator.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Content script to ping background and ensure MV3 service worker wakes.
2+
try {
3+
chrome.runtime?.sendMessage?.({ type: 'groupem-activate' });
4+
} catch { }

0 commit comments

Comments
 (0)