pgx
PGX — Lightweight Postgres for AI agents. Written in Rust. Thousands of isolated databases in one runtime. 🐘
Translation pending
Rapid, transparent, open-source EEG analysis platform for 19-channel recordings
DataTypeScript · PLpgSQLGitHub @alexdniOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Open source web based EEG visualizer and analyzer
Taken from the repository README
Loading the full README.
Read the full README ↗Rapid, transparent, open-source tool for analyzing 19-channel EEG recordings with support for Eyes-Open (EO) and Eyes-Closed (EC) conditions.
Watch the full demo on YouTube
timestamp column first or last, numeric (s/ms/µs/ns) or ISO 8601| Domain | Metrics |
|---|---|
| Power Spectral | Absolute & relative band power (Delta, Theta, Alpha1, Alpha2, SMR, Beta2, HiBeta, LowGamma) |
| Connectivity | Weighted Phase-Lag Index (wPLI), network graph metrics |
| Network Metrics | Global efficiency, clustering coefficient, small-worldness, interhemispheric connectivity |
| Complexity | Lempel-Ziv Complexity (LZC) per channel with normalization |
| Asymmetry | Frontal Alpha Asymmetry (FAA), Power Asymmetry Index (PAI) |
| Band Ratios | Theta/Beta, Alpha/Theta (frontal and posterior averages) |
| Alpha Peak | Individual Alpha Frequency (IAF) per channel |
Pattern flagging based on within-subject thresholds:
Rendered in the browser from the analysis results:
All signal processing runs server-side in Node.js inside the Next.js server — there is no
separate worker service. POST /api/analyses/[id]/process returns immediately and runs the job in a
worker_threads thread; the browser polls for completion and draws every visual (topomaps,
connectivity graphs, spectrograms) from the results JSON.
All-in-one container for local deployment:
┌─────────────────────────────────────────────────────┐
│ Docker Container │
│ ┌──────────────────────────────┐ ┌─────────────┐ │
│ │ Next.js (UI + API routes) │ │ PostgreSQL │ │
│ │ └ analysis worker thread │ │ Database │ │
│ │ (Port 3000) │ │ (Port 5432) │ │
│ └──────────────────────────────┘ └─────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────┐ │
│ │ Local Storage │ │
│ │ /data/storage/ │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────┘
Distributed architecture for multi-user deployment:
┌──────────────────────────┐ ┌──────────────┐
│ Vercel │ │ Supabase │
│ Next.js UI + API routes │────►│ PostgreSQL │
│ analysis in functions │ │ Storage │
└──────────────────────────┘ └──────────────┘
Supabase Auth (Google OAuth)
Artifact cleaning uses @divergentneuro/biofeedback-core, a private package on GitHub
Packages. It is loaded only on the server and is never sent to the browser (the build fails if
it reaches a client bundle — see scripts/check-client-bundle.mjs). To install dependencies you
need a GitHub token with read:packages access to the DivergentNeuro organization:
export NODE_AUTH_TOKEN=ghp_your_token # used by .npmrc; never commit it
npm ci
Without the token the rest of the app installs, but the build stops with a message explaining that the analysis engine is missing.
| Component | Docker Mode | Cloud Mode |
|---|---|---|
| Frontend | Next.js 14 (App Router) | Same |
| Backend | Next.js API Routes | Same |
| Database | PostgreSQL (embedded) | Supabase PostgreSQL |
| Storage | Local filesystem | Supabase Storage |
| Auth | Session-based login | Google OAuth |
| Analysis | Node.js worker thread in the Next.js server | Vercel Functions (Node.js) |
| Signal Processing | TypeScript (biofeedback-core artifact pipeline + lib/server/eeg) | Same |
| Visuals | Canvas / SVG / Chart.js in the browser | Same |
Clone the repository
git clone https://github.com/alexdni/squiggly.git
cd squiggly
Configure environment
cp .env.docker.example .env.docker
Edit .env.docker and set your credentials:
[email protected]
ADMIN_PASSWORD=your-secure-password
Build and start (the token is passed as a BuildKit secret and never stored in the image)
export NODE_AUTH_TOKEN=ghp_your_token
docker compose up -d --build
Access the application
Open http://localhost:3000 and log in with your admin credentials.
| Variable | Required | Default | Description |
|---|---|---|---|
ADMIN_EMAIL | Yes | - | Admin login email |
ADMIN_PASSWORD | Yes | - | Admin login password |
PORT | No | 3000 | Web server port |
MAX_UPLOAD_SIZE | No | 52428800 | Max upload size (50MB) |
All data is stored in the /data volume:
/data/
├── postgres/ # PostgreSQL database
└── storage/
├── recordings/ # Uploaded EEG files
├── visuals/ # Generated images
└── exports/ # PDF/JSON exports
Mount a named volume or local directory:
# Named volume (recommended)
docker compose up -d
# Or local directory
docker run -v /path/to/data:/data squiggly
# View logs
docker compose logs -f
# Stop the container
docker compose down
# Rebuild after code changes
docker compose build --no-cache
docker compose up -d
# Access PostgreSQL
docker exec -it squiggly psql -U squiggly
# Backup database
docker exec squiggly pg_dump -U squiggly squiggly > backup.sql
# Check health
curl http://localhost:3000/api/health
Container won't start:
docker logs squiggly
Analysis fails:
docker exec squiggly cat /var/log/supervisor/nextjs.log # look for [analysis <id>] lines
Reset everything:
docker compose down -v # WARNING: Deletes all data
docker compose up -d
For multi-user deployment with Google OAuth authentication. See DEPLOYMENT.md for details.
read:packages for the analysis enginesupabase/schema.sql), then the files in
supabase/migrations/recordings, visuals, exports (private)NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key # analyses write results with it
NODE_AUTH_TOKEN=ghp_your_token # build-time: installs the analysis engine
Cloud mode exposes a read-only MCP server so an AI assistant can read your EEG results and help interpret them. Server URL:
https://squiggly.alexni.ai/api/mcp
Claude.ai: Settings → Connectors → Add custom connector → paste the URL. ChatGPT: Settings → Connectors → enable developer mode → Create → paste the URL (OAuth).
You sign in to Squiggly, then approve the connection on the consent screen. Access is read-only and limited to the projects you can already open. The assistant sees EEG measurements only (QC, band power, connectivity, asymmetry, complexity, events, comparisons); client details, project names and file names are never shared. Projects appear as "Project 1a2b3c4d".
Tools: list_projects, list_sessions, get_session_summary, get_analysis_detail,
compare_sessions, get_metric_trend. Prompts: interpret_session, compare_two_sessions.
To disconnect an app, open Settings → Connected apps (/settings/connected-apps) and revoke it;
its next call is rejected. The endpoint is not available in Docker mode (AUTH_MODE=local returns 404).
squiggly/
├── app/ # Next.js App Router
│ ├── api/ # API routes
│ │ ├── analyses/ # Analysis endpoints
│ │ ├── projects/ # Project management
│ │ ├── recordings/ # Recording endpoints
│ │ └── storage/ # File storage endpoints
│ ├── dashboard/ # Dashboard page
│ ├── login/ # Login page
│ └── projects/ # Project pages
├── components/ # React components
│ └── visuals/ # Client-rendered topomaps, connectivity, spectrograms
├── lib/ # Shared utilities
│ ├── server/eeg/ # Server-only analysis: IO, pipeline, features, job runner
│ ├── server/theraq/ # TheraQ four-phase metrics engine
│ ├── auth/ # Authentication abstraction
│ ├── db/ # Database abstraction
│ ├── storage/ # Storage abstraction
│ └── prompts/ # AI prompt templates
├── docker/ # Docker configuration
├── scripts/ # Setup scripts
│ └── schema-docker.sql # Docker PostgreSQL schema
└── docker-compose.yml # Docker Compose config
Projects organize recordings for a subject/client. Add optional metadata (age, gender, primary concern).
Interactive dashboard showing:
Click "Re-Analyze" to reset to pending, adjust annotations or switch de-artifacting method, and re-run.
Select two recordings to compare:
Export a PDF report or a ZIP of every visualization from the analysis page, and download the cleaned recording from the QC panel.
Assign EO1 / EC / EO2 / TASK roles to four recordings in a project (auto-detected from file names) and run the four-phase TheraQ report from the project's TheraQ tab.
GET /api/analyses/[id] - Get analysis detailsPATCH /api/analyses/[id] - Update the analysis config, or reset it to pending for a re-runPOST /api/analyses/[id]/process - Start the server-side analysis (responds 202; poll GET /api/analyses/[id])GET /api/projects - List user's projectsPOST /api/projects - Create projectGET /api/projects/[id]/compare - Compare two recordingsGET / POST /api/projects/[id]/theraq-analysis - List / start TheraQ four-phase analysesGET /api/recordings?projectId=... - List recordingsPOST /api/recordings - Create recording entryPATCH /api/recordings/[id] - Set the recording's TheraQ phase roleGET /api/recordings/[id]/download - Short-lived signed URL for the recording fileGET /api/recordings/[id]/annotations - List annotations for a recordingPOST /api/recordings/[id]/annotations - Create an annotationDELETE /api/recordings/[id]/annotations?annotationId=... - Delete an annotation| Feature | Docker | Cloud |
|---|---|---|
| Setup complexity | Low (single command) | Medium (2 services) |
| Cost | Free (self-hosted) | ~$35-60/month |
| Users | Single user/team | Multi-user |
| Authentication | Email/password | Google OAuth |
| Internet required | No | Yes |
| Scaling | Limited | Horizontal |
| Backups | Manual | Automatic |
| Updates | Manual rebuild | Auto-deploy |
This EEG assessment platform is for educational and research use only.
Contributions are welcome! Please open an issue or pull request.
MIT License - see LICENSE file for details.
biofeedback-core; feature definitions originally implemented with MNE-Python