mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-11-07 21:23:02 -05:00
Nothing links or dlopens libvlc any more, so the dev package is no longer a build requirement anywhere: the debian, beowulf, ubuntu and split-package control files, the podman Containerfile, the redhat and opensuse specs, the centos CI image, and the five workflows that installed libvlc-dev. The redhat spec also required vlc-core at runtime, which was the dlopen target. Documentation follows: the libVLC source tab section, the macos note about libVLC not being found, and the WEB_FILTER_SOURCE source-type list. Two stale statements nearby are corrected while the files are open. The Remote source tab still said its RTSP method "may be removed in the future"; it was removed earlier on this branch. AGENTS.md still listed RemoteCameraRTSP and LibVLCCamera among the camera classes, both of which are now gone. All workflow yaml parses, the three edited rst files render, and the debian control field structure is unchanged apart from the removed entries. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015Y6FieTwEXuLhhR4e2yiax
336 lines
13 KiB
Markdown
336 lines
13 KiB
Markdown
# AI Agent Development Guide for ZoneMinder
|
|
|
|
> **Note**: This file guides AI coding agents (Claude Code, GitHub Copilot, Cursor, etc.) working on ZoneMinder.
|
|
> CLAUDE.md is a symlink to this file.
|
|
|
|
## Quick Reference (MANDATORY RULES)
|
|
|
|
1. **Testing First**: Write tests BEFORE/DURING implementation - NEVER skip. Tests written "later" never get written.
|
|
2. **Build System**: CMake with C++17, out-of-source builds in `build/`. In-source builds pollute the repo.
|
|
3. **Feature Workflow**: GitHub Issue -> Feature Branch -> Implement FULLY -> Tests Pass -> Get Approval -> Merge to master. Feature branches keep master stable.
|
|
4. **Commits**: Conventional format (`feat:`/`fix:`/`test:`), reference issues (`refs #n` or `fixes #n`). Enables automated changelog.
|
|
5. **Pre-Commit**: Tests pass, build succeeds, linting clean, no warnings.
|
|
6. **Never merge without user approval. Never leave features half-implemented.**
|
|
|
|
---
|
|
|
|
## What is ZoneMinder?
|
|
|
|
Linux-based CCTV surveillance system: capture, analysis, recording, and monitoring of video cameras.
|
|
|
|
- **C++ daemons** (`src/`) - Capture (`zmc`), analysis (`zma`), streaming (`zms`), utility (`zmu`)
|
|
- **PHP web interface** (`web/`) - Bootstrap + jQuery UI, AJAX endpoints in `web/ajax/`, views in `web/views/`
|
|
- **REST API** (`web/api/`) - CakePHP 2.x, controllers in `web/api/app/Controller/`, JWT auth
|
|
- **Perl scripts** (`scripts/`) - Daemon control (`zmdc.pl`), migrations (`zmupdate.pl`), filtering (`zmfilter.pl`)
|
|
- **MySQL database** (`db/`) - Schema in `db/zm_create.sql.in`, migrations in `db/zm_update-*.sql` (60+ versions)
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
### Data Flow
|
|
|
|
```
|
|
Camera -> zmc (capture) -> Shared Memory -> zma (analysis) -> Event Recording
|
|
| |
|
|
zms (streaming) Database + Disk
|
|
| |
|
|
Web Browsers <- Web Interface/API <- MySQL Storage
|
|
```
|
|
|
|
### Key Patterns
|
|
|
|
- **Shared Memory**: `zmc` writes frames to `/dev/shm`; `zma` and `zms` read from same buffers. Zero-copy for performance — this is why ZM can handle many cameras on modest hardware.
|
|
- **Monitor-Centric**: `Monitor` class (`src/zm_monitor.cpp/h`) is the central orchestrator. One monitor = one DB row = one set of daemons. Most changes to camera handling flow through this class.
|
|
- **Pluggable Cameras**: Abstract `Camera` base with: `LocalCamera` (V4L2), `RemoteCameraHTTP`, `FFmpegCamera`, `LibVNCCamera`. Add new camera types by subclassing Camera.
|
|
- **Event-Driven Recording**: Motion detection triggers `Event` objects with pre/post alarm buffers. Lifecycle: Create -> Record -> Close -> Archive/Delete. Events are the core unit of recorded footage.
|
|
- **Multi-Server Clustering**: Database-coordinated distributed architecture with shared monitors and storage.
|
|
|
|
### Directory Structure (Key Paths)
|
|
|
|
```
|
|
src/ C++ core (86+ source files): zm_monitor.*, zm_camera.*, zm_event.*, zm_zone.*, zm_image.*, zm_ffmpeg*.*
|
|
web/ PHP web interface
|
|
ajax/ AJAX handlers
|
|
includes/ PHP libraries and functions
|
|
views/ UI templates
|
|
skins/ Themes (classic skin)
|
|
js/, css/ Frontend assets
|
|
api/app/Controller/ CakePHP REST API controllers
|
|
api/app/Model/ CakePHP REST API models
|
|
scripts/ Perl system management (.in templates)
|
|
db/ Schema (zm_create.sql.in) and migrations (zm_update-*.sql)
|
|
tests/ Catch2 unit tests + test data
|
|
misc/ Server configs (apache, nginx, systemd)
|
|
dep/ Vendored deps (catch2, jwt-cpp)
|
|
.github/workflows/ CI/CD pipelines
|
|
```
|
|
|
|
---
|
|
|
|
## Development Workflow (MANDATORY)
|
|
|
|
### For every feature or bug fix:
|
|
|
|
1. **Create GitHub Issue**: `gh issue create --title "..." --label enhancement|bug`
|
|
2. **Create Feature Branch**: `git checkout -b <issue>-<description>` from master
|
|
3. **Write failing test first** (TDD)
|
|
4. **Implement** - follow existing patterns, keep changes minimal
|
|
5. **Build & test** - must all pass (see Build and Testing sections)
|
|
6. **Commit** in logical chunks with conventional messages
|
|
7. **Request user approval** - never merge without it
|
|
8. **After approval**: merge to master, delete branch, push, verify issue closes
|
|
|
|
### Technology-Specific Notes
|
|
|
|
- **C++ changes** (`src/`): Rebuild required, run ctest. Daemons must be restarted to pick up changes.
|
|
- **PHP/JS changes** (`web/`): No rebuild needed — PHP is interpreted, changes are live immediately. Test in browser + ESLint.
|
|
- **Database schema** (`db/`): Create migration file `zm_update-X.X.X.sql` for existing installs, also update `db/zm_create.sql.in` for fresh installs. Both must result in the same schema.
|
|
- **Perl scripts** (`scripts/`): Edit `.in` template files (NOT generated scripts). cmake substitutes `@ZM_*@` variables to produce the final scripts. When testing perl changes, any perl script will try to read /etc/zm/zm.conf and needs to be run as a user with permission to read it. Best to run with sudo -u www-data
|
|
- **API changes** (`web/api/`): Clear CakePHP cache (`tmp/cache/`) if you change models or routes. Test endpoints with curl.
|
|
|
|
### Example Workflow
|
|
|
|
```bash
|
|
gh issue create --title "Add event favorites" --label enhancement
|
|
# Note issue number, e.g. #42
|
|
git checkout master && git pull && git checkout -b 42-event-favorites
|
|
|
|
# Write test first, implement, build & test
|
|
cd build && cmake --build . && ctest
|
|
npx eslint .
|
|
|
|
# Commit
|
|
git add <files>
|
|
git commit -m "feat: add favorites toggle to event view refs #42"
|
|
|
|
# Ask user for approval, then after approval:
|
|
git checkout master && git merge 42-event-favorites
|
|
git push origin master
|
|
git branch -d 42-event-favorites && git push origin --delete 42-event-favorites
|
|
```
|
|
|
|
---
|
|
|
|
## Build System
|
|
|
|
```bash
|
|
# Standard build (out-of-source required)
|
|
mkdir build && cd build
|
|
cmake ..
|
|
cmake --build .
|
|
|
|
# Debug build with tests
|
|
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TEST_SUITE=ON ..
|
|
cmake --build .
|
|
|
|
# Build specific target
|
|
cmake --build . --target zmc
|
|
```
|
|
|
|
### Key CMake Options
|
|
|
|
| Option | Values | Default | Notes |
|
|
|--------|--------|---------|-------|
|
|
| `CMAKE_BUILD_TYPE` | Release/Debug/Optimised/Profile | Release | `Profile` = `-O2 -g -fno-omit-frame-pointer` for perf/flamegraph |
|
|
| `BUILD_TEST_SUITE` | ON/OFF | OFF | Enables Catch2 tests |
|
|
| `ENABLE_WERROR` | ON/OFF | OFF | Warnings as errors (CI uses ON) |
|
|
| `ASAN` | ON/OFF | OFF | AddressSanitizer |
|
|
| `TSAN` | ON/OFF | OFF | ThreadSanitizer (mutually exclusive with ASAN) |
|
|
| `ZM_CRYPTO_BACKEND` | openssl/gnutls | | |
|
|
| `ZM_JWT_BACKEND` | libjwt/jwt_cpp | | |
|
|
| `ZM_TARGET_DISTRO` | FreeBSD/fc/el/OS13 | (Debian) | Platform-specific paths |
|
|
| `ZM_ONVIF` | ON/OFF | ON | ONVIF camera support |
|
|
|
|
---
|
|
|
|
## Testing Requirements (MANDATORY)
|
|
|
|
### Workflow
|
|
|
|
1. Write a failing test that reproduces the issue or validates the feature
|
|
2. Implement the fix/feature
|
|
3. Run tests - verify they PASS
|
|
4. Run full test suite for regressions
|
|
5. Only then commit
|
|
|
|
### C++ Unit Tests (Catch2)
|
|
|
|
```bash
|
|
# Build with tests
|
|
cmake -DBUILD_TEST_SUITE=ON .. && cmake --build .
|
|
|
|
# Run all tests
|
|
ctest
|
|
# Or directly with more output
|
|
./tests/tests
|
|
|
|
# Run specific test / list tests
|
|
./tests/tests "[Box]"
|
|
./tests/tests --list-tests
|
|
./tests/tests "~[notCI]"
|
|
```
|
|
|
|
**Test location**: `tests/` directory
|
|
**Existing modules**: `zm_box.cpp`, `zm_comms.cpp`, `zm_crypt.cpp`, `zm_font.cpp`, `zm_poly.cpp`, `zm_utils.cpp`, `zm_vector2.cpp`
|
|
**Framework**: Catch2 with custom header `tests/zm_catch2.h`, main in `tests/main.cpp`
|
|
**Test data**: `tests/data/fonts/`
|
|
|
|
### JavaScript Linting
|
|
|
|
```bash
|
|
npx eslint . # Lint all
|
|
npx eslint --fix web/js/ # Auto-fix
|
|
```
|
|
|
|
ESLint config: `eslint.config.js` (ESLint 9 flat config, Google style guide). Runs in CI via `.github/workflows/ci-eslint.yml`.
|
|
|
|
### PHP/API Testing
|
|
|
|
Manual testing required. Test endpoints with curl/browser. Verify JSON responses, auth (session + JWT), error handling, DB persistence.
|
|
|
|
### Database Migration Testing
|
|
|
|
```bash
|
|
sudo zmupdate.pl --check # Check for updates
|
|
sudo zmupdate.pl # Apply migrations
|
|
```
|
|
|
|
When creating migrations: test upgrade path AND verify fresh install matches migrated schema.
|
|
|
|
### CI Notes
|
|
|
|
- Unit tests are **DISABLED** in CI (`BUILD_TEST_SUITE=0`) — some tests need hardware/network access. Running locally goes beyond CI requirements but is still expected for local development.
|
|
- CI does: multi-platform builds (Debian/Ubuntu/CentOS with GnuTLS/OpenSSL + libjwt/jwt_cpp matrix), ESLint, CodeQL security scanning
|
|
|
|
---
|
|
|
|
## Code Standards
|
|
|
|
### C++ (`src/`)
|
|
|
|
- **C++17** standard, follow existing patterns in file/module
|
|
- **Memory**: RAII, smart pointers where appropriate
|
|
- **Error handling**: Exceptions for exceptional cases, return codes for expected errors
|
|
- **Logging**: Use printf-style `Debug(1, "msg %s", val)`, `Info(...)`, `Warning(...)`, `Error(...)`, `Fatal(...)` — NOT iostream style. The number in Debug() is verbosity level (1-9).
|
|
|
|
### PHP (`web/`, `web/api/`)
|
|
|
|
- PSR-12 where practical, follow existing conventions
|
|
- **Security**: Validate ALL user input, use prepared statements (NOT string interpolation — legacy code has SQL injection bugs we're fixing), sanitize output with htmlspecialchars/json_encode, CSRF protection on forms
|
|
- CakePHP 2.x framework in `web/api/` — we're stuck on 2.x due to migration cost, don't try to upgrade it
|
|
|
|
### JavaScript (`web/js/`, inline in PHP)
|
|
|
|
- Google JavaScript Style Guide (ESLint configured)
|
|
- jQuery + Bootstrap (legacy codebase), ES6+ where browser support allows
|
|
|
|
### Perl (`scripts/`)
|
|
|
|
- Edit `.in` template files, NOT generated scripts — cmake substitutes variables like `@ZM_LOGDIR@` to produce the final scripts
|
|
- Use `ZoneMinder::` modules, `ZoneMinder::Logger` for logging
|
|
- Rerun cmake after editing `.in` files to regenerate the actual scripts
|
|
|
|
---
|
|
|
|
## Commit Standards
|
|
|
|
**Conventional format** with issue references:
|
|
|
|
```
|
|
feat|fix|test|docs|chore|refactor|perf|style: description refs #N
|
|
```
|
|
|
|
- `refs #N` references issue; `fixes #N` closes it
|
|
- Imperative mood ("add feature" not "added feature")
|
|
- Be detailed and descriptive, no vague summaries
|
|
- One logical change per commit
|
|
- **No superlative language** ("comprehensive", "critical", "major", "massive") — AI agents tend to use these; they make commit logs unreadable
|
|
- Split unrelated changes into separate commits — makes bisecting and reverting possible
|
|
|
|
---
|
|
|
|
## Pre-Commit Checklist (Single Source of Truth)
|
|
|
|
Before committing or claiming complete:
|
|
|
|
- [ ] Tests written/updated BEFORE or DURING implementation
|
|
- [ ] Build succeeds: `cmake --build .` (C++ changes)
|
|
- [ ] C++ tests pass: `ctest` or `./tests/tests`
|
|
- [ ] JavaScript linting passes: `npx eslint .`
|
|
- [ ] Manual testing done (PHP/web changes)
|
|
- [ ] No compiler warnings or linter errors
|
|
- [ ] Code follows existing patterns
|
|
- [ ] Commit messages follow conventional format with issue reference
|
|
- [ ] Feature is COMPLETE (not half-implemented)
|
|
- [ ] State which tests were run and their results
|
|
|
|
**NEVER commit if**: tests failing, tests missing for new code, build fails, warnings exist, feature incomplete.
|
|
|
|
---
|
|
|
|
## Debugging Quick Reference
|
|
|
|
```bash
|
|
# Debug build
|
|
cmake -DCMAKE_BUILD_TYPE=Debug .. && cmake --build .
|
|
|
|
# AddressSanitizer
|
|
cmake -DCMAKE_BUILD_TYPE=Debug -DASAN=ON .. && cmake --build .
|
|
|
|
# Debug logging
|
|
export ZM_DBG_LEVEL=9 ZM_DBG_LOG=/tmp/debug.log
|
|
./src/zmc -m 1
|
|
|
|
# Log locations: /var/log/zm/ (zmc_m1.log, zma_m2.log, etc.)
|
|
# Runtime log level: kill -USR1 <pid> (increase) / kill -USR2 <pid> (decrease)
|
|
```
|
|
|
|
---
|
|
|
|
## Contributing (For Humans)
|
|
|
|
- **Bug reports & features**: [GitHub Issues](https://github.com/ZoneMinder/zoneminder/issues) (read [posting rules](https://github.com/ZoneMinder/ZoneMinder/wiki/Github-Posting-Rules) first)
|
|
- **Support**: [Forums](https://forums.zoneminder.com), [Slack](https://zoneminder-chat.slack.com), [Discord](https://discord.gg/tHYyP9k66q)
|
|
- **PRs**: Fork -> feature branch -> implement + test -> PR. Maintainers merge after review.
|
|
- **Docs**: https://zoneminder.readthedocs.org (source in `docs/`)
|
|
|
|
---
|
|
|
|
## grepai - Semantic Code Search
|
|
|
|
**Use grepai as PRIMARY tool for code exploration and search.**
|
|
|
|
### When to Use grepai (REQUIRED)
|
|
|
|
Use `grepai search` INSTEAD OF Grep/Glob for:
|
|
- Understanding what code does or where functionality lives
|
|
- Finding implementations by intent ("authentication logic", "error handling")
|
|
- Exploring unfamiliar parts of the codebase
|
|
|
|
Only use Grep/Glob for exact text matching (variable names, imports, specific strings) or file path patterns.
|
|
|
|
If grepai fails (not running, index unavailable), fall back to Grep/Glob.
|
|
|
|
### Usage
|
|
|
|
```bash
|
|
grepai search "user authentication flow" --json --compact
|
|
grepai search "JWT token validation" --json --compact
|
|
```
|
|
|
|
### Call Graph Tracing
|
|
|
|
```bash
|
|
grepai trace callers "HandleRequest" --json
|
|
grepai trace callees "ProcessOrder" --json
|
|
grepai trace graph "ValidateToken" --depth 3 --json
|
|
```
|
|
|
|
### Workflow
|
|
|
|
1. `grepai search` to find relevant code
|
|
2. `grepai trace` to understand function relationships
|
|
3. `Read` tool to examine files from results
|
|
4. Grep only for exact string searches if needed
|