At the beginning of each coding session, before making any code changes, you MUST build a comprehensive understanding
of the codebase by invoking the /explore-codebase skill.
Before writing, modifying, or reviewing any code or documentation, you MUST invoke the appropriate skill to load Ataraxis framework conventions. This applies to ALL file types:
| Task | Skill to invoke |
|---|---|
| Writing or modifying Python code | /python-style |
| Writing or modifying README files | /readme-style |
| Writing or modifying pyproject.toml | /pyproject-style |
| Writing or modifying tox.ini files | /tox-config |
| Writing or modifying Sphinx docs files | /api-docs |
| Writing or modifying skill files | /skill-design |
| Creating or verifying project structure | /project-layout |
| Committing local changes | /commit |
This is non-negotiable. Each skill carries a verification checklist that you MUST complete before submitting any work.
Ataraxis framework projects often depend on other ataraxis-* or sollertia-* libraries. These libraries may be
stored locally in the same parent directory as this project, reachable as ../ from the repository root.
Before writing code that interacts with a cross-referenced library, you MUST:
-
Check for local version: Look for the library in the parent directory (e.g.,
../ataraxis-time/,../ataraxis-base-utilities/). -
Compare versions: If a local copy exists, compare its version against the latest release or main branch on GitHub:
- Read the local
pyproject.tomlto get the current version - Use
gh api repos/Sun-Lab-NBB/{repo-name}/releases/latestto check the latest release - Alternatively, check the main branch version on GitHub
- Read the local
-
Handle version mismatches: If the local version differs from the latest release or main branch, notify the user with the following options:
- Use online version: Fetch documentation and API details from the GitHub repository
- Update local copy: The user will pull the latest changes locally before proceeding
-
Proceed with correct source: Use whichever version the user selects as the authoritative reference for API usage, patterns, and documentation.
Why this matters: Skills and documentation may reference outdated APIs. Always verify against the actual library state to prevent integration errors.
Skills are distributed through the ataraxis marketplace and are loaded into Claude Code via the plugin system. They are not stored in this repository.
| Skill | Description |
|---|---|
/camera-setup |
Discovers and tests cameras over MCP, and guides encoding and GenICam configuration |
/camera-interface |
Documents VideoSystem API usage, constructor parameters, and encoding guidance |
/video-mcp-environment-setup |
Diagnoses MCP server connectivity and verifies the environment |
/cli-reference |
Documents every axvs command, option, and failure mode |
/post-recording |
Verifies recordings through log assembly, video validation, and handoff |
/pipeline |
Orchestrates the end-to-end pipeline and multi-camera planning |
/log-input-format |
Documents the NPZ archive format, source IDs, and DataLogger output |
/log-processing |
Orchestrates the log archive processing workflow via MCP tools |
/log-processing-results |
Documents output data formats and frame statistics analysis |
| Skill | Description |
|---|---|
/explore-codebase |
Performs in-depth codebase exploration at session start |
/explore-dependencies |
Explores installed ataraxis dependency APIs for reuse opportunities |
/audit-correctness |
Audits source code for bugs, edge cases, races, and leaks |
/audit-facts |
Audits documentation for factual accuracy against source code |
/audit-performance |
Audits source code for cost, speed, memory use, and dtype predictability |
/audit-project |
Orchestrates the four audits and merges their findings into one report |
/audit-style |
Audits files for style and convention compliance |
/python-style |
Applies Ataraxis framework Python coding conventions (REQUIRED for code changes) |
/readme-style |
Applies Ataraxis framework README conventions |
/pyproject-style |
Applies Ataraxis framework pyproject.toml conventions |
/tox-config |
Applies Ataraxis framework tox.ini conventions |
/api-docs |
Applies Ataraxis framework Sphinx API documentation conventions |
/skill-design |
Generates and verifies Claude Code skill files |
/project-layout |
Applies Ataraxis framework project directory structure conventions |
/commit |
Drafts Ataraxis framework style-compliant git commit messages |
/pr |
Drafts Ataraxis framework style-compliant pull request summaries |
/release |
Drafts Ataraxis framework style-compliant release notes |
This library provides an MCP server (axvs mcp) that exposes camera discovery, configuration, video recording,
manifest management, and log data processing tools. When working with this project or its dependencies, prefer using
available MCP tools over direct code execution when appropriate.
Guidelines for MCP usage:
-
Prefer MCP for runtime operations: For operations like camera discovery, CTI file management, GenICam configuration, and log processing batch workflows, use MCP tools rather than writing and executing Python code directly.
-
Use MCP for cross-library operations: When dependency libraries (e.g.,
ataraxis-data-structures,ataraxis-time) provide MCP servers, explore and use their tools for interacting with those libraries.
The library source code, tests, CLI, and MCP server implementation live in this repository (ataraxis-video-system) and
are distributed via PyPI. Claude Code skills and MCP server registration are distributed separately through the
ataraxis marketplace as plugins:
- video plugin (
ataraxis/plugins/video/): Registers theaxvs mcpserver with compatible MCP clients and provides video-specific skills for camera setup, pipeline orchestration, log processing, and post-recording verification. - automation plugin (
ataraxis/plugins/automation/): Provides shared development skills that enforce Ataraxis framework coding conventions (Python style, README style, commit messages, pyproject.toml, tox configuration) and general-purpose codebase exploration tools.
When modifying skills, edit the SKILL.md files in the ataraxis marketplace repository. When modifying the MCP server implementation or library code, edit the source files in this repository.
This is ataraxis-video-system, a Python library that interfaces with a wide range of cameras to flexibly record visual stream data as video files. It supports OpenCV and GenICam (Harvesters) camera interfaces with FFMPEG-based video encoding using CPU or GPU.
| Directory | Purpose |
|---|---|
src/ataraxis_video_system/ |
Main library source code |
src/.../video/ |
Camera interfaces, VideoSystem multiprocessing, FFMPEG encoding, GenICam configuration, manifests, and timestamps |
src/.../orchestration/ |
Job identity and layout, core and memory allocation, discovery and sizing, the job runner, and both execution paths |
src/.../interfaces/ |
Click-based axvs CLI, the MCP server instance and its tools, and the shared response machinery |
tests/ |
Test suite mirroring the video, orchestration, and interfaces subpackages |
docs/ |
Sphinx API documentation source |
- VideoSystem: Producer-consumer multiprocessing pattern. Constructor requires
system_id,data_logger,name, andoutput_directoryas positional arguments.__init__writes a camera manifest entry associating the system_id with the human-readable name. A producer process acquires frames from the camera interface and pushes them to a queue. A consumer process pops frames and streams raw bytes to FFMPEG via stdin. A 4-element SharedMemoryArray controls termination and frame-saving toggles via IPC. - GenICam Platform Support:
harvestersandgenicamcarry asys_platform != 'darwin' or (python_version < '3.14' and platform_machine == 'arm64')marker, becausegenicampublishes a macOS wheel only for Apple Silicon on Python 3.12 and 3.13. Intel Macs and Macs on Python 3.14 therefore support no GenICam interface.camera.pymirrors that marker in_GENICAM_RUNTIME_CLAIMED, which selects the wording ofGENICAM_UNAVAILABLE_REASON, and a guardedtry/except ImportErrorkeeps the module usable for the OpenCV and Mock interfaces there._require_genicam_runtime()aborts every GenICam hardware entry point, and discovery reports the interface absent. - Camera Interfaces: Three implementations behind a unified API: OpenCVCamera (cv2.VideoCapture),
HarvestersCamera (GenICam/Harvesters with NodeMap access), and MockCamera (synthetic frames for testing).
discover_camera_ids()returns CameraInformation objects from all available interfaces. - VideoSaver: Manages an FFMPEG subprocess (Popen with stdin=PIPE). A daemon thread drains stderr continuously to prevent pipe buffer deadlocks. Supports CPU (libx264/libx265) and GPU (h264_nvenc/hevc_nvenc) encoders.
- GenICam Configuration: Iterative stack-based NodeMap traversal collects ReadWrite leaf nodes. Configurations
serialize to YAML via GenicamConfiguration dataclass with camera identity metadata for validation on load.
read_camera_configuration()is the library root's entry point for external callers, andHarvestersCameraandharvester_connectionstayvideopackage exports that the CLI and the MCP tools consume. - Camera Manifest:
CameraManifest(YamlConfig subclass) associates source IDs with human-readable camera names in acamera_manifest.yamlfile alongside DataLogger archives.CameraSourceDatastores per-camera entries.write_camera_manifest()creates or updates the manifest. Used by log processing discovery to identify which archives were produced by ataraxis-video-system and to route processing by source ID. - Log Processing: Extracts frame acquisition timestamps from DataLogger
.npzarchives, one job per archive, into Feather files under acamera_timestamps/directory.resolve_jobs()reads the recording manifest,prepare_jobs()registers the resolved jobs without reading an archive, andsize_job()resolves a job's width and memory from one archive read.prepare_jobs()rejects a tree holding nocamera_manifest.yamlwhateverstrict_sourcesis set to, because the absent manifest is a property of the directory rather than of a requested source.run_log_processing_pipeline()runs one recording sequentially, or one job by canonical identifier. - MCP Server: A shared
MCPServerinstance (name="ataraxis-video-system") ininterfaces/mcp_instance.pybacks the tools in theinterfaces/*_tools.pymodules, and session globals ininterfaces/session_tools.pyenforce one active VideoSystem session. Batch log processing sizes each job withsize_job()and admits what the core and memory budgets fit, running an oversized job alone. A batch session is live while its manager thread runs, so the ending thread frees the single session slot andfinish_execution_session()waits for that and reports whether the slot is free through the cancellation'ssession_endedflag. The ataraxis video plugin registers the server with MCP clients. - CLI: Click command groups (
cti,check,configure) withrunfor interactive sessions,processfor log data processing, andmcpfor starting the MCP server. CLI uses system_id 111, MCP uses 112. The_report_command_failuredecorator reports a failed command's message atLogLevel.ERRORand exits zero.
- Multiprocessing Spawn:
mp.set_start_method("spawn")is set globally in__init__.pyfor cross-platform consistency. The VideoSystem's producer and consumer processes are daemon processes requiring explicitstop()calls, while the log processing pools spawn non-daemon workers that their owners shut down explicitly. - FFMPEG Stderr Draining: A dedicated thread reads FFMPEG's stderr continuously. Without this, the pipe buffer fills and blocks FFMPEG, deadlocking the encoding pipeline.
- Camera Reconnection: Cameras connect/disconnect during VideoSystem
__init__()to validate parameters. The producer process reconnects the camera independently (fresh connection per process). - SharedMemoryArray IPC: A 4-element uint8 array controls process lifecycle: index 0 = termination flag, index 1 = frame saving toggle, indices 2-3 = process initialization handshake signals.
- CTI File Persistence: The GenTL Producer path is stored in
platformdirs.user_data_dirascti_path.txt, persisting across runtimes. - Manifest-Based Log Discovery:
camera_manifest.yamlfiles tag DataLogger output directories with source-to-name mappings. Log processing discovery and batch preparation use manifests to identify which archives were produced by ataraxis-video-system and to route jobs by source ID. - Frame Display: Runs on a separate thread with its own Queue (decoupled from saver). Automatically disabled on macOS due to main-thread GUI restrictions.
- MyPy strict mode with full type annotations
- Google-style docstrings
- 120 character line limit
- Ruff for formatting and linting
- Python 3.12, 3.13, 3.14 support
- See style skills for complete conventions
Modifying VideoSystem:
- Review
src/ataraxis_video_system/video/video_system.pyfor current implementation - Static methods
_frame_production_loop()and_frame_saving_loop()run in separate processes - Test with actual camera hardware or MockCamera interface
Modifying camera interfaces:
- Review
src/ataraxis_video_system/video/camera.pyfor all three implementations - OpenCVCamera and HarvestersCamera share a common interface pattern (connect, grab, disconnect)
- CTI file management functions (
add_cti_file,check_cti_file) use platformdirs for persistence - Camera discovery must handle both OpenCV and Harvesters gracefully when hardware is unavailable
- Release the acquirer and the Harvester independently in
disconnect(), since a failedconnect()leaves a Harvester holding the GenTL Producer and stranding it hides every camera for the rest of the process
Modifying FFMPEG encoding:
- Review
src/ataraxis_video_system/video/saver.pyfor the VideoSaver class - Encoder command construction happens in
__init__()based on VideoEncoders enum selection - CPU presets (veryfast-veryslow) map to GPU p1-p7 equivalents
- The stderr drain thread is critical and must not be removed
Modifying GenICam configuration:
- Review
src/ataraxis_video_system/video/configuration.pyfor node traversal and serialization - Node enumeration uses iterative stack-based traversal, because a deep node tree overflows a recursive walk
- GenicamConfiguration is a YamlConfig subclass supporting
to_yaml()andfrom_yaml() - Strict identity checking compares camera model and serial number against YAML metadata
Adding or modifying CLI commands:
- Review
src/ataraxis_video_system/interfaces/cli.pyfor existing Click group structure - Use
console.echo()for output andconsole.error()for error handling
Modifying camera manifests:
- Review
src/ataraxis_video_system/video/manifest.pyfor data classes and writer CameraManifestextendsYamlConfigfromataraxis-data-structuresfor YAML serializationCameraSourceDatais a frozen dataclass storingid(int) andname(str)- Manifests are consumed by
discover_camera_data_toolin the MCP server for log processing discovery
Modifying log processing:
- Review
orchestration/discovery.pyfor resolution, preparation, and sizing,orchestration/worker.pyfor the single-job runner, andvideo/timestamps.pyfor the extraction algorithm extract_logged_camera_timestamps()reads.npzarchives viaLogArchiveReaderand returnsNDArray[np.uint64]ProcessingTrackermanages job lifecycle (SCHEDULED → RUNNING → SUCCEEDED/FAILED) via YAML state files_process_frame_message_batch()runs at the dispatch width of its job, in the pool workers thatextract_logged_camera_timestamps()opens
Adding or modifying MCP tools:
- Review the
interfaces/*_tools.pymodules for tool patterns (interfaces/mcp_instance.pyholds themcpinstance) - Enforce single-session constraint via
_active_sessionglobal state check - Log processing execution uses
JobExecutionState(from..orchestration) with core and memory budgets - Most tools return
dict[str, Any]structured data, and some return strings