AI-powered surveillance for smoking, littering, and security incidents. Built with TypeScript, Next.js, and the Google Gemini API.
The repo has three ways to run Aegis:
| Mode | Best for | What you need |
|---|---|---|
| Desktop app (recommended for demos) | On-site Mac/PC on camera Wi‑Fi | A .dmg (Mac) or .exe (Windows) from desktop/dist/ |
| Web dev | Local development | Node.js 20+, two terminals (client/ + server/) |
| Desktop dev | Test production-like packaging | Electron in desktop/ |
Pre-built installers live in desktop/dist/ after you or CI run npm run dist (Mac) or npm run dist:win (Windows). Recipients do not need Node.js, npm, or a .env file — config is baked into the app.
Option A — one command (from the repo, with a DMG in desktop/dist/):
cd desktop
chmod +x install-mac.sh
./install-mac.shOption B — manual:
- Open
desktop/dist/Aegis CCTV-0.1.0-arm64.dmg. - Drag Aegis CCTV to Applications.
- First launch: right-click → Open → Open (unsigned app bypass).
If macOS still blocks the app (“damaged” or “cannot be opened”), run this once in Terminal:
xattr -cr "/Applications/Aegis CCTV.app"
open -a "Aegis CCTV"Then connect to the camera Wi‑Fi and launch the app. Cameras are discovered automatically.
Full details: desktop/INSTALL-UNSIGNED-MAC.md
Option A — script (with an installer in desktop/dist/):
cd desktop
.\install-windows.ps1Or double-click desktop/install-windows.bat.
Option B — manual:
- Run
desktop/dist/Aegis CCTV Setup 0.1.0.exe. - If SmartScreen appears: More info → Run anyway.
- Launch from the Start menu.
Full details: desktop/INSTALL-UNSIGNED-WINDOWS.md
Trigger the Desktop installers GitHub Action (.github/workflows/desktop-build.yml) and download the Mac DMG and Windows EXE artifacts.
Two standalone Next.js apps — the UI proxies API calls to the backend over HTTP.
| Project | Role | Dev port |
|---|---|---|
client/ |
Dashboard UI, camera grid, thin /api proxies |
3000 |
server/ |
RTSP/ffmpeg, discovery, UniFi, Gemini, evidence API | 3001 |
# Terminal A — backend
cd server
npm install
cp .env.example .env.local # GEMINI_API_KEY, CLIENT_SERVER_SECRET, etc.
npm run dev
# Terminal B — frontend
cd client
npm install
cp .env.local.example .env.local # BACKEND_URL=http://localhost:3001
npm run devOpen http://localhost:3000. The frontend forwards /api/* to BACKEND_URL via client/lib/backendProxy.ts.
Optional local YOLO gate:
pip install -r models/requirements.txt
python models/server.py # :8000 — set YOLO_API_URL in server/.env.localThe Electron app bundles client/ and server/ as child processes with a local ffmpeg binary. See ELECTRON-DESKTOP-APP.md and desktop/README.md.
cd desktop
npm install
cp .env.example .env # production keys + camera defaults
npm run sync-config # copies .env → desktop-config/.env (baked into installer)
npm run dist # Mac: desktop/dist/*.dmg
npm run dist:win # Windows: desktop/dist/*.exe (run on Windows)After building, install locally:
npm run install:mac --prefix desktop # Mac
npm run install:win --prefix desktop # WindowsGEMINI_API_KEY=...
YOLO_LOCAL=0 # packaged builds use cloud YOLO
YOLO_API_URL=https://your-lightning/predict
CLIENT_SERVER_SECRET=...
EVIDENCE_DEV_STORAGE=memory
NEXT_PUBLIC_DEFAULT_CAMERA_USER=admin
NEXT_PUBLIC_DEFAULT_CAMERA_PASSWORDS=123456,hk123456┌─────────────────────────────────────────────────────────────┐
│ Aegis CCTV.app (Electron) OR browser → localhost:3000 │
├─────────────────────────────────────────────────────────────┤
│ client/ Next.js UI (:3000) │
│ server/ Next.js API (:3001) — RTSP, discovery, evidence │
│ ffmpeg-static (desktop) — RTSP → JPEG on LAN │
├─────────────────────────────────────────────────────────────┤
│ Cloud: Gemini API, Lightning YOLO gate (YOLO_API_URL) │
└─────────────────────────────────────────────────────────────┘
- No shared in-process imports between
client/andserver/— only HTTP. - Duplicated modules (
lib/detection.ts,lib/evidence.ts,cameraTypes.ts) must be kept in sync manually. - Camera traffic stays on the LAN in desktop mode; only AI calls leave the network.
| Path | Purpose |
|---|---|
client/ |
Next.js frontend |
server/ |
Next.js backend API |
desktop/ |
Electron wrapper, installers, install-mac.sh, install-windows.ps1 |
models/ |
LitServe YOLO (cloud or local :8000) |
desktop/dist/ |
Output: Aegis CCTV-*.dmg, Aegis CCTV Setup *.exe |
After install, these URLs open the app:
| URL | Screen |
|---|---|
aegis://open |
Dashboard |
aegis://login |
Login |
aegis://cameras/live |
Live cameras |
aegis://settings |
Settings |
open "aegis://cameras/live" # macOS test| Symptom | Fix |
|---|---|
| Mac: “app is damaged” | xattr -cr "/Applications/Aegis CCTV.app" then open -a "Aegis CCTV" |
| Mac: Gatekeeper on first open | Right-click → Open (once), or use ./desktop/install-mac.sh |
| Windows: SmartScreen | More info → Run anyway |
| No cameras | Join camera Wi‑Fi; check Credentials panel |
Filter server failed |
Check YOLO_API_URL or run local YOLO with YOLO_LOCAL=1 |
| Blank window after launch | Wait ~30s; quit and reopen once |
- desktop/README.md — desktop commands and config
- desktop/INSTALL-UNSIGNED-MAC.md — Mac install for recipients
- desktop/INSTALL-UNSIGNED-WINDOWS.md — Windows install for recipients
- ELECTRON-DESKTOP-APP.md — build spec
- AEGIS_AI_PIPELINE_ARCHITECTURE.md — AI pipeline