个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Open source web based EEG visualizer and analyzer
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 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