From 23d40bc55a1ff3dc70c8b05ae899091dcc856054 Mon Sep 17 00:00:00 2001 From: Inkaros Date: Tue, 16 Jun 2026 19:20:43 -0400 Subject: [PATCH 1/7] Updated plugin skill documentation to match current library source. -- Updated stale version references and checklist floors in the microcontroller-interface, firmware-module, camera-interface, and tox-config skills to current releases. -- Corrected MCP entry-point module paths to the interfaces subpackage (axci/axvs) in the communication and video environment-setup skills. -- Updated relocated source-file paths (microcontroller/interface.py, communication/mqtt.py, video/video_system.py) after package restructuring. -- Fixed video archive, feather, and frame filename and dtype documentation (uint64 onset, unpadded source IDs) and resolved related internal contradictions. -- Corrected the video log-processing worker-allocation model, the parallel-processing threshold, and the discovery-tool capabilities described in the post-recording workflow. -- Updated assorted skill facts: GenICam blacklisted_nodes, FFMPEG n8.1, plugin.json MCP registration, tool.coverage.run ordering, C++ archetype CLAUDE.md, and skill cross-references. --- plugins/automation/skills/api-docs/SKILL.md | 5 ++-- plugins/automation/skills/cpp-style/SKILL.md | 2 +- .../skills/explore-codebase/SKILL.md | 4 +-- .../references/archetype-trees.md | 2 ++ .../skills/pyproject-style/SKILL.md | 4 +++ .../automation/skills/skill-design/SKILL.md | 18 ++++++------- plugins/automation/skills/tox-config/SKILL.md | 7 ++--- .../SKILL.md | 2 +- .../skills/extraction-configuration/SKILL.md | 7 ++++- .../skills/log-input-format/SKILL.md | 15 +++++++++-- .../skills/log-processing-results/SKILL.md | 4 +-- .../skills/log-processing/SKILL.md | 19 +++++++------- .../skills/microcontroller-interface/SKILL.md | 8 +++--- .../skills/firmware-module/SKILL.md | 4 +-- .../references/api-reference.md | 2 +- .../video/skills/camera-interface/SKILL.md | 6 ++--- plugins/video/skills/camera-setup/SKILL.md | 26 ++++++++++++------- .../video/skills/log-input-format/SKILL.md | 6 ++--- .../skills/log-processing-results/SKILL.md | 6 ++--- plugins/video/skills/log-processing/SKILL.md | 22 ++++++++-------- plugins/video/skills/pipeline/SKILL.md | 6 ++--- plugins/video/skills/post-recording/SKILL.md | 20 +++++++++----- .../video-mcp-environment-setup/SKILL.md | 9 ++++--- 23 files changed, 121 insertions(+), 83 deletions(-) diff --git a/plugins/automation/skills/api-docs/SKILL.md b/plugins/automation/skills/api-docs/SKILL.md index 5a9cf20..43bf261 100644 --- a/plugins/automation/skills/api-docs/SKILL.md +++ b/plugins/automation/skills/api-docs/SKILL.md @@ -57,7 +57,7 @@ layout within each project is: ```text project-root/ ├── docs/ -│ ├── Makefile # Unix Sphinx wrapper (delegates to tox) +│ ├── Makefile # Minimal Sphinx wrapper (builds usually run via tox) │ ├── make.bat # Windows Sphinx wrapper │ └── source/ │ ├── conf.py # Sphinx configuration @@ -181,7 +181,8 @@ dependencies directly to downstream project pyproject.toml files. mypy (`docs/` is excluded), so the `copyright` builtin shadow needs no suppression. See `/python-style` for the framework-wide policy on IDE directives. - The `templates_path` and `exclude_patterns` fields are included but left at defaults - (`['_templates']` and `[]` respectively). + (`['_templates']` and `[]` respectively) for Python-only and hybrid archetypes. The C++-only + archetype omits both fields entirely (it uses a minimal breathe-only conf.py). - Napoleon is configured for Google-style docstrings only (`napoleon_numpy_docstring = False`). - All Napoleon and `sphinx_autodoc_typehints` settings MUST match the templates exactly. See [conf-py-templates.md](references/conf-py-templates.md) for the full settings. diff --git a/plugins/automation/skills/cpp-style/SKILL.md b/plugins/automation/skills/cpp-style/SKILL.md index 6b80cf0..c765773 100644 --- a/plugins/automation/skills/cpp-style/SKILL.md +++ b/plugins/automation/skills/cpp-style/SKILL.md @@ -230,7 +230,7 @@ and boolean returns: ```cpp bool RunActiveCommand() override { - switch (static_cast(GetActiveCommand())) + switch (static_cast(get_active_command())) { case kModuleCommands::kCheckState: CheckState(); return true; default: return false; diff --git a/plugins/automation/skills/explore-codebase/SKILL.md b/plugins/automation/skills/explore-codebase/SKILL.md index 1303e86..ac808e1 100644 --- a/plugins/automation/skills/explore-codebase/SKILL.md +++ b/plugins/automation/skills/explore-codebase/SKILL.md @@ -62,8 +62,8 @@ many files. **Large projects:** Launch 2-3 Explore subagents in parallel using the Task tool with `subagent_type: Explore`. Assign each subagent a different focus area: -- **Subagent 1: Structure and entry points** — Phase 1 (feature discovery) and Phase 4 - (configuration and test coverage) +- **Subagent 1: Structure and entry points** — Phase 1 (feature discovery, including configuration) + and Phase 4 (test coverage and implementation details) - **Subagent 2: Architecture and dependencies** — Phase 2 (code flow tracing) and Phase 3 (architecture analysis including import mapping and central component identification) - **Subagent 3: API surface and quality** — Public API enumeration, error handling patterns, diff --git a/plugins/automation/skills/project-layout/references/archetype-trees.md b/plugins/automation/skills/project-layout/references/archetype-trees.md index d6c1e9c..148fb44 100644 --- a/plugins/automation/skills/project-layout/references/archetype-trees.md +++ b/plugins/automation/skills/project-layout/references/archetype-trees.md @@ -158,6 +158,7 @@ project-root/ ├── .clang-format # C++ formatting configuration ├── .clang-tidy # C++ linting configuration ├── .gitignore +├── CLAUDE.md # Claude Code project instructions ├── Doxyfile # Doxygen documentation configuration ├── library.json # PlatformIO library manifest ├── LICENSE # GPL-3.0 license @@ -201,6 +202,7 @@ project-root/ ├── .clang-format # C++ formatting configuration ├── .clang-tidy # C++ linting configuration ├── .gitignore +├── CLAUDE.md # Claude Code project instructions ├── Doxyfile # Doxygen documentation configuration ├── LICENSE # GPL-3.0 license ├── platformio.ini # PlatformIO build configuration diff --git a/plugins/automation/skills/pyproject-style/SKILL.md b/plugins/automation/skills/pyproject-style/SKILL.md index bef574e..79ca106 100644 --- a/plugins/automation/skills/pyproject-style/SKILL.md +++ b/plugins/automation/skills/pyproject-style/SKILL.md @@ -94,6 +94,10 @@ projects. 11. `[tool.coverage.html]` 12. `[tool.coverage.report]` +When present, `[tool.coverage.run]` is placed either before `[tool.coverage.paths]` (e.g. for a +coverage `omit` list) or after `[tool.coverage.report]` (e.g. for `parallel` / `concurrency` +settings). + For C-extension projects using scikit-build-core, replace the hatch build targets with `[tool.scikit-build]` and `[tool.cibuildwheel]` sections at positions 6-7. diff --git a/plugins/automation/skills/skill-design/SKILL.md b/plugins/automation/skills/skill-design/SKILL.md index 015e69a..5a12768 100644 --- a/plugins/automation/skills/skill-design/SKILL.md +++ b/plugins/automation/skills/skill-design/SKILL.md @@ -388,15 +388,15 @@ CLAUDE.md follows the same conventions as skill files with one difference: ## Related skills -| Skill | Relationship | -|---------------------|----------------------------------------------------------------------| -| `/python-style` | Provides formatting conventions that skill files must also follow | -| `/cpp-style` | Provides C++ conventions relevant when skills reference C++ code | -| `/csharp-style` | Provides C# conventions relevant when skills reference C# code | -| `/project-layout` | Provides project directory conventions; owns `skills/` placement | -| `/readme-style` | Provides README conventions relevant when skills reference READMEs | -| `/commit` | Should be invoked after completing skill file changes | -| `/explore-codebase` | Provides project context needed when writing project-specific skills | +| Skill | Relationship | +|---------------------|----------------------------------------------------------------------------------| +| `/python-style` | Provides formatting conventions that skill files must also follow | +| `/cpp-style` | Provides C++ conventions relevant when skills reference C++ code | +| `/csharp-style` | Provides C# conventions relevant when skills reference C# code | +| `/project-layout` | Provides general project directory conventions; this skill owns `skills/` layout | +| `/readme-style` | Provides README conventions relevant when skills reference READMEs | +| `/commit` | Should be invoked after completing skill file changes | +| `/explore-codebase` | Provides project context needed when writing project-specific skills | --- diff --git a/plugins/automation/skills/tox-config/SKILL.md b/plugins/automation/skills/tox-config/SKILL.md index f0c6431..066b83a 100644 --- a/plugins/automation/skills/tox-config/SKILL.md +++ b/plugins/automation/skills/tox-config/SKILL.md @@ -70,7 +70,7 @@ Collect the project-specific values: |--------------------|---------------------------------------|---------------------------| | `{package_name}` | Package directory name under `src/` | `ataraxis_base_utilities` | | `{env_abbr}` | Short project abbreviation | `axbu` | -| `{version}` | Current ataraxis-automation release | `7.1.0` | +| `{version}` | Current ataraxis-automation release | `8.1.1` | | Python versions | `requires-python` in `pyproject.toml` | `py312, py313, py314` | | `basepython` | Earliest supported Python version | `py312` | | `--python-version` | Latest supported Python version | `3.14` | @@ -191,7 +191,7 @@ with a pinned ataraxis-automation version: ```ini [testenv:coverage] skip_install = true -deps = ataraxis-automation==7.1.0 +deps = ataraxis-automation==8.1.1 ``` This pattern applies to: `coverage`, `docs`, `build`, `upload`, `install`, `uninstall`, `create`, @@ -265,7 +265,8 @@ envlist = docs ### stubs - `depends = lint` — stubs are generated only after linting passes. -- Runs `stubgen` with `--include-private` and `-p {package_name}`. +- Runs `automation-cli process-typed-markers` first, then `stubgen -o stubs --include-private -p + {package_name} -v`, followed by `automation-cli process-stubs`. - After stub generation: `ruff format` → `ruff check --select I --fix ./src` to clean up stubs. ### test diff --git a/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md b/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md index 456a71a..26fd740 100644 --- a/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md +++ b/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md @@ -38,7 +38,7 @@ defined in `pyproject.toml`: ```toml [project.scripts] -axci = "ataraxis_communication_interface.cli:axci_cli" +axci = "ataraxis_communication_interface.interfaces.cli:axci_cli" ``` | Server | CLI command | Purpose | diff --git a/plugins/communication/skills/extraction-configuration/SKILL.md b/plugins/communication/skills/extraction-configuration/SKILL.md index 93a699d..239617f 100644 --- a/plugins/communication/skills/extraction-configuration/SKILL.md +++ b/plugins/communication/skills/extraction-configuration/SKILL.md @@ -164,7 +164,7 @@ instance. (e.g., encoder position updates, sensor readings, command completion signals) - **Kernel event codes** correspond to system-level messages (e.g., controller status, error reports, keepalive signals) -- Event codes above 50 are user-defined module events; codes 1-50 are reserved for system service messages +- Event codes above 50 are user-defined module events; codes 0-50 are reserved for system service messages The agent CANNOT determine which event codes to use by inspecting the codebase. Event codes are firmware-specific knowledge that must come from the user. @@ -188,6 +188,11 @@ module entries. Record the controller IDs, module types, and module IDs. Build the config structure with all controllers and modules from the manifest but with empty event codes. Present the structure to the user so they can see which controllers and modules are available. +No MCP tool exposes precursor generation, so the agent constructs the structure manually. A precursor +config can also be generated programmatically via `create_extraction_config(manifest_path)` or the +`axci config create` CLI command, which populate a controller entry for each registered controller with +empty event codes. + ### Step 4: Ask user for event codes For each module and (optionally) each kernel entry, ask the user which event codes to extract. Present diff --git a/plugins/communication/skills/log-input-format/SKILL.md b/plugins/communication/skills/log-input-format/SKILL.md index 576f6d2..0714cb6 100644 --- a/plugins/communication/skills/log-input-format/SKILL.md +++ b/plugins/communication/skills/log-input-format/SKILL.md @@ -201,12 +201,23 @@ and archives. The AXCI processing pipeline only processes archives referenced in ### Message format -Each entry in an `.npz` archive stores a serialized message as a byte array: +Each entry in an `.npz` archive stores a serialized message as a byte array. The shared DataLogger +container layout is: + +```text +[source_id: 1 byte][elapsed_us: 8 bytes (uint64)][payload: N bytes] +``` + +Everything after the source ID and timestamp is the opaque payload, whose structure is domain-specific +and must be parsed by the consumer. For AXCI data/state messages, the first payload byte is a `protocol` +byte that identifies the message type: ```text [source_id: 1 byte][elapsed_us: 8 bytes (uint64)][protocol: 1 byte][payload: N bytes] ``` +The onset message is the exception: its payload contains only the 8-byte timestamp and no protocol byte. + Archive keys follow the pattern `{source_id:03d}_{elapsed_us:020d}`, preserving the 3-digit zero-padded source ID and 20-digit zero-padded timestamp from the original `.npy` filenames. @@ -223,7 +234,7 @@ source ID and 20-digit zero-padded timestamp from the original `.npy` filenames. | Type | Identifier | Payload | Purpose | |-------|-------------------|----------------------------------------------|-----------------------------| -| Onset | `elapsed_us == 0` | 8 bytes: int64 UTC epoch microseconds | Absolute time reference | +| Onset | `elapsed_us == 0` | 8 bytes: uint64 UTC epoch microseconds | Absolute time reference | | Data | `elapsed_us > 0` | Protocol byte + command + event + typed data | Module/kernel data message | | State | `elapsed_us > 0` | Protocol byte + command + event | Module/kernel state message | diff --git a/plugins/communication/skills/log-processing-results/SKILL.md b/plugins/communication/skills/log-processing-results/SKILL.md index 4aa3fe8..6f10394 100644 --- a/plugins/communication/skills/log-processing-results/SKILL.md +++ b/plugins/communication/skills/log-processing-results/SKILL.md @@ -41,7 +41,7 @@ file discovery, schema reference, output verification, event analysis, and inter | Tool | Purpose | |---------------------------------------|-----------------------------------------------------------------------| -| `discover_microcontroller_data_tool` | Discovers manifests, log archives, and processed feather outputs | +| `discover_microcontroller_data_tool` | Discovers microcontroller manifests and confirmed log-archive sources | **Parameters:** @@ -72,7 +72,7 @@ files[]: Per-file verification results: columns: List of column names found type: "module", "kernel", or "unknown" (inferred from filename) total_files: Number of feather files found -output_directory: Absolute path to the microcontroller_data/ directory +output_directory: Absolute path to the output (parent) directory that was passed in (contains the microcontroller_data/ subdirectory) data_path: Absolute path to the microcontroller_data/ directory tracker: ProcessingTracker status summary (if tracker exists) ``` diff --git a/plugins/communication/skills/log-processing/SKILL.md b/plugins/communication/skills/log-processing/SKILL.md index ee983c7..b44beaf 100644 --- a/plugins/communication/skills/log-processing/SKILL.md +++ b/plugins/communication/skills/log-processing/SKILL.md @@ -245,8 +245,9 @@ probes each archive's message count and allocates workers using tier-based scali The system uses two layers of allocation: 1. **Per-job tier assignment** — each job is assigned a worker count based on its archive's message count - using a sqrt-derived formula (`ceil(sqrt(messages / 1,000))`), rounded to the nearest multiple of 5. - This determines the per-job worker tier: + using a sqrt-derived formula (`ceil(sqrt(messages / 1,000))`), rounded to the nearest multiple of 5 and + then floored to a minimum of 5 workers (`max(5, round(raw / 5) * 5)`) for any archive that exceeds the + parallel-processing threshold. This determines the per-job worker tier: | Archive Size | Worker Tier | Typical Scenario | |---------------|------------------|--------------------------------| @@ -310,13 +311,13 @@ To re-process an entire directory from scratch, call `clean_log_processing_outpu ### Preparation errors -| Error | Resolution | -|----------------------------|-------------------------------------------------------------------| -| "Directory does not exist" | Verify path exists | -| "Path is not a directory" | Verify path is a directory, not a file | -| "Length mismatch" | Ensure output_directories matches log_directories length | -| "Permission denied" | Check filesystem permissions | -| "Config file not found" | Verify extraction config path; use `/extraction-configuration` | +| Error | Resolution | +|--------------------------------------|-------------------------------------------------------------------| +| Non-existent / non-directory log path | Not a hard error; surfaces in the returned `invalid_paths` list. Verify the path exists and is a directory | +| "Length mismatch" | Ensure output_directories matches log_directories length | +| "Permission denied" | Check filesystem permissions | +| "Extraction config not found: ..." | Verify extraction config path; use `/extraction-configuration` | +| "Invalid extraction config: ..." | Validate config via `/extraction-configuration` | ### Execution errors diff --git a/plugins/communication/skills/microcontroller-interface/SKILL.md b/plugins/communication/skills/microcontroller-interface/SKILL.md index d6a32d6..bb04233 100644 --- a/plugins/communication/skills/microcontroller-interface/SKILL.md +++ b/plugins/communication/skills/microcontroller-interface/SKILL.md @@ -72,15 +72,15 @@ Check the locally installed ataraxis-communication-interface version against the pip show ataraxis-communication-interface ``` -The current version is **5.0.0**. If a version mismatch exists, ask the user how to proceed. +The current version is **6.0.1**. If a version mismatch exists, ask the user how to proceed. ### Step 2: API verification | File | What to Check | |---------------------------------------------------------------------------------------------------------|--------------------------------------------------| | `../ataraxis-communication-interface/src/ataraxis_communication_interface/__init__.py` | Exported classes, functions, and public API | -| `../ataraxis-communication-interface/src/ataraxis_communication_interface/microcontroller_interface.py` | MicroControllerInterface constructor and methods | -| `../ataraxis-communication-interface/src/ataraxis_communication_interface/communication.py` | MQTTCommunication API | +| `../ataraxis-communication-interface/src/ataraxis_communication_interface/microcontroller/interface.py` | MicroControllerInterface constructor and methods | +| `../ataraxis-communication-interface/src/ataraxis_communication_interface/communication/mqtt.py` | MQTTCommunication API | | Project `pyproject.toml` | Current pinned version dependency | --- @@ -576,7 +576,7 @@ Shutdown: MCI.stop() → DataLogger.stop() → assemble_log_archives() ```text Microcontroller Interface: -- [ ] Verified ataraxis-communication-interface version matches requirements (>=5.0.0) +- [ ] Verified ataraxis-communication-interface version matches requirements (>=6.0.0) - [ ] Verified microcontrollers are discoverable using /microcontroller-setup workflow - [ ] Allocated unique controller IDs in the 101-150 advised range - [ ] DataLogger initialized and started before MicroControllerInterface creation diff --git a/plugins/microcontroller/skills/firmware-module/SKILL.md b/plugins/microcontroller/skills/firmware-module/SKILL.md index d1611d4..2cceab2 100644 --- a/plugins/microcontroller/skills/firmware-module/SKILL.md +++ b/plugins/microcontroller/skills/firmware-module/SKILL.md @@ -73,7 +73,7 @@ Check the locally available ataraxis-micro-controller version: cat ../ataraxis-micro-controller/library.json | grep version ``` -The current version is **3.0.0**. If a version mismatch exists, ask the user how to proceed. +The current version is **3.0.1**. If a version mismatch exists, ask the user how to proceed. ### Step 2: API verification @@ -234,7 +234,7 @@ both sides when changing the parameter struct. ## SetupModule() Initialize hardware pins and reset parameters to defaults. This method is called by Kernel during -`Setup()` and on PC-requested resets. You MUST avoid blocking logic: +`Setup()` and on PC-requested resets. Avoid blocking or fail-prone logic: ```cpp bool SetupModule() override diff --git a/plugins/microcontroller/skills/firmware-module/references/api-reference.md b/plugins/microcontroller/skills/firmware-module/references/api-reference.md index 1f89c6f..d3dd986 100644 --- a/plugins/microcontroller/skills/firmware-module/references/api-reference.md +++ b/plugins/microcontroller/skills/firmware-module/references/api-reference.md @@ -1,7 +1,7 @@ # Module base class API reference Complete API reference for the `Module` base class and supporting classes in ataraxis-micro-controller. -All signatures are sourced from the library's header files at version 3.0.0. +All signatures are sourced from the library's header files at version 3.0.1. --- diff --git a/plugins/video/skills/camera-interface/SKILL.md b/plugins/video/skills/camera-interface/SKILL.md index 1765041..a5ee5ef 100644 --- a/plugins/video/skills/camera-interface/SKILL.md +++ b/plugins/video/skills/camera-interface/SKILL.md @@ -43,14 +43,14 @@ Check the locally installed ataraxis-video-system version against the latest rel pip show ataraxis-video-system ``` -The current version is **3.0.0**. If a version mismatch exists, ask the user how to proceed. +The current version is **4.0.1**. If a version mismatch exists, ask the user how to proceed. ### Step 2: API verification | File | What to Check | |----------------------------------------------------------------------|-------------------------------------------------| | `../ataraxis-video-system/src/ataraxis_video_system/__init__.py` | Exported classes, functions, and public API | -| `../ataraxis-video-system/src/ataraxis_video_system/video_system.py` | VideoSystem constructor parameters and methods | +| `../ataraxis-video-system/src/ataraxis_video_system/video/video_system.py` | VideoSystem constructor parameters and methods | | Project `pyproject.toml` | Current pinned version dependency | --- @@ -292,7 +292,7 @@ cause drops when the scene changes. Consider this when selecting presets. ```text Camera Interface: -- [ ] Verified ataraxis-video-system version matches requirements (>=3.0.0) +- [ ] Verified ataraxis-video-system version matches requirements (>=4.0.0) - [ ] Verified cameras are discoverable using /camera-setup workflow - [ ] Allocated unique system IDs in the 51-100 range (checked existing allocations) - [ ] DataLogger initialized and started before VideoSystem creation diff --git a/plugins/video/skills/camera-setup/SKILL.md b/plugins/video/skills/camera-setup/SKILL.md index 75a4f33..f57e54b 100644 --- a/plugins/video/skills/camera-setup/SKILL.md +++ b/plugins/video/skills/camera-setup/SKILL.md @@ -119,12 +119,12 @@ flag, output directory, video file path, and log directory. These tools are for Harvesters cameras only. They connect to the camera temporarily, perform the operation, and disconnect. -| Tool | Parameters | Purpose | -|----------------------------|--------------------------------------------------|-------------------------------------------------| -| `read_genicam_node_tool` | `camera_index`, `node_name` | Reads a single node or lists all writable nodes | -| `write_genicam_node_tool` | `camera_index`, `node_name`, `value` | Sets a GenICam node value | -| `dump_genicam_config_tool` | `camera_index`, `output_file` | Exports full camera config to YAML | -| `load_genicam_config_tool` | `camera_index`, `config_file`, `strict_identity` | Applies config from YAML to camera | +| Tool | Parameters | Purpose | +|----------------------------|----------------------------------------------------------------------|-------------------------------------------------| +| `read_genicam_node_tool` | `camera_index`, `node_name`, `blacklisted_nodes` | Reads a single node or lists all writable nodes | +| `write_genicam_node_tool` | `camera_index`, `node_name`, `value` | Sets a GenICam node value | +| `dump_genicam_config_tool` | `camera_index`, `output_file`, `blacklisted_nodes` | Exports full camera config to YAML | +| `load_genicam_config_tool` | `camera_index`, `config_file`, `strict_identity`, `blacklisted_nodes` | Applies config from YAML to camera | **`read_genicam_node_tool` behavior:** - With `node_name` provided: returns detailed metadata (type, value, access mode, range, unit, description) @@ -139,6 +139,10 @@ disconnect. - `strict_identity` (default `false`): when `true`, aborts if camera model/serial does not match the config file; when `false`, warns but proceeds +**`blacklisted_nodes` (read/dump/load tools):** +- Optional `list[str] | None`; when omitted, defaults to `{"CustomerIDKey", "CustomerValueKey", "TestPattern"}` +- Pass an empty list (`[]`) to disable blacklisting and operate on all matching nodes + ### Camera manifest management Camera manifests (`camera_manifest.yaml`) identify which log archives in a DataLogger output directory were @@ -171,7 +175,7 @@ manifest management for retroactive tagging or inspection. Run this before any camera work to verify the host system is ready: 1. Call `check_runtime_requirements_tool` -2. If FFMPEG is missing, instruct the user to install FFMPEG n8.0+ +2. If FFMPEG is missing, instruct the user to install FFMPEG n8.1 3. If GPU is None and hardware encoding is desired, verify NVIDIA drivers 4. If CTI is None and Harvesters cameras are needed, call `set_cti_file_tool` with the user's CTI path @@ -191,7 +195,7 @@ Use this workflow to verify a camera works before writing integration code: 1. Ask the user for an output directory 2. Call `start_video_session_tool` with the camera index from discovery -3. Verify the session starts (check `get_session_status_tool` returns "Running") +3. Verify the session starts (check `get_session_status_tool` returns "running") 4. Call `start_frame_saving_tool` to test recording 5. Call `stop_frame_saving_tool` to end recording 6. Call `stop_video_session_tool` to release resources @@ -259,7 +263,9 @@ Monochrome cameras gain nothing from YUV444 since all chrominance channels are z | 25-35 | Low quality | Preview and testing only | | 35-51 | Very low | Not recommended | -The default QP of 15 is calibrated for H265. For H264, QP 15-20 produces equivalent visual quality. +The default QP of 15 is calibrated for H265 and is likely too low for H264. As a rough starting point, a +slightly higher QP (around 15-20) is a reasonable place to begin for H264; tune it for your scene and +throughput rather than treating it as a documented equivalence. --- @@ -310,7 +316,7 @@ When transitioning from MCP-based testing to writing VideoSystem code, use this | Symptom | Likely Cause | Resolution | |----------------------------------------------------|------------------------------------|-------------------------------------------------------------| -| `check_runtime_requirements_tool` → FFMPEG Missing | FFMPEG not installed | Install FFMPEG n8.0+ and ensure it is on PATH | +| `check_runtime_requirements_tool` → FFMPEG Missing | FFMPEG not installed | Install FFMPEG n8.1 and ensure it is on PATH | | `check_runtime_requirements_tool` → GPU None | No NVIDIA GPU or drivers | Install NVIDIA drivers, or use CPU encoding (gpu=-1) | | `list_cameras_tool` returns no cameras | No cameras connected | Check physical connections, drivers, CTI configuration | | `start_video_session_tool` → error | Session already active | Call `stop_video_session_tool` first | diff --git a/plugins/video/skills/log-input-format/SKILL.md b/plugins/video/skills/log-input-format/SKILL.md index 0a952b2..ea00426 100644 --- a/plugins/video/skills/log-input-format/SKILL.md +++ b/plugins/video/skills/log-input-format/SKILL.md @@ -144,8 +144,8 @@ A recording session with one DataLogger produces: ```text recording_root/ -├── video_051.mp4 # Video output from VideoSystem (system_id=51) -├── video_052.mp4 # Video output from VideoSystem (system_id=52) +├── 051.mp4 # Video output from VideoSystem (system_id=51) +├── 052.mp4 # Video output from VideoSystem (system_id=52) └── session_data_log/ # DataLogger output (instance_name="session") ├── camera_manifest.yaml # Camera manifest (auto-written by VideoSystem.__init__) ├── 051_00000000000000000000.npy # Raw logs (before assembly) @@ -217,7 +217,7 @@ source ID and 20-digit zero-padded timestamp from the original `.npy` filenames. | Type | Identifier | Payload | Purpose | |-------|-------------------|---------------------------------------|-----------------------------------| -| Onset | `elapsed_us == 0` | 8 bytes: int64 UTC epoch microseconds | Absolute time reference | +| Onset | `elapsed_us == 0` | 8 bytes: uint64 UTC epoch microseconds | Absolute time reference | | Frame | `elapsed_us > 0` | Empty (`payload.size == 0`) | Frame acquisition event | | Data | `elapsed_us > 0` | Non-empty (`payload.size > 0`) | Generic data event (filtered out) | diff --git a/plugins/video/skills/log-processing-results/SKILL.md b/plugins/video/skills/log-processing-results/SKILL.md index 985e8ef..fec04bc 100644 --- a/plugins/video/skills/log-processing-results/SKILL.md +++ b/plugins/video/skills/log-processing-results/SKILL.md @@ -112,9 +112,9 @@ Rows are ordered chronologically. Each row corresponds to one acquired frame. ### Naming convention -Files follow the pattern `camera_{source_id}_timestamps.feather` where `source_id` is the zero-padded -system ID string from the DataLogger archive (e.g., `camera_051_timestamps.feather` for system_id=51, -`camera_112_timestamps.feather` for an MCP session). +Files follow the pattern `camera_{source_id}_timestamps.feather` where `source_id` is the un-padded +string form of the integer system ID from the DataLogger archive (e.g., `camera_51_timestamps.feather` +for system_id=51, `camera_112_timestamps.feather` for an MCP session). ### ProcessingTracker file diff --git a/plugins/video/skills/log-processing/SKILL.md b/plugins/video/skills/log-processing/SKILL.md index 88bcc15..f13cca6 100644 --- a/plugins/video/skills/log-processing/SKILL.md +++ b/plugins/video/skills/log-processing/SKILL.md @@ -162,7 +162,7 @@ Single-phase timestamp extraction pipeline: Key architectural facts: - **ProcessingTracker** manages job lifecycle: `SCHEDULED` → `RUNNING` → `SUCCEEDED` / `FAILED` via YAML state files - **Single execution session** constraint: only one batch execution can run at a time -- **Parallel processing** activates automatically for archives with >2000 messages +- **Parallel processing** activates automatically for archives with >=2000 messages - **Output layout:** All processing output is written under a `camera_timestamps/` subdirectory within the output directory provided by the user - **Output naming:** `camera_{source_id}_timestamps.feather` (Feather IPC format) @@ -235,16 +235,17 @@ The execution tool uses **budget-based worker allocation** with a single `worker directly controls memory footprint (each worker spawns a separate process). Before dispatching, the tool probes each archive's message count and allocates workers using square root scaling: -The system uses two layers of allocation: +The system uses two cooperating mechanisms: -1. **Budget division** — divides the available budget evenly among concurrent parallel jobs, snapped to - multiples of 5. Two 648k archives on a 128-core machine each get 60 workers. +1. **Per-job worker count** — each parallel job is allocated exactly `ceil(sqrt(messages / 1,000))` + workers, snapped to a multiple of 5 (with a minimum of 5). This sqrt-derived value is the actual + per-job allocation. A 648k-message archive yields 25 workers. -2. **Saturation floor** — a sqrt-derived minimum (`ceil(sqrt(messages / 1,000))`) prevents the budget - division from spreading cores too thin. If division gave each job fewer cores than the floor, - concurrency is reduced until each job gets at least the floor. Example floors: +2. **Budget-limited concurrency** — the worker budget does not raise the per-job worker count; it only + caps how many such jobs run concurrently (`available // per_job_workers`). When many large jobs + compete for a limited budget, fewer groups run at once. Per-job worker counts by archive size: -| Archive Size | Saturation Floor | Typical Scenario | +| Archive Size | Per-Job Workers | Typical Scenario | |---------------|------------------|-----------------------------| | < 2,000 msgs | 1 (sequential) | Short recording | | 10,000 msgs | 5 | ~1.5 min at 120 fps | @@ -252,9 +253,8 @@ The system uses two layers of allocation: | 250,000 msgs | 15 | ~35 min at 120 fps | | 648,000 msgs | 25 | 1.5 h at 120 fps | -The budget division determines the actual allocation (often much higher than the floor). The floor -only limits concurrency when many large jobs compete for a limited budget. Two cores are reserved for -system operations. +The per-job worker count comes solely from square-root scaling; the worker budget governs concurrency +(how many groups run at once), not the per-job worker count. Two cores are reserved for system operations. When `worker_budget=-1`, the system resolves the total using the host machine's available CPU cores via `resolve_worker_count`. Reduce `worker_budget` to limit memory footprint on constrained systems. diff --git a/plugins/video/skills/pipeline/SKILL.md b/plugins/video/skills/pipeline/SKILL.md index 9ae2622..e5b8e66 100644 --- a/plugins/video/skills/pipeline/SKILL.md +++ b/plugins/video/skills/pipeline/SKILL.md @@ -151,9 +151,9 @@ A single shared DataLogger is the preferred topology for all use cases: ```text DataLogger(instance_name="session") - ├── VideoSystem(system_id=51, name="face_camera") → 051_log.npz + camera_manifest.yaml - ├── VideoSystem(system_id=52, name="body_camera") → 052_log.npz - └── VideoSystem(system_id=53, name="arena_camera") → 053_log.npz + ├── VideoSystem(system_id=51, name="face_camera") → 51_log.npz + camera_manifest.yaml + ├── VideoSystem(system_id=52, name="body_camera") → 52_log.npz + └── VideoSystem(system_id=53, name="arena_camera") → 53_log.npz ``` All cameras share one log directory, all timestamps are correlated, one `assemble_log_archives` call diff --git a/plugins/video/skills/post-recording/SKILL.md b/plugins/video/skills/post-recording/SKILL.md index 7aab354..5621766 100644 --- a/plugins/video/skills/post-recording/SKILL.md +++ b/plugins/video/skills/post-recording/SKILL.md @@ -123,7 +123,8 @@ manual assembly tool. **Note:** This tool requires `camera_manifest.yaml` files to exist in DataLogger output directories. These manifests are written automatically by `VideoSystem.__init__()`. For each confirmed manifest source, the tool locates the corresponding log archive, video file, and processed timestamp feather -output, returning a flat `sources` list. +output, returning a flat `sources` list. The return also includes a flat `log_directories` list (which +feeds batch `/log-processing`) plus `total_sources` and `total_log_directories` aggregate counts. --- @@ -136,7 +137,8 @@ You MUST follow these steps after every recording session. 2. **Verify video file** — Call `validate_video_file_tool` with the `video_file` path. Confirm: - The file exists and has non-zero `file_size_bytes` - - `frame_count` is greater than 0 + - `frame_count` is greater than 0 (note: `frame_count` may be `null` when ffprobe cannot report + `nb_frames` for the container, so treat a `null` value as "unknown" rather than zero frames) - `codec`, `width`, `height`, and `frame_rate` match expected session parameters - If `video_file` is `null`, no frames were saved (verify that `start_frame_saving_tool` was called) @@ -147,9 +149,12 @@ You MUST follow these steps after every recording session. list includes a `log_archive` path. If `archives_assembled` is `false`, call `assemble_log_archives_tool` with the `log_directory` path, then verify with the discovery tool. -4. **Cross-reference frame counts** — Compare the video `frame_count` from `validate_video_file_tool` with the - archive message count from the discovery tool. These should be approximately equal (within 1-2 frames due to - pipeline buffering). Large discrepancies indicate data loss. +4. **Confirm archive presence for cross-referencing** — `discover_camera_data_tool` confirms that each + source's `log_archive` exists but does not compute an archive message count. The genuine frame-count + vs. message-count cross-check (video `frame_count` from `validate_video_file_tool` against the archive + message count) can only be performed after `/log-processing`, where the message count becomes available. + They should be approximately equal (within 1-2 frames due to pipeline buffering); large discrepancies + indicate data loss. 5. **Assess readiness** — Run through the handoff checklist below. When all conditions are met, invoke `/log-processing` to begin timestamp extraction. @@ -191,8 +196,9 @@ retroactively register camera sources before running discovery. - Video `frame_count` should approximate the number of frame messages in the log archive minus the onset message (i.e., `archive_frame_messages - 1`). - Video `duration_seconds` should match `(last_timestamp - first_timestamp)` from processed timestamps. -- These cross-checks can only be fully validated after log processing completes via `/log-processing-results`. - At this stage, use the archive message count from `discover_camera_data_tool` for a rough comparison. +- These cross-checks can only be validated after log processing completes via `/log-processing-results`, + because the archive message count is not available until then. At this stage, `discover_camera_data_tool` + can only confirm that each source's `log_archive` path exists, not its message count. - Processed output (feather files and tracker) is written to a `camera_timestamps/` subdirectory under the output directory, not directly into the log directory. diff --git a/plugins/video/skills/video-mcp-environment-setup/SKILL.md b/plugins/video/skills/video-mcp-environment-setup/SKILL.md index ad1cdae..9876f6f 100644 --- a/plugins/video/skills/video-mcp-environment-setup/SKILL.md +++ b/plugins/video/skills/video-mcp-environment-setup/SKILL.md @@ -38,15 +38,16 @@ ataraxis-video-system provides a single MCP server accessed through the `axvs` C ```toml [project.scripts] -axvs = "ataraxis_video_system.cli:axvs_cli" +axvs = "ataraxis_video_system.interfaces.cli:axvs_cli" ``` | Server | CLI command | Purpose | |-------------------------|-------------|------------------------------------------------------------------| | `ataraxis-video-system` | `axvs mcp` | Camera discovery, video session management, log processing tools | -The server accepts a `--transport` option (defaults to `stdio`). The project's `.mcp.json` configures the -Claude assistant to launch the server automatically: +The server accepts a `--transport` option (defaults to `stdio`). The plugin manifest +`.claude-plugin/plugin.json` configures the Claude assistant to launch the server automatically via its +`mcpServers` block: ```json { @@ -69,7 +70,7 @@ The ataraxis video plugin's Claude integration is split across two distribution | Component | Distributed via | What it provides | |------------------------------------|-----------------------------------|----------------------------------------------------------------------------| | Skills (`/camera-interface`, etc.) | ataraxis video plugin | Skill files that guide agents through workflows | -| MCP server registrations | ataraxis video plugin | `.mcp.json` entries that tell the Claude assistant how to start the server | +| MCP server registrations | ataraxis video plugin | `plugin.json` `mcpServers` entries that tell the Claude assistant how to start the server | | MCP server code (`axvs mcp`) | ataraxis-video-system pip package | The actual CLI command and server implementation | Installing the plugin alone registers the MCP server and makes skills available, but the server will fail to From 9fd7ef1a5a5f897c3f0ae7e1f8e31f68c19c1178 Mon Sep 17 00:00:00 2001 From: Ivan Kondratyev Date: Wed, 17 Jun 2026 13:28:45 -0400 Subject: [PATCH 2/7] Fixed style-compliance violations across all plugin skills. -- Split five oversized SKILL.md files under the 500-line limit by moving detail into reference files. -- Realigned markdown tables to vertically align pipes and extend dashes to the full column width. -- Wrapped prose lines that exceeded the 120-character limit. -- Standardized section headers to sentence case. -- Renamed the Related skills table column header from Role to Relationship. -- Standardized scope cross-references to the (see /skill) form. -- Corrected terminology, voice, and casing inconsistencies and a broken table cell. --- .../automation/skills/audit-style/SKILL.md | 26 +-- plugins/automation/skills/cpp-style/SKILL.md | 165 +++----------- .../cpp-style/references/class-patterns.md | 100 ++++++++- .../cpp-style/references/doxygen-and-types.md | 26 +++ .../references/libraries-and-tools.md | 15 ++ .../automation/skills/csharp-style/SKILL.md | 166 ++------------ .../csharp-style/references/class-patterns.md | 2 +- .../references/libraries-and-tools.md | 144 ++++++++++++ .../references/xml-docs-and-types.md | 26 +++ .../skills/explore-dependencies/SKILL.md | 8 +- .../skills/pyproject-style/SKILL.md | 8 +- .../references/tool-configurations.md | 4 +- .../automation/skills/python-style/SKILL.md | 92 ++------ .../python-style/references/anti-patterns.md | 2 +- .../python-style/references/class-patterns.md | 73 ++++++ .../automation/skills/readme-style/SKILL.md | 6 +- plugins/automation/skills/release/SKILL.md | 2 +- .../skill-design/references/anti-patterns.md | 2 +- .../SKILL.md | 2 +- .../skills/extraction-configuration/SKILL.md | 18 +- .../skills/log-input-format/SKILL.md | 22 +- .../skills/log-processing-results/SKILL.md | 18 +- .../skills/log-processing/SKILL.md | 54 ++--- .../skills/microcontroller-interface/SKILL.md | 141 ++---------- .../references/api-reference.md | 209 ++++++++++++++---- .../skills/microcontroller-setup/SKILL.md | 22 +- .../communication/skills/pipeline/SKILL.md | 20 +- .../skills/firmware-module/SKILL.md | 147 ++---------- .../references/api-reference.md | 126 +++++++++++ .../video/skills/camera-interface/SKILL.md | 28 +-- .../references/api-reference.md | 28 +-- plugins/video/skills/camera-setup/SKILL.md | 29 +-- .../video/skills/log-input-format/SKILL.md | 32 +-- .../skills/log-processing-results/SKILL.md | 21 +- plugins/video/skills/log-processing/SKILL.md | 44 ++-- plugins/video/skills/pipeline/SKILL.md | 23 +- plugins/video/skills/post-recording/SKILL.md | 18 +- .../video-mcp-environment-setup/SKILL.md | 8 +- 38 files changed, 1005 insertions(+), 872 deletions(-) diff --git a/plugins/automation/skills/audit-style/SKILL.md b/plugins/automation/skills/audit-style/SKILL.md index 1f0c94d..4fedd9b 100644 --- a/plugins/automation/skills/audit-style/SKILL.md +++ b/plugins/automation/skills/audit-style/SKILL.md @@ -241,19 +241,19 @@ You MUST adhere to the following discipline during every audit. ## Related skills -| Skill | Relationship | -|-------------------------|------------------------------------------------------------------------------------------| -| `/audit-facts` | Sibling audit for factual accuracy against source code | -| `/python-style` | Provides the Python style checklist; loaded when scope contains Python files | -| `/cpp-style` | Provides the C++ style checklist; loaded when scope contains C++ files | -| `/csharp-style` | Provides the C# style checklist; loaded when scope contains C# files | -| `/readme-style` | Provides the README style checklist; loaded when scope contains README files | -| `/pyproject-style` | Provides the pyproject.toml style checklist; loaded when scope contains pyproject.toml | -| `/tox-config` | Provides the tox.ini style checklist; loaded when scope contains tox.ini | -| `/api-docs` | Provides the Sphinx docs style checklist; loaded when scope contains docs files | -| `/skill-design` | Provides the skill and CLAUDE.md style checklist; loaded when scope contains skill files | -| `/project-layout` | Provides the project directory style checklist; loaded when target is a project root | -| `/explore-codebase` | Provides project structure context; invoke first when auditing an unfamiliar codebase | +| Skill | Relationship | +|---------------------|------------------------------------------------------------------------------------------| +| `/audit-facts` | Sibling audit for factual accuracy against source code | +| `/python-style` | Provides the Python style checklist; loaded when scope contains Python files | +| `/cpp-style` | Provides the C++ style checklist; loaded when scope contains C++ files | +| `/csharp-style` | Provides the C# style checklist; loaded when scope contains C# files | +| `/readme-style` | Provides the README style checklist; loaded when scope contains README files | +| `/pyproject-style` | Provides the pyproject.toml style checklist; loaded when scope contains pyproject.toml | +| `/tox-config` | Provides the tox.ini style checklist; loaded when scope contains tox.ini | +| `/api-docs` | Provides the Sphinx docs style checklist; loaded when scope contains docs files | +| `/skill-design` | Provides the skill and CLAUDE.md style checklist; loaded when scope contains skill files | +| `/project-layout` | Provides the project directory style checklist; loaded when target is a project root | +| `/explore-codebase` | Provides project structure context; invoke first when auditing an unfamiliar codebase | --- diff --git a/plugins/automation/skills/cpp-style/SKILL.md b/plugins/automation/skills/cpp-style/SKILL.md index c765773..7886bef 100644 --- a/plugins/automation/skills/cpp-style/SKILL.md +++ b/plugins/automation/skills/cpp-style/SKILL.md @@ -31,10 +31,10 @@ code. You MUST verify your changes against the checklist before submitting. - Cross-language consistency with Python and C# conventions **Does not cover:** -- README file conventions (invoke `/readme-style`) -- Commit message conventions (invoke `/commit`) -- Skill file and CLAUDE.md conventions (invoke `/skill-design`) -- Codebase exploration workflows (invoke `/explore-codebase`) +- README file conventions (see `/readme-style`) +- Commit message conventions (see `/commit`) +- Skill file and CLAUDE.md conventions (see `/skill-design`) +- Codebase exploration workflows (see `/explore-codebase`) --- @@ -50,14 +50,14 @@ Read this entire file. The core conventions below apply to ALL C++ code. Based on the task, load the appropriate reference files: -| Task | Reference to load | -|-----------------------------------------------|-------------------------------------------------------------| -| Writing or modifying Doxygen docs / types | [doxygen-and-types.md](references/doxygen-and-types.md) | -| Writing classes, templates, enums, or structs | [class-patterns.md](references/class-patterns.md) | -| Using Arduino/PlatformIO, clang tools, tests | [libraries-and-tools.md](references/libraries-and-tools.md) | -| Using nanobind extensions, CMake, GIL | [libraries-and-tools.md](references/libraries-and-tools.md) | -| Deploying or verifying tool config files | [assets/](assets/) directory | -| Reviewing code before submission | [anti-patterns.md](references/anti-patterns.md) | +| Task | Reference to load | +|---------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------| +| Writing or modifying Doxygen docs / types, or comments | [doxygen-and-types.md](references/doxygen-and-types.md) | +| Writing classes, templates, enums, structs, function calls, guard clauses, or formatting (blank lines, line length) | [class-patterns.md](references/class-patterns.md) | +| Using Arduino/PlatformIO, clang tools, tests, or verifying config files | [libraries-and-tools.md](references/libraries-and-tools.md) | +| Using nanobind extensions, CMake, GIL | [libraries-and-tools.md](references/libraries-and-tools.md) | +| Deploying or verifying tool config files | [assets/](assets/) directory | +| Reviewing code before submission | [anti-patterns.md](references/anti-patterns.md) | Load multiple references when the task spans multiple domains. @@ -137,22 +137,22 @@ Use **full words**, not abbreviations: ### Identifiers -| Element | Convention | Example | -|-----------------------|----------------------------|------------------------------------------------------| -| Classes | PascalCase | `TransportLayer`, `EncoderModule`, `COBSProcessor` | -| Methods | PascalCase | `SendData`, `ReceiveData`, `SetupModule` | -| Accessors | `get_`/`set_` snake_case | `get_buffer_size`, `set_baud_rate` | -| Private members | `_snake_case` | `_port`, `_cobs_processor`, `_custom_parameters` | -| Local variables | snake_case | `start_index`, `payload_size`, `new_motion` | -| Parameters | snake_case | `module_type`, `module_id`, `baud_rate` | -| Constants | `kPascalCase` | `kTimeout`, `kSerialBufferSize`, `kCalibrationDelay` | -| Enum types | `kPascalCase` | `kCustomStatusCodes`, `kModuleCommands` | -| Enum values | `kPascalCase` | `kStandby`, `kRotatedCW`, `kOpen` | -| Template type params | PascalCase | `PolynomialType`, `BufferType` | -| Template value params | `kPascalCase` | `kPinA`, `kMaximumTransmittedPayloadSize` | -| Namespaces | snake_case | `axtlmc_shared_assets`, `axmc_communication_assets` | -| Struct members | snake_case | `module_type`, `pulse_duration`, `return_code` | -| Macros | UPPER_SNAKE | `PACKED_STRUCT`, `ENCODER_USE_INTERRUPTS` | +| Element | Convention | Example | +|-----------------------|--------------------------|------------------------------------------------------| +| Classes | PascalCase | `TransportLayer`, `EncoderModule`, `COBSProcessor` | +| Methods | PascalCase | `SendData`, `ReceiveData`, `SetupModule` | +| Accessors | `get_`/`set_` snake_case | `get_buffer_size`, `set_baud_rate` | +| Private members | `_snake_case` | `_port`, `_cobs_processor`, `_custom_parameters` | +| Local variables | snake_case | `start_index`, `payload_size`, `new_motion` | +| Parameters | snake_case | `module_type`, `module_id`, `baud_rate` | +| Constants | `kPascalCase` | `kTimeout`, `kSerialBufferSize`, `kCalibrationDelay` | +| Enum types | `kPascalCase` | `kCustomStatusCodes`, `kModuleCommands` | +| Enum values | `kPascalCase` | `kStandby`, `kRotatedCW`, `kOpen` | +| Template type params | PascalCase | `PolynomialType`, `BufferType` | +| Template value params | `kPascalCase` | `kPinA`, `kMaximumTransmittedPayloadSize` | +| Namespaces | snake_case | `axtlmc_shared_assets`, `axmc_communication_assets` | +| Struct members | snake_case | `module_type`, `pulse_duration`, `return_code` | +| Macros | UPPER_SNAKE_CASE | `PACKED_STRUCT`, `ENCODER_USE_INTERRUPTS` | ### Functions @@ -204,19 +204,7 @@ static constexpr int32_t kMultiplier = kInvertDirection ? -1 : 1; // NOLINT(*-d ## Function calls -Prefer clarity to brevity. For functions with multiple parameters of the same type or boolean -parameters, use inline comments to label arguments: - -```cpp -// Good - labeled arguments clarify meaning -SendData( - static_cast(kCustomStatusCodes::kRotatedCW), // status_code - delta // value -); - -// Acceptable - single argument or meaning obvious -CompleteCommand(); -``` +See [class-patterns.md](references/class-patterns.md) for argument-labeling conventions in function calls. --- @@ -264,27 +252,7 @@ Use a structured format: context ("Unable to..."), constraint ("must be..."), ac ## Comments -### Inline comments - -- Use third person imperative ("Configures..." not "This section configures...") -- Place above the code, not at end of line (unless short trailing comments) -- Use comments to explain non-obvious logic or provide hardware-specific context - -```cpp -// Resets the overflow tracker. The overflow accumulates insignificant motion between reporting -// cycles to filter sensor noise while preserving real displacement. -_overflow = 0; -``` - -### What to avoid - -- Don't reiterate the obvious (e.g., `// Set x to 5` before `x = 5`) -- Don't add Doxygen comments to code you didn't write or modify -- Don't use heavy section separator blocks (e.g., `// ======` or `// ------`) -- Don't include `@code` / `@endcode` example blocks in Doxygen documentation. Examples go stale - as APIs evolve and create maintenance debt. Keep documentation concise — the `@brief`, `@param`, - and `@returns` tags are sufficient. This parallels the Python convention of not including - Examples sections in docstrings +See [doxygen-and-types.md](references/doxygen-and-types.md) for inline comment conventions and what to avoid. --- @@ -372,21 +340,7 @@ match the class name converted to snake_case (e.g., `transport_layer.h` contains ## Guard clauses and boolean expressions -Prefer early returns (guard clauses) over deeply nested conditionals: - -```cpp -void SendPulse() -{ - if (!kOutput) - { - AbortCommand(); - return; - } - - // Main logic at minimal indentation level. - Pulse(); -} -``` +See [class-patterns.md](references/class-patterns.md) for guard-clause and early-return conventions. --- @@ -422,70 +376,19 @@ struct CustomRuntimeParameters ## Blank lines -- **One blank line** between method definitions within a class (enforced by clang-format - `SeparateDefinitionBlocks: Always`) -- **One blank line** before access modifiers (`public:`, `private:`) -- **No blank line** after an opening brace or before a closing brace -- **One blank line** between logical groups of statements within a method -- **One blank line** after include blocks before code +See [class-patterns.md](references/class-patterns.md) for blank-line placement rules. --- ## Line length and formatting -- Maximum line length: **120 characters** (clang-format `ColumnLimit: 120`) -- Formatter: **clang-format** (config in `.clang-format`) -- Linter: **clang-tidy** (config in `.clang-tidy`, `WarningsAsErrors: '*'`) -- Brace style: **Allman** (opening braces on new lines for all constructs) -- Indentation: **4 spaces** (no tabs) -- Pointer/reference alignment: **Left** (`int* pointer`, `int& reference`) - -### Aligned assignments - -Consecutive assignments and macros are aligned for readability: - -```cpp -_custom_parameters.report_CCW = true; -_custom_parameters.report_CW = true; -_custom_parameters.delta_threshold = 15; -``` - -### Template declarations - -Template declarations always appear on a separate line: - -```cpp -template -class EncoderModule final : public Module -``` - -### Short statements - -Short case labels and simple if/else statements may appear on a single line (enforced by -clang-format `AllowShortCaseLabelsOnASingleLine: true`): - -```cpp -case kModuleCommands::kCheckState: CheckState(); return true; -case kModuleCommands::kReset: ResetEncoder(); return true; -default: return false; - -if (kTonePin == 255) _custom_parameters.tone_duration = 0; -``` +See [class-patterns.md](references/class-patterns.md) for line length, brace style, and statement formatting. --- ## Configuration files -Canonical configs are stored in [assets/](assets/). When working in a C++ project, verify that -`.clang-format` and `.clang-tidy` in the project root match the canonical versions. - -- **Embedded** `.clang-format`: [assets/embedded/.clang-format](assets/embedded/.clang-format) -- **Extension** `.clang-format`: [assets/extension/.clang-format](assets/extension/.clang-format) -- **Shared** `.clang-tidy`: [assets/.clang-tidy](assets/.clang-tidy) - -The two `.clang-format` variants differ only in `AccessModifierOffset` (`0` vs `-2`) and -`IndentAccessModifiers` (`true` vs `false`). All other settings are identical. The `.clang-tidy` -configuration is shared across both archetypes. +See [libraries-and-tools.md](references/libraries-and-tools.md) for `.clang-format` and `.clang-tidy` locations. --- diff --git a/plugins/automation/skills/cpp-style/references/class-patterns.md b/plugins/automation/skills/cpp-style/references/class-patterns.md index 7a330ca..e7fd5b3 100644 --- a/plugins/automation/skills/cpp-style/references/class-patterns.md +++ b/plugins/automation/skills/cpp-style/references/class-patterns.md @@ -504,10 +504,10 @@ with `@property` accessors, while dataclass fields are public. This parallels the Python distinction between `@property` (simple attribute access) and methods (operations that "do something"): -| Use | When | -|---------------------------|--------------------------------------------------------------| -| `get_`/`set_` accessor | Returns or sets a single data member with no side effects | -| PascalCase method | Performs computation, I/O, or has side effects | +| Use | When | +|------------------------|-----------------------------------------------------------| +| `get_`/`set_` accessor | Returns or sets a single data member with no side effects | +| PascalCase method | Performs computation, I/O, or has side effects | ```cpp // Good - accessor for trivial field access @@ -587,3 +587,95 @@ Rules: third-party namespaces - **Libraries with `.cpp` files**: Never use `using namespace` in header files (pollutes the global namespace for all includers). Place `using namespace` in `.cpp` files only + +--- + +## Function calls + +Prefer clarity to brevity. For functions with multiple parameters of the same type or boolean +parameters, use inline comments to label arguments: + +```cpp +// Good - labeled arguments clarify meaning +SendData( + static_cast(kCustomStatusCodes::kRotatedCW), // status_code + delta // value +); + +// Acceptable - single argument or meaning obvious +CompleteCommand(); +``` + +--- + +## Blank lines + +- **One blank line** between method definitions within a class (enforced by clang-format + `SeparateDefinitionBlocks: Always`) +- **One blank line** before access modifiers (`public:`, `private:`) +- **No blank line** after an opening brace or before a closing brace +- **One blank line** between logical groups of statements within a method +- **One blank line** after include blocks before code + +--- + +## Line length and formatting + +- Maximum line length: **120 characters** (clang-format `ColumnLimit: 120`) +- Formatter: **clang-format** (config in `.clang-format`) +- Linter: **clang-tidy** (config in `.clang-tidy`, `WarningsAsErrors: '*'`) +- Brace style: **Allman** (opening braces on new lines for all constructs) +- Indentation: **4 spaces** (no tabs) +- Pointer/reference alignment: **Left** (`int* pointer`, `int& reference`) + +### Aligned assignments + +Consecutive assignments and macros are aligned for readability: + +```cpp +_custom_parameters.report_CCW = true; +_custom_parameters.report_CW = true; +_custom_parameters.delta_threshold = 15; +``` + +### Template declarations + +Template declarations always appear on a separate line: + +```cpp +template +class EncoderModule final : public Module +``` + +### Short statements + +Short case labels and simple if/else statements may appear on a single line (enforced by +clang-format `AllowShortCaseLabelsOnASingleLine: true`): + +```cpp +case kModuleCommands::kCheckState: CheckState(); return true; +case kModuleCommands::kReset: ResetEncoder(); return true; +default: return false; + +if (kTonePin == 255) _custom_parameters.tone_duration = 0; +``` + +--- + +## Guard clauses and boolean expressions + +Prefer early returns (guard clauses) over deeply nested conditionals: + +```cpp +void SendPulse() +{ + if (!kOutput) + { + AbortCommand(); + return; + } + + // Main logic at minimal indentation level. + Pulse(); +} +``` diff --git a/plugins/automation/skills/cpp-style/references/doxygen-and-types.md b/plugins/automation/skills/cpp-style/references/doxygen-and-types.md index 453ac35..8712e1e 100644 --- a/plugins/automation/skills/cpp-style/references/doxygen-and-types.md +++ b/plugins/automation/skills/cpp-style/references/doxygen-and-types.md @@ -398,3 +398,29 @@ static constexpr uint32_t kCalibrationDelay = 300000; Exception: `#define` is required for Arduino library configuration macros (e.g., `ENCODER_USE_INTERRUPTS`) that must precede header inclusion. + +--- + +## Comments + +### Inline comments + +- Use third person imperative ("Configures..." not "This section configures...") +- Place above the code, not at end of line (unless short trailing comments) +- Use comments to explain non-obvious logic or provide hardware-specific context + +```cpp +// Resets the overflow tracker. The overflow accumulates insignificant motion between reporting +// cycles to filter sensor noise while preserving real displacement. +_overflow = 0; +``` + +### What to avoid + +- Don't reiterate the obvious (e.g., `// Set x to 5` before `x = 5`) +- Don't add Doxygen comments to code you didn't write or modify +- Don't use heavy section separator blocks (e.g., `// ======` or `// ------`) +- Don't include `@code` / `@endcode` example blocks in Doxygen documentation. Examples go stale + as APIs evolve and create maintenance debt. Keep documentation concise — the `@brief`, `@param`, + and `@returns` tags are sufficient. This parallels the Python convention of not including + Examples sections in docstrings diff --git a/plugins/automation/skills/cpp-style/references/libraries-and-tools.md b/plugins/automation/skills/cpp-style/references/libraries-and-tools.md index 4c173c7..8e6d559 100644 --- a/plugins/automation/skills/cpp-style/references/libraries-and-tools.md +++ b/plugins/automation/skills/cpp-style/references/libraries-and-tools.md @@ -603,3 +603,18 @@ Unlike embedded code, extension code may use the full C++ standard library: | Target platform | Teensy / Arduino | Windows, Linux, macOS | | AccessModifierOffset | 0 | -2 (in .clang-format) | | Distribution | Firmware images | Binary wheels via cibuildwheel | + +--- + +## Configuration files + +Canonical configs are stored in [assets/](assets/). When working in a C++ project, verify that +`.clang-format` and `.clang-tidy` in the project root match the canonical versions. + +- **Embedded** `.clang-format`: [assets/embedded/.clang-format](assets/embedded/.clang-format) +- **Extension** `.clang-format`: [assets/extension/.clang-format](assets/extension/.clang-format) +- **Shared** `.clang-tidy`: [assets/.clang-tidy](assets/.clang-tidy) + +The two `.clang-format` variants differ only in `AccessModifierOffset` (`0` vs `-2`) and +`IndentAccessModifiers` (`true` vs `false`). All other settings are identical. The `.clang-tidy` +configuration is shared across both archetypes. diff --git a/plugins/automation/skills/csharp-style/SKILL.md b/plugins/automation/skills/csharp-style/SKILL.md index e3802fc..36e5761 100644 --- a/plugins/automation/skills/csharp-style/SKILL.md +++ b/plugins/automation/skills/csharp-style/SKILL.md @@ -28,10 +28,10 @@ code. You MUST verify your changes against the checklist before submitting. - Cross-language consistency with C++ and Python conventions **Does not cover:** -- README file conventions (invoke `/readme-style`) -- Commit message conventions (invoke `/commit`) -- Skill file and CLAUDE.md conventions (invoke `/skill-design`) -- Codebase exploration workflows (invoke `/explore-codebase`) +- README file conventions (see `/readme-style`) +- Commit message conventions (see `/commit`) +- Skill file and CLAUDE.md conventions (see `/skill-design`) +- Codebase exploration workflows (see `/explore-codebase`) --- @@ -47,13 +47,13 @@ Read this entire file. The core conventions below apply to ALL C# code. Based on the task, load the appropriate reference files: -| Task | Reference to load | -|---------------------------------------------|-------------------------------------------------------------| -| Writing or modifying XML docs / type usage | [xml-docs-and-types.md](references/xml-docs-and-types.md) | -| Writing classes, enums, or Unity components | [class-patterns.md](references/class-patterns.md) | -| Using LINQ, async, IDisposable, or testing | [libraries-and-tools.md](references/libraries-and-tools.md) | -| Deploying or verifying tool config files | [assets/](assets/) directory | -| Reviewing code before submission | [anti-patterns.md](references/anti-patterns.md) | +| Task | Reference to load | +|------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------| +| Writing or modifying XML docs / type usage / comments | [xml-docs-and-types.md](references/xml-docs-and-types.md) | +| Writing classes, enums, or Unity components | [class-patterns.md](references/class-patterns.md) | +| Using LINQ, async, IDisposable, testing; function calls, blank lines, formatting, tooling, config files, guard clauses | [libraries-and-tools.md](references/libraries-and-tools.md) | +| Deploying or verifying tool config files | [assets/](assets/) directory | +| Reviewing code before submission | [anti-patterns.md](references/anti-patterns.md) | Load multiple references when the task spans multiple domains. @@ -191,23 +191,7 @@ For detailed immutability patterns (`readonly struct`, records, `in` parameters) ## Function calls -Prefer **named arguments** when the meaning is not obvious from the value alone: - -```csharp -// Good - named arguments clarify boolean and same-type parameters -CreateChannel(topic: "sensors/encoder", isListener: true, qosLevel: 2); -Instantiate(prefab: segmentPrefab, position: spawnPosition, rotation: Quaternion.identity); - -// Acceptable - single argument or meaning obvious from type/name -Mathf.Abs(difference); -Debug.Log(message); -GetComponent(); -``` - -Use named arguments when a method has: -- Boolean parameters (always name them) -- Multiple parameters of the same type -- Parameters whose meaning is unclear from the value +See [libraries-and-tools.md](references/libraries-and-tools.md) for named argument conventions. --- @@ -304,27 +288,7 @@ Debug.LogError("Failed to load task template from YAML file."); ## Comments -### Inline comments - -- Use third person imperative ("Configures..." not "This section configures...") -- Place above the code, not at end of line (unless very short) -- Use comments to explain non-obvious logic or provide context - -```csharp -// Measures actual prefab lengths and compares with configuration. -float[] measuredSegmentLengths = Utility.GetSegmentLengths(segmentPrefabs); -``` - -### What to avoid - -- Don't reiterate the obvious (e.g., `// Set x to 5` before `x = 5`) -- Don't add XML docs to code you didn't write or modify -- Don't use heavy section separator blocks (e.g., `// ======` or `// ------`) -- Don't use `#region` / `#endregion` blocks (use blank lines between logical groups instead) -- Don't use `this.` qualifier (exception: disambiguating a parameter from a field) -- Don't use IDE-specific suppression comments (e.g., ReSharper/Rider `// ReSharper disable` or `// noinspection`). - Remove any you encounter — CSharpier and the EditorConfig-configured analyzers are authoritative; suppress a genuine - analyzer finding only with the standard `#pragma warning disable CODE` or `[SuppressMessage]`, never an IDE directive +See [xml-docs-and-types.md](references/xml-docs-and-types.md) for inline comment conventions and what to avoid. --- @@ -410,123 +374,29 @@ message types may remain in the containing class's file. ## Guard clauses and boolean expressions -Prefer early returns (guard clauses) over deeply nested conditionals. Use explicit boolean -checks, `string.IsNullOrEmpty()` for strings, and `== null` / `!= null` for null checks: - -```csharp -/// Checks if the occupancy duration has been met while the animal is in the zone. -void Update() -{ - if (!isActive || boundaryDisarmed) - return; - - if (string.IsNullOrEmpty(_zoneName)) - return; - - if (_occupancyTimer.IsRunning && inZone) - { - if (_occupancyTimer.ElapsedMilliseconds >= occupancyDurationMs) - { - OnOccupancyMet(); - } - } -} -``` +See [libraries-and-tools.md](references/libraries-and-tools.md) for guard clause and boolean expression conventions. --- ## Blank lines -- **One blank line** between method definitions within a class -- **One blank line** after using directive blocks before namespace/class -- **No blank line** after an opening brace or before a closing brace -- **One blank line** between logical groups of statements within a method - ---- +See [libraries-and-tools.md](references/libraries-and-tools.md) for blank line conventions. ## Line length and formatting -- Maximum line length: **120 characters** -- Formatter: **CSharpier** (config in `.csharpierrc.yaml`) -- Style enforcement: **EditorConfig** (config in `.editorconfig`) -- Brace style: **Allman** (opening braces on new lines for all constructs) -- Indentation: **4 spaces** (no tabs) -- Line endings: **LF** (Unix-style) - -### String formatting - -- Use **string interpolation** (`$"..."`) for all string formatting -- Use verbatim strings (`@"..."`) for paths and multi-line strings -- Use **double quotes** for all strings - -### Trailing commas - -C# does not enforce trailing commas in the same way as Python. Follow CSharpier's output for -comma placement in multi-line constructs. - -### Brace rules - -Always use braces for control flow statements, even single-line bodies: - -```csharp -// Good -if (template == null) -{ - return; -} - -// Acceptable for simple guard clauses -if (!isActive) - return; -``` +See [libraries-and-tools.md](references/libraries-and-tools.md) for line length, formatting, and brace rules. --- ## Tooling -### CSharpier - -CSharpier is the primary formatter. Install and use it before committing: - -```bash -dotnet tool install -g csharpier # Install globally -csharpier . # Format all files -csharpier --check . # Check without modifying (CI mode) -``` - -Configuration lives in `.csharpierrc.yaml`: - -```yaml -printWidth: 120 -useTabs: false -tabWidth: 4 -endOfLine: lf -``` - -### EditorConfig - -The `.editorconfig` file enforces naming conventions, brace style, and spacing rules in -IDEs. It is the source of truth for style rules that CSharpier does not cover (naming, -`var` preferences, expression-bodied members). - -### CSharpier ignore - -The `.csharpierignore` file excludes Unity-generated directories (`Library/`, `Temp/`, -`Logs/`) and third-party packages from formatting. +See [libraries-and-tools.md](references/libraries-and-tools.md) for CSharpier and EditorConfig tooling. --- ## Configuration files -Canonical configs are stored in [assets/](assets/). When working in a C# project, verify that -`.csharpierrc.yaml`, `.editorconfig`, and `.csharpierignore` in the project root match these: - -- [assets/.csharpierrc.yaml](assets/.csharpierrc.yaml) -- [assets/.editorconfig](assets/.editorconfig) -- [assets/.csharpierignore](assets/.csharpierignore) - -The `.csharpierignore` contains generic entries only. Individual projects may need additional -project-specific entries (e.g., paths to auto-generated scripts). +See [libraries-and-tools.md](references/libraries-and-tools.md) for configuration file references. --- diff --git a/plugins/automation/skills/csharp-style/references/class-patterns.md b/plugins/automation/skills/csharp-style/references/class-patterns.md index 418c605..6cab948 100644 --- a/plugins/automation/skills/csharp-style/references/class-patterns.md +++ b/plugins/automation/skills/csharp-style/references/class-patterns.md @@ -254,7 +254,7 @@ public enum MessageTypes ### Rules - **XML documentation**: Document every enum member with a `` tag -- **Class docstring**: Imperative mood ("Defines the...") +- **Class summary**: Imperative mood ("Defines the...") - **PascalCase**: Both enum type names and values use PascalCase - **Trailing comma**: Include trailing comma after the last member - **Explicit values**: Use only when stability across versions matters (protocols, serialization) diff --git a/plugins/automation/skills/csharp-style/references/libraries-and-tools.md b/plugins/automation/skills/csharp-style/references/libraries-and-tools.md index f0b202c..f9d69d8 100644 --- a/plugins/automation/skills/csharp-style/references/libraries-and-tools.md +++ b/plugins/automation/skills/csharp-style/references/libraries-and-tools.md @@ -475,3 +475,147 @@ if (topicName.Contains("Gimbl")) // Uses CurrentCulture on some .NET versions behavior is irrelevant - Never use `StringComparison.CurrentCulture` or `StringComparison.InvariantCulture` unless displaying sorted text to users + +--- + +## Function calls + +Prefer **named arguments** when the meaning is not obvious from the value alone: + +```csharp +// Good - named arguments clarify boolean and same-type parameters +CreateChannel(topic: "sensors/encoder", isListener: true, qosLevel: 2); +Instantiate(prefab: segmentPrefab, position: spawnPosition, rotation: Quaternion.identity); + +// Acceptable - single argument or meaning obvious from type/name +Mathf.Abs(difference); +Debug.Log(message); +GetComponent(); +``` + +Use named arguments when a method has: +- Boolean parameters (always name them) +- Multiple parameters of the same type +- Parameters whose meaning is unclear from the value + +--- + +## Blank lines + +- **One blank line** between method definitions within a class +- **One blank line** after using directive blocks before namespace/class +- **No blank line** after an opening brace or before a closing brace +- **One blank line** between logical groups of statements within a method + +--- + +## Line length and formatting + +- Maximum line length: **120 characters** +- Formatter: **CSharpier** (config in `.csharpierrc.yaml`) +- Style enforcement: **EditorConfig** (config in `.editorconfig`) +- Brace style: **Allman** (opening braces on new lines for all constructs) +- Indentation: **4 spaces** (no tabs) +- Line endings: **LF** (Unix-style) + +### String formatting + +- Use **string interpolation** (`$"..."`) for all string formatting +- Use verbatim strings (`@"..."`) for paths and multi-line strings +- Use **double quotes** for all strings + +### Trailing commas + +C# does not enforce trailing commas in the same way as Python. Follow CSharpier's output for +comma placement in multi-line constructs. + +### Brace rules + +Always use braces for control flow statements, even single-line bodies: + +```csharp +// Good +if (template == null) +{ + return; +} + +// Acceptable for simple guard clauses +if (!isActive) + return; +``` + +--- + +## Tooling + +### CSharpier + +CSharpier is the primary formatter. Install and use it before committing: + +```bash +dotnet tool install -g csharpier # Install globally +csharpier . # Format all files +csharpier --check . # Check without modifying (CI mode) +``` + +Configuration lives in `.csharpierrc.yaml`: + +```yaml +printWidth: 120 +useTabs: false +tabWidth: 4 +endOfLine: lf +``` + +### EditorConfig + +The `.editorconfig` file enforces naming conventions, brace style, and spacing rules in +IDEs. It is the source of truth for style rules that CSharpier does not cover (naming, +`var` preferences, expression-bodied members). + +### CSharpier ignore + +The `.csharpierignore` file excludes Unity-generated directories (`Library/`, `Temp/`, +`Logs/`) and third-party packages from formatting. + +--- + +## Configuration files + +Canonical configs are stored in [assets/](assets/). When working in a C# project, verify that +`.csharpierrc.yaml`, `.editorconfig`, and `.csharpierignore` in the project root match these: + +- [assets/.csharpierrc.yaml](assets/.csharpierrc.yaml) +- [assets/.editorconfig](assets/.editorconfig) +- [assets/.csharpierignore](assets/.csharpierignore) + +The `.csharpierignore` contains generic entries only. Individual projects may need additional +project-specific entries (e.g., paths to auto-generated scripts). + +--- + +## Guard clauses and boolean expressions + +Prefer early returns (guard clauses) over deeply nested conditionals. Use explicit boolean +checks, `string.IsNullOrEmpty()` for strings, and `== null` / `!= null` for null checks: + +```csharp +/// Checks if the occupancy duration has been met while the animal is in the zone. +void Update() +{ + if (!isActive || boundaryDisarmed) + return; + + if (string.IsNullOrEmpty(_zoneName)) + return; + + if (_occupancyTimer.IsRunning && inZone) + { + if (_occupancyTimer.ElapsedMilliseconds >= occupancyDurationMs) + { + OnOccupancyMet(); + } + } +} +``` diff --git a/plugins/automation/skills/csharp-style/references/xml-docs-and-types.md b/plugins/automation/skills/csharp-style/references/xml-docs-and-types.md index 0f35f24..95b3ba2 100644 --- a/plugins/automation/skills/csharp-style/references/xml-docs-and-types.md +++ b/plugins/automation/skills/csharp-style/references/xml-docs-and-types.md @@ -472,3 +472,29 @@ List corridors = new List(); // Key-value mapping Dictionary cueIdentifiers = new Dictionary(); ``` + +--- + +## Comments + +### Inline comments + +- Use third person imperative ("Configures..." not "This section configures...") +- Place above the code, not at end of line (unless very short) +- Use comments to explain non-obvious logic or provide context + +```csharp +// Measures actual prefab lengths and compares with configuration. +float[] measuredSegmentLengths = Utility.GetSegmentLengths(segmentPrefabs); +``` + +### What to avoid + +- Don't reiterate the obvious (e.g., `// Set x to 5` before `x = 5`) +- Don't add XML docs to code you didn't write or modify +- Don't use heavy section separator blocks (e.g., `// ======` or `// ------`) +- Don't use `#region` / `#endregion` blocks (use blank lines between logical groups instead) +- Don't use `this.` qualifier (exception: disambiguating a parameter from a field) +- Don't use IDE-specific suppression comments (e.g., ReSharper/Rider `// ReSharper disable` or `// noinspection`). + Remove any you encounter — CSharpier and the EditorConfig-configured analyzers are authoritative; suppress a genuine + analyzer finding only with the standard `#pragma warning disable CODE` or `[SuppressMessage]`, never an IDE directive diff --git a/plugins/automation/skills/explore-dependencies/SKILL.md b/plugins/automation/skills/explore-dependencies/SKILL.md index 308032e..8be09fd 100644 --- a/plugins/automation/skills/explore-dependencies/SKILL.md +++ b/plugins/automation/skills/explore-dependencies/SKILL.md @@ -12,7 +12,7 @@ user-invocable: true # Dependency exploration -Explores installed ataraxis library source code to build a live API snapshot for the +Explores installed ataraxis dependency source code to build a live API snapshot for the current project. You MUST run this skill before writing code that uses ataraxis library features. Static reference @@ -33,9 +33,9 @@ available and how they work. **Does not cover:** - Third-party library exploration (NumPy, Click, etc.) — read their docs directly -- Modifying dependency versions or adding new dependencies (invoke `/pyproject-style`) -- Applying Python coding conventions (invoke `/python-style`) -- Exploring the project's own codebase structure (invoke `/explore-codebase`) +- Modifying dependency versions or adding new dependencies (see `/pyproject-style`) +- Applying Python coding conventions (see `/python-style`) +- Exploring the project's own codebase structure (see `/explore-codebase`) --- diff --git a/plugins/automation/skills/pyproject-style/SKILL.md b/plugins/automation/skills/pyproject-style/SKILL.md index 79ca106..6b4b335 100644 --- a/plugins/automation/skills/pyproject-style/SKILL.md +++ b/plugins/automation/skills/pyproject-style/SKILL.md @@ -29,10 +29,10 @@ pyproject.toml file. You MUST verify your changes against the checklist before s - Project type distinctions (core library vs application, pure-Python vs C-extension) **Does not cover:** -- Python code style (invoke `/python-style`) -- README file conventions (invoke `/readme-style`) -- Commit message conventions (invoke `/commit`) -- tox.ini configuration (invoke `/tox-config`) +- Python code style (see `/python-style`) +- README file conventions (see `/readme-style`) +- Commit message conventions (see `/commit`) +- tox.ini configuration (see `/tox-config`) --- diff --git a/plugins/automation/skills/pyproject-style/references/tool-configurations.md b/plugins/automation/skills/pyproject-style/references/tool-configurations.md index 7527fdf..5a80a2a 100644 --- a/plugins/automation/skills/pyproject-style/references/tool-configurations.md +++ b/plugins/automation/skills/pyproject-style/references/tool-configurations.md @@ -104,7 +104,7 @@ force-sort-within-sections = true # Forces "as" and "from" imports for the same length-sort = true # Places shorter imports first ``` -### Universal ruff ignores +### Universal Ruff ignores These ignores are present in all projects: @@ -126,7 +126,7 @@ lint.ignore = [ ] ``` -### Project-specific ruff ignores +### Project-specific Ruff ignores Add these ignores only when the project requires them: diff --git a/plugins/automation/skills/python-style/SKILL.md b/plugins/automation/skills/python-style/SKILL.md index ed25496..f791feb 100644 --- a/plugins/automation/skills/python-style/SKILL.md +++ b/plugins/automation/skills/python-style/SKILL.md @@ -28,10 +28,10 @@ code. You MUST verify your changes against the checklist before submitting. - Test file conventions **Does not cover:** -- README file conventions (invoke `/readme-style`) -- Commit message conventions (invoke `/commit`) -- Skill file and CLAUDE.md conventions (invoke `/skill-design`) -- Codebase exploration workflows (invoke `/explore-codebase`) +- README file conventions (see `/readme-style`) +- Commit message conventions (see `/commit`) +- Skill file and CLAUDE.md conventions (see `/skill-design`) +- Codebase exploration workflows (see `/explore-codebase`) --- @@ -47,13 +47,13 @@ Read this entire file. The core conventions below apply to ALL Python code. Based on the task, load the appropriate reference files: -| Task | Reference to load | -|------------------------------------------|---------------------------------------------------------------| -| Writing or modifying docstrings/types | [docstrings-and-types.md](references/docstrings-and-types.md) | -| Writing classes, dataclasses, or enums | [class-patterns.md](references/class-patterns.md) | -| Using ataraxis libs, Numba, Click, tests | [libraries-and-tools.md](references/libraries-and-tools.md) | -| Using ataraxis library features | Invoke `/explore-dependencies` first, then load above | -| Reviewing code before submission | [anti-patterns.md](references/anti-patterns.md) | +| Task | Reference to load | +|-------------------------------------------------------|---------------------------------------------------------------| +| Writing or modifying docstrings/types | [docstrings-and-types.md](references/docstrings-and-types.md) | +| Writing classes, dataclasses, enums, or `__init__.py` | [class-patterns.md](references/class-patterns.md) | +| Using ataraxis libs, Numba, Click, tests | [libraries-and-tools.md](references/libraries-and-tools.md) | +| Using ataraxis library features | Invoke `/explore-dependencies` first, then load above | +| Reviewing code before submission | [anti-patterns.md](references/anti-patterns.md) | Load multiple references when the task spans multiple domains. @@ -250,74 +250,8 @@ from .spline_grid import SplineGrid ## \_\_init\_\_.py conventions -There are two types of `__init__.py` files with different docstring requirements. - -### Top-level library \_\_init\_\_.py - -The top-level `__init__.py` (e.g., `src/library_name/__init__.py`) uses an extended docstring with -documentation links and authors: - -```python -"""Provides assets for processing and analyzing neural imaging data. - -See the `documentation `_ for the description of -available assets. See the `source code repository `_ -for more details. - -Authors: Author Name (Handle) -""" - -from .module_one import ClassOne, function_one -from .module_two import ClassTwo, ClassThree - -# console.enable() belongs only in top-level application libraries (e.g., sl-experiment). -# Component libraries must NOT enable console — the application entry point handles this. - -__all__ = [ - "ClassOne", - "ClassThree", - "ClassTwo", - "function_one", -] -``` - -### Subpackage \_\_init\_\_.py - -Subpackage `__init__.py` files (e.g., `src/library_name/subpackage/__init__.py`) use a single-line -docstring only: - -```python -"""Provides configuration and runtime data classes for the processing pipeline.""" - -from .config import Config, Settings -from .data import DataStore - -__all__ = [ - "Config", - "DataStore", - "Settings", -] -``` - -### Rules - -- **Top-level docstring**: The first line MUST be the bare project description — the same sentence - used in all other canonical description locations (`pyproject.toml`, `welcome.rst`, `README.md`) - with no language or project name prefix. Include documentation link, source repository link, - and authors. Email addresses in the `Authors:` line are optional and omitted by default -- **Subpackage docstring**: Use a single-line docstring describing what the subpackage provides. - Do NOT include documentation links, source repository links, or authors — these belong only in - the top-level library `__init__.py` -- **Console initialization**: `console.enable()` belongs only in top-level application libraries - that serve as the final entry point (e.g., `sl-experiment`). Component and dependency libraries - (e.g., `ataraxis-video-system`) must NOT call `console.enable()` — the top-level application - is responsible for enabling the console before any component library code runs -- **Explicit `__all__`**: Every `__init__.py` must declare `__all__` with all public API members -- **Alphabetical sorting**: Sort `__all__` entries alphabetically -- **One-time configuration logic**: `__init__.py` files may contain logic that benefits from - being executed exactly once on import (e.g., setting the multiprocessing start method, - configuring environment variables for platform compatibility). Beyond that, `__init__.py` files - should contain only imports and `__all__` +See [class-patterns.md](references/class-patterns.md) for top-level library and subpackage +`__init__.py` docstring, `__all__`, and console initialization conventions. --- diff --git a/plugins/automation/skills/python-style/references/anti-patterns.md b/plugins/automation/skills/python-style/references/anti-patterns.md index de455ac..06071d0 100644 --- a/plugins/automation/skills/python-style/references/anti-patterns.md +++ b/plugins/automation/skills/python-style/references/anti-patterns.md @@ -86,7 +86,7 @@ Transform code to match project style: |------------------------------------|--------------------------|------------------------------------------------| | `np.zeros((4,), np.float32)` | Positional dtype arg | `np.zeros((4,), dtype=np.float32)` | | `raise ValueError(...)` | Wrong error handling | `console.error(message=..., error=ValueError)` | -| `from typing import Optional` | Old-style optional | Use `Type | +| `from typing import Optional` | Old-style optional | Use `Type \| None` | | `@numba.njit` without `cache=True` | Recompiles every run | `@numba.njit(cache=True)` | | Inconsistent f-string prefixes | Confusing multi-line | Use `f` prefix on all lines | | `'single quotes'` | Violates ruff formatting | Use `"double quotes"` | diff --git a/plugins/automation/skills/python-style/references/class-patterns.md b/plugins/automation/skills/python-style/references/class-patterns.md index 1545f98..e5564f5 100644 --- a/plugins/automation/skills/python-style/references/class-patterns.md +++ b/plugins/automation/skills/python-style/references/class-patterns.md @@ -325,3 +325,76 @@ result = [ iterated once (e.g., passed directly to `sum()`, `any()`, `all()`) - Use explicit loops only when the loop body has **side effects** (I/O, mutation, logging) that do not produce a collection + +--- + +## \_\_init\_\_.py conventions + +There are two types of `__init__.py` files with different docstring requirements. + +### Top-level library \_\_init\_\_.py + +The top-level `__init__.py` (e.g., `src/library_name/__init__.py`) uses an extended docstring with +documentation links and authors: + +```python +"""Provides assets for processing and analyzing neural imaging data. + +See the `documentation `_ for the description of +available assets. See the `source code repository `_ +for more details. + +Authors: Author Name (Handle) +""" + +from .module_one import ClassOne, function_one +from .module_two import ClassTwo, ClassThree + +# console.enable() belongs only in top-level application libraries (e.g., sl-experiment). +# Component libraries must NOT enable console — the application entry point handles this. + +__all__ = [ + "ClassOne", + "ClassThree", + "ClassTwo", + "function_one", +] +``` + +### Subpackage \_\_init\_\_.py + +Subpackage `__init__.py` files (e.g., `src/library_name/subpackage/__init__.py`) use a single-line +docstring only: + +```python +"""Provides configuration and runtime data classes for the processing pipeline.""" + +from .config import Config, Settings +from .data import DataStore + +__all__ = [ + "Config", + "DataStore", + "Settings", +] +``` + +### Rules + +- **Top-level docstring**: The first line MUST be the bare project description — the same sentence + used in all other canonical description locations (`pyproject.toml`, `welcome.rst`, `README.md`) + with no language or project name prefix. Include documentation link, source repository link, + and authors. Email addresses in the `Authors:` line are optional and omitted by default +- **Subpackage docstring**: Use a single-line docstring describing what the subpackage provides. + Do NOT include documentation links, source repository links, or authors — these belong only in + the top-level library `__init__.py` +- **Console initialization**: `console.enable()` belongs only in top-level application libraries + that serve as the final entry point (e.g., `sl-experiment`). Component and dependency libraries + (e.g., `ataraxis-video-system`) must NOT call `console.enable()` — the top-level application + is responsible for enabling the console before any component library code runs +- **Explicit `__all__`**: Every `__init__.py` must declare `__all__` with all public API members +- **Alphabetical sorting**: Sort `__all__` entries alphabetically +- **One-time configuration logic**: `__init__.py` files may contain logic that benefits from + being executed exactly once on import (e.g., setting the multiprocessing start method, + configuring environment variables for platform compatibility). Beyond that, `__init__.py` files + should contain only imports and `__all__` diff --git a/plugins/automation/skills/readme-style/SKILL.md b/plugins/automation/skills/readme-style/SKILL.md index 4a795be..0ee8556 100644 --- a/plugins/automation/skills/readme-style/SKILL.md +++ b/plugins/automation/skills/readme-style/SKILL.md @@ -29,9 +29,9 @@ submitting. - PyPI rendering compatibility **Does not cover:** -- Python code style (invoke `/python-style`) -- Commit message conventions (invoke `/commit`) -- Skill file and CLAUDE.md conventions (invoke `/skill-design`) +- Python code style (see `/python-style`) +- Commit message conventions (see `/commit`) +- Skill file and CLAUDE.md conventions (see `/skill-design`) --- diff --git a/plugins/automation/skills/release/SKILL.md b/plugins/automation/skills/release/SKILL.md index 494b6dc..a915a22 100644 --- a/plugins/automation/skills/release/SKILL.md +++ b/plugins/automation/skills/release/SKILL.md @@ -177,7 +177,7 @@ Release Notes Compliance: - [ ] Sibling-library versions confirmed by the user (sollertia only) - [ ] `**Major Changes:**` numbered list ordered from most to least impactful - [ ] Each item is past tense and ends with a period -- [ ] Condenses many pull requests into a few impactful themes (does not list every PR) +- [ ] Condenses many pull requests into a few impactful themes (does not list every pull request) - [ ] Does NOT include `## What's Changed` or `**Full Changelog**` - [ ] Contains NO authorship details, co-author tags, or attribution - [ ] Contains NO references to tools or AI unless explicitly requested by the user diff --git a/plugins/automation/skills/skill-design/references/anti-patterns.md b/plugins/automation/skills/skill-design/references/anti-patterns.md index eeb3ba0..d75cff4 100644 --- a/plugins/automation/skills/skill-design/references/anti-patterns.md +++ b/plugins/automation/skills/skill-design/references/anti-patterns.md @@ -49,7 +49,7 @@ inconsistently. **Wrong:** A single skill covering Python style, README formatting, commit messages, and skill design. -**Correct:** Four separate skills (`/python-style`, `/commit`, `/skill-design`) each with a +**Correct:** Four separate skills (`/python-style`, `/readme-style`, `/commit`, `/skill-design`) each with a focused scope declaration. ### Missing trigger conditions diff --git a/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md b/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md index 26fd740..c1e54d6 100644 --- a/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md +++ b/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md @@ -215,7 +215,7 @@ session. ## Proactive behavior -You SHOULD proactively invoke this skill when: +You should proactively invoke this skill when: - A session begins and MCP tools from the ataraxis-communication-interface server are expected but unavailable - Any ataraxis-communication-interface MCP tool call fails with a connection or server error - The user mentions issues with MCP server connectivity or environment setup diff --git a/plugins/communication/skills/extraction-configuration/SKILL.md b/plugins/communication/skills/extraction-configuration/SKILL.md index 239617f..0ba92a3 100644 --- a/plugins/communication/skills/extraction-configuration/SKILL.md +++ b/plugins/communication/skills/extraction-configuration/SKILL.md @@ -292,15 +292,15 @@ controllers: ## Related skills -| Skill | Relationship | -|------------------------------|------------------------------------------------------------------| -| `/microcontroller-setup` | Upstream: manifest creation and recording discovery | -| `/microcontroller-interface` | Upstream: code that produces the manifests used here | -| `/log-input-format` | Reference: archive format that extraction config targets | -| `/log-processing` | Downstream: consumes the validated extraction config | -| `/log-processing-results` | Downstream: output format depends on config targets | -| `/pipeline` | Context: extraction config is phase 3 of the end-to-end pipeline | -| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for config tools | +| Skill | Relationship | +|----------------------------------------|------------------------------------------------------------------| +| `/microcontroller-setup` | Upstream: manifest creation and recording discovery | +| `/microcontroller-interface` | Upstream: code that produces the manifests used here | +| `/log-input-format` | Reference: archive format that extraction config targets | +| `/log-processing` | Downstream: consumes the validated extraction config | +| `/log-processing-results` | Downstream: output format depends on config targets | +| `/pipeline` | Context: extraction config is phase 3 of the end-to-end pipeline | +| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for config tools | --- diff --git a/plugins/communication/skills/log-input-format/SKILL.md b/plugins/communication/skills/log-input-format/SKILL.md index 0714cb6..17d82d4 100644 --- a/plugins/communication/skills/log-input-format/SKILL.md +++ b/plugins/communication/skills/log-input-format/SKILL.md @@ -106,7 +106,7 @@ controller-produced log archives. Directories without a `microcontroller_manifes discovered. Manifests also associate controller IDs with human-readable names and enumerate the hardware modules managed by each controller. -**Key difference from axvs manifests:** AXCI manifests include a `modules` list per controller, providing +**Key difference from AXVS manifests:** AXCI manifests include a `modules` list per controller, providing full hardware module metadata (type, id, name). AXVS camera manifests only have source ID and camera name. --- @@ -188,7 +188,7 @@ recording_root/ Each log directory is an **independent processing unit**. The discovery tool groups archives by their parent directory, and each directory is prepared and processed independently. -### Mixed axvs and axci recording +### Mixed AXVS and AXCI recording When microcontrollers and cameras share a DataLogger, the log directory contains both types of manifests and archives. The AXCI processing pipeline only processes archives referenced in the @@ -315,15 +315,15 @@ Before running the log processing pipeline, verify these conditions: ## Related skills -| Skill | Relationship | -|------------------------------|----------------------------------------------------------------------| -| `/microcontroller-setup` | Upstream: MCP tools that assemble and discover archives | -| `/microcontroller-interface` | Upstream: MicroControllerInterface instances that produce log data | -| `/extraction-configuration` | Context: extraction config determines which messages are extracted | -| `/log-processing` | Downstream: consumes archives in the format documented here | -| `/log-processing-results` | Downstream: documents the output format produced from these archives | -| `/pipeline` | Context: reference skill for the end-to-end pipeline phases | -| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for discovery and processing | +| Skill | Relationship | +|----------------------------------------|----------------------------------------------------------------------| +| `/microcontroller-setup` | Upstream: MCP tools that assemble and discover archives | +| `/microcontroller-interface` | Upstream: MicroControllerInterface instances that produce log data | +| `/extraction-configuration` | Context: extraction config determines which messages are extracted | +| `/log-processing` | Downstream: consumes archives in the format documented here | +| `/log-processing-results` | Downstream: documents the output format produced from these archives | +| `/pipeline` | Context: reference skill for the end-to-end pipeline phases | +| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for discovery and processing | --- diff --git a/plugins/communication/skills/log-processing-results/SKILL.md b/plugins/communication/skills/log-processing-results/SKILL.md index 6f10394..d3676fc 100644 --- a/plugins/communication/skills/log-processing-results/SKILL.md +++ b/plugins/communication/skills/log-processing-results/SKILL.md @@ -258,15 +258,15 @@ To determine detailed job status, use `get_batch_status_overview_tool` from `/lo ## Related skills -| Skill | Relationship | -|------------------------------|---------------------------------------------------------------------| -| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for tool access | -| `/microcontroller-setup` | Upstream: MCP discovery tools that locate archives and recordings | -| `/microcontroller-interface` | Upstream: code that produces the data analyzed here | -| `/extraction-configuration` | Context: extraction config determines which events appear in output | -| `/log-input-format` | Reference: input archive format and source ID semantics | -| `/log-processing` | Upstream: processing workflow that produces this output | -| `/pipeline` | Context: results analysis is phase 6 of the end-to-end pipeline | +| Skill | Relationship | +|----------------------------------------|---------------------------------------------------------------------| +| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for tool access | +| `/microcontroller-setup` | Upstream: MCP discovery tools that locate archives and recordings | +| `/microcontroller-interface` | Upstream: code that produces the data analyzed here | +| `/extraction-configuration` | Context: extraction config determines which events appear in output | +| `/log-input-format` | Reference: input archive format and source ID semantics | +| `/log-processing` | Upstream: processing workflow that produces this output | +| `/pipeline` | Context: results analysis is phase 6 of the end-to-end pipeline | --- diff --git a/plugins/communication/skills/log-processing/SKILL.md b/plugins/communication/skills/log-processing/SKILL.md index b44beaf..c3fb65e 100644 --- a/plugins/communication/skills/log-processing/SKILL.md +++ b/plugins/communication/skills/log-processing/SKILL.md @@ -111,10 +111,10 @@ directories. For legacy sessions without manifests, use `write_microcontroller_m **`execute_log_processing_jobs_tool` parameters:** -| Parameter | Type | Default | Description | -|-----------------|--------------|------------|-----------------------------------------------------------------------------------------------------------------------| -| `jobs` | `list[dict]` | (required) | Job descriptors from prepare manifest (log_directory, output_directory, tracker_path, job_id, source_id, config_path) | -| `worker_budget` | `int` | `-1` | Total CPU cores for the session; -1 for automatic resolution. Controls memory footprint. | +| Parameter | Type | Default | Description | +|-----------------|--------------|------------|-------------------------------------------------------------------------------------------------------------------------| +| `jobs` | `list[dict]` | (required) | Job descriptors from execution manifest (log_directory, output_directory, tracker_path, job_id, source_id, config_path) | +| `worker_budget` | `int` | `-1` | Total CPU cores for the session; -1 for automatic resolution. Controls memory footprint. | ### Monitoring and management tools @@ -224,7 +224,7 @@ The processing workflow uses a **prepare-then-execute** model: the budget controls memory footprint and the system allocates workers per job automatically based on archive size. -8. **Execute jobs** — Call `execute_log_processing_jobs_tool` with the job descriptors from the prepare +8. **Execute jobs** — Call `execute_log_processing_jobs_tool` with the job descriptors from the execution manifest and confirmed resource settings. 9. **Monitor progress** — Use `get_log_processing_status_tool` to check per-job progress. Optionally use @@ -311,13 +311,13 @@ To re-process an entire directory from scratch, call `clean_log_processing_outpu ### Preparation errors -| Error | Resolution | -|--------------------------------------|-------------------------------------------------------------------| +| Error | Resolution | +|---------------------------------------|------------------------------------------------------------------------------------------------------------| | Non-existent / non-directory log path | Not a hard error; surfaces in the returned `invalid_paths` list. Verify the path exists and is a directory | -| "Length mismatch" | Ensure output_directories matches log_directories length | -| "Permission denied" | Check filesystem permissions | -| "Extraction config not found: ..." | Verify extraction config path; use `/extraction-configuration` | -| "Invalid extraction config: ..." | Validate config via `/extraction-configuration` | +| "Length mismatch" | Ensure output_directories matches log_directories length | +| "Permission denied" | Check filesystem permissions | +| "Extraction config not found: ..." | Verify extraction config path; use `/extraction-configuration` | +| "Invalid extraction config: ..." | Validate config via `/extraction-configuration` | ### Execution errors @@ -329,27 +329,27 @@ To re-process an entire directory from scratch, call `clean_log_processing_outpu ### Processing failure routing -| Error Pattern | Action | -|--------------------------------------|---------------------------------------------------------------| -| Archive not found / file read errors | Verify .npz archives exist in log directory | -| Invalid extraction config | Validate config via `/extraction-configuration` | -| MCP tools unavailable | Invoke `/communication-mcp-environment-setup` | -| Out of memory | Reduce `worker_budget` | -| Corrupt tracker or partial output | Call `clean_log_processing_output_tool`, then re-prepare | +| Error Pattern | Action | +|--------------------------------------|----------------------------------------------------------| +| Archive not found / file read errors | Verify .npz archives exist in log directory | +| Invalid extraction config | Validate config via `/extraction-configuration` | +| MCP tools unavailable | Invoke `/communication-mcp-environment-setup` | +| Out of memory | Reduce `worker_budget` | +| Corrupt tracker or partial output | Call `clean_log_processing_output_tool`, then re-prepare | --- ## Related skills -| Skill | Role | -|------------------------------|------------------------------------------------------------------| -| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity | -| `/microcontroller-setup` | Upstream: hardware discovery and manifest management | -| `/microcontroller-interface` | Upstream: code that produces the log data being processed | -| `/extraction-configuration` | Upstream: extraction config that controls what data is extracted | -| `/log-input-format` | Reference: input archive format and source ID semantics | -| `/log-processing-results` | Downstream: output data discovery and event analysis | -| `/pipeline` | Context: log processing is phase 5 of the end-to-end pipeline | +| Skill | Relationship | +|----------------------------------------|------------------------------------------------------------------| +| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity | +| `/microcontroller-setup` | Upstream: hardware discovery and manifest management | +| `/microcontroller-interface` | Upstream: code that produces the log data being processed | +| `/extraction-configuration` | Upstream: extraction config that controls what data is extracted | +| `/log-input-format` | Reference: input archive format and source ID semantics | +| `/log-processing-results` | Downstream: output data discovery and event analysis | +| `/pipeline` | Context: log processing is phase 5 of the end-to-end pipeline | --- diff --git a/plugins/communication/skills/microcontroller-interface/SKILL.md b/plugins/communication/skills/microcontroller-interface/SKILL.md index bb04233..7116d32 100644 --- a/plugins/communication/skills/microcontroller-interface/SKILL.md +++ b/plugins/communication/skills/microcontroller-interface/SKILL.md @@ -5,7 +5,8 @@ description: >- instances for microcontroller communication. Covers MicroControllerInterface initialization and lifecycle, ModuleInterface subclassing with command and parameter sending, MQTTCommunication setup, system ID allocation, and DataLogger integration. Use when writing code that creates - MicroControllerInterface or MQTTCommunication instances or needs to understand the AXCI API. + MicroControllerInterface or MQTTCommunication instances or needs to understand the + ataraxis-communication-interface API. user-invocable: false --- @@ -94,7 +95,8 @@ See [references/api-reference.md](references/api-reference.md) for the complete - MQTTCommunication constructor and lifecycle methods - All public data classes (ModuleData, ModuleState, ModuleSourceData, MicroControllerSourceData) - Configuration classes (MicroControllerManifest, ExtractionConfig hierarchy) -- Constants and utility functions +- Constants, utility functions, the message protocol, data payload types, the keepalive mechanism, + DataLogger topology, and the MCP-to-code parameter bridge --- @@ -328,100 +330,19 @@ MQTTCommunication() → connect() → [publish/subscribe] → disconnect() ## Message protocol -All PC-microcontroller communication uses a structured message protocol with typed messages identified -by protocol codes. Understanding this protocol is essential for debugging communication issues. - -### Outgoing messages (PC → microcontroller) - -| Protocol Code | Message Type | Description | -|---------------|-----------------------|-----------------------------------------------------------| -| 1 | RepeatedModuleCommand | Module command that executes recurrently at a cycle delay | -| 2 | OneOffModuleCommand | Module command that executes once | -| 3 | DequeueModuleCommand | Removes all queued commands from a module | -| 4 | KernelCommand | System-level command (reset, identify, keepalive) | -| 5 | ModuleParameters | Sets runtime parameters on a module | - -### Incoming messages (microcontroller → PC) - -| Protocol Code | Message Type | Description | -|---------------|--------------------------|----------------------------------------------------------------| -| 6 | ModuleData | Module event with a typed data payload (command, event, data) | -| 7 | KernelData | Kernel event with a typed data payload (command, event, data) | -| 8 | ModuleState | Module event without data (command, event only) | -| 9 | KernelState | Kernel event without data (command, event only) | -| 10 | ReceptionCode | Acknowledgement that the microcontroller received a PC message | -| 11 | ControllerIdentification | Microcontroller ID response during initialization | -| 12 | ModuleIdentification | Module type+id response during initialization | - -### Event code ranges - -| Range | Owner | Description | -|-------|--------|--------------------------------------------------------------------------------| -| 1-50 | System | Reserved service codes for internal module status (errors, command completion) | -| 51+ | User | User-defined event codes for application-specific data and state messages | - -Event codes are unique within each module and within the kernel — the same code always carries the -same semantic meaning regardless of which command was executing when the message was sent. This means -event codes identify the *type* of event, not a command-specific response. The extraction pipeline -and `process_received_data()` both rely on this invariant. - -Messages with event codes in the user range (51+) and matching a module's `data_codes` set are -routed to `process_received_data()`. Messages with event codes matching `error_codes` raise -`RuntimeError` and abort the runtime. +See [references/api-reference.md](references/api-reference.md) for the message protocol and code tables. --- ## Supported data payload types -The firmware resolves prototype codes at compile time for all data transmitted via `SendData()`. The -PC side deserializes them into numpy values. The `data_object` field in `ModuleData` and the -`dtype`/`data` columns in processed feather files use numpy types from this table. - -| Numpy Type | C++ Equivalent | Size | Supported Element Counts | -|--------------|----------------|---------|----------------------------------------------------------------------------------| -| `np.bool_` | `bool` | 1 byte | 1-15, 16, 24, 32, 40, 48, 52, 248 | -| `np.uint8` | `uint8_t` | 1 byte | 1-15, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 64, 96, 128, 192, 244, 248 | -| `np.int8` | `int8_t` | 1 byte | 1-15, 16, 24, 32, 40, 48, 52, 92, 132, 172, 212, 244, 248 | -| `np.uint16` | `uint16_t` | 2 bytes | 1-15, 16, 20, 24, 26, 32, 48, 64, 96, 122, 124 | -| `np.int16` | `int16_t` | 2 bytes | 1-15, 16, 20, 24, 26, 32, 48, 64, 96, 122, 124 | -| `np.uint32` | `uint32_t` | 4 bytes | 1-15, 16, 20, 24, 32, 48, 62 | -| `np.int32` | `int32_t` | 4 bytes | 1-15, 16, 20, 24, 32, 48, 62 | -| `np.float32` | `float` | 4 bytes | 1-15, 16, 20, 24, 32, 48, 62 | -| `np.uint64` | `uint64_t` | 8 bytes | 1-15, 16, 20, 24, 31 | -| `np.int64` | `int64_t` | 8 bytes | 1-15, 16, 20, 24, 31 | -| `np.float64` | `double` | 8 bytes | 1-15, 16, 20, 24, 31 | - -An element count of 1 represents a scalar value. For arrays, `ModuleData.data_object` is a numpy -array of the corresponding dtype. The maximum payload is 248 bytes; array element counts are -constrained by `floor(248 / element_size)`. `uint8` arrays have the densest count coverage and can -serve as a generic bytes buffer for packed structures. +See [references/api-reference.md](references/api-reference.md) for data payload types and element counts. --- ## Keepalive mechanism -The keepalive system detects communication failures between the PC and the microcontroller during -runtime. It is optional and controlled by the `keepalive_interval` constructor parameter. - -**How it works:** -1. When `keepalive_interval > 0`, the PC sends a KernelCommand (command code 5) to the - microcontroller at the specified interval (in milliseconds) -2. The microcontroller's Kernel tracks the time since the last received keepalive message -3. If the microcontroller does not receive a keepalive within its configured timeout, it performs - an emergency reset (all modules return to default state) and reports error code 10 - (KEEPALIVE_TIMEOUT) via a KernelData message - -**When to enable:** -- Enable keepalive for safety-critical hardware that must be reset if the PC loses communication - (e.g., actuators, valves, motors) -- Disable (`keepalive_interval=0`) for passive sensors or when the microcontroller firmware does - not implement keepalive handling - -**Debugging keepalive issues:** -- Error code 10 with a timeout duration in the data payload indicates the microcontroller - triggered an emergency reset due to missed keepalive messages -- Common causes: PC process stalled, serial buffer overflow, USB disconnection, CPU contention - preventing the communication process from sending keepalive messages on time +See [references/api-reference.md](references/api-reference.md) for the keepalive mechanism and debugging. --- @@ -500,37 +421,13 @@ advised ranges. ## DataLogger topology -A single shared DataLogger is the preferred topology: - -```python -logger = DataLogger(output_directory=session_directory, instance_name="session") -logger.start() - -ctrl1 = MicroControllerInterface(controller_id=np.uint8(101), data_logger=logger, ...) -ctrl2 = MicroControllerInterface(controller_id=np.uint8(102), data_logger=logger, ...) -``` - -All controllers sharing one logger: correlated timestamps, single archive assembly, single processing batch. - -### Coordinated lifecycle ordering - -```text -Startup: DataLogger.start() → MCI.__init__() → MCI.start() -Shutdown: MCI.stop() → DataLogger.stop() → assemble_log_archives() -``` +See [references/api-reference.md](references/api-reference.md) for DataLogger topology and lifecycle ordering. --- ## Bridge from MCP -### What MCP testing reveals for code - -| MCP Discovery | Informs Code Parameter | How | -|-----------------------------------------------|-------------------------------|---------------------------| -| Device path from `list_microcontrollers_tool` | `port` | Pass device path directly | -| Microcontroller ID | `controller_id` | Use as `np.uint8(id)` | -| Baudrate used in discovery | `baudrate` | Same value | -| MQTT broker from `check_mqtt_broker_tool` | `MQTTCommunication(ip, port)` | Pass to MQTT constructor | +See [references/api-reference.md](references/api-reference.md) for the MCP-to-code parameter mapping table. --- @@ -559,16 +456,16 @@ Shutdown: MCI.stop() → DataLogger.stop() → assemble_log_archives() ## Related skills -| Skill | Relationship | -|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `/microcontroller:firmware-module` | Firmware-side counterpart: use for C++ Module subclassing, command handlers, parameter structs, and main.cpp integration. Codes and parameter layouts must match. | -| `/microcontroller-setup` | Covers MCP-based discovery, MQTT testing, and manifest management | -| `/extraction-configuration` | Downstream: configure extraction parameters before processing | -| `/log-input-format` | Reference: documents archive format produced by this code | -| `/log-processing` | Downstream: processes archives from MicroControllerInterface data | -| `/log-processing-results` | Downstream: analyzes output from processed archives | -| `/pipeline` | Context: end-to-end orchestration and multi-controller planning | -| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for API verification | +| Skill | Relationship | +|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `/microcontroller:firmware-module` | Firmware-side counterpart: use for C++ Module subclassing, command handlers, parameter structs, and main.cpp integration. Codes and parameter layouts must match. | +| `/microcontroller-setup` | Covers MCP-based discovery, MQTT testing, and manifest management | +| `/extraction-configuration` | Downstream: configure extraction parameters before processing | +| `/log-input-format` | Reference: documents archive format produced by this code | +| `/log-processing` | Downstream: processes archives from MicroControllerInterface data | +| `/log-processing-results` | Downstream: analyzes output from processed archives | +| `/pipeline` | Context: end-to-end orchestration and multi-controller planning | +| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for API verification | --- diff --git a/plugins/communication/skills/microcontroller-interface/references/api-reference.md b/plugins/communication/skills/microcontroller-interface/references/api-reference.md index bb80a7e..9bb60a2 100644 --- a/plugins/communication/skills/microcontroller-interface/references/api-reference.md +++ b/plugins/communication/skills/microcontroller-interface/references/api-reference.md @@ -68,11 +68,11 @@ MicroControllerInterface( ### Methods -| Method | Returns | Description | -|----------------------|---------|--------------------------------------------------------------------------| -| `start()` | `None` | Spawns communication process, verifies identities, enters comm cycle. | -| `stop()` | `None` | Terminates communication process and releases all resources. | -| `reset_controller()` | `None` | Resets the microcontroller to its default state. | +| Method | Returns | Description | +|----------------------|---------|--------------------------------------------------------------------------------| +| `start()` | `None` | Spawns communication process, verifies identities, enters communication cycle. | +| `stop()` | `None` | Terminates communication process and releases all resources. | +| `reset_controller()` | `None` | Resets the microcontroller to its default state. | ### Properties @@ -100,29 +100,29 @@ ModuleInterface( ) ``` -| Parameter | Type | Default | Description | -|---------------|------------------------|---------|--------------------------------------------------| -| `module_type` | `np.uint8` | - | Module family code (1-255). Matches firmware. | -| `module_id` | `np.uint8` | - | Module instance ID (1-255). Matches firmware. | -| `name` | `str` | - | Human-readable name. Written to manifest. | -| `error_codes` | `set[np.uint8] / None` | `None` | Event codes that trigger RuntimeError. | -| `data_codes` | `set[np.uint8] / None` | `None` | Event codes routed to `process_received_data()`. | +| Parameter | Type | Default | Description | +|---------------|-------------------------|------------|--------------------------------------------------| +| `module_type` | `np.uint8` | (required) | Module family code (1-255). Matches firmware. | +| `module_id` | `np.uint8` | (required) | Module instance ID (1-255). Matches firmware. | +| `name` | `str` | (required) | Human-readable name. Written to manifest. | +| `error_codes` | `set[np.uint8] \| None` | `None` | Event codes that trigger RuntimeError. | +| `data_codes` | `set[np.uint8] \| None` | `None` | Event codes routed to `process_received_data()`. | ### Abstract methods -| Method | Args | Description | -|----------------------------------|----------------------------|------------------------------------------------------| -| `initialize_remote_assets()` | None | Initialize non-picklable resources for comm process. | -| `terminate_remote_assets()` | None | Release resources from `initialize_remote_assets`. | -| `process_received_data(message)` | `ModuleData / ModuleState` | Handle data_codes messages. Keep fast. | +| Method | Args | Description | +|----------------------------------|-----------------------------|----------------------------------------------------------------| +| `initialize_remote_assets()` | `None` | Initializes non-picklable resources for communication process. | +| `terminate_remote_assets()` | `None` | Releases resources from `initialize_remote_assets`. | +| `process_received_data(message)` | `ModuleData \| ModuleState` | Handles `data_codes` messages. Keeps fast. | ### Command methods -| Method | Key Parameters | Description | -|-------------------------|--------------------------------------------------------------------------------------------------|-----------------------------------| -| `send_command()` | `command: np.uint8, noblock: np.bool_, repetition_delay: np.uint32 = 0` | Send command to module. | -| `send_parameters()` | `parameter_data: tuple[np.unsignedinteger \| np.signedinteger \| np.bool_ \| np.floating, ...]` | Send parameters to module. | -| `reset_command_queue()` | None | Clear the module's command queue. | +| Method | Key Parameters | Description | +|-------------------------|-------------------------------------------------------------------------------------------------|------------------------------------| +| `send_command()` | `command: np.uint8, noblock: np.bool_, repetition_delay: np.uint32 = 0` | Sends command to module. | +| `send_parameters()` | `parameter_data: tuple[np.unsignedinteger \| np.signedinteger \| np.bool_ \| np.floating, ...]` | Sends parameters to module. | +| `reset_command_queue()` | `None` | Clears the module's command queue. | ### Properties @@ -154,20 +154,20 @@ MQTTCommunication( ) ``` -| Parameter | Type | Default | Description | -|--------------------|--------------------------|---------------|----------------------------------------| -| `ip` | `str` | `"127.0.0.1"` | MQTT broker IP address. | -| `port` | `int` | `1883` | MQTT broker socket port. | -| `monitored_topics` | `tuple[str, ...] / None` | `None` | Topics to subscribe for incoming data. | +| Parameter | Type | Default | Description | +|--------------------|---------------------------|---------------|----------------------------------------| +| `ip` | `str` | `"127.0.0.1"` | MQTT broker IP address. | +| `port` | `int` | `1883` | MQTT broker socket port. | +| `monitored_topics` | `tuple[str, ...] \| None` | `None` | Topics to subscribe for incoming data. | ### Methods -| Method | Returns | Description | -|------------------------------------|--------------------------------------------|-------------------------------------------------------------------| -| `connect()` | `None` | Connects to broker and subscribes to monitored topics. | -| `disconnect()` | `None` | Disconnects from broker. Called automatically on garbage collect. | -| `send_data(topic, payload=None)` | `None` | Publishes data to the specified MQTT topic. | -| `get_data()` | `tuple[str, bytes \| bytearray] \| None` | Returns next received `(topic, payload)` or `None` if empty. | +| Method | Returns | Description | +|----------------------------------|------------------------------------------|-------------------------------------------------------------------| +| `connect()` | `None` | Connects to broker and subscribes to monitored topics. | +| `disconnect()` | `None` | Disconnects from broker. Called automatically on garbage collect. | +| `send_data(topic, payload=None)` | `None` | Publishes data to the specified MQTT topic. | +| `get_data()` | `tuple[str, bytes \| bytearray] \| None` | Returns next received `(topic, payload)` or `None` if empty. | ### Properties @@ -233,9 +233,9 @@ Per-controller identification metadata for manifests. Registry of controllers and their modules within a DataLogger output directory. -| Field | Type | Description | -|---------------|---------------------------------------|----------------------------------| -| `controllers` | `list[MicroControllerSourceData]` | Registered controller entries. | +| Field | Type | Description | +|---------------|-----------------------------------|--------------------------------| +| `controllers` | `list[MicroControllerSourceData]` | Registered controller entries. | Methods: `save(file_path)`, `load(file_path)` (classmethod). @@ -255,7 +255,7 @@ Methods: `save(file_path)`, `load(file_path)` (classmethod). |-----------------|--------------------------------------|--------------------------------| | `controller_id` | `int` | Controller ID to extract from. | | `modules` | `tuple[ModuleExtractionConfig, ...]` | Module extraction entries. | -| `kernel` | `KernelExtractionConfig / None` | Optional kernel extraction. | +| `kernel` | `KernelExtractionConfig \| None` | Optional kernel extraction. | ### ModuleExtractionConfig (frozen dataclass) @@ -332,3 +332,138 @@ IDs to process are resolved from the config. Prefer MCP batch tools for multi-ar - numpy, polars, paho-mqtt, click, httpx - ataraxis-time, ataraxis-base-utilities, ataraxis-data-structures, ataraxis-transport-layer-pc - mcp (for MCP server) + +--- + +## Message protocol + +All PC-microcontroller communication uses a structured message protocol with typed messages identified +by protocol codes. Understanding this protocol is essential for debugging communication issues. + +### Outgoing messages (PC → microcontroller) + +| Protocol Code | Message Type | Description | +|---------------|-----------------------|-----------------------------------------------------------| +| 1 | RepeatedModuleCommand | Module command that executes recurrently at a cycle delay | +| 2 | OneOffModuleCommand | Module command that executes once | +| 3 | DequeueModuleCommand | Removes all queued commands from a module | +| 4 | KernelCommand | System-level command (reset, identify, keepalive) | +| 5 | ModuleParameters | Sets runtime parameters on a module | + +### Incoming messages (microcontroller → PC) + +| Protocol Code | Message Type | Description | +|---------------|--------------------------|----------------------------------------------------------------| +| 6 | ModuleData | Module event with a typed data payload (command, event, data) | +| 7 | KernelData | Kernel event with a typed data payload (command, event, data) | +| 8 | ModuleState | Module event without data (command, event only) | +| 9 | KernelState | Kernel event without data (command, event only) | +| 10 | ReceptionCode | Acknowledgement that the microcontroller received a PC message | +| 11 | ControllerIdentification | Microcontroller ID response during initialization | +| 12 | ModuleIdentification | Module type+id response during initialization | + +### Event code ranges + +| Range | Owner | Description | +|-------|--------|--------------------------------------------------------------------------------| +| 1-50 | System | Reserved service codes for internal module status (errors, command completion) | +| 51+ | User | User-defined event codes for application-specific data and state messages | + +Event codes are unique within each module and within the kernel — the same code always carries the +same semantic meaning regardless of which command was executing when the message was sent. This means +event codes identify the *type* of event, not a command-specific response. The extraction pipeline +and `process_received_data()` both rely on this invariant. + +Messages with event codes in the user range (51+) and matching a module's `data_codes` set are +routed to `process_received_data()`. Messages with event codes matching `error_codes` raise +`RuntimeError` and abort the runtime. + +--- + +## Supported data payload types + +The firmware resolves prototype codes at compile time for all data transmitted via `SendData()`. The +PC side deserializes them into numpy values. The `data_object` field in `ModuleData` and the +`dtype`/`data` columns in processed feather files use numpy types from this table. + +| Numpy Type | C++ Equivalent | Size | Supported Element Counts | +|--------------|----------------|---------|----------------------------------------------------------------------------------| +| `np.bool_` | `bool` | 1 byte | 1-15, 16, 24, 32, 40, 48, 52, 248 | +| `np.uint8` | `uint8_t` | 1 byte | 1-15, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 64, 96, 128, 192, 244, 248 | +| `np.int8` | `int8_t` | 1 byte | 1-15, 16, 24, 32, 40, 48, 52, 92, 132, 172, 212, 244, 248 | +| `np.uint16` | `uint16_t` | 2 bytes | 1-15, 16, 20, 24, 26, 32, 48, 64, 96, 122, 124 | +| `np.int16` | `int16_t` | 2 bytes | 1-15, 16, 20, 24, 26, 32, 48, 64, 96, 122, 124 | +| `np.uint32` | `uint32_t` | 4 bytes | 1-15, 16, 20, 24, 32, 48, 62 | +| `np.int32` | `int32_t` | 4 bytes | 1-15, 16, 20, 24, 32, 48, 62 | +| `np.float32` | `float` | 4 bytes | 1-15, 16, 20, 24, 32, 48, 62 | +| `np.uint64` | `uint64_t` | 8 bytes | 1-15, 16, 20, 24, 31 | +| `np.int64` | `int64_t` | 8 bytes | 1-15, 16, 20, 24, 31 | +| `np.float64` | `double` | 8 bytes | 1-15, 16, 20, 24, 31 | + +An element count of 1 represents a scalar value. For arrays, `ModuleData.data_object` is a numpy +array of the corresponding dtype. The maximum payload is 248 bytes; array element counts are +constrained by `floor(248 / element_size)`. `uint8` arrays have the densest count coverage and can +serve as a generic bytes buffer for packed structures. + +--- + +## Keepalive mechanism + +The keepalive system detects communication failures between the PC and the microcontroller during +runtime. It is optional and controlled by the `keepalive_interval` constructor parameter. + +**How it works:** +1. When `keepalive_interval > 0`, the PC sends a KernelCommand (command code 5) to the + microcontroller at the specified interval (in milliseconds) +2. The microcontroller's Kernel tracks the time since the last received keepalive message +3. If the microcontroller does not receive a keepalive within its configured timeout, it performs + an emergency reset (all modules return to default state) and reports error code 10 + (KEEPALIVE_TIMEOUT) via a KernelData message + +**When to enable:** +- Enable keepalive for safety-critical hardware that must be reset if the PC loses communication + (e.g., actuators, valves, motors) +- Disable (`keepalive_interval=0`) for passive sensors or when the microcontroller firmware does + not implement keepalive handling + +**Debugging keepalive issues:** +- Error code 10 with a timeout duration in the data payload indicates the microcontroller + triggered an emergency reset due to missed keepalive messages +- Common causes: PC process stalled, serial buffer overflow, USB disconnection, CPU contention + preventing the communication process from sending keepalive messages on time + +--- + +## Bridge from MCP + +### What MCP testing reveals for code + +| MCP Discovery | Informs Code Parameter | How | +|-----------------------------------------------|-------------------------------|---------------------------| +| Device path from `list_microcontrollers_tool` | `port` | Pass device path directly | +| Microcontroller ID | `controller_id` | Use as `np.uint8(id)` | +| Baudrate used in discovery | `baudrate` | Same value | +| MQTT broker from `check_mqtt_broker_tool` | `MQTTCommunication(ip, port)` | Pass to MQTT constructor | + +--- + +## DataLogger topology + +A single shared DataLogger is the preferred topology: + +```python +logger = DataLogger(output_directory=session_directory, instance_name="session") +logger.start() + +ctrl1 = MicroControllerInterface(controller_id=np.uint8(101), data_logger=logger, ...) +ctrl2 = MicroControllerInterface(controller_id=np.uint8(102), data_logger=logger, ...) +``` + +All controllers sharing one logger: correlated timestamps, single archive assembly, single processing batch. + +### Coordinated lifecycle ordering + +```text +Startup: DataLogger.start() → MCI.__init__() → MCI.start() +Shutdown: MCI.stop() → DataLogger.stop() → assemble_log_archives() +``` diff --git a/plugins/communication/skills/microcontroller-setup/SKILL.md b/plugins/communication/skills/microcontroller-setup/SKILL.md index 095f3d0..9ba7796 100644 --- a/plugins/communication/skills/microcontroller-setup/SKILL.md +++ b/plugins/communication/skills/microcontroller-setup/SKILL.md @@ -117,7 +117,7 @@ total_controllers: Number of registered controllers | `controller_name` | `str` | (required) | Human-readable name for the controller | | `modules` | `list[dict]` | (required) | Module descriptors: each must have `module_type`, `module_id`, `name` | -**Important:** The agent MUST know the controller ID, name, and module details. Do not guess these values. +**Important:** You MUST know the controller ID, name, and module details. Do not guess these values. Each module dictionary must have keys: `module_type` (int), `module_id` (int), `name` (str). Creates a new manifest if none exists; appends to the existing manifest otherwise. @@ -230,7 +230,7 @@ When transitioning from MCP-based discovery to writing MicroControllerInterface | Baudrate used in discovery | `baudrate` | Same value (default: 115200) | | MQTT broker host/port | `MQTTCommunication(ip, port)` | Pass to MQTTCommunication constructor | -### System ID semantics +### Source ID semantics | Range | Assignment | Notes | |---------|------------------------------------|---------------------------------------------------| @@ -260,15 +260,15 @@ advised ranges. ## Related skills -| Skill | Relationship | -|------------------------------|--------------------------------------------------------------------| -| `/microcontroller-interface` | Covers writing MicroControllerInterface code after testing via MCP | -| `/extraction-configuration` | Downstream: configure extraction parameters before processing | -| `/log-input-format` | Reference: documents the archive format produced by this workflow | -| `/log-processing` | Downstream: processes archives assembled by this skill | -| `/log-processing-results` | Downstream: analyzes output from processed archives | -| `/pipeline` | Context: end-to-end orchestration and multi-controller planning | -| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for all tool interactions | +| Skill | Relationship | +|----------------------------------------|--------------------------------------------------------------------| +| `/microcontroller-interface` | Covers writing MicroControllerInterface code after testing via MCP | +| `/extraction-configuration` | Downstream: configure extraction parameters before processing | +| `/log-input-format` | Reference: documents the archive format produced by this workflow | +| `/log-processing` | Downstream: processes archives assembled by this skill | +| `/log-processing-results` | Downstream: analyzes output from processed archives | +| `/pipeline` | Context: end-to-end orchestration and multi-controller planning | +| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for all tool interactions | --- diff --git a/plugins/communication/skills/pipeline/SKILL.md b/plugins/communication/skills/pipeline/SKILL.md index 9462de2..88aad55 100644 --- a/plugins/communication/skills/pipeline/SKILL.md +++ b/plugins/communication/skills/pipeline/SKILL.md @@ -11,7 +11,7 @@ user-invocable: false # Pipeline -End-to-end orchestration reference for microcontroller data acquisition and analysis. Covers single and +End-to-end orchestration reference for microcontroller data acquisition and analysis, covering single and multi-controller setups, phase ordering, handoff conditions, and decision guidance. --- @@ -263,15 +263,15 @@ For multi-DataLogger setups, process each DataLogger output directory as a separ ## Related skills -| Skill | Role | -|------------------------------|---------------------------------------------------------------| -| `/communication-mcp-environment-setup` | Phase 1: environment verification | -| `/microcontroller-setup` | Phase 2: hardware discovery and manifest management | -| `/extraction-configuration` | Phase 3: extraction config creation and validation | -| `/microcontroller-interface` | Phase 4: MicroControllerInterface code for recording | -| `/log-input-format` | Reference: archive format for troubleshooting | -| `/log-processing` | Phase 5: data extraction | -| `/log-processing-results` | Phase 6: output verification and event analysis | +| Skill | Relationship | +|----------------------------------------|------------------------------------------------------| +| `/communication-mcp-environment-setup` | Phase 1: environment verification | +| `/microcontroller-setup` | Phase 2: hardware discovery and manifest management | +| `/extraction-configuration` | Phase 3: extraction config creation and validation | +| `/microcontroller-interface` | Phase 4: MicroControllerInterface code for recording | +| `/log-input-format` | Reference: archive format for troubleshooting | +| `/log-processing` | Phase 5: data extraction | +| `/log-processing-results` | Phase 6: output verification and event analysis | --- diff --git a/plugins/microcontroller/skills/firmware-module/SKILL.md b/plugins/microcontroller/skills/firmware-module/SKILL.md index 2cceab2..b41f70a 100644 --- a/plugins/microcontroller/skills/firmware-module/SKILL.md +++ b/plugins/microcontroller/skills/firmware-module/SKILL.md @@ -25,7 +25,7 @@ Python ModuleInterface counterpart, use `/communication:microcontroller-interfac - Three required virtual methods: SetupModule, SetCustomParameters, RunActiveCommand - Command handler patterns: immediate, multi-stage with non-blocking delay, sensor polling - Runtime parameter structures with `PACKED_STRUCT` macro -- Event and status code conventions (system 0-50, user 51-250) +- Event code conventions (system 0-50, user 51-250) - Sending data to PC via `SendData()` overloads - Template-based module design with compile-time pin configuration - Static assertions for compile-time validation @@ -92,7 +92,9 @@ Read the source files to confirm the API has not changed since this skill was wr See [references/api-reference.md](references/api-reference.md) for the complete Module base class API including constructor parameters, ExecutionControlParameters fields, all protected utility method -signatures, kCoreStatusCodes, Kernel constructor, and Communication constructor. +signatures, kCoreStatusCodes, Kernel constructor, and Communication constructor. The same reference +also holds the command handler patterns (immediate, multi-stage non-blocking delay, sensor polling) +and the optional implementation hints. The prototype code for each `SendData()` call is resolved automatically at compile time from the C++ type of the data object via the `ResolvePrototype` function in `axmc_shared_assets.h`. Users do not @@ -159,7 +161,7 @@ private: }; ``` -### Custom status codes enum +### Custom event codes enum Custom event codes MUST use values 51-250. Values 0-50 are reserved for system use. Each event code MUST be unique within the module class and MUST carry the same semantic meaning regardless of which @@ -201,14 +203,14 @@ public: } PACKED_STRUCT parameters; ``` -| C++ Type | Size | Python Equivalent | Typical Use | -|------------|---------|-------------------|---------------------------| -| `bool` | 1 byte | `np.bool_` | Enable flags | -| `uint8_t` | 1 byte | `np.uint8` | Small counts, codes | -| `uint16_t` | 2 bytes | `np.uint16` | ADC values, medium counts | -| `uint32_t` | 4 bytes | `np.uint32` | Microsecond durations | -| `int32_t` | 4 bytes | `np.int32` | Signed large values | -| `float` | 4 bytes | `np.float32` | Calibrated sensor values | +| C++ Type | Size | Numpy Equivalent | Typical Use | +|------------|---------|------------------|---------------------------| +| `bool` | 1 byte | `np.bool_` | Enable flags | +| `uint8_t` | 1 byte | `np.uint8` | Small counts, codes | +| `uint16_t` | 2 bytes | `np.uint16` | ADC values, medium counts | +| `uint32_t` | 4 bytes | `np.uint32` | Microsecond durations | +| `int32_t` | 4 bytes | `np.int32` | Signed large values | +| `float` | 4 bytes | `np.float32` | Calibrated sensor values | **Cross-language correspondence:** The PC sends parameters as a numpy-typed tuple via `send_parameters()`. Each tuple element maps to the struct field at the same position: @@ -311,79 +313,8 @@ bool RunActiveCommand() override ## Command handler patterns -### Immediate command - -For commands that complete in a single step: - -```cpp -void Echo() -{ - SendData(static_cast(kStates::kEcho), parameters.echo_value); - CompleteCommand(); -} -``` - -You MUST call `CompleteCommand()` at the end of every command handler. Failure to do so deadlocks -the module. - -### Multi-stage command with non-blocking delay - -For commands requiring timed steps. Stages start at 1, not 0: - -```cpp -void Pulse() -{ - switch (get_command_stage()) - { - case 1: - digitalWrite(kPin, HIGH); - SendData(static_cast(kStates::kHigh)); - AdvanceCommandStage(); - break; - - case 2: - if (WaitForMicros(parameters.on_duration)) AdvanceCommandStage(); - break; - - case 3: - digitalWrite(kPin, LOW); - SendData(static_cast(kStates::kLow)); - AdvanceCommandStage(); - break; - - case 4: - if (WaitForMicros(parameters.off_duration)) CompleteCommand(); - break; - - default: AbortCommand(); break; - } -} -``` - -**Stage-based execution rules:** -- Use `get_command_stage()` to read the current stage (stages start at 1) -- Call `AdvanceCommandStage()` to move to the next stage (also resets the delay timer) -- `WaitForMicros(duration)` returns `true` when the duration has elapsed, `false` while waiting -- In non-blocking mode, `WaitForMicros` returns immediately with `false` if the time has not elapsed, - allowing other modules to execute. In blocking mode, it blocks in-place until the time has passed. -- Call `CompleteCommand()` on the final stage -- The `default` case should call `AbortCommand()` to handle unexpected stages - -### Sensor polling command - -For repeated sensor readings: - -```cpp -void ReadSensor() -{ - const uint16_t value = AnalogRead(kSensorPin, parameters.pool_size); - SendData(static_cast(kStates::kValueRead), value); - CompleteCommand(); -} -``` - -`AnalogRead(pin, pool_size)` reads and averages `pool_size` samples. Set `pool_size` to 0 or 1 -to disable averaging. `DigitalRead(pin, pool_size)` works the same way for digital pins. +See [references/api-reference.md](references/api-reference.md) for the immediate, multi-stage +non-blocking delay, and sensor polling command handler patterns with full code examples. --- @@ -517,49 +448,9 @@ class EncoderModule final : public Module ## Implementation hints -These are optional efficiency patterns observed in production modules. They are not required but may -improve robustness or readability for certain hardware designs. - -**Constexpr pin logic for polarity-configurable modules:** When a template parameter controls whether -hardware is normally-open vs. normally-closed (or similar polarity inversion), compute the active/inactive -logic levels as constexpr booleans rather than branching at runtime: - -```cpp -template -class ValveModule final : public Module -{ - static constexpr bool kOpen = kNormallyClosed ? HIGH : LOW; - static constexpr bool kClose = kNormallyClosed ? LOW : HIGH; - // ... - // Then use kOpen/kClose directly: digitalWriteFast(kPin, kOpen); -}; -``` - -**Sensor hysteresis for polling commands:** When a sensor-polling command runs recurrently, tracking the -previous reading avoids flooding the PC with redundant zero or steady-state messages. Report only when -the value crosses a meaningful threshold or when the state changes: - -```cpp -void CheckSensor() -{ - const uint16_t value = AnalogRead(kPin, parameters.pool_size); - const bool above_threshold = value >= parameters.signal_threshold; - - if (above_threshold) - { - SendData(static_cast(kStates::kDetected), value); - _previous_zero = false; - } - else if (!_previous_zero) - { - SendData(static_cast(kStates::kDetected), static_cast(0)); - _previous_zero = true; - } - CompleteCommand(); -} -``` - -This reduces serial bandwidth and log archive size without losing transition information. +See [references/api-reference.md](references/api-reference.md) for optional efficiency patterns, +including constexpr pin logic for polarity-configurable modules and sensor hysteresis for polling +commands. --- @@ -587,7 +478,7 @@ Firmware Module: - [ ] Static assertions at top of class body (after opening brace, before public:) - [ ] Constructor calls Module(module_type, module_id, communication) - [ ] kCommands enum defines commands with values >= 1 -- [ ] Custom status codes enum defines event codes with values 51-250 +- [ ] Custom event codes enum defines event codes with values 51-250 - [ ] CustomRuntimeParameters struct uses PACKED_STRUCT macro - [ ] SetupModule() configures pins and resets parameters to defaults - [ ] SetCustomParameters() calls ExtractParameters() (not _communication.ExtractModuleParameters()) diff --git a/plugins/microcontroller/skills/firmware-module/references/api-reference.md b/plugins/microcontroller/skills/firmware-module/references/api-reference.md index d3dd986..2489f88 100644 --- a/plugins/microcontroller/skills/firmware-module/references/api-reference.md +++ b/plugins/microcontroller/skills/firmware-module/references/api-reference.md @@ -261,3 +261,129 @@ explicit Communication(Stream& communication_port); Creates a TransportLayer instance with CRC16 (polynomial 0x1021, init 0xFFFF, final XOR 0x0000). Reserves up to ~1 kB of RAM (~700 bytes on lower-end boards). + +--- + +## Command handler patterns + +### Immediate command + +For commands that complete in a single step: + +```cpp +void Echo() +{ + SendData(static_cast(kStates::kEcho), parameters.echo_value); + CompleteCommand(); +} +``` + +You MUST call `CompleteCommand()` at the end of every command handler. Failure to do so deadlocks +the module. + +### Multi-stage command with non-blocking delay + +For commands requiring timed steps. Stages start at 1, not 0: + +```cpp +void Pulse() +{ + switch (get_command_stage()) + { + case 1: + digitalWrite(kPin, HIGH); + SendData(static_cast(kStates::kHigh)); + AdvanceCommandStage(); + break; + + case 2: + if (WaitForMicros(parameters.on_duration)) AdvanceCommandStage(); + break; + + case 3: + digitalWrite(kPin, LOW); + SendData(static_cast(kStates::kLow)); + AdvanceCommandStage(); + break; + + case 4: + if (WaitForMicros(parameters.off_duration)) CompleteCommand(); + break; + + default: AbortCommand(); break; + } +} +``` + +**Stage-based execution rules:** +- Use `get_command_stage()` to read the current stage (stages start at 1) +- Call `AdvanceCommandStage()` to move to the next stage (also resets the delay timer) +- `WaitForMicros(duration)` returns `true` when the duration has elapsed, `false` while waiting +- In non-blocking mode, `WaitForMicros` returns immediately with `false` if the time has not elapsed, + allowing other modules to execute. In blocking mode, it blocks in-place until the time has passed. +- Call `CompleteCommand()` on the final stage +- The `default` case should call `AbortCommand()` to handle unexpected stages + +### Sensor polling command + +For repeated sensor readings: + +```cpp +void ReadSensor() +{ + const uint16_t value = AnalogRead(kSensorPin, parameters.pool_size); + SendData(static_cast(kStates::kValueRead), value); + CompleteCommand(); +} +``` + +`AnalogRead(pin, pool_size)` reads and averages `pool_size` samples. Set `pool_size` to 0 or 1 +to disable averaging. `DigitalRead(pin, pool_size)` works the same way for digital pins. + +--- + +## Implementation hints + +These are optional efficiency patterns observed in production modules. They are not required but may +improve robustness or readability for certain hardware designs. + +**Constexpr pin logic for polarity-configurable modules:** When a template parameter controls whether +hardware is normally-open vs. normally-closed (or similar polarity inversion), compute the active/inactive +logic levels as constexpr booleans rather than branching at runtime: + +```cpp +template +class ValveModule final : public Module +{ + static constexpr bool kOpen = kNormallyClosed ? HIGH : LOW; + static constexpr bool kClose = kNormallyClosed ? LOW : HIGH; + // ... + // Then use kOpen/kClose directly: digitalWriteFast(kPin, kOpen); +}; +``` + +**Sensor hysteresis for polling commands:** When a sensor-polling command runs recurrently, tracking the +previous reading avoids flooding the PC with redundant zero or steady-state messages. Report only when +the value crosses a meaningful threshold or when the state changes: + +```cpp +void CheckSensor() +{ + const uint16_t value = AnalogRead(kPin, parameters.pool_size); + const bool above_threshold = value >= parameters.signal_threshold; + + if (above_threshold) + { + SendData(static_cast(kStates::kDetected), value); + _previous_zero = false; + } + else if (!_previous_zero) + { + SendData(static_cast(kStates::kDetected), static_cast(0)); + _previous_zero = true; + } + CompleteCommand(); +} +``` + +This reduces serial bandwidth and log archive size without losing transition information. diff --git a/plugins/video/skills/camera-interface/SKILL.md b/plugins/video/skills/camera-interface/SKILL.md index a5ee5ef..bd15e2a 100644 --- a/plugins/video/skills/camera-interface/SKILL.md +++ b/plugins/video/skills/camera-interface/SKILL.md @@ -47,11 +47,11 @@ The current version is **4.0.1**. If a version mismatch exists, ask the user how ### Step 2: API verification -| File | What to Check | -|----------------------------------------------------------------------|-------------------------------------------------| -| `../ataraxis-video-system/src/ataraxis_video_system/__init__.py` | Exported classes, functions, and public API | -| `../ataraxis-video-system/src/ataraxis_video_system/video/video_system.py` | VideoSystem constructor parameters and methods | -| Project `pyproject.toml` | Current pinned version dependency | +| File | What to Check | +|----------------------------------------------------------------------------|------------------------------------------------| +| `../ataraxis-video-system/src/ataraxis_video_system/__init__.py` | Exported classes, functions, and public API | +| `../ataraxis-video-system/src/ataraxis_video_system/video/video_system.py` | VideoSystem constructor parameters and methods | +| Project `pyproject.toml` | Current pinned version dependency | --- @@ -276,15 +276,15 @@ cause drops when the scene changes. Consider this when selecting presets. ## Related skills -| Skill | Relationship | -|---------------------------|--------------------------------------------------------------------------| -| `/camera-setup` | Covers MCP-based camera discovery, testing, and encoding parameter guide | -| `/post-recording` | Downstream: verification after recording sessions | -| `/log-input-format` | Reference: documents archive format produced by VideoSystem code | -| `/log-processing` | Downstream: processes archives from VideoSystem instances | -| `/log-processing-results` | Downstream: analyzes frame statistics from processed archives | -| `/pipeline` | Context: end-to-end orchestration and multi-camera planning | -| `/video-mcp-environment-setup` | Prerequisite: MCP server connectivity for API verification | +| Skill | Relationship | +|--------------------------------|--------------------------------------------------------------------------| +| `/camera-setup` | Covers MCP-based camera discovery, testing, and encoding parameter guide | +| `/post-recording` | Downstream: verification after recording sessions | +| `/log-input-format` | Reference: documents archive format produced by VideoSystem code | +| `/log-processing` | Downstream: processes archives from VideoSystem instances | +| `/log-processing-results` | Downstream: analyzes frame statistics from processed archives | +| `/pipeline` | Context: end-to-end orchestration and multi-camera planning | +| `/video-mcp-environment-setup` | Prerequisite: MCP server connectivity for API verification | --- diff --git a/plugins/video/skills/camera-interface/references/api-reference.md b/plugins/video/skills/camera-interface/references/api-reference.md index dd48775..63cbfd9 100644 --- a/plugins/video/skills/camera-interface/references/api-reference.md +++ b/plugins/video/skills/camera-interface/references/api-reference.md @@ -1,4 +1,4 @@ -# ataraxis-video-system API Reference +# ataraxis-video-system API reference Complete API reference for ataraxis-video-system v3.0.0. @@ -39,7 +39,7 @@ from ataraxis_video_system import ( --- -## VideoSystem Class +## VideoSystem class The main orchestration class for camera acquisition and video encoding. @@ -67,7 +67,7 @@ VideoSystem( ) ``` -### Constructor Parameters +### Constructor parameters | Parameter | Type | Required | Default | Description | |--------------------------|-----------------------------|----------|------------------------------|--------------------------------------------------------------------------------------------------------| @@ -146,7 +146,7 @@ stop() <-------------------------------------------------+ ```python class CameraInterfaces(StrEnum): - HARVESTERS = "harvesters" # GeniCam-compatible cameras (GigE, USB3 Vision) + HARVESTERS = "harvesters" # GenICam-compatible cameras (GigE, USB3 Vision) OPENCV = "opencv" # Consumer-grade USB cameras MOCK = "mock" # Testing only (simulated camera) ``` @@ -190,7 +190,7 @@ class InputPixelFormats(StrEnum): --- -## Data Classes +## Data classes ### CameraInformation @@ -275,7 +275,7 @@ log archives. --- -## Discovery Functions +## Discovery functions ### discover_camera_ids @@ -305,7 +305,7 @@ Returns the configured CTI file path if valid, or None if not configured or the --- -## Utility Functions +## Utility functions ### check_ffmpeg_availability @@ -361,11 +361,11 @@ processing for worker-tier pool sharing). --- -## Data Logging Format +## Data logging format VideoSystem logs frame acquisition timestamps using the DataLogger class from ataraxis-data-structures. -### Standard Log Entry +### Standard log entry Each entry is a 1D numpy uint8 array: @@ -374,7 +374,7 @@ Each entry is a 1D numpy uint8 array: | 0 | 1 byte | System ID (uint8) | | 1 | 8 bytes | Timestamp (uint64, microseconds since onset) | -### Onset Entry +### Onset entry The first log entry for each VideoSystem uses a special format: @@ -429,7 +429,7 @@ The first log entry for each VideoSystem uses a special format: | ataraxis-base-utilities | >=6,<7 | Logging and console output | | numpy | >=2,<3 | Array operations and system_id type | | opencv-python | >=4.13,<5 | Camera interface and frame display | -| harvesters | >=1,<2 | GeniCam camera support | +| harvesters | >=1,<2 | GenICam camera support | ### External @@ -439,15 +439,15 @@ The first log entry for each VideoSystem uses a special format: | CTI file | No | GenTL Producer for Harvesters cameras | | NVIDIA GPU | No | Hardware-accelerated encoding (optional) | -### Python Version +### Python version Requires `>=3.12,<3.15`. --- -## Code Examples +## Code examples -### Basic Camera Acquisition +### Basic camera acquisition ```python from pathlib import Path diff --git a/plugins/video/skills/camera-setup/SKILL.md b/plugins/video/skills/camera-setup/SKILL.md index f57e54b..ab647dc 100644 --- a/plugins/video/skills/camera-setup/SKILL.md +++ b/plugins/video/skills/camera-setup/SKILL.md @@ -66,7 +66,8 @@ Harvesters #0: Allied Vision Mako G-040B (DEV_1234) 1936x1216@40fps ``` Each line shows the interface type, camera index, and native resolution/frame rate. Harvesters cameras also show model -and serial number. The camera index is the value to pass to `start_video_session_tool` or to the `VideoSystem` constructor. +and serial number. The camera index is the value to pass to `start_video_session_tool` +or to the `VideoSystem` constructor. ### Video session management @@ -120,10 +121,10 @@ These tools are for Harvesters cameras only. They connect to the camera temporar disconnect. | Tool | Parameters | Purpose | -|----------------------------|----------------------------------------------------------------------|-------------------------------------------------| -| `read_genicam_node_tool` | `camera_index`, `node_name`, `blacklisted_nodes` | Reads a single node or lists all writable nodes | -| `write_genicam_node_tool` | `camera_index`, `node_name`, `value` | Sets a GenICam node value | -| `dump_genicam_config_tool` | `camera_index`, `output_file`, `blacklisted_nodes` | Exports full camera config to YAML | +|----------------------------|-----------------------------------------------------------------------|-------------------------------------------------| +| `read_genicam_node_tool` | `camera_index`, `node_name`, `blacklisted_nodes` | Reads a single node or lists all writable nodes | +| `write_genicam_node_tool` | `camera_index`, `node_name`, `value` | Sets a GenICam node value | +| `dump_genicam_config_tool` | `camera_index`, `output_file`, `blacklisted_nodes` | Exports full camera config to YAML | | `load_genicam_config_tool` | `camera_index`, `config_file`, `strict_identity`, `blacklisted_nodes` | Applies config from YAML to camera | **`read_genicam_node_tool` behavior:** @@ -329,15 +330,15 @@ When transitioning from MCP-based testing to writing VideoSystem code, use this ## Related skills -| Skill | Relationship | -|---------------------------|-------------------------------------------------------------------| -| `/camera-interface` | Covers writing VideoSystem integration code after testing via MCP | -| `/post-recording` | Downstream: verification after recording sessions | -| `/log-input-format` | Reference: documents the archive format produced by this workflow | -| `/log-processing` | Downstream: processes archives from camera sessions | -| `/log-processing-results` | Downstream: analyzes frame statistics from processed archives | -| `/pipeline` | Context: end-to-end orchestration and multi-camera planning | -| `/video-mcp-environment-setup` | Prerequisite: MCP server connectivity for all tool interactions | +| Skill | Relationship | +|--------------------------------|-------------------------------------------------------------------| +| `/camera-interface` | Covers writing VideoSystem integration code after testing via MCP | +| `/post-recording` | Downstream: verification after recording sessions | +| `/log-input-format` | Reference: documents the archive format produced by this workflow | +| `/log-processing` | Downstream: processes archives from camera sessions | +| `/log-processing-results` | Downstream: analyzes frame statistics from processed archives | +| `/pipeline` | Context: end-to-end orchestration and multi-camera planning | +| `/video-mcp-environment-setup` | Prerequisite: MCP server connectivity for all tool interactions | --- diff --git a/plugins/video/skills/log-input-format/SKILL.md b/plugins/video/skills/log-input-format/SKILL.md index ea00426..5855150 100644 --- a/plugins/video/skills/log-input-format/SKILL.md +++ b/plugins/video/skills/log-input-format/SKILL.md @@ -10,7 +10,7 @@ user-invocable: false # Log input format -Documents the input data format required by the camera timestamp extraction pipeline, including how log +Documents the input data format required by the log processing pipeline, including how log archives are produced, their internal structure, and source ID semantics. --- @@ -215,11 +215,11 @@ source ID and 20-digit zero-padded timestamp from the original `.npy` filenames. ### Message types -| Type | Identifier | Payload | Purpose | -|-------|-------------------|---------------------------------------|-----------------------------------| +| Type | Identifier | Payload | Purpose | +|-------|-------------------|----------------------------------------|-----------------------------------| | Onset | `elapsed_us == 0` | 8 bytes: uint64 UTC epoch microseconds | Absolute time reference | -| Frame | `elapsed_us > 0` | Empty (`payload.size == 0`) | Frame acquisition event | -| Data | `elapsed_us > 0` | Non-empty (`payload.size > 0`) | Generic data event (filtered out) | +| Frame | `elapsed_us > 0` | Empty (`payload.size == 0`) | Frame acquisition event | +| Data | `elapsed_us > 0` | Non-empty (`payload.size > 0`) | Generic data event (filtered out) | **Onset message:** The first message in every archive has `elapsed_us=0`. Its payload contains the UTC epoch timestamp (microseconds since epoch) that serves as the absolute time reference. All other @@ -229,8 +229,8 @@ timestamps in the archive are relative to this onset. microseconds elapsed since onset and an empty payload. The processing pipeline extracts only these messages. -**Data messages:** Messages with non-empty payloads carry domain-specific data. The camera timestamp -extraction pipeline filters these out (`payload.size == 0` check). +**Data messages:** Messages with non-empty payloads carry domain-specific data. The log processing +pipeline filters these out (`payload.size == 0` check). ### Timestamp resolution @@ -271,15 +271,15 @@ Before running the log processing pipeline, verify these conditions: ## Related skills -| Skill | Relationship | -|---------------------------|----------------------------------------------------------------------| -| `/camera-setup` | Upstream: MCP sessions that produce archives in this format | -| `/camera-interface` | Upstream: VideoSystem instances that produce the log data | -| `/post-recording` | Upstream: validates and assembles archives in this format | -| `/log-processing` | Downstream: consumes archives in the format documented here | -| `/log-processing-results` | Downstream: documents the output format produced from these archives | -| `/pipeline` | Context: reference skill for the end-to-end pipeline phases | -| `/video-mcp-environment-setup` | Prerequisite: MCP server connectivity for discovery and processing | +| Skill | Relationship | +|--------------------------------|----------------------------------------------------------------------| +| `/camera-setup` | Upstream: MCP sessions that produce archives in this format | +| `/camera-interface` | Upstream: VideoSystem instances that produce the log data | +| `/post-recording` | Upstream: validates and assembles archives in this format | +| `/log-processing` | Downstream: consumes archives in the format documented here | +| `/log-processing-results` | Downstream: documents the output format produced from these archives | +| `/pipeline` | Context: reference skill for the end-to-end pipeline phases | +| `/video-mcp-environment-setup` | Prerequisite: MCP server connectivity for discovery and processing | --- diff --git a/plugins/video/skills/log-processing-results/SKILL.md b/plugins/video/skills/log-processing-results/SKILL.md index fec04bc..b509aea 100644 --- a/plugins/video/skills/log-processing-results/SKILL.md +++ b/plugins/video/skills/log-processing-results/SKILL.md @@ -9,9 +9,8 @@ user-invocable: false # Log processing results -Complete output data format documentation for the camera timestamp extraction pipeline. Covers feather file -discovery, schema reference, frame statistics analysis, and interpretation guidance for discussing results -with users. +Documents the camera timestamp extraction output data format, covering feather file discovery, schema +reference, frame statistics analysis, and interpretation guidance for discussing results with users. --- @@ -274,15 +273,15 @@ To determine detailed job status (SCHEDULED, RUNNING, SUCCEEDED, FAILED), check ## Related skills -| Skill | Relationship | -|--------------------------|--------------------------------------------------------------------| +| Skill | Relationship | +|--------------------------------|--------------------------------------------------------------------| | `/video-mcp-environment-setup` | Prerequisite: MCP server connectivity for tool access | -| `/camera-setup` | Upstream: MCP discovery tools that locate archives and recordings | -| `/camera-interface` | Context: VideoSystem configuration determines expected frame rates | -| `/post-recording` | Upstream: verifies session outputs before processing | -| `/log-input-format` | Reference: input archive format and source ID semantics | -| `/log-processing` | Upstream: processing workflow that produces this output | -| `/pipeline` | Context: results analysis is phase 6 of the end-to-end pipeline | +| `/camera-setup` | Upstream: MCP discovery tools that locate archives and recordings | +| `/camera-interface` | Context: VideoSystem configuration determines expected frame rates | +| `/post-recording` | Upstream: verifies session outputs before processing | +| `/log-input-format` | Reference: input archive format and source ID semantics | +| `/log-processing` | Upstream: processing workflow that produces this output | +| `/pipeline` | Context: results analysis is phase 6 of the end-to-end pipeline | --- diff --git a/plugins/video/skills/log-processing/SKILL.md b/plugins/video/skills/log-processing/SKILL.md index f13cca6..289105b 100644 --- a/plugins/video/skills/log-processing/SKILL.md +++ b/plugins/video/skills/log-processing/SKILL.md @@ -245,13 +245,13 @@ The system uses two cooperating mechanisms: caps how many such jobs run concurrently (`available // per_job_workers`). When many large jobs compete for a limited budget, fewer groups run at once. Per-job worker counts by archive size: -| Archive Size | Per-Job Workers | Typical Scenario | -|---------------|------------------|-----------------------------| -| < 2,000 msgs | 1 (sequential) | Short recording | -| 10,000 msgs | 5 | ~1.5 min at 120 fps | -| 50,000 msgs | 10 | ~7 min at 120 fps | -| 250,000 msgs | 15 | ~35 min at 120 fps | -| 648,000 msgs | 25 | 1.5 h at 120 fps | +| Archive Size | Per-Job Workers | Typical Scenario | +|--------------|-----------------|---------------------| +| < 2,000 msgs | 1 (sequential) | Short recording | +| 10,000 msgs | 5 | ~1.5 min at 120 fps | +| 50,000 msgs | 10 | ~7 min at 120 fps | +| 250,000 msgs | 15 | ~35 min at 120 fps | +| 648,000 msgs | 25 | 1.5 h at 120 fps | The per-job worker count comes solely from square-root scaling; the worker budget governs concurrency (how many groups run at once), not the per-job worker count. Two cores are reserved for system operations. @@ -323,26 +323,26 @@ To re-process an entire directory from scratch, call `clean_log_processing_outpu ### Processing failure routing -| Error Pattern | Action | -|--------------------------------------|---------------------------------------------------------------| -| Archive not found / file read errors | Verify .npz archives exist in log directory | -| MCP tools unavailable | Invoke `/video-mcp-environment-setup` | -| Out of memory | Reduce `worker_budget` | -| Corrupt tracker or partial output | Call `clean_log_processing_output_tool`, then re-prepare | +| Error Pattern | Action | +|--------------------------------------|----------------------------------------------------------| +| Archive not found / file read errors | Verify .npz archives exist in log directory | +| MCP tools unavailable | Invoke `/video-mcp-environment-setup` | +| Out of memory | Reduce `worker_budget` | +| Corrupt tracker or partial output | Call `clean_log_processing_output_tool`, then re-prepare | --- ## Related skills -| Skill | Role | -|---------------------------|-----------------------------------------------------------------| -| `/video-mcp-environment-setup` | Prerequisite: MCP server connectivity | -| `/camera-setup` | Upstream: camera discovery and testing | -| `/camera-interface` | Upstream: VideoSystem integration code that produces logs | -| `/post-recording` | Upstream: verifies archives before processing | -| `/log-input-format` | Reference: input archive format and source ID semantics | -| `/log-processing-results` | Downstream: output data discovery and frame statistics analysis | -| `/pipeline` | Context: log processing is phase 5 of the end-to-end pipeline | +| Skill | Relationship | +|--------------------------------|-----------------------------------------------------------------| +| `/video-mcp-environment-setup` | Prerequisite: MCP server connectivity | +| `/camera-setup` | Upstream: camera discovery and testing | +| `/camera-interface` | Upstream: VideoSystem integration code that produces logs | +| `/post-recording` | Upstream: verifies archives before processing | +| `/log-input-format` | Reference: input archive format and source ID semantics | +| `/log-processing-results` | Downstream: output data discovery and frame statistics analysis | +| `/pipeline` | Context: log processing is phase 5 of the end-to-end pipeline | --- diff --git a/plugins/video/skills/pipeline/SKILL.md b/plugins/video/skills/pipeline/SKILL.md index e5b8e66..043fca4 100644 --- a/plugins/video/skills/pipeline/SKILL.md +++ b/plugins/video/skills/pipeline/SKILL.md @@ -64,7 +64,8 @@ Setup → Discovery → → Recording → Processing → ### Phase 3: Recording session - **Skill:** `/camera-setup` (MCP) or `/camera-interface` (code) -- **MCP path:** `start_video_session_tool` → `start_frame_saving_tool` → `stop_frame_saving_tool` → `stop_video_session_tool` +- **MCP path:** `start_video_session_tool` → `start_frame_saving_tool` → + `stop_frame_saving_tool` → `stop_video_session_tool` - **Code path:** DataLogger init/start → VideoSystem init/start → `start_frame_saving` → `stop_frame_saving` → `stop` → logger stop → `assemble_log_archives` - **Handoff condition:** Session stopped, video file(s) exist @@ -93,7 +94,7 @@ Setup → Discovery → → Recording → Processing → ### Interface selection ```text -Does the camera support GenTL (GeniCam Transport Layer)? +Does the camera support GenTL (GenICam Transport Layer)? YES → Harvesters (preferred interface; provides GenICam node control) NO → Is the camera a USB webcam or consumer device? YES → OpenCV @@ -300,15 +301,15 @@ After processing, use `analyze_camera_frame_statistics_tool` with all camera fea ## Related skills -| Skill | Role | -|---------------------------|--------------------------------------------------------| -| `/video-mcp-environment-setup` | Phase 1: environment verification | -| `/camera-setup` | Phase 2-3: MCP-based discovery, testing, and recording | -| `/camera-interface` | Phase 3: code-based VideoSystem integration | -| `/post-recording` | Phase 4: output verification and archive assembly | -| `/log-input-format` | Reference: archive format for troubleshooting | -| `/log-processing` | Phase 5: timestamp extraction | -| `/log-processing-results` | Phase 6: frame statistics and quality analysis | +| Skill | Relationship | +|--------------------------------|--------------------------------------------------------| +| `/video-mcp-environment-setup` | Phase 1: environment verification | +| `/camera-setup` | Phase 2-3: MCP-based discovery, testing, and recording | +| `/camera-interface` | Phase 3: code-based VideoSystem integration | +| `/post-recording` | Phase 4: output verification and archive assembly | +| `/log-input-format` | Reference: archive format for troubleshooting | +| `/log-processing` | Phase 5: timestamp extraction | +| `/log-processing-results` | Phase 6: frame statistics and quality analysis | --- diff --git a/plugins/video/skills/post-recording/SKILL.md b/plugins/video/skills/post-recording/SKILL.md index 5621766..6eb6b6f 100644 --- a/plugins/video/skills/post-recording/SKILL.md +++ b/plugins/video/skills/post-recording/SKILL.md @@ -237,15 +237,15 @@ Post-Recording Readiness: ## Related skills -| Skill | Relationship | -|---------------------------|-----------------------------------------------------------| -| `/camera-setup` | Upstream: MCP session management that produces recordings | -| `/camera-interface` | Upstream: VideoSystem code that produces recordings | -| `/log-input-format` | Reference: archive format and source ID semantics | -| `/log-processing` | Downstream: processes archives into frame timestamps | -| `/log-processing-results` | Downstream: analyzes processed frame statistics | -| `/pipeline` | Context: end-to-end orchestration including this phase | -| `/video-mcp-environment-setup` | Prerequisite: MCP server connectivity for tool access | +| Skill | Relationship | +|--------------------------------|-----------------------------------------------------------| +| `/camera-setup` | Upstream: MCP session management that produces recordings | +| `/camera-interface` | Upstream: VideoSystem code that produces recordings | +| `/log-input-format` | Reference: archive format and source ID semantics | +| `/log-processing` | Downstream: processes archives into frame timestamps | +| `/log-processing-results` | Downstream: analyzes processed frame statistics | +| `/pipeline` | Context: end-to-end orchestration including this phase | +| `/video-mcp-environment-setup` | Prerequisite: MCP server connectivity for tool access | --- diff --git a/plugins/video/skills/video-mcp-environment-setup/SKILL.md b/plugins/video/skills/video-mcp-environment-setup/SKILL.md index 9876f6f..4bf4c09 100644 --- a/plugins/video/skills/video-mcp-environment-setup/SKILL.md +++ b/plugins/video/skills/video-mcp-environment-setup/SKILL.md @@ -67,11 +67,11 @@ where ataraxis-video-system is installed must be active before launching the ass The ataraxis video plugin's Claude integration is split across two distribution channels: -| Component | Distributed via | What it provides | -|------------------------------------|-----------------------------------|----------------------------------------------------------------------------| -| Skills (`/camera-interface`, etc.) | ataraxis video plugin | Skill files that guide agents through workflows | +| Component | Distributed via | What it provides | +|------------------------------------|-----------------------------------|-------------------------------------------------------------------------------------------| +| Skills (`/camera-interface`, etc.) | ataraxis video plugin | Skill files that guide agents through workflows | | MCP server registrations | ataraxis video plugin | `plugin.json` `mcpServers` entries that tell the Claude assistant how to start the server | -| MCP server code (`axvs mcp`) | ataraxis-video-system pip package | The actual CLI command and server implementation | +| MCP server code (`axvs mcp`) | ataraxis-video-system pip package | The actual CLI command and server implementation | Installing the plugin alone registers the MCP server and makes skills available, but the server will fail to start because the `axvs` CLI command is not present. The pip package must also be installed in the active From cea9186135883ae3beb72f08e73b232cc21c6a9b Mon Sep 17 00:00:00 2001 From: Ivan Kondratyev Date: Wed, 17 Jun 2026 15:29:15 -0400 Subject: [PATCH 3/7] Expanded plugin skills with missing agentic-surface coverage. -- Added missing behavioral, failure-mode, and data-format coverage to the video, communication, and microcontroller skills. -- Corrected the video log-input-format claim that processing does not require the camera manifest, plus other source-contradicting statements. -- Added the /platformio-config skill documenting platformio.ini and library.json conventions. -- Added reference-only CLI tables (axvs, axci, tox, pio, automation-cli) flagged for human use to answer user questions. -- Documented .pyi stubs as generated, transient artifacts purged by tox -e lint and regenerated by tox -e stubs. -- Added C++ PlatformIO archetype coverage to the readme-style, project-layout, audit-style, and explore-codebase skills. -- Bumped the automation, video, communication, and microcontroller plugin manifest versions. --- README.md | 1 + plugins/automation/.claude-plugin/plugin.json | 2 +- .../automation/skills/audit-facts/SKILL.md | 6 + .../automation/skills/audit-style/SKILL.md | 26 ++- plugins/automation/skills/commit/SKILL.md | 3 + plugins/automation/skills/cpp-style/SKILL.md | 5 +- .../cpp-style/references/anti-patterns.md | 2 +- .../cpp-style/references/class-patterns.md | 5 +- .../cpp-style/references/doxygen-and-types.md | 15 +- .../automation/skills/csharp-style/SKILL.md | 5 +- .../csharp-style/references/class-patterns.md | 27 +-- .../references/xml-docs-and-types.md | 13 +- .../skills/explore-codebase/SKILL.md | 49 ++-- .../skills/explore-dependencies/SKILL.md | 12 + .../skills/platformio-config/SKILL.md | 215 ++++++++++++++++++ .../references/config-templates.md | 131 +++++++++++ plugins/automation/skills/pr/SKILL.md | 9 +- .../automation/skills/project-layout/SKILL.md | 28 ++- .../references/archetype-trees.md | 13 +- .../skills/pyproject-style/SKILL.md | 1 + .../references/project-metadata.md | 6 + .../references/tool-configurations.md | 5 + .../automation/skills/python-style/SKILL.md | 30 ++- .../references/libraries-and-tools.md | 3 + .../references/section-templates.md | 56 ++++- plugins/automation/skills/release/SKILL.md | 17 +- .../automation/skills/skill-design/SKILL.md | 10 +- .../references/progressive-disclosure.md | 2 +- plugins/automation/skills/tox-config/SKILL.md | 9 + .../references/environment-templates.md | 59 ++++- .../communication/.claude-plugin/plugin.json | 2 +- .../skills/extraction-configuration/SKILL.md | 30 +++ .../skills/log-input-format/SKILL.md | 19 +- .../skills/log-processing-results/SKILL.md | 17 +- .../skills/log-processing/SKILL.md | 33 +++ .../skills/microcontroller-interface/SKILL.md | 14 +- .../references/api-reference.md | 6 +- .../skills/microcontroller-setup/SKILL.md | 30 ++- .../communication/skills/pipeline/SKILL.md | 12 +- .../.claude-plugin/plugin.json | 2 +- .../skills/firmware-module/SKILL.md | 28 +++ .../references/api-reference.md | 6 +- plugins/video/.claude-plugin/plugin.json | 2 +- .../video/skills/camera-interface/SKILL.md | 12 +- .../references/api-reference.md | 51 +---- plugins/video/skills/camera-setup/SKILL.md | 29 +++ .../video/skills/log-input-format/SKILL.md | 31 ++- .../skills/log-processing-results/SKILL.md | 8 +- plugins/video/skills/log-processing/SKILL.md | 32 ++- plugins/video/skills/pipeline/SKILL.md | 8 +- plugins/video/skills/post-recording/SKILL.md | 14 ++ 51 files changed, 996 insertions(+), 155 deletions(-) create mode 100644 plugins/automation/skills/platformio-config/SKILL.md create mode 100644 plugins/automation/skills/platformio-config/references/config-templates.md diff --git a/README.md b/README.md index c798329..fcb811f 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,7 @@ project structure, and more. | `/api-docs` | Applies Sun Lab API documentation conventions | | `/project-layout` | Applies Sun Lab project directory structure conventions | | `/tox-config` | Applies Sun Lab tox.ini conventions | +| `/platformio-config` | Applies Sun Lab platformio.ini and library.json conventions | | `/audit-facts` | Audits documentation files against source code for factual accuracy | | `/audit-style` | Audits files against applicable style skill checklists for compliance | | `/commit` | Drafts style-compliant git commit messages | diff --git a/plugins/automation/.claude-plugin/plugin.json b/plugins/automation/.claude-plugin/plugin.json index ad88f35..19de7b2 100644 --- a/plugins/automation/.claude-plugin/plugin.json +++ b/plugins/automation/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "automation", - "version": "1.2.0", + "version": "1.3.0", "description": "Provides the shared software development skills that enforce conventions and code style in Ataraxis and derived projects.", "repository": "https://github.com/Sun-Lab-NBB/ataraxis", "license": "Apache-2.0", diff --git a/plugins/automation/skills/audit-facts/SKILL.md b/plugins/automation/skills/audit-facts/SKILL.md index 4f0e78e..5304aa9 100644 --- a/plugins/automation/skills/audit-facts/SKILL.md +++ b/plugins/automation/skills/audit-facts/SKILL.md @@ -227,6 +227,12 @@ and where. You MUST adhere to the following discipline during every audit. - Never invent source. If you cannot open the source after reasonable search, mark UNVERIFIABLE. +- Facts not derivable from the audited repo's own source (external toolchain version floors, + installer requirements, cross-repo version pins, environment prerequisites) are authoritative + by default. Report them as UNVERIFIABLE only when they appear internally contradicted or stale; + otherwise omit them, or set the Suggested fix to "leave as-is — authoritative external + requirement" rather than a removal or change. `/readme-style` is the source of the canonical + install-section requirements (e.g. the mamba 2.3.2+ / miniforge3 floor). - Never paraphrase source and present it as a verbatim quote. Use the Read tool and copy. - Never expand scope to restructure, restyle, or refactor. This skill produces findings only. - Never flag style, formatting, structural, or convention issues. Those belong to diff --git a/plugins/automation/skills/audit-style/SKILL.md b/plugins/automation/skills/audit-style/SKILL.md index 4fedd9b..73aa34a 100644 --- a/plugins/automation/skills/audit-style/SKILL.md +++ b/plugins/automation/skills/audit-style/SKILL.md @@ -77,17 +77,21 @@ There is no "covered area" reduction. For each file in scope, identify the applicable style skill using the binding table: -| File pattern | Style skill | -|---------------------------------------|--------------------| -| `*.py` | `/python-style` | -| `*.cs` | `/csharp-style` | -| `*.h`, `*.hpp`, `*.cpp` | `/cpp-style` | -| `README.md` | `/readme-style` | -| `pyproject.toml` | `/pyproject-style` | -| `tox.ini` | `/tox-config` | -| `docs/*.rst`, `conf.py`, `Makefile` | `/api-docs` | -| `SKILL.md`, `CLAUDE.md`, `AGENTS.md` | `/skill-design` | -| Project directory tree | `/project-layout` | +| File pattern | Style skill | +|---------------------------------------------------------------------------|----------------------| +| `*.py` | `/python-style` | +| `*.cs` | `/csharp-style` | +| `*.h`, `*.hpp`, `*.cpp`, `.clang-format`, `.clang-tidy`, `CMakeLists.txt` | `/cpp-style` | +| `README.md` | `/readme-style` | +| `pyproject.toml` | `/pyproject-style` | +| `tox.ini` | `/tox-config` | +| `platformio.ini`, `library.json` | `/platformio-config` | +| `docs/*.rst`, `conf.py`, `Makefile`, `make.bat`, `Doxyfile` | `/api-docs` | +| `SKILL.md`, `CLAUDE.md`, `AGENTS.md` | `/skill-design` | +| Project directory tree | `/project-layout` | + +If a file in scope matches no binding row, mark it UNAUDITED in the plan and report (no +applicable style skill) and flag no findings against it. Classify the audit tier: diff --git a/plugins/automation/skills/commit/SKILL.md b/plugins/automation/skills/commit/SKILL.md index 46afdb9..64d7a5d 100644 --- a/plugins/automation/skills/commit/SKILL.md +++ b/plugins/automation/skills/commit/SKILL.md @@ -45,6 +45,9 @@ Run the following git commands in parallel using the Bash tool: `master`; confirm via `git symbolic-ref --short refs/remotes/origin/HEAD` and strip the `origin/` prefix when a remote exists). +If `git status` shows no staged, unstaged, or untracked changes, stop and report that there is nothing to commit +rather than running `git add`/`git commit`. + ### Step 2: Analyze changes Review every changed file and understand: diff --git a/plugins/automation/skills/cpp-style/SKILL.md b/plugins/automation/skills/cpp-style/SKILL.md index 7886bef..8932a64 100644 --- a/plugins/automation/skills/cpp-style/SKILL.md +++ b/plugins/automation/skills/cpp-style/SKILL.md @@ -359,7 +359,8 @@ are the primary example. class TransportLayer { public: - [[nodiscard]] uint8_t get_runtime_status() const { return _runtime_status; } + [[nodiscard]] + uint8_t get_runtime_status() const { return _runtime_status; } private: uint8_t _runtime_status = 0; @@ -403,6 +404,7 @@ See [libraries-and-tools.md](references/libraries-and-tools.md) for `.clang-form | `/skill-design` | Provides skill file conventions; invoke for skill authoring tasks | | `/explore-codebase` | Provides project context that informs style-compliant code changes | | `/api-docs` | Provides Doxygen/Breathe API documentation build conventions | +| `/platformio-config`| Covers platformio.ini and library.json field/section conventions; cpp-style covers C++ source only | --- @@ -452,6 +454,7 @@ C++ Style Compliance: - [ ] Include guards use LIBRARY_PREFIX_FILE_NAME_H pattern - [ ] Include sorting delegated to clang-format (do not manually reorder) - [ ] Pointer/reference alignment is left (int* pointer, int& reference) +- [ ] Attributes ([[nodiscard]], [[maybe_unused]]) on their own line above the declaration (BreakAfterAttributes: Always) - [ ] Consecutive assignments aligned (AlignConsecutiveAssignments) - [ ] Template declarations on separate lines - [ ] Guard clauses / early returns preferred over deep nesting diff --git a/plugins/automation/skills/cpp-style/references/anti-patterns.md b/plugins/automation/skills/cpp-style/references/anti-patterns.md index 7cd0ceb..9c43466 100644 --- a/plugins/automation/skills/cpp-style/references/anti-patterns.md +++ b/plugins/automation/skills/cpp-style/references/anti-patterns.md @@ -93,7 +93,7 @@ reviewing code before submission. | Missing `const` on unchanged local | `const int32_t new_motion = ...` | const correctness | | Missing `const` on value parameter | `void Foo(const uint8_t pin)` | const value parameters | | Missing `explicit` on constructor | `explicit TransportLayer(Stream& port)` | Prevent implicit conversions | -| Missing `[[nodiscard]]` on getter | `[[nodiscard]] bool ReadData(...) const` | Mark pure query methods | +| Missing `[[nodiscard]]` on getter | `[[nodiscard]]` on its own line above `bool ReadData(...) const` | Mark pure query methods | | Missing `override` on virtual | `bool RunActiveCommand() override` | Enforced by clang-tidy | | Missing `final` on leaf class | `class EncoderModule final : public Module` | Prevent unintended subclassing | | `auto result = Process()` | `uint8_t result = Process()` | Explicit types when not obvious | diff --git a/plugins/automation/skills/cpp-style/references/class-patterns.md b/plugins/automation/skills/cpp-style/references/class-patterns.md index e7fd5b3..e35b9c9 100644 --- a/plugins/automation/skills/cpp-style/references/class-patterns.md +++ b/plugins/automation/skills/cpp-style/references/class-patterns.md @@ -512,7 +512,8 @@ methods (operations that "do something"): ```cpp // Good - accessor for trivial field access /// Returns the module's type identifier. -[[nodiscard]] uint8_t get_module_type() const { return _module_type; } +[[nodiscard]] +uint8_t get_module_type() const { return _module_type; } // Good - PascalCase method for operations with side effects /// Sends the specified data to the connected PC via the serial port. @@ -627,6 +628,8 @@ CompleteCommand(); - Brace style: **Allman** (opening braces on new lines for all constructs) - Indentation: **4 spaces** (no tabs) - Pointer/reference alignment: **Left** (`int* pointer`, `int& reference`) +- Attributes (`[[nodiscard]]`, `[[maybe_unused]]`, etc.) always appear on their own line directly + above the declaration (clang-format `BreakAfterAttributes: Always`); do not write them inline ### Aligned assignments diff --git a/plugins/automation/skills/cpp-style/references/doxygen-and-types.md b/plugins/automation/skills/cpp-style/references/doxygen-and-types.md index 8712e1e..5fa2233 100644 --- a/plugins/automation/skills/cpp-style/references/doxygen-and-types.md +++ b/plugins/automation/skills/cpp-style/references/doxygen-and-types.md @@ -206,7 +206,8 @@ For methods with parameters that need documentation, use `/** ... */` blocks: * @returns true if the requested number of bytes was successfully read, false otherwise. */ template -[[nodiscard]] bool ReadData(ReadObject& object) const +[[nodiscard]] +bool ReadData(ReadObject& object) const ``` ### When to use block vs inline @@ -225,15 +226,18 @@ should ideally be a single sentence: ```cpp // Good - single-sentence accessor docs /// Returns the size of the instance's transmission buffer, in bytes. -[[nodiscard]] static constexpr uint16_t get_transmission_buffer_size() +[[nodiscard]] +static constexpr uint16_t get_transmission_buffer_size() /// Returns the runtime status of the most recently called method. -[[nodiscard]] uint8_t get_runtime_status() const +[[nodiscard]] +uint8_t get_runtime_status() const // Avoid - multi-sentence accessor docs (move details to the class @brief instead) /// Returns the runtime status of the most recently called method. The status is updated /// after each call to SendData or ReceiveData, and tracks whether the operation succeeded. -[[nodiscard]] uint8_t get_runtime_status() const +[[nodiscard]] +uint8_t get_runtime_status() const ``` --- @@ -342,7 +346,8 @@ const bool data_received = tl_class.ReceiveData(); EncoderModule(const uint8_t module_type, const uint8_t module_id, Communication& communication) // [[nodiscard]] on const methods -[[nodiscard]] bool ReadData(ReadObject& object) const +[[nodiscard]] +bool ReadData(ReadObject& object) const ``` ### Integer types diff --git a/plugins/automation/skills/csharp-style/SKILL.md b/plugins/automation/skills/csharp-style/SKILL.md index 36e5761..aa2b61a 100644 --- a/plugins/automation/skills/csharp-style/SKILL.md +++ b/plugins/automation/skills/csharp-style/SKILL.md @@ -335,7 +335,10 @@ All definitions within a file follow this vertical ordering from top to bottom: 1. **File-level XML documentation** (`/// ` block describing the file) 2. **Using directives** -3. **Namespace declaration** (file-scoped preferred: `namespace SL.Config;`) +3. **Namespace declaration** (block-scoped is the project convention: `namespace SL.Config { ... }`, + with class members indented one level inside the block). Although `assets/.editorconfig` carries + `csharp_style_namespace_declarations = file_scoped:suggestion`, the exemplar code overrides it and + block-scoped is the practiced form. 4. **Enumerations** (type definitions that other code depends on) 5. **Class declaration** with members in this order: a. Constants (`const` and `static readonly` fields) diff --git a/plugins/automation/skills/csharp-style/references/class-patterns.md b/plugins/automation/skills/csharp-style/references/class-patterns.md index 6cab948..9a19ee3 100644 --- a/plugins/automation/skills/csharp-style/references/class-patterns.md +++ b/plugins/automation/skills/csharp-style/references/class-patterns.md @@ -12,7 +12,8 @@ classes inherit from MonoBehaviour. ### Lifecycle method ordering -Unity lifecycle methods must appear in their natural execution order: +Unity lifecycle methods must appear in their natural execution order. They are declared +`private` like any other method — never rely on the implicit default: ```csharp /// Manages an infinite corridor VR task with probabilistic segment transitions. @@ -23,31 +24,31 @@ public class Task : MonoBehaviour // Private fields /// Called once before Start. Initializes references and validates configuration. - void Awake() + private void Awake() { // Early initialization, component references } /// Called once after Awake. Performs setup that depends on other components. - void Start() + private void Start() { // Setup that depends on other components being initialized } /// Called every frame. Updates task state and checks for transitions. - void Update() + private void Update() { // Per-frame logic } /// Called every fixed timestep. Updates physics-dependent calculations. - void FixedUpdate() + private void FixedUpdate() { // Physics calculations } /// Called when the component is destroyed. Cleans up subscriptions and resources. - void OnDestroy() + private void OnDestroy() { // Cleanup: unsubscribe events, release resources } @@ -82,7 +83,7 @@ or `Start()` instead of calling `GetComponent()` in `Update()`: private MeshRenderer _meshRenderer; /// Initializes cached component references. -void Awake() +private void Awake() { if (!TryGetComponent(out _meshRenderer)) { @@ -97,7 +98,7 @@ Unity collider callbacks follow a consistent pattern: ```csharp /// Called when the animal enters the trigger zone collider. -void OnTriggerEnter(Collider other) +private void OnTriggerEnter(Collider other) { if (!isActive) return; @@ -107,7 +108,7 @@ void OnTriggerEnter(Collider other) } /// Called when the animal exits the trigger zone collider. -void OnTriggerExit(Collider other) +private void OnTriggerExit(Collider other) { if (!isActive) return; @@ -133,13 +134,13 @@ while the component is active: private MQTTChannel _lickChannel; /// Subscribes to MQTT lick events when the component becomes active. -void OnEnable() +private void OnEnable() { _lickChannel.Event.AddListener(OnLickDetected); } /// Unsubscribes from MQTT lick events when the component becomes inactive. -void OnDisable() +private void OnDisable() { _lickChannel.Event.RemoveListener(OnLickDetected); } @@ -151,13 +152,13 @@ Use `+=` and `-=` for C# events. Every `+=` must have a matching `-=`: ```csharp /// Subscribes to the zone boundary event. -void OnEnable() +private void OnEnable() { _occupancyZone.BoundaryDisarmed += OnBoundaryDisarmed; } /// Unsubscribes from the zone boundary event. -void OnDisable() +private void OnDisable() { _occupancyZone.BoundaryDisarmed -= OnBoundaryDisarmed; } diff --git a/plugins/automation/skills/csharp-style/references/xml-docs-and-types.md b/plugins/automation/skills/csharp-style/references/xml-docs-and-types.md index 95b3ba2..d24f6f3 100644 --- a/plugins/automation/skills/csharp-style/references/xml-docs-and-types.md +++ b/plugins/automation/skills/csharp-style/references/xml-docs-and-types.md @@ -39,7 +39,7 @@ public class OccupancyZone : MonoBehaviour ```csharp // Single-line (preferred for most members) /// Initializes the occupancy timer. -void Start() +private void Start() // Multi-line (when description is long) /// @@ -189,6 +189,17 @@ Rules: - Order multiple `` tags alphabetically by exception type name - In Unity MonoBehaviour methods, prefer `Debug.LogError` over throwing (see SKILL.md) +### See cref references + +Use `` inside `` and `` to link to other fields, +constants, methods, classes, interfaces, and generic types — not only exception types. This +enables IDE navigation between related members: + +```csharp +/// Resets the corridor to the configured for reproducible runs. +public void ResetZone() +``` + ### Inheritdoc Use `` when overriding a method or implementing an interface where the base diff --git a/plugins/automation/skills/explore-codebase/SKILL.md b/plugins/automation/skills/explore-codebase/SKILL.md index ac808e1..8b5323b 100644 --- a/plugins/automation/skills/explore-codebase/SKILL.md +++ b/plugins/automation/skills/explore-codebase/SKILL.md @@ -42,6 +42,12 @@ You MUST follow these steps when this skill is invoked. Quickly assess the project to select the appropriate exploration tier. Run a file count and directory listing to make this determination before proceeding. +Ataraxis source uses GENERATED `.pyi` stubs (one per `.py`). They are purged during development +(`tox -e lint`) and only present at release (`tox -e stubs`), so a dev tree often has none — treat +their absence as normal, never a gap. When present, exclude `.pyi` from file counts, dependency maps, +and test-coverage mapping, and always read the `.py` module (not the stub) for docstrings and the +documented API. Do not spend tokens reading or editing stubs. + | Tier | Indicators | Approach | |--------|---------------------------------------------------------------|-------------------------------| | Small | Single package, < 10 source files, no subpackages | Single-pass exploration | @@ -87,14 +93,20 @@ combined. For large projects, phases may be distributed across parallel subagent Identify the project's entry points, boundaries, and configuration. -1. **Entry points** — CLI commands, API endpoints, main functions, GUI entry points. Check +1. **Orientation documents** — Read the repo-root `CLAUDE.md` (and `README.md`) for project purpose, + architecture summary, and conventions before tracing source. Treat them as orientation, not ground + truth for API details. +2. **Entry points** — CLI commands, API endpoints, main functions, GUI entry points. Check `pyproject.toml` for `[project.scripts]` and `[project.entry-points]` sections. -2. **Configuration mechanisms** — `pyproject.toml` settings, environment variables, CLI argument +3. **Configuration mechanisms** — `pyproject.toml` settings, environment variables, CLI argument defaults, YAML/JSON/TOML config files, `.env` files, and dataclass-based configuration objects. -3. **Public API surface** — Classes, functions, and constants exported from `__init__.py` files. +4. **Public API surface** — Classes, functions, and constants exported from `__init__.py` files. Note which modules use `__all__` to restrict exports. -4. **CLI command signatures** — For CLI-based projects, document each command's name, arguments, +5. **CLI command signatures** — For CLI-based projects, document each command's name, arguments, options, and purpose. +6. **MCP tools** — When an MCP server exists (an `interfaces/` package, `*_tools.py` modules, or an + ` mcp` script), enumerate each MCP tool with its name, parameters, and return/output shape. + These tools are a major public surface for AI agents. ### Phase 2: Code flow tracing @@ -128,7 +140,8 @@ Analyze the structural relationships between components. Examine specifics that inform future modifications. 1. **Test coverage mapping** — For each source module, identify the corresponding test file(s). Note - any source modules that lack test coverage. + any source modules that lack test coverage. Ataraxis test files use the `_test.py` suffix + (e.g. `camera_test.py` for `camera.py`), not the `test_` prefix — see `/project-layout`. 2. **Key algorithms and data structures** — Document non-trivial algorithms, important data structures (dataclasses, TypedDicts, NamedTuples), and their locations. 3. **Error handling patterns** — How errors are raised, caught, and reported to the user. Note @@ -151,10 +164,11 @@ For small projects, omit sections that do not apply. 4. **Call chain summary** — Entry point → layer → core logic flow for primary paths 5. **Import dependency map** — Which modules depend on which, with central components highlighted 6. **Public API surface** — Exported classes, functions, and constants -7. **Configuration** — All configuration mechanisms discovered -8. **Test coverage** — Source module → test file mapping, noting gaps -9. **Notable patterns** — Design patterns, conventions, and cross-cutting concerns -10. **Areas of concern** — Technical debt, complexity hotspots, missing coverage +7. **MCP tools** — When an MCP server exists, each tool with its parameters and return/output shape +8. **Configuration** — All configuration mechanisms discovered +9. **Test coverage** — Source module → test file mapping, noting gaps +10. **Notable patterns** — Design patterns, conventions, and cross-cutting concerns +11. **Areas of concern** — Technical debt, complexity hotspots, missing coverage ### Example output @@ -206,6 +220,13 @@ Exported from `__init__.py` via `__all__`: - `PipelineConfig` (dataclass) - `PipelineResult` (dataclass) +## MCP tools + +| Tool | Location | Parameters | Returns | +|---------------------|----------------------------|------------------------|----------------------| +| `run_pipeline_tool` | mcp/processing_tools.py | `config_path: str` | run summary dict | +| `list_sessions_tool`| mcp/discovery_tools.py | `data_directory: str` | list of session dicts| + ## Configuration | Mechanism | Location | Purpose | @@ -218,9 +239,9 @@ Exported from `__init__.py` via `__all__`: | Source Module | Test File | Coverage | |------------------------------|------------------------------------|----------| -| pipeline.py | tests/test_pipeline.py | Yes | -| registration/register.py | tests/test_registration.py | Yes | -| detection/detect.py | tests/test_detection.py | Yes | +| pipeline.py | tests/pipeline_test.py | Yes | +| registration/register.py | tests/registration_test.py | Yes | +| detection/detect.py | tests/detection_test.py | Yes | | mcp/server.py | (none) | Gap | ## Notable patterns @@ -259,7 +280,9 @@ Exported from `__init__.py` via `__all__`: Invoke at session start to ensure full context before making changes. Prevents blind modifications and ensures understanding of existing patterns. When the project has ataraxis dependencies (check `pyproject.toml`), also invoke `/explore-dependencies` to build a live API -snapshot of each dependency. +snapshot of each dependency. Ataraxis dependencies may exist locally in the parent directory; when +they do, `/explore-dependencies` should reconcile the local version against the latest GitHub release +(`gh api repos/.../releases/latest`) before trusting its API. Do NOT make code changes during exploration. Present findings and wait for user direction. diff --git a/plugins/automation/skills/explore-dependencies/SKILL.md b/plugins/automation/skills/explore-dependencies/SKILL.md index 8be09fd..4ea55a3 100644 --- a/plugins/automation/skills/explore-dependencies/SKILL.md +++ b/plugins/automation/skills/explore-dependencies/SKILL.md @@ -71,6 +71,18 @@ python -c "import ; print(.__file__)" This returns the path to the package's `__init__.py`. The parent directory contains all source modules. +Obtain the package version with the hyphenated PyPI name (not the import name); ataraxis +`__init__.py` files do not expose `__version__`, so resolve it at runtime instead: + +```bash +python -c "import importlib.metadata; print(importlib.metadata.version(''))" +``` + +For C++ ataraxis libraries (ataraxis-transport-layer-mc, ataraxis-micro-controller), the +`python -c "import ..."` resolution does not apply. Locate the source under +`.pio/libdeps//src` and enumerate public classes from the library's header files rather than +from `__all__`. + If a package is not installed, note it as unavailable and skip to the next dependency. ### Step 4: Enumerate public APIs diff --git a/plugins/automation/skills/platformio-config/SKILL.md b/plugins/automation/skills/platformio-config/SKILL.md new file mode 100644 index 0000000..30a9a4d --- /dev/null +++ b/plugins/automation/skills/platformio-config/SKILL.md @@ -0,0 +1,215 @@ +--- +name: platformio-config +description: >- + Applies platformio.ini and library.json conventions when creating or modifying PlatformIO C++ + project and library configuration files. Covers per-board environment sections, build flags, + pinned lib_deps, library.json metadata, the lib_deps<->dependencies mirroring rule, the main.cpp + export exclusion, and library.json as the single source of the C++ library version. Use when + creating or modifying platformio.ini or library.json, adding a board or dependency, or when the + user asks about PlatformIO configuration conventions. +user-invocable: false +--- + +# PlatformIO configuration style guide + +Applies conventions for the two PlatformIO configuration files a C++ microcontroller library ships: +`platformio.ini` (local build, test, and upload configuration) and `library.json` (the published +PlatformIO registry manifest). This is the C++ PlatformIO analogue of `/pyproject-style` and +`/tox-config`. + +You MUST read this skill and load the reference templates before creating or modifying either file. +You MUST verify your changes against the checklist before submitting. + +--- + +## Scope + +**Covers:** +- `platformio.ini` per-board `[env:]` sections, the standard field set, build flags/unflags +- `lib_deps` dependency pinning and the registry-owner naming convention +- `library.json` metadata, `headers`, `dependencies`, `export`, and `build` fields +- The `lib_deps` <-> `dependencies` mirroring rule and per-dependency `platforms` scoping +- `library.json` `version` as the single source of the C++ library version + +**Does not cover:** +- C++ source code style (see `/cpp-style`) +- Firmware Module/Kernel implementation (see `microcontroller:firmware-module`) +- Project directory structure and which files belong where (see `/project-layout`) +- Python `pyproject.toml` / `tox.ini` configuration (see `/pyproject-style`, `/tox-config`) + +--- + +## Workflow + +You MUST follow these steps when this skill is invoked. + +### Step 1: Read this skill + +Read this entire file. The conventions below apply to ALL ataraxis PlatformIO libraries. + +### Step 2: Load the reference templates + +Load [config-templates.md](references/config-templates.md) for the full annotated `platformio.ini` +and `library.json` examples when creating either file from scratch or adding a board/dependency. + +### Step 3: Apply conventions + +Write or modify the file following all conventions from this file and the loaded template. When +adding or changing a dependency, apply the mirroring rule (below) to BOTH files in the same change. + +### Step 4: Verify compliance + +Complete the verification checklist at the end of this file. Every item must pass. + +--- + +## platformio.ini conventions + +`platformio.ini` declares one build environment per supported board. It governs local builds, unit +tests, and uploads; it does NOT carry a version (the library version lives only in `library.json`). + +### Environment sections + +Declare one `[env:]` section per supported board, named for the board (`teensy41`, `due`, +`mega`). Each section uses this field set: + +| Field | Convention | +|-------------------|----------------------------------------------------------------------------------| +| `platform` | The board's PlatformIO platform (`teensy`, `atmelsam`, `atmelavr`) | +| `board` | The PlatformIO board id (`teensy41`, `due`, `megaatmega2560`) | +| `framework` | `arduino` | +| `monitor_speed` | Serial monitor baud rate for that board (board-specific, e.g. `115200`) | +| `test_framework` | `unity` | +| `upload_protocol` | Set when the board needs a non-default uploader (e.g. `teensy-cli` for Teensy) | +| `build_flags` | `-std=c++17` (the project C++ standard) | +| `build_unflags` | Add `-std=gnu++11` on boards whose Arduino core pins an older standard (AVR/SAM) | +| `lib_deps` | Pinned third-party and ataraxis dependencies (see below) | + +`build_unflags = -std=gnu++11` is required only where the board's default toolchain would otherwise +override `build_flags` (the AVR `mega` and SAM `due` cores); Teensy needs no unflag. Omit a field +when the board does not need it (e.g. a board with no dependencies omits `lib_deps` entirely). + +### Board / platform mapping + +| Board id | platform | +|-------------------|------------| +| `teensy41` | `teensy` | +| `due` | `atmelsam` | +| `megaatmega2560` | `atmelavr` | + +### lib_deps pinning + +List each dependency as `registry_owner/name@^MAJOR.MINOR.PATCH`. The registry owner is the +lowercase PlatformIO registry account, NOT the GitHub org — ataraxis libraries are published under +`inkaros` (e.g. `inkaros/ataraxis-transport-layer-mc@^3.0.0`); third-party deps use their own owners +(`arminjo/digitalWriteFast@^1.3.1`, `pfeerick/elapsedMillis@^1.0.6`). Use the caret (`^`) range so +patch/minor updates are accepted. List a dependency only under the boards that need it. + +--- + +## library.json conventions + +`library.json` is the PlatformIO registry manifest — what consumers receive when they add the +library via `lib_deps`. Pin `$schema` to the official PlatformIO schema URL and order fields as in +the template. + +| Field | Convention | +|----------------|--------------------------------------------------------------------------------------------------------------| +| `$schema` | `https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/schema/library.json` | +| `name` | The library name (matches the repository) | +| `version` | The library version — the SINGLE source of truth (see Versioning) | +| `description` | One sentence, matching the README/repository description | +| `keywords` | Comma-separated discovery keywords | +| `repository` | `{ "type": "git", "url": "https://github.com/Sun-Lab-NBB/" }` | +| `homepage` | The Netlify API-docs URL | +| `authors` | Author objects; the primary author carries `"maintainer": true` | +| `license` | `Apache-2.0` | +| `frameworks` | `["arduino"]` | +| `platforms` | Every platform the library supports (`["atmelavr", "atmelsam", "teensy"]`) | +| `headers` | The PUBLIC header(s) consumers include — a string for one, an array for several | +| `dependencies` | Published dependency list — MUST mirror `lib_deps` (see mirroring rule) | +| `export` | `include` (`./examples/*`, `./src/*`) and `exclude` (`./src/main.cpp`) | +| `build` | `{ "flags": "-std=c++17" }`, mirroring `platformio.ini` `build_flags` | + +### headers + +`headers` lists only the PUBLIC headers a consumer includes (e.g. `["kernel.h", "communication.h", +"module.h", "axmc_shared_assets.h"]`), not every file under `src/`. Use a bare string when the +library exposes a single header (`"transport_layer.h"`). + +### export and the main.cpp exclusion + +`export.include` ships `./examples/*` and `./src/*`, and `export.exclude` MUST list `./src/main.cpp`. +`src/main.cpp` is the local build/test harness (see `microcontroller:firmware-module`) and must never +be shipped to consumers, even though it lives under `src/`. + +--- + +## The lib_deps <-> dependencies mirroring rule + +`platformio.ini` `lib_deps` (used for local builds/tests) and `library.json` `dependencies` (shipped +to consumers) MUST describe the same dependency set with the same owner, name, and version. Whenever +you add, remove, or re-pin a dependency, update BOTH files in the same change. + +Scope each `library.json` dependency to the boards that need it with a `platforms` array that matches +which `[env]` sections list it in `lib_deps`: + +- A dependency in every board's `lib_deps` -> `"platforms": ["atmelsam", "atmelavr", "teensy"]`. +- A dependency only in the `due`/`mega` `lib_deps` -> `"platforms": ["atmelsam", "atmelavr"]`. + +```json +{ "owner": "pfeerick", "name": "elapsedMillis", "version": "^1.0.6", "platforms": ["atmelsam", "atmelavr"] } +``` + +--- + +## Versioning + +`library.json` `version` is the SINGLE source of truth for the C++ library version — releases are +cut from it, and there is no Python-style single-sourcing helper. `platformio.ini` carries no version +field. When releasing, bump `library.json` `version` (see `/release`). + +--- + +## pio command reference + +These are the PlatformIO development-automation commands (agent-runnable, the C++ analogue of +`tox` envs). The PR gate for a PlatformIO library is `tox` (docs) plus `pio check` and `pio test`. + +| Command | Purpose | +|------------------------|---------------------------------------------------------------| +| `pio project init` | Scaffold/refresh the PlatformIO project from `platformio.ini` | +| `pio project metadata` | Emit resolved per-env build metadata (IDE/index integration) | +| `pio run` | Build the firmware/library for the selected environment(s) | +| `pio test` | Run the Unity unit tests on the selected environment(s) | +| `pio check` | Run static analysis on the source | + +--- + +## Verification checklist + +```text +PlatformIO configuration: +- [ ] platformio.ini has one [env:] section per supported board, named for the board +- [ ] Each env sets platform, board, framework=arduino, monitor_speed, test_framework=unity, build_flags=-std=c++17 +- [ ] build_unflags=-std=gnu++11 present on AVR/SAM boards that need it; upload_protocol set where required +- [ ] lib_deps entries are pinned as registry_owner/name@^X.Y.Z (ataraxis libs under the inkaros owner) +- [ ] library.json pins $schema and orders fields per the template +- [ ] headers lists only the public consumer-facing header(s) +- [ ] export.include ships ./examples/* and ./src/*; export.exclude lists ./src/main.cpp +- [ ] library.json dependencies mirror platformio.ini lib_deps (same owner/name/version) +- [ ] each library.json dependency's platforms array matches the boards that list it in lib_deps +- [ ] library.json version is set (the single source of the C++ library version); platformio.ini has no version +``` + +--- + +## Related skills + +| Skill | Relationship | +|-----------------------------------|----------------------------------------------------------------------| +| `/project-layout` | Owner of where platformio.ini/library.json sit in the C++ archetypes | +| `/cpp-style` | C++ source style (scopes out these config files) | +| `microcontroller:firmware-module` | The src/main.cpp harness that export excludes and the module sources | +| `/readme-style` | C++ PlatformIO README Installation/Developers sections | +| `/release` | Uses library.json version as the C++ library release version | diff --git a/plugins/automation/skills/platformio-config/references/config-templates.md b/plugins/automation/skills/platformio-config/references/config-templates.md new file mode 100644 index 0000000..be57c1b --- /dev/null +++ b/plugins/automation/skills/platformio-config/references/config-templates.md @@ -0,0 +1,131 @@ +# PlatformIO configuration templates + +Full annotated templates for `platformio.ini` and `library.json`. Adapt the board set, headers, and +dependencies to the library; keep field ordering and the mirroring rule. + +--- + +## platformio.ini + +One `[env:]` section per supported board. The Teensy env needs no `build_unflags`; the AVR +(`mega`) and SAM (`due`) envs add `build_unflags = -std=gnu++11` so `build_flags = -std=c++17` takes +effect. `lib_deps` is omitted from a board that has no dependencies. + +```ini +[env:teensy41] +platform = teensy +board = teensy41 +framework = arduino +monitor_speed = 115200 +test_framework = unity +upload_protocol = teensy-cli +build_flags = -std=c++17 +lib_deps = + arminjo/digitalWriteFast@^1.3.1 + inkaros/ataraxis-transport-layer-mc@^3.0.0 + +[env:due] +platform = atmelsam +board = due +framework = arduino +monitor_speed = 5250000 +test_framework = unity +build_unflags = -std=gnu++11 +build_flags = -std=c++17 +lib_deps = + pfeerick/elapsedMillis@^1.0.6 + arminjo/digitalWriteFast@^1.3.1 + inkaros/ataraxis-transport-layer-mc@^3.0.0 + +[env:mega] +platform = atmelavr +board = megaatmega2560 +framework = arduino +monitor_speed = 1000000 +test_framework = unity +build_unflags = -std=gnu++11 +build_flags = -std=c++17 +lib_deps = + pfeerick/elapsedMillis@^1.0.6 + arminjo/digitalWriteFast@^1.3.1 + inkaros/ataraxis-transport-layer-mc@^3.0.0 +``` + +--- + +## library.json + +The published registry manifest. `dependencies` mirrors the union of all `lib_deps` above; each +dependency's `platforms` array names the boards whose `lib_deps` list it (`elapsedMillis` is only in +`due`/`mega`, so it is scoped to `atmelsam`/`atmelavr`; `digitalWriteFast` and the ataraxis library +are in every board, so they list all three). `export.exclude` drops `./src/main.cpp`. `headers` +lists only the public consumer headers — use a bare string for a single-header library. + +```json +{ + "$schema": "https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/schema/library.json", + "name": "ataraxis-micro-controller", + "version": "3.0.1", + "description": "Provides the framework for integrating custom hardware modules with a centralized PC control interface.", + "keywords": "arduino, teensy, ataraxis, communication, serial, integration, hardware modules", + "repository": { + "type": "git", + "url": "https://github.com/Sun-Lab-NBB/ataraxis-micro-controller" + }, + "homepage": "https://ataraxis-micro-controller-api-docs.netlify.app/", + "authors": + [ + { + "name": "Ivan Kondratyev", + "url": "https://github.com/Inkaros", + "email" : "ik278@cornell.edu", + "maintainer": true + } + ], + "license": "Apache-2.0", + "frameworks": ["arduino"], + "platforms": ["atmelavr", "atmelsam", "teensy"], + "headers": ["kernel.h", "communication.h", "module.h", "axmc_shared_assets.h"], + "dependencies": + [ + { + "owner": "pfeerick", + "name": "elapsedMillis", + "version": "^1.0.6", + "platforms": ["atmelsam", "atmelavr"] + }, + { + "owner": "arminjo", + "name": "digitalWriteFast", + "version": "^1.3.1", + "platforms": ["atmelsam", "atmelavr", "teensy"] + }, + { + "owner": "inkaros", + "name": "ataraxis-transport-layer-mc", + "version": "^3.0.1", + "platforms": ["atmelsam", "atmelavr", "teensy"] + } + ], + "export": { + "include": + [ + "./examples/*", + "./src/*" + ], + "exclude": + [ + "./src/main.cpp" + ] + }, + "build": { + "flags": "-std=c++17" + } +} +``` + +For a single-header library, `headers` is a bare string instead of an array: + +```json +"headers": "transport_layer.h", +``` diff --git a/plugins/automation/skills/pr/SKILL.md b/plugins/automation/skills/pr/SKILL.md index a1bf84f..48de5cf 100644 --- a/plugins/automation/skills/pr/SKILL.md +++ b/plugins/automation/skills/pr/SKILL.md @@ -39,9 +39,12 @@ Run the following git commands in parallel using the Bash tool: 1. Determine the active branch with `git branch --show-current` and the default branch (commonly `main` or `master`; confirm via `git symbolic-ref --short refs/remotes/origin/HEAD` and strip the `origin/` prefix when a - remote exists). -2. `git log ..HEAD --oneline` to list the commits unique to the active branch. -3. `git diff ...HEAD --stat` to see the overall scope of changed files (use the three-dot form to + remote exists). If that command errors with `is not a symbolic ref`, run `git remote set-head origin -a` to + populate `origin/HEAD`, otherwise fall back to checking for `main` then `master`. +2. If the active branch IS the default branch, stop: no pull request can be drafted from the default branch (the + `..HEAD` diff range is empty). Tell the user to switch to or create a feature branch first. +3. `git log ..HEAD --oneline` to list the commits unique to the active branch. +4. `git diff ...HEAD --stat` to see the overall scope of changed files (use the three-dot form to compare against the merge base). ### Step 2: Analyze the branch diff --git a/plugins/automation/skills/project-layout/SKILL.md b/plugins/automation/skills/project-layout/SKILL.md index 76f6044..da9bf27 100644 --- a/plugins/automation/skills/project-layout/SKILL.md +++ b/plugins/automation/skills/project-layout/SKILL.md @@ -223,6 +223,12 @@ src/ └── py.typed ``` +`.pyi` stub files (and the `py.typed` marker) are GENERATED artifacts, never hand-authored. +`tox -e stubs` produces them and they ship with releases, but `tox -e lint` +(`automation-cli purge-stubs`) removes them from the working tree during development — so their +presence is release-phase-dependent. Do not create, hand-edit, or treat a missing `.pyi` as a +layout violation; to change typing, edit the `.py` and regenerate. + ### PlatformIO library (header-only `src/`) ```text @@ -260,16 +266,17 @@ Assets/ ## Related skills -| Skill | Relationship | -|--------------------|--------------------------------------------------------------------------| -| `/api-docs` | Owns the internal `docs/` structure; this skill owns directory placement | -| `/python-style` | Owns file-level ordering within Python source files | -| `/cpp-style` | Owns file-level ordering within C++ source files | -| `/csharp-style` | Owns file-level ordering within C# source files | -| `/pyproject-style` | Owns `pyproject.toml` structure; references `src/` layout convention | -| `/tox-config` | Owns `tox.ini` conventions; `tox.ini` is a common root file | -| `/readme-style` | Owns `README.md` content conventions | -| `/skill-design` | Owns `plugins/automation/skills/` directory structure conventions | +| Skill | Relationship | +|----------------------|--------------------------------------------------------------------------| +| `/api-docs` | Owns the internal `docs/` structure; this skill owns directory placement | +| `/python-style` | Owns file-level ordering within Python source files | +| `/cpp-style` | Owns file-level ordering within C++ source files | +| `/csharp-style` | Owns file-level ordering within C# source files | +| `/pyproject-style` | Owns `pyproject.toml` structure; references `src/` layout convention | +| `/tox-config` | Owns `tox.ini` conventions; `tox.ini` is a common root file | +| `/platformio-config` | Owns `platformio.ini` and `library.json` conventions (C++ archetypes) | +| `/readme-style` | Owns `README.md` content conventions | +| `/skill-design` | Owns `plugins/automation/skills/` directory structure conventions | --- @@ -306,6 +313,7 @@ Source Directory: - [ ] Python+C++ extension uses flat namespace under src/ (c_extensions/, wrapper/, etc.) - [ ] PlatformIO projects use src/ with header-only .h files - [ ] Unity projects use Assets/ with task-specific subdirectories +- [ ] No hand-authored or stale .pyi stubs committed mid-development (stubs are generated at release time via tox -e stubs) Environment Directory: - [ ] Python projects have envs/ with 6 files (3 platforms x 2 files each) diff --git a/plugins/automation/skills/project-layout/references/archetype-trees.md b/plugins/automation/skills/project-layout/references/archetype-trees.md index 148fb44..3aaf412 100644 --- a/plugins/automation/skills/project-layout/references/archetype-trees.md +++ b/plugins/automation/skills/project-layout/references/archetype-trees.md @@ -36,7 +36,7 @@ project-root/ │ │ ├── __init__.py │ │ └── module.py │ ├── __init__.py # Package init with public API re-exports -│ ├── __init__.pyi # (optional) Stub file for re-exports +│ ├── __init__.pyi # Generated stub for re-exports (present in releases only) │ ├── module.py # Source modules │ └── py.typed # PEP 561 marker for typed packages ├── tests/ @@ -57,6 +57,11 @@ project-root/ ataraxis-automation, `axbu` for ataraxis-base-utilities). - The `tests/` directory mirrors the `src/package_name/` structure. Test files use the `_test.py` suffix (e.g., `automation_test.py`). +- `.pyi` stub files (and the `py.typed` marker) are GENERATED artifacts, never hand-authored. + `tox -e stubs` produces them and they ship with releases, but `tox -e lint` + (`automation-cli purge-stubs`) removes them from the working tree during development — so their + presence is release-phase-dependent. Do not create, hand-edit, or treat a missing `.pyi` as a + layout violation; to change typing, edit the `.py` and regenerate. - The `.pypirc` file may exist locally but is not committed to version control. - Build artifacts (`dist/`, `reports/`, `coverage.xml`) are gitignored. @@ -95,13 +100,13 @@ project-root/ │ ├── python_wrapper/ # Pure Python wrapper around C++ extension │ │ ├── __init__.py │ │ ├── wrapper_module.py # Python class wrapping C++ class -│ │ └── wrapper_module.pyi # Stub file for wrapper +│ │ └── wrapper_module.pyi # Generated stub for wrapper (present in releases only) │ ├── pure_python_module/ # (optional) Additional pure Python subpackages │ │ ├── __init__.py │ │ └── module.py │ ├── __init__.py # Top-level package init -│ ├── __init__.pyi # Top-level stub file -│ ├── module_ext.pyi # Stub for compiled C++ extension +│ ├── __init__.pyi # Generated top-level stub (present in releases only) +│ ├── module_ext.pyi # Generated stub for compiled C++ extension (releases only) │ └── py.typed # PEP 561 marker ├── tests/ │ ├── python_wrapper/ # Tests for Python wrapper diff --git a/plugins/automation/skills/pyproject-style/SKILL.md b/plugins/automation/skills/pyproject-style/SKILL.md index 6b4b335..19b29ed 100644 --- a/plugins/automation/skills/pyproject-style/SKILL.md +++ b/plugins/automation/skills/pyproject-style/SKILL.md @@ -323,6 +323,7 @@ Tool Configurations: - [ ] Ruff: Google docstring convention - [ ] Ruff: isort configured (case-sensitive, combine-as-imports, etc.) - [ ] Ruff: __init__.py ignores F401 and F403 +- [ ] Ruff: test-file ignores present when a tests/ directory exists - [ ] Ruff: Each ignore has an explanatory inline comment - [ ] MyPy: Configuration tier matches project type (full strict or minimal) - [ ] MyPy: Standard exclusion list present diff --git a/plugins/automation/skills/pyproject-style/references/project-metadata.md b/plugins/automation/skills/pyproject-style/references/project-metadata.md index bb359c5..ccff73c 100644 --- a/plugins/automation/skills/pyproject-style/references/project-metadata.md +++ b/plugins/automation/skills/pyproject-style/references/project-metadata.md @@ -156,6 +156,12 @@ All production projects use: "Topic :: Scientific/Engineering", ``` +Treat the audience/topic split above as a starting point. Choose the `Topic` classifier to match the project's domain +rather than always defaulting to `Topic :: Software Development`. Practiced domain-specific values include +`Topic :: Communications` (ataraxis-communication-interface, ataraxis-transport-layer-pc) and +`Topic :: Multimedia :: Video` (ataraxis-video-system); projects without a more specific domain keep +`Topic :: Software Development`. + ### Python versions List each supported minor version individually: diff --git a/plugins/automation/skills/pyproject-style/references/tool-configurations.md b/plugins/automation/skills/pyproject-style/references/tool-configurations.md index 5a80a2a..fa647fb 100644 --- a/plugins/automation/skills/pyproject-style/references/tool-configurations.md +++ b/plugins/automation/skills/pyproject-style/references/tool-configurations.md @@ -93,6 +93,11 @@ convention = "google" ] ``` +When a `tests/` directory exists, add a second per-file-ignores key for test files relaxing test-specific lint +rules. Spell the glob `**/tests/**/*.py` or `tests/**/*.py` to match the project's layout. The commonly relaxed rules +are `S101`, `SLF001`, `PLR2004`, `ANN`/`ANN001`/`ANN201`, `D`/`D202`, `INP001`, `PT006`, and `ARG001`; the exact set +varies per project. Each ignore carries an explanatory inline comment, as elsewhere. + ### Ruff isort ```toml diff --git a/plugins/automation/skills/python-style/SKILL.md b/plugins/automation/skills/python-style/SKILL.md index f791feb..f6b900c 100644 --- a/plugins/automation/skills/python-style/SKILL.md +++ b/plugins/automation/skills/python-style/SKILL.md @@ -88,7 +88,7 @@ consistency across languages while respecting each language's idiomatic standard **Python-specific divergences from C++:** - Functions and methods use snake_case (not PascalCase as in C++) -- Constants use `_UPPER_SNAKE_CASE` (not `kPascalCase` as in C++) +- Constants use `_UPPER_SNAKE_CASE` for private / `UPPER_SNAKE_CASE` for public (not `kPascalCase` as in C++) - Enum values use `UPPER_SNAKE_CASE` (not `kPascalCase` as in C++) - Documentation uses Google-style docstrings (not Doxygen `@tags`) - Error handling uses `console.error()` or `raise` (not status codes) @@ -96,7 +96,7 @@ consistency across languages while respecting each language's idiomatic standard **Python-specific divergences from C#:** - Functions and methods use snake_case (not PascalCase as in C#) -- Constants use `_UPPER_SNAKE_CASE` (not PascalCase as in C#) +- Constants use `_UPPER_SNAKE_CASE` for private / `UPPER_SNAKE_CASE` for public (not PascalCase as in C#) - Enum values use `UPPER_SNAKE_CASE` (not PascalCase as in C#) - Documentation uses Google-style docstrings (not XML `` tags) - Private members use `_snake_case` (not `_camelCase` as in C#) @@ -125,11 +125,16 @@ Use **full words**, not abbreviations: ### Constants -Module-level constants with type annotations, descriptive names, and inline docstrings: +Module-level constants with type annotations, descriptive names, and inline docstrings. Constants +intended for export (listed in `__all__`) use bare `UPPER_SNAKE_CASE`; constants internal to a +module use `_UPPER_SNAKE_CASE`: ```python _MINIMUM_SAMPLE_COUNT: int = 100 """Minimum number of samples required for statistical validity.""" + +MAXIMUM_QUANTIZATION_VALUE: int = 51 +"""Maximum quantization value accepted by the encoder.""" ``` --- @@ -155,6 +160,14 @@ Exceptions: Note: standard `@njit` / `@jit` functions do support keyword arguments and are not exempt from this rule. +On the signature side, make boolean flag parameters keyword-only by placing them after a `*,` +separator, so callers must pass them by name: + +```python +def transfer_directory(source: Path, destination: Path, *, verify_integrity: bool = False, + remove_source: bool = False) -> None: ... +``` + --- ## Error handling @@ -176,6 +189,10 @@ def process_data(self, data: NDArray[np.float32], threshold: float) -> None: In projects that do not depend on `ataraxis-base-utilities`, use standard `raise` with the same message format. +`console.error` is typed `NoReturn` and always raises the supplied exception, so no `raise` or +`return` should follow it — treat it as a terminating call in guard clauses (mypy understands the +`NoReturn` contract). + ### Error message format - Start with context: "Unable to [action] using [input]." @@ -287,6 +304,13 @@ must appear **above** the functions and classes that use them. themselves, the order is: enumerations first, then public helper functions, then private helper functions, then dataclasses at the bottom. +### Stub files + +`.pyi` stub files and the `py.typed` marker are GENERATED, never hand-authored. `tox -e stubs` +produces them and they ship with releases; never create or hand-edit a stub — change typing by +editing the `.py` source and regenerating. If stale stubs are cluttering a dev session, purge them +with `tox -e lint` (`automation-cli purge-stubs`). + --- ## Boolean expressions diff --git a/plugins/automation/skills/python-style/references/libraries-and-tools.md b/plugins/automation/skills/python-style/references/libraries-and-tools.md index a66493e..eb32c86 100644 --- a/plugins/automation/skills/python-style/references/libraries-and-tools.md +++ b/plugins/automation/skills/python-style/references/libraries-and-tools.md @@ -218,6 +218,9 @@ if mode == 3: # noqa: PLR2004 - LICK_TRAINING mode value from VisualizerMode en ... ``` +Defensive or unreachable guard branches and hardware- or OS-dependent code paths are annotated with +`# pragma: no cover` to satisfy the coverage gate. + ### IDE inspection directives IDE-specific inspection-suppression comments are NOT used in this codebase and MUST be removed whenever encountered. diff --git a/plugins/automation/skills/readme-style/references/section-templates.md b/plugins/automation/skills/readme-style/references/section-templates.md index e18304f..181b1ea 100644 --- a/plugins/automation/skills/readme-style/references/section-templates.md +++ b/plugins/automation/skills/readme-style/references/section-templates.md @@ -106,15 +106,17 @@ control. ## Features -Optional. When present, use a bulleted list of key capabilities. The **last bullet** must state -the license type: +Optional. When present, use a bulleted list of key capabilities. The **first bullet** states the +supported platforms/OS ("Supports Windows, Linux, and macOS." for PC libraries, "Supports all +recent Arduino and Teensy architectures and platforms." for microcontroller libraries). The +**last bullet** must state the license type: ```markdown ## Features -- Automated environment creation and management via mamba and uv. +- Supports Windows, Linux, and macOS. - Unified CLI for linting, type checking, testing, and documentation builds. -- Cross-platform support for Windows, Linux, and macOS. +- Automated environment creation and management via mamba and uv. - Apache 2.0 License. ``` @@ -212,6 +214,39 @@ Use the following command to install the library and all of its dependencies via Replace `PACKAGE-NAME` with the actual PyPI package name. +### C++ / PlatformIO libraries + +C++ PlatformIO libraries use a Source and a `### Platformio` subsection (not `### pip`). The +Source subsection moves the distribution's `src` contents into the consuming project's directory +and adds the relevant `#include` directives; the Platformio subsection declares the dependency via +`lib_deps`: + +```markdown +## Installation + +### Source + +***Note,*** installation from source is ***highly discouraged*** for anyone who is not an active +project developer. + +1. Download this repository to the local machine using the preferred method, such as git-cloning. + Use one of the [stable releases](https://github.com/Sun-Lab-NBB/PROJECT-NAME/tags). +2. Unpack the downloaded tarball and move all 'src' contents into the appropriate destination + ('include,' 'src,' or 'libs') directory of the project that needs to use this library. +3. Add the project's `#include` directives at the top of the main.cpp file and each consuming + header file. + +### Platformio + +1. Navigate to the project's platformio.ini file and add the following line to the target + environment specification: `lib_deps = inkaros/PACKAGE-NAME@^MAJOR.0.0`. +2. Add the project's `#include` directives at the top of the main.cpp file and each consuming + header file. +``` + +Replace `PROJECT-NAME` with the repository name, `PACKAGE-NAME` with the PlatformIO registry +package name, and `MAJOR` with the current major version. + --- ## Usage @@ -385,6 +420,19 @@ directories (`.tox`, `.ruff_cache`, `.mypy_cache`, etc.) manually or via a CLI c resolves the issue. ```` +### C++ / PlatformIO variant + +C++ PlatformIO projects differ from the Python template above: + +- **Installing the Project**: install the [PlatformIO](https://platformio.org/install/integration) + IDE/plugin instead of mamba/tox, then run `pio project init` and (for IDEs lacking native + PlatformIO support) `pio project metadata`. +- **Additional Dependencies**: Tox and Doxygen (both on the system path), used to build the API + documentation. +- **Development Automation**: driven by the PlatformIO CLI; tox is reserved for tasks not covered + by PlatformIO, such as API documentation generation. +- **PR gate**: the `tox`, `pio check`, and `pio test` tasks must all pass before merging. + --- ## Standard ending sections diff --git a/plugins/automation/skills/release/SKILL.md b/plugins/automation/skills/release/SKILL.md index a915a22..46bed63 100644 --- a/plugins/automation/skills/release/SKILL.md +++ b/plugins/automation/skills/release/SKILL.md @@ -39,12 +39,18 @@ Run the following git commands using the Bash tool: 1. Identify the previous release tag with `git tag --sort=-v:refname` (most recent first) or `git describe --tags --abbrev=0`. -2. List the pull requests merged since that tag with `git log ..HEAD --merges --oneline`. Each merge - commit names the pull request number and source branch, and its body carries the pull request title. +2. List the pull requests merged since that tag with `git log ..HEAD --merges --format='%h %s%n%b'`. + The `Merge pull request #N from ...` subject line names only the number and source branch — the pull request + title and description live in the commit body, so you MUST read the body (not `--oneline`) to draft the notes. 3. Review the aggregate change scope with `git diff ..HEAD --stat`. -If the repository has no prior release tag, summarize the full history (`git log --merges --oneline`) and note that -this is the first release. +If `--merges` returns few or no results relative to the `git diff --stat` scope, the repository likely uses +squash- or rebase-merged pull requests or direct commits to the default branch, which produce no merge commit. +Enumerate from `git log ..HEAD --oneline --no-merges` instead and reconcile both so no merged work +is silently dropped. + +If the repository has no prior release tag, summarize the full history (`git log --merges --format='%h %s%n%b'`) +and note that this is the first release. ### Step 2: Determine the platform @@ -60,6 +66,9 @@ Determine whether the project is an ataraxis library or a sollertia library from Infer the release type from the change set and recommend it to the user. You MUST ask the user to confirm the type before finalizing the notes — never decide it unilaterally. +For C++ PlatformIO libraries the release version is single-sourced from `library.json` (not pyproject.toml); see +`/platformio-config`. + | Type | Use case | |-------|------------------------------------------------------------------------------------------| | Major | Breaking API changes, removals, re-licensing, or migrations requiring downstream updates | diff --git a/plugins/automation/skills/skill-design/SKILL.md b/plugins/automation/skills/skill-design/SKILL.md index 5a12768..c692642 100644 --- a/plugins/automation/skills/skill-design/SKILL.md +++ b/plugins/automation/skills/skill-design/SKILL.md @@ -124,8 +124,11 @@ For each aspect of the skill's behavior, decide the appropriate freedom level: ### Step 4: Create the directory structure +In this repo every skill lives under `plugins//skills//`. The plugin's +`.claude-plugin/plugin.json` with `"skills": "./skills/"` is what registers the skills directory: + ```text -skill-name/ +plugins//skills/skill-name/ ├── SKILL.md # Main instructions (always loaded) └── references/ # Detailed material (loaded on demand) └── detailed-rules.md # Only if SKILL.md would exceed 500 lines @@ -153,6 +156,11 @@ Run through the verification checklist at the end of this skill. Then invoke the current repository to verify it produces correct behavior. Test with both explicit invocation (`/skill-name`) and contextual descriptions to confirm the trigger conditions work. +A new skill under an existing plugin needs no manual registration — the plugin.json `"skills": +"./skills/"` glob auto-discovers it. If the new skill introduces a new plugin, add that plugin to +the repo's `.claude-plugin/marketplace.json` `plugins` array. Adding or materially changing a +plugin's skills should bump `version` in that plugin's `.claude-plugin/plugin.json`. + --- ## SKILL.md conventions diff --git a/plugins/automation/skills/skill-design/references/progressive-disclosure.md b/plugins/automation/skills/skill-design/references/progressive-disclosure.md index 88d9628..f9034c3 100644 --- a/plugins/automation/skills/skill-design/references/progressive-disclosure.md +++ b/plugins/automation/skills/skill-design/references/progressive-disclosure.md @@ -15,7 +15,7 @@ reference material available when needed. ## Directory structure ```text -skill-name/ +plugins//skills/skill-name/ ├── SKILL.md # Main instructions (loaded when triggered) ├── references/ # Detailed reference material (loaded on demand) │ ├── field-reference.md diff --git a/plugins/automation/skills/tox-config/SKILL.md b/plugins/automation/skills/tox-config/SKILL.md index 066b83a..2920b2b 100644 --- a/plugins/automation/skills/tox-config/SKILL.md +++ b/plugins/automation/skills/tox-config/SKILL.md @@ -380,6 +380,15 @@ basepython = py312 # Earliest supported version controls lint/mypy ruleset --- +## Command reference + +For the full list of tox environments and the underlying `automation-cli` commands (with options) +that the pipeline runs, see [Command reference](references/environment-templates.md). Agents drive +these via `tox -e `; the `automation-cli` commands are documented there for diagnostics and +for answering user questions. + +--- + ## Related skills | Skill | Relationship | diff --git a/plugins/automation/skills/tox-config/references/environment-templates.md b/plugins/automation/skills/tox-config/references/environment-templates.md index 5953521..c40709a 100644 --- a/plugins/automation/skills/tox-config/references/environment-templates.md +++ b/plugins/automation/skills/tox-config/references/environment-templates.md @@ -52,6 +52,13 @@ setenv = UV_PRERELEASE = allow ``` +tox does not merge `setenv` — an env that defines its own `setenv` block (test and coverage both +set `COVERAGE_FILE`) fully replaces the inherited base `setenv` rather than extending it. So if a +project needs prereleases during testing, re-declare `UV_PRERELEASE = allow` inside the test env +`setenv` alongside `COVERAGE_FILE` (see ataraxis-transport-layer-pc/tox.ini, which does this; +ataraxis-communication-interface and ataraxis-video-system keep prereleases out of test envs by +omitting it). + ### lint environment ```ini @@ -139,7 +146,11 @@ description = aggregates test coverage data. Uses 'loadgroup' balancing and all logical cores to optimize task runtime speed. dependency_groups = dev -setenv = COVERAGE_FILE = reports{/}.coverage.{envname} +setenv = + COVERAGE_FILE = reports{/}.coverage.{envname} + # Re-declare here only if the project needs prereleases during testing — this setenv block + # fully replaces the base [testenv] setenv (tox does not merge). + # UV_PRERELEASE = allow commands = pytest --import-mode=append --cov={package_name} --cov-config=pyproject.toml \ --cov-report=xml --junitxml=reports/pytest.xml.{envname} -n logical --dist loadgroup @@ -419,3 +430,49 @@ The tox.ini structure is identical to the full pipeline except: - The test and coverage environment definitions may be omitted entirely or left as unused definitions for future use. - The `install` environment's `depends` list omits test and coverage dependencies. + +--- + +## Command reference + +These are the development-automation commands. Agents normally drive them via `tox -e `; the +underlying `automation-cli` commands are documented for diagnostics and for answering user +questions. + +### tox environments + +| Environment | Purpose | +|------------------------------|--------------------------------------------------------------------------| +| `lint` | Purges `.pyi` stubs, then runs `ruff format`, `ruff check --fix`, `mypy` | +| `stubs` | Regenerates the `py.typed` marker and `.pyi` stub files | +| `{py312,py313,py314}-test` | Runs the test suite under each Python version, collecting coverage | +| `coverage` | Combines per-version coverage and junit reports into xml + html | +| `docs` | Builds API docs with Sphinx (and Doxygen for C++/hybrid projects) | +| `build` | Builds the sdist and wheel distributions | +| `upload` | Uploads the `dist/` files to PyPI via twine | +| `install` | Builds and installs the project into its development mamba environment | +| `uninstall` | Uninstalls the project from its development mamba environment | +| `create` | Creates the development mamba environment and installs dependencies | +| `remove` | Removes (deletes) the development mamba environment | +| `provision` | Removes and (re)creates the development mamba environment | +| `export` | Exports the mamba environment to `envs/` as `.yml` and `spec.txt` | +| `import` | Creates or updates the mamba environment from the stored `.yml` file | + +`tox -e lint` purges `.pyi` stubs (via `automation-cli purge-stubs`) so they do not interfere with +mypy; `tox -e stubs` regenerates them afterward. + +### automation-cli commands + +| Command | Key options | Purpose | +|--------------------------|-----------------------------------------------------------------------|---------------------------------------------------------------------| +| `process-typed-markers` | — | Places the `py.typed` marker only at the library root | +| `process-stubs` | — | Distributes generated stubs from `stubs/` into the source tree | +| `purge-stubs` | — | Removes all `.pyi` stub files from the source tree | +| `acquire-pypi-token` | `-rt`/`--replace-token` | Ensures a valid PyPI token is stored in `.pypirc` | +| `install-project` | `-e`/`--environment-name`, `-ed`/`--environment-directory`, `--prerelease` | Builds and installs the project into the mamba environment | +| `uninstall-project` | `-e`/`--environment-name`, `-ed`/`--environment-directory` | Uninstalls the project from the mamba environment | +| `create-environment` | `-e`/`--environment-name`, `-p`/`--python-version`, `-ed`/`--environment-directory`, `--prerelease` | Creates the mamba environment and installs dependencies | +| `remove-environment` | `-e`/`--environment-name`, `-ed`/`--environment-directory` | Removes (deletes) the mamba environment | +| `provision-environment` | `-e`/`--environment-name`, `-p`/`--python-version`, `-ed`/`--environment-directory`, `--prerelease` | Removes and recreates the mamba environment | +| `import-environment` | `-e`/`--environment-name`, `-ed`/`--environment-directory` | Creates or updates the mamba environment from the stored `.yml` | +| `export-environment` | `-e`/`--environment-name`, `-ed`/`--environment-directory` | Exports the mamba environment to `envs/` as `.yml` and `spec.txt` | diff --git a/plugins/communication/.claude-plugin/plugin.json b/plugins/communication/.claude-plugin/plugin.json index 0224df8..c5cbe4a 100644 --- a/plugins/communication/.claude-plugin/plugin.json +++ b/plugins/communication/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "communication", - "version": "1.1.0", + "version": "1.2.0", "description": "Provides microcontroller discovery, extraction configuration, log processing, and pipeline orchestration skills for ataraxis-communication-interface. Includes MCP bindings for hardware discovery, manifest management, and batch data processing.", "repository": "https://github.com/Sun-Lab-NBB/ataraxis", "license": "Apache-2.0", diff --git a/plugins/communication/skills/extraction-configuration/SKILL.md b/plugins/communication/skills/extraction-configuration/SKILL.md index 0ba92a3..683ebd5 100644 --- a/plugins/communication/skills/extraction-configuration/SKILL.md +++ b/plugins/communication/skills/extraction-configuration/SKILL.md @@ -166,6 +166,10 @@ instance. keepalive signals) - Event codes above 50 are user-defined module events; codes 0-50 are reserved for system service messages +Extraction filters each module against only its own `event_codes` set (no cross-module leakage), so +listing the same code value under two modules is safe and isolated; any message for an unlisted module or +an unlisted event code is silently excluded from output with no error. + The agent CANNOT determine which event codes to use by inspecting the codebase. Event codes are firmware-specific knowledge that must come from the user. @@ -275,6 +279,18 @@ controllers: | Controller ID exists in manifest | "Controller ID not found in manifest" | | Module (type, id) pair exists in manifest | "Module (type, id) not registered in manifest" | +### Runtime enforcement (not covered by the validate tool) + +The config may list only a subset of the manifest's controllers and modules (extraction is selective), +but every `controller_id` it lists must resolve to exactly one `.npz` archive in the log directory at +processing time. A missing archive raises `FileNotFoundError` and duplicate matching archives raise +`ValueError`. `validate_extraction_config_tool` does NOT verify on-disk archive presence, so a structurally +valid config can still crash `/log-processing`. + +The empty-`event_codes` rule is also enforced at runtime: processing raises `ValueError` if any configured +module or kernel entry has empty `event_codes`. The `axci config create` precursor always ships empty event +codes by design, so it must be filled in before processing. + --- ## Troubleshooting @@ -290,6 +306,20 @@ controllers: --- +## CLI reference (human-facing — do not invoke) + +> **CLI reference — for answering user questions only.** The `axci` command-line interface is a +> **human-facing** tool. **Agents must never invoke `axci` commands** — every agent-driven operation has an +> equivalent MCP tool (noted in the table). This section exists solely so the agent can answer user +> questions about the CLI. + +| Command | Key options | Purpose | MCP equivalent | +|----------------------|----------------------------------------|------------------------------------------------------|------------------------------------------------------| +| `axci config create` | `-m/--manifest-path`, `-o/--output-path` | Writes a precursor config from the manifest (empty event codes) | None (no MCP tool exposes precursor generation) | +| `axci config show` | `-c/--config-path` | Prints a config's controllers, modules, and event codes | `read_extraction_config_tool` | + +--- + ## Related skills | Skill | Relationship | diff --git a/plugins/communication/skills/log-input-format/SKILL.md b/plugins/communication/skills/log-input-format/SKILL.md index 17d82d4..7376778 100644 --- a/plugins/communication/skills/log-input-format/SKILL.md +++ b/plugins/communication/skills/log-input-format/SKILL.md @@ -106,6 +106,13 @@ controller-produced log archives. Directories without a `microcontroller_manifes discovered. Manifests also associate controller IDs with human-readable names and enumerate the hardware modules managed by each controller. +**Manifest gates, config selects:** The controller IDs to process are taken from the `ExtractionConfig` +(`resolved_config.controllers`) and are the sole source of truth for which archives are processed — not +the manifest or which `.npz` files exist on disk. Each config controller ID must also appear in +`microcontroller_manifest.yaml`, or processing raises a `ValueError` listing the unregistered IDs and the +registered set. Manifest controllers the config omits are simply not processed. The manifest only +validates/gates; it does not select. + **Key difference from AXVS manifests:** AXCI manifests include a `modules` list per controller, providing full hardware module metadata (type, id, name). AXVS camera manifests only have source ID and camera name. @@ -277,7 +284,9 @@ After the leading protocol byte, the remaining bytes follow protocol-specific la - **module_type** — Module family code of the sending module (module messages only) - **module_id** — Instance ID of the sending module (module messages only) - **command** — The command code the module/kernel was executing -- **event** — The event code identifying the message type +- **event** — The event code identifying the message type. The processing pipeline filters on the event + code alone (the command is recorded but not used to select messages), and firmware guarantees event + codes are unique within each module/kernel — see `/extraction-configuration`. - **prototype_code** — Identifies the numpy dtype and size of the data bytes (auto-resolved at compile time by the firmware library; data messages only) - **data** — The serialized data value (data messages only) @@ -305,6 +314,14 @@ Before running the log processing pipeline, verify these conditions: 3. **Archive naming valid** — Files match the `{source_id}_log.npz` pattern. + - **One archive per source ID** — Exactly one `{source_id}_log.npz` may exist anywhere under the + search root. `find_log_archive` recursively rglobs the pattern, and more than one match raises a + `ValueError` ("Found N matching archives, but expected exactly one") — duplicates fail, not first-wins. + - **Single parent directory per invocation** — All source IDs processed in one local invocation must + resolve to the same parent directory. If resolved archives span more than one directory, + `run_log_processing_pipeline` raises a `ValueError` ("span multiple directories ... Each DataLogger + output directory must be processed independently"). Point the pipeline at each logger directory separately. + 4. **Onset message present** — Each archive must contain exactly one onset message (elapsed_us=0) with a valid UTC epoch payload. Archives missing the onset message cannot be processed. diff --git a/plugins/communication/skills/log-processing-results/SKILL.md b/plugins/communication/skills/log-processing-results/SKILL.md index d3676fc..a7841cf 100644 --- a/plugins/communication/skills/log-processing-results/SKILL.md +++ b/plugins/communication/skills/log-processing-results/SKILL.md @@ -118,6 +118,10 @@ results[]: Per-file analysis results: total_files: Number of files analyzed ``` +`inter_event_timing` is `{}` when `total_rows < 2`. For an empty file, `summary` is just +`{total_rows: 0}` (no timestamps/duration), with empty `event_distribution`, `command_distribution`, and +`sample_rows`. + --- ## Recommended query order @@ -172,6 +176,12 @@ config's event codes. Multiple feather files may be produced per source ID (one per module extraction target plus an optional kernel file). This differs from the axvs pipeline which produces one file per source. +A configured module or kernel produces a feather file **only if at least one message matched its event +codes**; a fully empty archive produces no files at all. All of these cases still report `SUCCEEDED`. A +missing expected file therefore means the configured event codes never fired — not data loss or a +processing failure. Cross-check it against the event distribution (`query_extracted_events_tool`) or the +input archive before treating it as a problem. + ### ProcessingTracker file The `microcontroller_processing_tracker.yaml` file tracks job lifecycle per output directory. Each job has: @@ -217,6 +227,10 @@ value = np.frombuffer(payload, dtype=np.dtype(dtype_str)) The `dtype` column contains the numpy dtype string that was used to serialize the data on the microcontroller side. Common dtypes include `uint8`, `uint16`, `uint32`, `int32`, `float32`. +Rows from `*_STATE` events carry null `dtype`/`data` by design — a state code reported via the `event` +column with no payload — while `*_DATA` events carry a numpy dtype string and serialized bytes. Null is +the expected signature of a state-report event, not corruption. + ### Module vs kernel files - **Module files** contain data from specific hardware modules (sensors, actuators, encoders). Each @@ -276,7 +290,8 @@ To determine detailed job status, use `get_batch_status_overview_tool` from `/lo Log Processing Output Completeness: - [ ] Output directory contains `microcontroller_data/` subdirectory - [ ] Feather files verified via `verify_processing_output_tool` (schema correct) -- [ ] All expected module and kernel files present (cross-reference with extraction config) +- [ ] All expected module and kernel files present (cross-reference with extraction config; a missing + file with a SUCCEEDED job means its event codes never fired, not a failure) - [ ] Processing tracker shows SUCCEEDED for all jobs - [ ] Event analysis performed via `query_extracted_events_tool` - [ ] Event distribution matches expected firmware event codes diff --git a/plugins/communication/skills/log-processing/SKILL.md b/plugins/communication/skills/log-processing/SKILL.md index c3fb65e..c7c608a 100644 --- a/plugins/communication/skills/log-processing/SKILL.md +++ b/plugins/communication/skills/log-processing/SKILL.md @@ -109,6 +109,12 @@ directories. For legacy sessions without manifests, use `write_microcontroller_m | `output_directories` | `list[str]` | (required) | Absolute paths for per-directory output. Must match log_directories length. | | `config_path` | `str` | (required) | Absolute path to the validated ExtractionConfig YAML file. | +**Note:** Prepare filters `source_ids` down to those with an on-disk `{source_id}_log.npz` archive and silently +drops the rest with no error. A directory with no matching archives returns `jobs: []`, `source_ids: []`, and +`tracker_path: None` while still reporting `success: True`. After preparing, verify the returned source_ids/jobs +match the requested set — a mismatch (or `tracker_path: None`) means archives are missing for the dropped IDs, not +a failure to retry. + **`execute_log_processing_jobs_tool` parameters:** | Parameter | Type | Default | Description | @@ -127,6 +133,13 @@ directories. For legacy sessions without manifests, use `write_microcontroller_m | `get_batch_status_overview_tool` | Aggregate status across all log directories under root | | `clean_log_processing_output_tool` | Deletes `microcontroller_data/` subdirectories for re-processing | +**Note:** `get_log_processing_status_tool`, `get_log_processing_timing_tool`, and `cancel_log_processing_tool` +report only on the single active in-memory execution session (the most recent `execute_log_processing_jobs_tool` +call) and return a no-active-session response otherwise — e.g. when called before execute or after a server +restart, even if trackers with running jobs exist on disk (status/timing return `'No execution session exists.'`; +cancel returns `{canceled: False}` with `'No execution session is active.'`). For status of directories not in the +active session, use `get_batch_status_overview_tool`, which reads trackers from disk. + **`reset_log_processing_jobs_tool` parameters:** | Parameter | Type | Default | Description | @@ -164,6 +177,8 @@ Key architectural facts: - **ProcessingTracker** manages job lifecycle: `SCHEDULED` → `RUNNING` → `SUCCEEDED` / `FAILED` via YAML state files - **Single execution session** constraint: only one batch execution can run at a time - **Parallel processing** activates automatically for archives with >=2000 messages +- **Empty archives:** an archive with zero data messages completes as `SUCCEEDED` and produces no feather files — + this is expected, not a failure to retry or clean - **ExtractionConfig** controls which modules, kernel messages, and event codes are extracted per controller - **Output layout:** All processing output is written under a `microcontroller_data/` subdirectory within the output directory provided by the user @@ -283,6 +298,9 @@ Summary: 5/8 jobs complete | 1 running | 2 queued | 0 failed | 104 | SCHEDULED | -- | ``` +A job may report status `UNKNOWN` when its tracker entry is unreadable or missing — resolve by re-preparing, not +by reset (which is for `FAILED` jobs). Status entries also carry an optional `executor_id` field. + When using `get_batch_status_overview_tool` for multi-directory status: ```text @@ -339,6 +357,21 @@ To re-process an entire directory from scratch, call `clean_log_processing_outpu --- +## CLI reference (human-facing — do not invoke) + +> **CLI reference — for answering user questions only.** The `axci` command-line interface is a **human-facing** +> tool. **Agents must never invoke `axci` commands** — every agent-driven operation has an equivalent MCP tool +> (noted in the table). This section exists solely so the agent can answer user questions about the CLI. + +This is the human path that the "do not run processing via CLI" instruction in Agent requirements refers to. +`axci process` handles ONE directory per invocation, whereas the MCP workflow batches many. + +| Command | Key options | Purpose | MCP equivalent | +|----------------|----------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------|---------------------------------------------------------------------------------| +| `axci process` | `-ld/--log-directory`, `-od/--output-directory`, `-c/--config`, `-id/--job-id`, `-w/--workers`, `-p/--progress/--no-progress` | Extracts module and kernel data from one directory's archives | `prepare_log_processing_batch_tool` / `execute_log_processing_jobs_tool` (batch) | + +--- + ## Related skills | Skill | Relationship | diff --git a/plugins/communication/skills/microcontroller-interface/SKILL.md b/plugins/communication/skills/microcontroller-interface/SKILL.md index 7116d32..065b578 100644 --- a/plugins/communication/skills/microcontroller-interface/SKILL.md +++ b/plugins/communication/skills/microcontroller-interface/SKILL.md @@ -145,6 +145,10 @@ MicroControllerInterface() → start() → [communication active] → stop() - `reset_controller()` resets the microcontroller to its default state - `stop()` terminates the communication process and releases all resources +`start()` and `stop()` are idempotent (each is a no-op if the interface is already in the target state), and +`__del__` calls `stop()` plus the multiprocessing Manager shutdown, so a garbage-collected interface releases +its process automatically. + After `stop()`, the DataLogger can be stopped and archives assembled. ### Properties @@ -255,6 +259,13 @@ module.send_parameters(parameter_data=(np.uint16(500), np.float32(1.5))) module.reset_command_queue() ``` +`send_command()`, `send_parameters()`, and `reset_command_queue()` raise `RuntimeError` until the module +interface is passed to a `MicroControllerInterface`, which wires the input queue during `__init__()` (not +`start()`). In addition, `send_command()` and `send_parameters()` may only be called from the main runtime +process — calling them from the spawned communication worker process raises `RuntimeError`, because their +message-builder caches are stripped when the interface is pickled into that process (`reset_command_queue()` +works wherever the input queue is wired). + ### Parameter struct correspondence The `parameter_data` tuple must match the firmware's `PACKED_STRUCT` field-by-field — same count, same @@ -321,7 +332,8 @@ MQTTCommunication() → connect() → [publish/subscribe] → disconnect() ``` - `connect()` establishes the broker connection and subscribes to monitored topics -- `send_data(topic, payload=None)` publishes data to the specified MQTT topic +- `send_data(topic, payload=None)` publishes a payload (`str | bytes | bytearray | float | None`, where + `None` publishes an empty message) to the specified MQTT topic; raises `ConnectionError` if not connected - `get_data()` returns the next received `(topic, payload)` tuple or `None` if empty - `has_data` property returns `True` if there are received messages waiting - `disconnect()` releases the connection (also called automatically on garbage collection) diff --git a/plugins/communication/skills/microcontroller-interface/references/api-reference.md b/plugins/communication/skills/microcontroller-interface/references/api-reference.md index 9bb60a2..5631c46 100644 --- a/plugins/communication/skills/microcontroller-interface/references/api-reference.md +++ b/plugins/communication/skills/microcontroller-interface/references/api-reference.md @@ -166,7 +166,7 @@ MQTTCommunication( |----------------------------------|------------------------------------------|-------------------------------------------------------------------| | `connect()` | `None` | Connects to broker and subscribes to monitored topics. | | `disconnect()` | `None` | Disconnects from broker. Called automatically on garbage collect. | -| `send_data(topic, payload=None)` | `None` | Publishes data to the specified MQTT topic. | +| `send_data(topic, payload=None)` | `None` | Publishes a payload (`str \| bytes \| bytearray \| float \| None`; `None` = empty message) to the topic. Raises `ConnectionError` if not connected. | | `get_data()` | `tuple[str, bytes \| bytearray] \| None` | Returns next received `(topic, payload)` or `None` if empty. | ### Properties @@ -419,6 +419,10 @@ runtime. It is optional and controlled by the `keepalive_interval` constructor p 3. If the microcontroller does not receive a keepalive within its configured timeout, it performs an emergency reset (all modules return to default state) and reports error code 10 (KEEPALIVE_TIMEOUT) via a KernelData message +4. In the other direction, if the microcontroller does not return the keepalive acknowledgement + (a ReceptionCode message with reception_code 255) within one `keepalive_interval`, the PC + communication process issues a reset command and raises `RuntimeError`, terminating the interface. + This PC-side failure is distinct from and additional to the MCU-reported error code 10 **When to enable:** - Enable keepalive for safety-critical hardware that must be reset if the PC loses communication diff --git a/plugins/communication/skills/microcontroller-setup/SKILL.md b/plugins/communication/skills/microcontroller-setup/SKILL.md index 9ba7796..35d820e 100644 --- a/plugins/communication/skills/microcontroller-setup/SKILL.md +++ b/plugins/communication/skills/microcontroller-setup/SKILL.md @@ -122,6 +122,12 @@ Each module dictionary must have keys: `module_type` (int), `module_id` (int), ` Creates a new manifest if none exists; appends to the existing manifest otherwise. +This tool ALWAYS appends — it does not detect or replace existing entries. Calling it twice for the same +`controller_id` creates a duplicate manifest entry, which `discover_microcontroller_data_tool` will then +report as two separate sources (it iterates every controller in the manifest). Read the manifest first with +`read_microcontroller_manifest_tool`; if the controller is already registered, do not call write again. To +correct a wrong entry, edit the YAML manually. + **`discover_microcontroller_data_tool` parameters:** | Parameter | Type | Default | Description | @@ -161,6 +167,10 @@ running discovery. | `remove_sources` | `bool` | `true` | Delete original .npy files after assembly | | `verify_integrity` | `bool` | `false` | Verify archive integrity before removing sources | +The defaults permanently delete the raw .npy files (`remove_sources=true`) without verifying the archive +first (`verify_integrity=false`). For irreplaceable or legacy recordings, pass `verify_integrity=true` (and +optionally `remove_sources=false`) to keep the raw entries until you have confirmed the archives are valid. + **Return structure:** ```text status: "assembled" @@ -193,6 +203,9 @@ Run this to identify which microcontrollers are connected and their IDs: - Verify the MQTT broker service is running (e.g., `systemctl status mosquitto`) - Check firewall rules allow connections on the specified port - Verify the host address is correct +3. A raw tool error (rather than the "not reachable" message) usually means the host/hostname could not be + resolved or is malformed — the underlying `connect()` only returns the friendly message for + connection-level failures. Verify the host string before assuming the broker service is down. ### Manifest inspection and retroactive tagging @@ -202,7 +215,8 @@ Run this to identify which microcontrollers are connected and their IDs: **Retroactively tag a legacy session:** 1. Call `write_microcontroller_manifest_tool` with the log directory, controller ID, controller name, - and module list + and module list (this always appends — read the manifest first and do not write a `controller_id` + that is already registered, or discovery will report it as a duplicate source) 2. Verify by calling `read_microcontroller_manifest_tool` on the created manifest 3. Run `discover_microcontroller_data_tool` to confirm the session is now discoverable @@ -258,6 +272,20 @@ advised ranges. --- +## CLI reference (human-facing — do not invoke) + +> **CLI reference — for answering user questions only.** The `axci` command-line interface is a +> **human-facing** tool. **Agents must never invoke `axci` commands** — every agent-driven operation has an +> equivalent MCP tool (noted in the table). This section exists solely so the agent can answer user +> questions about the CLI. + +| Command | Key options | Purpose | MCP equivalent | +|-------------|-----------------------------------------------------------------|-----------------------------------------------------|------------------------------| +| `axci id` | `-b`/`--baudrate` (default 115200) | Discovers connected Arduino/Teensy microcontrollers | `list_microcontrollers_tool` | +| `axci mqtt` | `-h`/`--host` (default 127.0.0.1), `-p`/`--port` (default 1883) | Checks whether an MQTT broker is reachable | `check_mqtt_broker_tool` | + +--- + ## Related skills | Skill | Relationship | diff --git a/plugins/communication/skills/pipeline/SKILL.md b/plugins/communication/skills/pipeline/SKILL.md index 88aad55..23826b9 100644 --- a/plugins/communication/skills/pipeline/SKILL.md +++ b/plugins/communication/skills/pipeline/SKILL.md @@ -64,8 +64,11 @@ Setup → Discovery → Config → → Processing - **Skill:** `/extraction-configuration` - **Actions:** Read manifest, generate precursor config, ask user for event codes, write and validate config - **Handoff condition:** Validated extraction config YAML file exists -- **Note:** This phase can be done before or after recording. For repeat experiments with the same hardware, - reuse an existing config. +- **Note:** This phase can be done before or after the recording *run*, but generating a precursor config + from the manifest requires the MicroControllerInterface instances to have been constructed first + (construction writes `microcontroller_manifest.yaml`). For a brand-new hardware setup, instantiate the + interfaces first, or author the config by hand. For repeat experiments with the same hardware, reuse an + existing config. ### Phase 4: Recording session @@ -225,6 +228,11 @@ All controllers sharing a DataLogger write to the same log directory and the sam 4. Process all source IDs in a single batch for efficiency 5. Output: multiple feather files per controller under `microcontroller_data/` subdirectory +The extraction config's `controller_id` list is the authoritative selector for which archives are +processed (the set is resolved from the config, not the manifest). Omitting a controller from the config +silently skips it (no error or warning); every config `controller_id` must be registered in the manifest +or processing raises ValueError. To process all controllers, the config must list every controller's ID. + For multi-DataLogger setups, process each DataLogger output directory as a separate batch. --- diff --git a/plugins/microcontroller/.claude-plugin/plugin.json b/plugins/microcontroller/.claude-plugin/plugin.json index 1474454..cb62df0 100644 --- a/plugins/microcontroller/.claude-plugin/plugin.json +++ b/plugins/microcontroller/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "microcontroller", - "version": "1.1.0", + "version": "1.2.0", "description": "Provides firmware module implementation skills for ataraxis-micro-controller.", "repository": "https://github.com/Sun-Lab-NBB/ataraxis", "license": "Apache-2.0", diff --git a/plugins/microcontroller/skills/firmware-module/SKILL.md b/plugins/microcontroller/skills/firmware-module/SKILL.md index b41f70a..cb02567 100644 --- a/plugins/microcontroller/skills/firmware-module/SKILL.md +++ b/plugins/microcontroller/skills/firmware-module/SKILL.md @@ -144,6 +144,10 @@ CustomModule( - `module_id` identifies the specific instance within the family. Must be unique per type. - `communication` is the shared Communication instance created before any modules. +Also declare an overriding virtual destructor — `~CustomModule() override = default;` — because the +Kernel manages modules through `Module*` pointers; the base virtual destructor is load-bearing (see +[references/api-reference.md](references/api-reference.md)). + --- ## Code definitions @@ -191,6 +195,7 @@ private: ### Runtime parameters structure Parameter structs MUST use the `PACKED_STRUCT` macro to ensure correct binary serialization with the PC. +The struct size MUST be 1-250 bytes (compile-time enforced by a `static_assert` in `ExtractModuleParameters`). Field order and types must exactly match the PC-side `send_parameters()` tuple: ```cpp @@ -257,6 +262,10 @@ bool SetupModule() override - Set all parameter fields to their default values - Return `true` on success, `false` on failure (failure bricks the controller until firmware reset) +On keepalive timeout the Kernel emits kernel status 10 (`kKeepAliveTimeout`) and re-runs `Setup()`, which +re-invokes every module's `SetupModule()` and clears all command buffers and hardware states — so +`SetupModule()` must be safe to call repeatedly. + --- ## SetCustomParameters() @@ -316,6 +325,18 @@ bool RunActiveCommand() override See [references/api-reference.md](references/api-reference.md) for the immediate, multi-stage non-blocking delay, and sensor polling command handler patterns with full code examples. +### Recurrent vs one-off commands + +The PC queues each command as either **one-off** (`kOneOffModuleCommand`) or **recurrent** +(`kRepeatedModuleCommand`, carrying a `cycle_delay`). Write handlers identically for both — always +call `CompleteCommand()` when the work is done — but note the runtime difference: a recurrent command +auto-reactivates at stage 1 after its `cycle_delay`, and `CompleteCommand()` deliberately suppresses +the `kCommandCompleted` (status 2) message for recurrent commands until they are dequeued or replaced +(one-off commands always report completion). Expect repeated activation for recurrent commands and use +the multi-stage non-blocking-delay / sensor-polling patterns to avoid flooding the PC. The PC sets the +recurrence interval via `send_command(repetition_delay=...)` — see +`communication:microcontroller-interface`. + --- ## Sending data to PC @@ -391,6 +412,11 @@ Kernel axmc_kernel(kControllerID, axmc_communication, modules, kKeepaliveInterva void setup() { Serial.begin(115200); + +#if !defined(__AVR__) + analogReadResolution(12); +#endif + axmc_kernel.Setup(); } @@ -406,6 +432,7 @@ void loop() - Module constructor arguments: `(module_type, module_id, communication)` - The `modules[]` array must contain at least one element (enforced by `static_assert`) - `Serial.begin()` baudrate must match the PC-side `baudrate` parameter +- Modules that perform analog reads require 12-bit resolution via `analogReadResolution(12)`; AVR boards (fixed 10-bit ADC, no `analogReadResolution()`) must guard the call with `#if !defined(__AVR__)` --- @@ -477,6 +504,7 @@ Firmware Module: - [ ] Template parameters use const keyword - [ ] Static assertions at top of class body (after opening brace, before public:) - [ ] Constructor calls Module(module_type, module_id, communication) +- [ ] Declares an overriding virtual destructor (~CustomModule() override = default;) - [ ] kCommands enum defines commands with values >= 1 - [ ] Custom event codes enum defines event codes with values 51-250 - [ ] CustomRuntimeParameters struct uses PACKED_STRUCT macro diff --git a/plugins/microcontroller/skills/firmware-module/references/api-reference.md b/plugins/microcontroller/skills/firmware-module/references/api-reference.md index 2489f88..fc004b6 100644 --- a/plugins/microcontroller/skills/firmware-module/references/api-reference.md +++ b/plugins/microcontroller/skills/firmware-module/references/api-reference.md @@ -185,8 +185,10 @@ bool ExtractParameters(ObjectType& storage_object); ``` Unpacks the received ModuleParameters message payload into the specified storage object. Internally -delegates to `Communication::ExtractModuleParameters()`. Returns `true` on success, `false` on -error (size mismatch, wrong message type, etc.). +delegates to `Communication::ExtractModuleParameters()`, which `static_assert`s the struct size is 1-250 +bytes (compile-time error otherwise). Returns `true` on success, `false` on one of three conditions: +`kExtractionForbidden` (message is not a ModuleParameters message), `kParameterMismatch` (received byte +count does not equal `sizeof(struct)`), or `kParsingError` (payload parsing failed). --- diff --git a/plugins/video/.claude-plugin/plugin.json b/plugins/video/.claude-plugin/plugin.json index aa55074..627551c 100644 --- a/plugins/video/.claude-plugin/plugin.json +++ b/plugins/video/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "video", - "version": "1.1.0", + "version": "1.2.0", "description": "Provides camera acquisition, video recording, log processing, and pipeline orchestration skills for ataraxis-video-system. Includes MCP bindings for interactive camera discovery, testing, and session management.", "repository": "https://github.com/Sun-Lab-NBB/ataraxis", "license": "Apache-2.0", diff --git a/plugins/video/skills/camera-interface/SKILL.md b/plugins/video/skills/camera-interface/SKILL.md index bd15e2a..9c20432 100644 --- a/plugins/video/skills/camera-interface/SKILL.md +++ b/plugins/video/skills/camera-interface/SKILL.md @@ -101,9 +101,13 @@ Key constructor notes: Harvesters cameras, set resolution and frame rate via GenICam configuration (see `/camera-setup`) rather than overriding through these parameters. The VideoSystem overrides are primarily intended for OpenCV cameras that lack GenICam node control. -- `display_frame_rate` defaults to `None` (preview disabled). Set to an integer FPS to enable. +- `display_frame_rate` defaults to `None` (preview disabled). Set to a positive integer FPS not exceeding + the camera's acquisition frame rate to enable, else `__init__` raises `TypeError`. Frame display is + unsupported on macOS: it is auto-disabled (a warning is emitted), so the value has no effect there. - `gpu` defaults to `-1` (CPU encoding). Set to `0+` for NVIDIA GPU encoding. -- `color` is a keyword-only parameter defaulting to `None` (auto-detect from camera). +- `color` is a keyword-only parameter defaulting to `None`. For OpenCV and Mock, `None` resolves to + monochrome (`False`) — a color OpenCV camera left at `None` silently records grayscale, so pass + `color=True` explicitly to record color. Only Harvesters infers color/mono from the GenICam config. ### Lifecycle @@ -113,7 +117,9 @@ VideoSystem() → start() → [start_frame_saving() → stop_frame_saving()] → - `start()` begins frame acquisition without saving. Useful for preview or warm-up. - `start_frame_saving()` / `stop_frame_saving()` toggle recording while acquisition continues. -- `stop()` terminates acquisition and releases all resources. Must be called explicitly. +- `stop()` terminates acquisition and releases all resources. Must be called explicitly. It blocks until + all buffered frames are encoded, up to a 10-minute cap; beyond that it force-kills the consumer and + discards remaining frames. ### System ID allocation diff --git a/plugins/video/skills/camera-interface/references/api-reference.md b/plugins/video/skills/camera-interface/references/api-reference.md index 63cbfd9..3ab88fc 100644 --- a/plugins/video/skills/camera-interface/references/api-reference.md +++ b/plugins/video/skills/camera-interface/references/api-reference.md @@ -85,7 +85,7 @@ VideoSystem( | `video_encoder` | `VideoEncoders / str` | No | `VideoEncoders.H265` | Video codec: H264 or H265 | | `encoder_speed_preset` | `EncoderSpeedPresets / int` | No | `EncoderSpeedPresets.SLOW` | Encoding speed vs quality tradeoff (1-7) | | `output_pixel_format` | `OutputPixelFormats / str` | No | `OutputPixelFormats.YUV444` | Output color format: YUV420 or YUV444 | -| `quantization_parameter` | `int` | No | `15` | Quality parameter 0-51 (lower = higher quality) | +| `quantization_parameter` | `int` | No | `15` | Quality parameter -1..51 (lower = higher quality); -1 defers QP to the encoder default | | `color` | `bool / None` | No | `None` | Color mode for OpenCV/Mock (True=BGR, False=MONO). Keyword-only. Harvesters infers from camera config. | **Notes:** @@ -94,6 +94,8 @@ VideoSystem( identification - `frame_width`, `frame_height`, and `frame_rate` default to the camera's native values when set to None - `color` is only used by OpenCV and Mock interfaces; Harvesters cameras determine color mode from their GenICam config +- `quantization_parameter` accepts -1 to 51 inclusive; -1 is a sentinel that defers QP choice to the + encoder's own default, distinct from QP 0 (near-lossless) - The output video file is named `{system_id:03d}.mp4` in the output directory ### Methods @@ -386,51 +388,8 @@ The first log entry for each VideoSystem uses a special format: --- -## Architecture - -```text -+------------------------------------------------------------------+ -| VideoSystem | | | | | -| +------------------------------------------------------------+ | | | | | -| | Main Process | | | | -| | - Initialization and configuration | | | | -| | - Lifecycle management (start/stop) | | | | -| | - Frame saving control | | | | -| +------------------------------------------------------------+ | | | | | -|----------------------------------------------------------------|-------------------------------------|-----|---------------------------|-----| -| v v | | | | | -| +--------------------+ +----------------------------------+ | | | | | -| | Producer Process | | Consumer Process | | -| | - Camera driver | | - Frame encoding (FFMPEG) | | -| | - Frame grabbing | --> | - MP4 container writing | | -| | - Timestamp gen | | - Live preview display | | -| +--------------------+ +----------------------------------+ | | | | | -|----------------------------------------------------------------|-------------------------------------|-----|---------------------------|-----| -| v | | | | | -| +--------------------+ | | | | | -| | DataLogger | | | | -| | - Timestamp I/O | | | | -| | - .npy file write | | | | -| +--------------------+ | | | | | -+------------------------------------------------------------------+ -``` - ---- - ## Dependencies -### Runtime - -| Package | Version | Purpose | -|----------------------------|---------------|----------------------------------------| -| ataraxis-video-system | >=3.0.0 | This library | -| ataraxis-data-structures | >=6,<7 | DataLogger, SharedMemoryArray | -| ataraxis-time | >=6,<7 | Precision timing | -| ataraxis-base-utilities | >=6,<7 | Logging and console output | -| numpy | >=2,<3 | Array operations and system_id type | -| opencv-python | >=4.13,<5 | Camera interface and frame display | -| harvesters | >=1,<2 | GenICam camera support | - ### External | Dependency | Required | Purpose | @@ -439,10 +398,6 @@ The first log entry for each VideoSystem uses a special format: | CTI file | No | GenTL Producer for Harvesters cameras | | NVIDIA GPU | No | Hardware-accelerated encoding (optional) | -### Python version - -Requires `>=3.12,<3.15`. - --- ## Code examples diff --git a/plugins/video/skills/camera-setup/SKILL.md b/plugins/video/skills/camera-setup/SKILL.md index ab647dc..c8b271e 100644 --- a/plugins/video/skills/camera-setup/SKILL.md +++ b/plugins/video/skills/camera-setup/SKILL.md @@ -99,6 +99,12 @@ Only one video session can be active at a time. | `output_pixel_format` | `str` | `"yuv420p"` | Pixel format: `"yuv420p"` or `"yuv444p"` | | `quantization_parameter` | `int` | `15` | Compression quality (0 = best, 51 = worst) | +- `interface`: `"mock"` produces synthetic frames with no hardware involvement and is intended only for + pipeline/library testing; to test a real camera use `"opencv"` or `"harvesters"`. +- `display_frame_rate`: on macOS, preview display is automatically disabled regardless of this value, so the + absence of a preview window on macOS is expected and not a session failure. On other platforms it must not + exceed `frame_rate`. + See the encoding parameter guidance section below for recommendations on encoder, preset, pixel format, and quantization parameter selection. @@ -328,6 +334,29 @@ When transitioning from MCP-based testing to writing VideoSystem code, use this --- +## CLI reference (human-facing — do not invoke) + +> **CLI reference — for answering user questions only.** The `axvs` command-line interface is a **human-facing** +> tool. **Agents must never invoke `axvs` commands** — every agent-driven operation has an equivalent MCP tool +> (noted in the table). This section exists solely so the agent can answer user questions about the CLI. + +| Command | Key options | Purpose | MCP equivalent | +|--------------------------|-----------------------------------------------------------------------|--------------------------------------------------------|-----------------------------------------------------------------------| +| `axvs run` | `-i/--interface`, `-c/--camera-index`, `-g/--gpu-index`, `-o/--output-directory`, `-m/--monochrome`, `-w/--width`, `-h/--height`, `-f/--frame-rate` | Interactive single-camera live imaging test | `start_video_session_tool` / `stop_video_session_tool` | +| `axvs cti set` | `-f/--file-path` | Configures the GenICam GenTL Producer (.cti) file | `set_cti_file_tool` | +| `axvs cti check` | (none) | Verifies the configured CTI file is valid | `get_cti_status_tool` | +| `axvs check devices` | (none) | Discovers connected cameras and their indices | `list_cameras_tool` | +| `axvs check compatibility` | (none) | Checks FFMPEG/GPU video-encoding requirements | `check_runtime_requirements_tool` | +| `axvs configure read` | `-c/--camera-index`, `-n/--node-name`, `-b/--blacklisted-node`, `--no-blacklist` | Reads a GenICam node or lists writable nodes | `read_genicam_node_tool` | +| `axvs configure write` | `-c/--camera-index`, `-n/--node-name`, `-v/--value` | Writes a GenICam node value | `write_genicam_node_tool` | +| `axvs configure dump` | `-c/--camera-index`, `-o/--output-file`, `-b/--blacklisted-node`, `--no-blacklist` | Exports the full camera config to YAML | `dump_genicam_config_tool` | +| `axvs configure load` | `-c/--camera-index`, `-f/--config-file`, `--strict`, `-b/--blacklisted-node`, `--no-blacklist` | Applies a YAML config to the camera | `load_genicam_config_tool` | + +The `axvs run` session is driven by interactive keypresses (`q` to terminate, `w` to start saving frames, `s` to +stop saving frames) that have no MCP analogue; the MCP session is tool-driven. + +--- + ## Related skills | Skill | Relationship | diff --git a/plugins/video/skills/log-input-format/SKILL.md b/plugins/video/skills/log-input-format/SKILL.md index 5855150..7cb9d1f 100644 --- a/plugins/video/skills/log-input-format/SKILL.md +++ b/plugins/video/skills/log-input-format/SKILL.md @@ -91,10 +91,14 @@ sources: - **Manual:** Use `write_camera_manifest_tool` (see `/camera-setup`) to retroactively tag legacy log directories that predate the manifest system. -**Why manifests matter:** The `discover_camera_data_tool` uses manifest-based routing to -identify axvs-produced log archives. Directories without a `camera_manifest.yaml` will not be discovered -by this tool. Manifests also associate source IDs with human-readable names and enable the discovery tool -to locate corresponding video files by camera name. +**Why manifests matter:** The manifest is a hard gate for both discovery and processing. +`discover_camera_data_tool` uses manifest-based routing to identify axvs-produced log archives, so +directories without a `camera_manifest.yaml` will not be discovered by this tool. Beyond discovery, +`run_log_processing_pipeline` requires the manifest as well: it raises `FileNotFoundError` when none +is found, raises `ValueError` when it has no sources, resolves the source IDs to process from the +manifest when `log_ids` is None, and rejects any requested `log_id` not registered in the manifest. +Manifests also associate source IDs with human-readable names and enable the discovery tool to locate +corresponding video files by camera name. --- @@ -179,6 +183,13 @@ Each log directory is an **independent processing unit**. The discovery tool gro parent directory (the DataLogger output directory), and each directory is prepared and processed independently. +Source-ID-to-archive resolution requires exactly one matching `{source_id}_log.npz` under the +recursively searched tree (`ValueError` on duplicates), and all resolved archives must share a single +parent directory (`ValueError` otherwise, "Each DataLogger output directory must be processed +independently"). Therefore `run_log_processing_pipeline` must be invoked once per DataLogger output +directory, not once per recording root, and a duplicate source ID across nested subdirectories is a +fatal error, not a combined-processing path. + ### Multiple recordings under one root The discovery tool recursively searches a root directory and groups log directories by recording root: @@ -250,10 +261,14 @@ processing via `ProcessPoolExecutor`. Before running the log processing pipeline, verify these conditions: -1. **Camera manifest present** — Log directories should contain a `camera_manifest.yaml` file for - `discover_camera_data_tool` to locate them. If missing, use `write_camera_manifest_tool` - to create one. Note: the processing pipeline itself does not require manifests — they are only - needed for the manifest-based discovery tool. +1. **Camera manifest present** — Log directories MUST contain a `camera_manifest.yaml` file. The + manifest is required both by `discover_camera_data_tool` and by `run_log_processing_pipeline` + itself: the pipeline locates it via recursive `rglob` (using the first match), raises + `FileNotFoundError` when none is found, and raises `ValueError` when it has no source entries. + When `log_ids` is None the pipeline resolves the source IDs to process from the manifest, and it + rejects any requested `log_id` not registered in the manifest. Job IDs are a deterministic function + of `(job_name, source_id)`, so an "invalid job_id" error from the pipeline likewise means the source + ID is not registered in the manifest. If missing, use `write_camera_manifest_tool` to create one. 2. **Archives assembled** — Log directories contain `.npz` files, not just raw `.npy` files. If only `.npy` files are present, `assemble_log_archives()` must be run first. diff --git a/plugins/video/skills/log-processing-results/SKILL.md b/plugins/video/skills/log-processing-results/SKILL.md index b509aea..d572302 100644 --- a/plugins/video/skills/log-processing-results/SKILL.md +++ b/plugins/video/skills/log-processing-results/SKILL.md @@ -141,7 +141,7 @@ The `analyze_camera_frame_statistics_tool` returns a dictionary with three secti | `last_timestamp_us` | `int` | Last frame timestamp (microseconds since UTC epoch) | | `duration_us` | `int` | Total recording duration in microseconds | | `duration_seconds` | `float` | Total recording duration in seconds | -| `estimated_fps` | `float` | Estimated frame rate: `(frames - 1) / duration` | +| `estimated_fps` | `float` | Estimated frame rate: `(frames - 1) / duration`; `0.0` when duration is zero (single-frame, or degenerate capture with identical timestamps) — a "cannot compute" sentinel, not a measured 0 fps | ### inter_frame_timing @@ -185,6 +185,12 @@ Each entry in `drop_locations`: inter-frame interval. Gaps exceeding this threshold are classified as frame drops. The number of lost frames per gap is estimated by dividing the gap duration by the median interval and rounding. +**Edge cases:** When `total_frames == 0`, only `basic_stats.total_frames` is returned and +`inter_frame_timing` / `frame_drop_analysis` are empty `{}`. When `total_frames == 1`, `basic_stats` is +fully populated but `duration_us`, `duration_seconds`, and `estimated_fps` are `0`, and the timing and +drop sections are again empty `{}`. Check `total_frames >= 2` before indexing into `inter_frame_timing` +or `frame_drop_analysis` to avoid `KeyError`s. + --- ## Interpretation guidance diff --git a/plugins/video/skills/log-processing/SKILL.md b/plugins/video/skills/log-processing/SKILL.md index 289105b..04328cf 100644 --- a/plugins/video/skills/log-processing/SKILL.md +++ b/plugins/video/skills/log-processing/SKILL.md @@ -243,7 +243,10 @@ The system uses two cooperating mechanisms: 2. **Budget-limited concurrency** — the worker budget does not raise the per-job worker count; it only caps how many such jobs run concurrently (`available // per_job_workers`). When many large jobs - compete for a limited budget, fewer groups run at once. Per-job worker counts by archive size: + compete for a limited budget, fewer groups run at once. Same-tier jobs are split into + `available // tier_workers` concurrent groups; each group reuses one process pool and runs its archives + sequentially, so concurrency is per-group, not strictly per-job, and surplus same-tier archives wait + within a group. Per-job worker counts by archive size: | Archive Size | Per-Job Workers | Typical Scenario | |--------------|-----------------|---------------------| @@ -253,8 +256,7 @@ The system uses two cooperating mechanisms: | 250,000 msgs | 15 | ~35 min at 120 fps | | 648,000 msgs | 25 | 1.5 h at 120 fps | -The per-job worker count comes solely from square-root scaling; the worker budget governs concurrency -(how many groups run at once), not the per-job worker count. Two cores are reserved for system operations. +Two cores are reserved for system operations. When `worker_budget=-1`, the system resolves the total using the host machine's available CPU cores via `resolve_worker_count`. Reduce `worker_budget` to limit memory footprint on constrained systems. @@ -263,6 +265,11 @@ via `resolve_worker_count`. Reduce `worker_budget` to limit memory footprint on ## Status formatting +The `get_log_processing_status_tool` response carries both an `active` flag (manager thread alive) and a +`canceled` flag, plus a `message` of `No execution session exists.` when no session ever ran. Treat `active` +as the completion signal and `canceled` as the cancellation/draining path (active jobs finish while no new +jobs start). Per-job entries may also include an `executor_id`. + When presenting batch status to the user, format as a table: ```text @@ -289,6 +296,10 @@ When using `get_batch_status_overview_tool` for multi-directory status: | /data/session2/logs/ | failed | 1 | 1 | 2 | ``` +The per-directory `status` is one of five labels resolved by priority — `failed` (any failed job; overrides +all) > `completed` (all succeeded) > `processing` (any running) > `not_started` (all scheduled) > `in_progress` +(otherwise) — plus `error` when a tracker cannot be read. A directory with 3 succeeded + 1 failed reports `failed`. + --- ## Re-running failed jobs @@ -332,6 +343,21 @@ To re-process an entire directory from scratch, call `clean_log_processing_outpu --- +## CLI reference (human-facing — do not invoke) + +> **CLI reference — for answering user questions only.** The `axvs` command-line interface is a +> **human-facing** tool. **Agents must never invoke `axvs` commands** — every agent-driven operation has an +> equivalent MCP tool (noted in the table). This section exists solely so the agent can answer user +> questions about the CLI. + +| Command | Key options | Purpose | MCP equivalent | +|---------------|----------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------|------------------------------------------------------------------------| +| `axvs process` | `-ld/--log-directory`, `-od/--output-directory`, `-id/--job-id`, `-li/--log-id` (repeatable), `-w/--workers`, `-p/--progress` | Extracts frame timestamps from the `.npz` log archives under one directory | The prepare/execute/status batch tools documented above (`prepare_log_processing_batch_tool`, `execute_log_processing_jobs_tool`, `get_log_processing_status_tool`) | + +`axvs process` handles ONE log directory per invocation, whereas the MCP workflow batches many directories. + +--- + ## Related skills | Skill | Relationship | diff --git a/plugins/video/skills/pipeline/SKILL.md b/plugins/video/skills/pipeline/SKILL.md index 043fca4..345cee8 100644 --- a/plugins/video/skills/pipeline/SKILL.md +++ b/plugins/video/skills/pipeline/SKILL.md @@ -160,6 +160,9 @@ DataLogger(instance_name="session") All cameras share one log directory, all timestamps are correlated, one `assemble_log_archives` call consolidates everything, and one processing batch covers all source IDs. Each VideoSystem writes an entry to `camera_manifest.yaml` during initialization, enabling manifest-based discovery downstream. +The manifest append is not idempotent -- re-constructing a VideoSystem against an already-used output +directory appends a duplicate source entry rather than replacing it, so use a fresh session directory +per recording. Multiple DataLoggers should only be used if a single logger cannot handle the load, leading to excessive buffering. This is extremely rare in practice. When it does occur, each DataLogger creates a separate @@ -249,7 +252,10 @@ This simplifies batch processing: 4. Output: one feather file per camera under a `camera_timestamps/` subdirectory (`camera_timestamps/camera_51_timestamps.feather`, `camera_timestamps/camera_52_timestamps.feather`, etc.) -For multi-DataLogger setups, process each DataLogger output directory as a separate batch. +For multi-DataLogger setups, process each DataLogger output directory as a separate batch. This is +enforced -- passing source IDs whose archives live in different DataLogger directories into one batch +raises ValueError ("Each DataLogger output directory must be processed independently"). Run one discovery +and batch per output directory. --- diff --git a/plugins/video/skills/post-recording/SKILL.md b/plugins/video/skills/post-recording/SKILL.md index 6eb6b6f..4d5415e 100644 --- a/plugins/video/skills/post-recording/SKILL.md +++ b/plugins/video/skills/post-recording/SKILL.md @@ -126,6 +126,11 @@ source, the tool locates the corresponding log archive, video file, and processe output, returning a flat `sources` list. The return also includes a flat `log_directories` list (which feeds batch `/log-processing`) plus `total_sources` and `total_log_directories` aggregate counts. +**Caution:** `video_file`/`timestamps_file` are resolved by a name-then-ID substring heuristic with +path-proximity tie-breaking, not exact paths. A `None` `video_file` means "not matched", not necessarily +"not on disk" — confirm with `validate_video_file_tool` using the path returned by the stop tool. Beware false +matches when a camera name or the zero-padded ID appears in an unrelated `.mp4` stem under the root. + --- ## Post-recording workflow @@ -218,6 +223,10 @@ Post-Recording Readiness: - [ ] Archive naming matches {source_id}_log.npz pattern ``` +Video files are named `{system_id:03d}.mp4` (zero-padded to 3 digits, e.g. `001.mp4`, `042.mp4`), whereas log +archives use the bare integer `{source_id}_log.npz` (`1_log.npz`, `42_log.npz`). The same source ID drives both; +only the video name is padded. + --- ## Troubleshooting @@ -233,6 +242,11 @@ Post-Recording Readiness: | `validate_video_file_tool` returns error | File corrupt or ffprobe unavailable | Check FFMPEG installation; re-record if needed | | MCP tools unavailable | Server not running | Invoke `/video-mcp-environment-setup` | +A frame deficit concentrated at the **end** of a recording is a distinct case: `stop()` waits up to +10 minutes for the saver queue to drain, then forcibly terminates the consumer and discards the +unencoded tail with no error surfaced by the stop tool. It means the encoder could not keep up at +shutdown — use a faster `encoder_speed_preset` or hardware encoding next time. + --- ## Related skills From 1b56a0f757ae84b868265c365bd87c03588393e9 Mon Sep 17 00:00:00 2001 From: Ivan Kondratyev Date: Wed, 17 Jun 2026 16:58:59 -0400 Subject: [PATCH 4/7] Realigned plugin skills to ataraxis-focused conventions. -- Replaced deprecated "Sun Lab" wording with "ataraxis framework", keeping credit and ownership attribution. -- Removed the deprecated sl-* namespace and external project names in favor of ataraxis examples and generic placeholders. -- Removed an inaccurate ataraxis cross-dependency on a downstream package. -- Generalized the release skill to distinguish independent libraries from unified cross-dependent library sets. -- Clarified the environment-name abbreviation rule for multi-repository components versus standalone projects. -- Added a Sollertia platform link to the README adoption roadmap. --- README.md | 46 +++++----- .../automation/skills/audit-style/SKILL.md | 4 +- .../automation/skills/csharp-style/SKILL.md | 6 +- .../csharp-style/assets/.csharpierrc.yaml | 4 +- .../skills/csharp-style/assets/.editorconfig | 4 +- .../csharp-style/references/anti-patterns.md | 4 +- .../skills/explore-codebase/SKILL.md | 89 +++++++++---------- .../skills/explore-dependencies/SKILL.md | 2 +- .../references/library-catalog.md | 16 ++-- .../references/archetype-trees.md | 4 +- .../skills/pyproject-style/SKILL.md | 10 +-- .../references/project-metadata.md | 20 ++--- .../references/tool-configurations.md | 32 +++---- .../python-style/references/class-patterns.md | 4 +- .../references/section-templates.md | 5 +- plugins/automation/skills/release/SKILL.md | 38 ++++---- plugins/automation/skills/tox-config/SKILL.md | 24 ++--- .../references/environment-templates.md | 8 +- 18 files changed, 157 insertions(+), 163 deletions(-) diff --git a/README.md b/README.md index fcb811f..f406f63 100644 --- a/README.md +++ b/README.md @@ -174,31 +174,31 @@ Add Ataraxis MCP servers to your Claude Code configuration (`~/.claude.json`): ## Claude Code Skills This repository serves as a [Claude Code](https://docs.anthropic.com/en/docs/claude-code) plugin marketplace, -distributing a set of agentic skills that enforce Sun Lab development conventions across all downstream projects. These +distributing a set of agentic skills that enforce ataraxis framework development conventions across all downstream projects. These skills provide Claude Code with project-specific knowledge about coding style, documentation format, commit messages, project structure, and more. ### Available Skills -| Skill | Description | -|-------------------------|---------------------------------------------------------------------------| -| `/explore-codebase` | Performs in-depth codebase exploration at the start of a session | -| `/explore-dependencies` | Explores installed ataraxis/Sun Lab library APIs for dependency awareness | -| `/python-style` | Applies Sun Lab Python coding conventions | -| `/cpp-style` | Applies Sun Lab C++ coding conventions | -| `/csharp-style` | Applies Sun Lab C# coding conventions | -| `/readme-style` | Applies Sun Lab README conventions | -| `/pyproject-style` | Applies Sun Lab pyproject.toml conventions | -| `/api-docs` | Applies Sun Lab API documentation conventions | -| `/project-layout` | Applies Sun Lab project directory structure conventions | -| `/tox-config` | Applies Sun Lab tox.ini conventions | -| `/platformio-config` | Applies Sun Lab platformio.ini and library.json conventions | -| `/audit-facts` | Audits documentation files against source code for factual accuracy | -| `/audit-style` | Audits files against applicable style skill checklists for compliance | -| `/commit` | Drafts style-compliant git commit messages | -| `/pr` | Drafts a style-compliant pull request summary for the active branch | -| `/release` | Drafts style-compliant release notes summarizing merged pull requests | -| `/skill-design` | Generates, updates, and verifies skill files and CLAUDE.md | +| Skill | Description | +|-------------------------|------------------------------------------------------------------------| +| `/explore-codebase` | Performs in-depth codebase exploration at the start of a session | +| `/explore-dependencies` | Explores installed ataraxis library APIs for dependency awareness | +| `/python-style` | Applies ataraxis framework Python coding conventions | +| `/cpp-style` | Applies ataraxis framework C++ coding conventions | +| `/csharp-style` | Applies ataraxis framework C# coding conventions | +| `/readme-style` | Applies ataraxis framework README conventions | +| `/pyproject-style` | Applies ataraxis framework pyproject.toml conventions | +| `/api-docs` | Applies ataraxis framework API documentation conventions | +| `/project-layout` | Applies ataraxis framework project directory structure conventions | +| `/tox-config` | Applies ataraxis framework tox.ini conventions | +| `/platformio-config` | Applies ataraxis framework platformio.ini and library.json conventions | +| `/audit-facts` | Audits documentation files against source code for factual accuracy | +| `/audit-style` | Audits files against applicable style skill checklists for compliance | +| `/commit` | Drafts style-compliant git commit messages | +| `/pr` | Drafts a style-compliant pull request summary for the active branch | +| `/release` | Drafts style-compliant release notes summarizing merged pull requests | +| `/skill-design` | Generates, updates, and verifies skill files and CLAUDE.md | ### Installing for Claude Code @@ -276,8 +276,10 @@ AI: Created buzzer module with pulse, toggle on, and toggle off commands. 3. **Encode recurring workflows as skills** that guide AI agents 4. **Iterate as hardware evolves** with AI-assisted development -The Sun Lab's implementation libraries (`sl-*`) serve as open-source templates for building -custom acquisition systems. +The Ataraxis libraries provide open-source building blocks for assembling custom acquisition +systems. For a complete platform built on Ataraxis, see +[Sollertia](https://github.com/Sun-Lab-NBB/sollertia) — a platform for AI-assisted data acquisition +and management. --- diff --git a/plugins/automation/skills/audit-style/SKILL.md b/plugins/automation/skills/audit-style/SKILL.md index 73aa34a..32312d4 100644 --- a/plugins/automation/skills/audit-style/SKILL.md +++ b/plugins/automation/skills/audit-style/SKILL.md @@ -2,7 +2,7 @@ name: audit-style description: >- Performs a thorough style-compliance audit of source code, configuration, or documentation - files against the applicable Sun Lab style skill checklists. Walks every line of every file + files against the applicable ataraxis framework style skill checklists. Walks every line of every file in scope and reports only non-compliant findings with verbatim checklist citations. Use when auditing a Python package, a config file, a README, or any project file for style, formatting, naming, documentation quality, or convention compliance. Use when the user @@ -12,7 +12,7 @@ user-invocable: true # Style compliance audit -Audits files against the authoritative Sun Lab style skill checklists, reporting only +Audits files against the authoritative ataraxis framework style skill checklists, reporting only non-compliant findings with verbatim checklist citations. You MUST read this entire skill and load every applicable style skill checklist before starting diff --git a/plugins/automation/skills/csharp-style/SKILL.md b/plugins/automation/skills/csharp-style/SKILL.md index aa2b61a..2eec0b5 100644 --- a/plugins/automation/skills/csharp-style/SKILL.md +++ b/plugins/automation/skills/csharp-style/SKILL.md @@ -133,7 +133,7 @@ Use **full words**, not abbreviations: | Constants | PascalCase | `LengthComparisonEpsilon` | | Enum types | PascalCase | `ControllerTypes`, `StimulusMode` | | Enum values | PascalCase | `LinearTreadmill`, `OccupancyBased` | -| Namespaces | PascalCase | `Gimbl`, `SL.Config` | +| Namespaces | PascalCase | `Gimbl`, `Project.Config` | | Interfaces | `IPascalCase` | `IConfigurable`, `IResettable` | | Type parameters | `TPascalCase` | `TMessage`, `TConfig` | @@ -304,7 +304,7 @@ using System.Collections.Generic; using System.IO; using UnityEngine; using Gimbl; -using SL.Config; +using Project.Config; ``` ### `using static` directives @@ -335,7 +335,7 @@ All definitions within a file follow this vertical ordering from top to bottom: 1. **File-level XML documentation** (`/// ` block describing the file) 2. **Using directives** -3. **Namespace declaration** (block-scoped is the project convention: `namespace SL.Config { ... }`, +3. **Namespace declaration** (block-scoped is the project convention: `namespace Project.Config { ... }`, with class members indented one level inside the block). Although `assets/.editorconfig` carries `csharp_style_namespace_declarations = file_scoped:suggestion`, the exemplar code overrides it and block-scoped is the practiced form. diff --git a/plugins/automation/skills/csharp-style/assets/.csharpierrc.yaml b/plugins/automation/skills/csharp-style/assets/.csharpierrc.yaml index ea75a87..a713fbf 100644 --- a/plugins/automation/skills/csharp-style/assets/.csharpierrc.yaml +++ b/plugins/automation/skills/csharp-style/assets/.csharpierrc.yaml @@ -1,5 +1,5 @@ -# CSharpier configuration for sl-unity-tasks -# Provides C# formatting similar to the clang-format style used in sl-micro-controllers. +# CSharpier configuration for C# Unity projects +# Provides C# formatting similar to the clang-format style used in the C++ firmware projects. # # Installation: # dotnet tool install -g csharpier diff --git a/plugins/automation/skills/csharp-style/assets/.editorconfig b/plugins/automation/skills/csharp-style/assets/.editorconfig index 5f5e241..0a8b190 100644 --- a/plugins/automation/skills/csharp-style/assets/.editorconfig +++ b/plugins/automation/skills/csharp-style/assets/.editorconfig @@ -1,5 +1,5 @@ -# EditorConfig for sl-unity-tasks -# Provides C# formatting based on the Google style guide principles used in sl-micro-controllers. +# EditorConfig for C# Unity projects +# Provides C# formatting based on the Google style guide principles used in the C++ firmware projects. # This results in a visual style that is largely similar between C++, C#, and Python code, # improving cross-language developer experience. diff --git a/plugins/automation/skills/csharp-style/references/anti-patterns.md b/plugins/automation/skills/csharp-style/references/anti-patterns.md index 3b13043..2cec5d6 100644 --- a/plugins/automation/skills/csharp-style/references/anti-patterns.md +++ b/plugins/automation/skills/csharp-style/references/anti-patterns.md @@ -597,10 +597,10 @@ private const float Epsilon = 0.01f; private const int MaxRetries = 3; // Wrong - snake_case namespace from C++ convention -namespace sl_config { } +namespace project_config { } // Correct - PascalCase namespace -namespace SL.Config { } +namespace Project.Config { } // Wrong - get_/set_ accessor methods from C++ convention public float get_Position() { return _position; } diff --git a/plugins/automation/skills/explore-codebase/SKILL.md b/plugins/automation/skills/explore-codebase/SKILL.md index 8b5323b..5ddf8d5 100644 --- a/plugins/automation/skills/explore-codebase/SKILL.md +++ b/plugins/automation/skills/explore-codebase/SKILL.md @@ -175,88 +175,87 @@ For small projects, omit sections that do not apply. ```markdown ## Project purpose -Provides a reimplemented suite2p library for neural imaging analysis with multi-day cell tracking -capabilities for the Sun Lab at Cornell University. +Provides a camera interface library for OpenCV and GeniCam cameras with real-time FFMPEG video +encoding, including an MCP server and CLI tools for camera management. ## Entry points and CLI commands -| Entry Point | Location | Description | -|-----------------|---------------------------|------------------------------------------| -| `sl-suite2p` | pyproject.toml scripts | Main CLI entry point | -| `run` | cli.py:run | Executes single-day processing pipeline | -| `run-multiday` | cli.py:run_multiday | Executes multi-day tracking pipeline | -| `mcp` | cli.py:mcp | Starts the MCP server | +| Entry Point | Location | Description | +|----------------|------------------------|-------------------------------------| +| `axvs` | pyproject.toml scripts | Main CLI entry point | +| `list-cameras` | cli.py:list_cameras | Enumerates connected cameras | +| `live` | cli.py:live | Opens a live camera preview session | +| `mcp` | cli.py:mcp | Starts the MCP server | ## Key components -| Component | Location | Purpose | -|--------------------|--------------------------------|---------------------------------------------------| -| Pipeline | src/sl_suite2p/pipeline.py | Main single-day processing pipeline orchestration | -| Multi-day Tracking | src/sl_suite2p/multiday/ | Cross-session cell tracking and alignment | -| Registration | src/sl_suite2p/registration/ | Image registration and motion correction | -| Detection | src/sl_suite2p/detection/ | Cell detection algorithms | -| Configuration | src/sl_suite2p/configuration/ | Pipeline configuration management | -| MCP Server | src/sl_suite2p/mcp/ | AI agent integration via MCP | +| Component | Location | Purpose | +|-----------------|-------------------------------------------|----------------------------------------| +| VideoSystem | src/ataraxis_video_system/video_system.py | Top-level camera acquisition lifecycle | +| Camera backends | src/ataraxis_video_system/camera/ | OpenCV and GeniCam camera interfaces | +| Savers | src/ataraxis_video_system/saver/ | FFMPEG-based video and image encoders | +| Configuration | src/ataraxis_video_system/configuration/ | Acquisition and encoding settings | +| MCP Server | src/ataraxis_video_system/mcp/ | AI agent integration via MCP | ## Call chain summary -`sl-suite2p run` → `cli.py:run` → `pipeline.py:run_pipeline` → `registration/register.py:register` -→ `detection/detect.py:detect_cells` → `extraction/extract.py:extract_signals` -→ `classification/classify.py:classify_cells` → writes output to `suite2p/` directory. +`axvs live` → `cli.py:live` → `video_system.py:VideoSystem.start` +→ `camera/opencv_camera.py:OpenCVCamera.connect` → `saver/video_saver.py:VideoSaver.create_encoder` +→ writes encoded frames to the output directory. ## Import dependency map Central components (imported by 5+ modules): -- `configuration/pipeline_config.py` — imported by pipeline, registration, detection, extraction -- `utils/io.py` — imported by all processing modules +- `configuration/acquisition_config.py` — imported by video_system, camera, saver +- `camera/camera_base.py` — base class imported by all camera backends - `types.py` — imported by all modules for shared type definitions -Dependency direction: cli → pipeline → processing modules → utils/io + configuration. +Dependency direction: cli → video_system → camera + saver → configuration. ## Public API surface Exported from `__init__.py` via `__all__`: -- `run_pipeline(config: PipelineConfig) -> PipelineResult` -- `PipelineConfig` (dataclass) -- `PipelineResult` (dataclass) +- `VideoSystem` (class) +- `CameraBackends` (enum) +- `SaverBackends` (enum) ## MCP tools -| Tool | Location | Parameters | Returns | -|---------------------|----------------------------|------------------------|----------------------| -| `run_pipeline_tool` | mcp/processing_tools.py | `config_path: str` | run summary dict | -| `list_sessions_tool`| mcp/discovery_tools.py | `data_directory: str` | list of session dicts| +| Tool | Location | Parameters | Returns | +|---------------------|------------------------|------------------|----------------------| +| `list_cameras_tool` | mcp/discovery_tools.py | (none) | list of camera dicts | +| `check_camera_tool` | mcp/discovery_tools.py | `camera_id: int` | camera status dict | ## Configuration -| Mechanism | Location | Purpose | -|-----------------|---------------------------------|--------------------------------------| -| `PipelineConfig`| configuration/pipeline_config.py| Dataclass with all pipeline settings | -| CLI arguments | cli.py | Override config values at runtime | -| YAML config | User-provided path | Full pipeline configuration file | +| Mechanism | Location | Purpose | +|---------------------|-------------------------------------|------------------------------------------| +| `AcquisitionConfig` | configuration/acquisition_config.py | Dataclass with camera + encoder settings | +| CLI arguments | cli.py | Override config values at runtime | +| YAML config | User-provided path | Full acquisition configuration file | ## Test coverage -| Source Module | Test File | Coverage | -|------------------------------|------------------------------------|----------| -| pipeline.py | tests/pipeline_test.py | Yes | -| registration/register.py | tests/registration_test.py | Yes | -| detection/detect.py | tests/detection_test.py | Yes | -| mcp/server.py | (none) | Gap | +| Source Module | Test File | Coverage | +|-------------------------|-----------------------------|----------| +| video_system.py | tests/video_system_test.py | Yes | +| camera/opencv_camera.py | tests/opencv_camera_test.py | Yes | +| saver/video_saver.py | tests/video_saver_test.py | Yes | +| mcp/server.py | (none) | Gap | ## Notable patterns -- Numba-accelerated computation for image processing +- Multiprocessing for concurrent acquisition and encoding - Configuration dataclasses with validation - MyPy strict mode with full type annotations -- Processing modules follow a consistent register → detect → extract → classify pipeline +- Camera backends follow a consistent connect → grab → release interface ## Areas of concern - `mcp/server.py` lacks test coverage -- Large refactoring effort from original suite2p codebase still in progress -- Multi-day tracking module has high cyclomatic complexity -- Several `# type: ignore` suppressions in registration module +- GeniCam backend requires a vendor SDK that is unavailable in CI +- Saver module has high cyclomatic complexity +- Several `# type: ignore` suppressions in the camera backend ``` --- diff --git a/plugins/automation/skills/explore-dependencies/SKILL.md b/plugins/automation/skills/explore-dependencies/SKILL.md index 4ea55a3..f5133fa 100644 --- a/plugins/automation/skills/explore-dependencies/SKILL.md +++ b/plugins/automation/skills/explore-dependencies/SKILL.md @@ -52,7 +52,7 @@ ecosystem, domain-to-library mappings, and import names. Read the project's `pyproject.toml` and extract all ataraxis dependencies from `[project.dependencies]` and `[project.optional-dependencies]`. Match package names that start -with `ataraxis-` or `sl-`. +with `ataraxis-` (or the project's own first-party namespace prefix). If `pyproject.toml` is not found, check for `setup.cfg`, `setup.py`, or `requirements.txt` as fallbacks. diff --git a/plugins/automation/skills/explore-dependencies/references/library-catalog.md b/plugins/automation/skills/explore-dependencies/references/library-catalog.md index 5951124..3723f9d 100644 --- a/plugins/automation/skills/explore-dependencies/references/library-catalog.md +++ b/plugins/automation/skills/explore-dependencies/references/library-catalog.md @@ -58,17 +58,15 @@ All repositories are under `https://github.com/Sun-Lab-NBB/`: --- -## Downstream libraries +## First-party application libraries -Downstream libraries follow the `sl-*` naming pattern. These are application-level libraries -built on top of the ataraxis infrastructure for specific workflows: +A project may also depend on its own first-party application libraries — higher-level packages built +on top of the ataraxis infrastructure for specific workflows such as experiment orchestration, data +analysis, or acquisition tooling. -- `sl-experiment` — Experiment orchestration and session management -- `sl-suite2p` — Neural imaging analysis pipeline (reimplemented suite2p) -- Other `sl-*` packages — Lab-specific analysis and acquisition tools - -These follow the same exploration workflow as ataraxis libraries: match `sl-` prefixed package -names in `pyproject.toml`, resolve with `python -c "import ..."`, and read their `__all__` exports. +These follow the same exploration workflow as the ataraxis libraries: match the project's first-party +package prefix in `pyproject.toml`, resolve each with `python -c "import ..."`, and read their +`__all__` exports. --- diff --git a/plugins/automation/skills/project-layout/references/archetype-trees.md b/plugins/automation/skills/project-layout/references/archetype-trees.md index 3aaf412..9d111de 100644 --- a/plugins/automation/skills/project-layout/references/archetype-trees.md +++ b/plugins/automation/skills/project-layout/references/archetype-trees.md @@ -186,7 +186,7 @@ project-root/ ## C++ PlatformIO firmware -Based on `sl-micro-controllers`. +Based on a microcontroller firmware project. ```text project-root/ @@ -230,7 +230,7 @@ project-root/ ## C# Unity -Based on `sl-unity-tasks`. +Based on a Unity behavioral-task project. ```text project-root/ diff --git a/plugins/automation/skills/pyproject-style/SKILL.md b/plugins/automation/skills/pyproject-style/SKILL.md index 19b29ed..d89b509 100644 --- a/plugins/automation/skills/pyproject-style/SKILL.md +++ b/plugins/automation/skills/pyproject-style/SKILL.md @@ -58,11 +58,11 @@ Based on the task, load the appropriate reference files: Identify the project type to apply the correct configuration tier: -| Project type | Naming pattern | MyPy mode | Python support | Dependency style | -|--------------|----------------|-------------|----------------|------------------| -| Core library | `ataraxis-*` | Full strict | `>=3.12,<3.15` | Range (`>=X,=3.14,<3.15` | Range (`>=X,=3.12,<3.15` | Range (`>=X,=3.12,<3.15` | Range (`>=X,=3.14,<3.15` | Range (`>=X,=3.12,<3.15` | Range (`>=X,=5,<6", "ataraxis-base-utilities>=5,<6", "ataraxis-data-structures>=5,<6", -"sl-shared-assets>=7,<8", ``` ### Platform-specific dependencies @@ -364,7 +363,7 @@ command-name = "package_name.module:function" - Use short, memorable command names - Use hyphens for multi-word commands -- Prefix with project abbreviation for namespacing (e.g., `axci-id`, `axvs`, `ss2p`) +- Prefix with project abbreviation for namespacing (e.g., `axci-id`, `axvs`) ### Examples from projects @@ -373,9 +372,6 @@ command-name = "package_name.module:function" | ataraxis-automation | `automation-cli` | `ataraxis_automation.cli:cli` | | ataraxis-video-system | `axvs` | `ataraxis_video_system.cli:axvs_cli` | | ataraxis-communication-interface | `axci-id` | `...microcontroller_interface:identify_interfaces` | -| sl-behavior | `sl-behavior` | `sl_behavior.cli:cli` | -| sl-shared-assets | `sl-configure` | `sl_shared_assets.interfaces.configure:configure` | -| sl-suite2p | `ss2p` | `sl_suite2p.interface.cli:ss2p` | For Click-based CLIs, point to the Click group or command object directly. diff --git a/plugins/automation/skills/pyproject-style/references/tool-configurations.md b/plugins/automation/skills/pyproject-style/references/tool-configurations.md index fa647fb..082b33c 100644 --- a/plugins/automation/skills/pyproject-style/references/tool-configurations.md +++ b/plugins/automation/skills/pyproject-style/references/tool-configurations.md @@ -29,7 +29,7 @@ packages = ["src/package_name"] Additional directories may be included when they are part of the distributed package: ```toml -packages = ["src/sl_suite2p", "notebooks"] +packages = ["src/package_name", "notebooks"] packages = ["src/ataraxis_video_system", "examples"] ``` @@ -135,20 +135,20 @@ lint.ignore = [ Add these ignores only when the project requires them: -| Ignore | Reason | Projects using it | -|----------|---------------------------------------|----------------------------------------------------| -| `ANN401` | `Any` type is needed | ataraxis-automation, sl-experiment | -| `BLE001` | Blind exception catching is necessary | ataraxis-automation, ataraxis-video-system | -| `S602` | Subprocess calls are needed | ataraxis-automation, ataraxis-video-system | -| `S607` | Partial executable paths are needed | ataraxis-automation | -| `FBT001` | Positional boolean arguments (UI) | sl-suite2p, ataraxis-communication-interface | -| `FBT002` | Boolean default values (UI) | sl-suite2p, ataraxis-communication-interface | -| `FBT003` | Boolean positional in function calls | sl-suite2p | -| `SLF001` | Private member access is necessary | sl-suite2p, ataraxis-communication-interface | -| `SIM115` | Non-context-manager file operations | sl-suite2p | -| `TID252` | Relative imports required | ataraxis-video-system | -| `T201` | Print statements are needed | sl-experiment | -| `W293` | Whitespace in UI formatting | sl-behavior, sl-experiment, sl-forgery, sl-suite2p | +| Ignore | Reason | Projects using it | +|----------|---------------------------------------|--------------------------------------------| +| `ANN401` | `Any` type is needed | ataraxis-automation | +| `BLE001` | Blind exception catching is necessary | ataraxis-automation, ataraxis-video-system | +| `S602` | Subprocess calls are needed | ataraxis-automation, ataraxis-video-system | +| `S607` | Partial executable paths are needed | ataraxis-automation | +| `FBT001` | Positional boolean arguments (UI) | ataraxis-communication-interface | +| `FBT002` | Boolean default values (UI) | ataraxis-communication-interface | +| `FBT003` | Boolean positional in function calls | application projects | +| `SLF001` | Private member access is necessary | ataraxis-communication-interface | +| `SIM115` | Non-context-manager file operations | application projects | +| `TID252` | Relative imports required | ataraxis-video-system | +| `T201` | Print statements are needed | application projects | +| `W293` | Whitespace in UI formatting | application projects | ### Ruff unused arguments @@ -207,7 +207,7 @@ Replace `project-name` in the first exclude entry with the actual project name ( ### Minimal mode (applications) -Used by `sl-*` and `pirt` projects: +Used by application projects: ```toml # MyPy configuration section. diff --git a/plugins/automation/skills/python-style/references/class-patterns.md b/plugins/automation/skills/python-style/references/class-patterns.md index e5564f5..de4d285 100644 --- a/plugins/automation/skills/python-style/references/class-patterns.md +++ b/plugins/automation/skills/python-style/references/class-patterns.md @@ -350,7 +350,7 @@ Authors: Author Name (Handle) from .module_one import ClassOne, function_one from .module_two import ClassTwo, ClassThree -# console.enable() belongs only in top-level application libraries (e.g., sl-experiment). +# console.enable() belongs only in top-level application libraries (the project's entry-point package). # Component libraries must NOT enable console — the application entry point handles this. __all__ = [ @@ -389,7 +389,7 @@ __all__ = [ Do NOT include documentation links, source repository links, or authors — these belong only in the top-level library `__init__.py` - **Console initialization**: `console.enable()` belongs only in top-level application libraries - that serve as the final entry point (e.g., `sl-experiment`). Component and dependency libraries + that serve as the final entry point. Component and dependency libraries (e.g., `ataraxis-video-system`) must NOT call `console.enable()` — the top-level application is responsible for enabling the console before any component library code runs - **Explicit `__all__`**: Every `__init__.py` must declare `__all__` with all public API members diff --git a/plugins/automation/skills/readme-style/references/section-templates.md b/plugins/automation/skills/readme-style/references/section-templates.md index 181b1ea..c688d54 100644 --- a/plugins/automation/skills/readme-style/references/section-templates.md +++ b/plugins/automation/skills/readme-style/references/section-templates.md @@ -10,7 +10,7 @@ files. ```markdown # project-name -Supports tox-based development automation pipelines used by other Sun (NeuroAI) lab projects. +Supports tox-based development automation pipelines used by other ataraxis framework projects. ``` The title must match the repository and package name (lowercase, hyphenated). The one-line @@ -48,8 +48,7 @@ the one-line description from the first badge. ![PyPI - Wheel](https://img.shields.io/pypi/wheel/PACKAGE-NAME) ``` -Replace `PACKAGE-NAME` with the actual PyPI package name (e.g., `sl-shared-assets`, -`ataraxis-time`). +Replace `PACKAGE-NAME` with the actual PyPI package name (e.g., `ataraxis-time`). ### C++ / PlatformIO libraries diff --git a/plugins/automation/skills/release/SKILL.md b/plugins/automation/skills/release/SKILL.md index 46bed63..ec33168 100644 --- a/plugins/automation/skills/release/SKILL.md +++ b/plugins/automation/skills/release/SKILL.md @@ -3,7 +3,7 @@ name: release description: >- Drafts style-compliant release notes by summarizing the pull requests merged since the previous release. Infers and recommends the release type (major, minor, or patch) for the user to confirm, then produces a numbered list of the - most impactful changes. Includes a sibling-library compatibility statement for sollertia releases only. Use when + most impactful changes. Includes a sibling-library compatibility statement for cross-dependent library sets only. Use when preparing a release, drafting release notes, or when the user invokes /release. user-invocable: true --- @@ -20,7 +20,7 @@ Drafts style-compliant release notes summarizing the pull requests merged since - Identifying the previous release and the pull requests merged since then - Inferring and recommending the release type (major, minor, patch) for user confirmation - Drafting release notes with a numbered list of the most impactful changes -- Including a sibling-library compatibility statement for sollertia releases +- Including a sibling-library compatibility statement for cross-dependent library sets **Does not cover:** - Creating tags, GitHub releases, or publishing (the user does this) @@ -52,14 +52,14 @@ is silently dropped. If the repository has no prior release tag, summarize the full history (`git log --merges --format='%h %s%n%b'`) and note that this is the first release. -### Step 2: Determine the platform +### Step 2: Determine the dependency model -Determine whether the project is an ataraxis library or a sollertia library from its package or repository name: +Determine whether the project is an independent library or part of a unified, cross-dependent library set: -- **sollertia-*** — the sollertia platform ships as a unified set of cross-dependent libraries, so the release notes - MUST include a compatibility statement (Step 4). -- **ataraxis-*** — the ataraxis libraries are independent and have no enforced cross-dependency web, so the release - notes MUST NOT include a compatibility statement. +- **Cross-dependent set** — the project ships as one of a unified set of sibling libraries released and versioned + together, so the release notes MUST include a compatibility statement (Step 4). +- **Independent library** — the project (like the ataraxis libraries) has no enforced cross-dependency web, so the + release notes MUST NOT include a compatibility statement. ### Step 3: Infer and recommend the release type @@ -75,11 +75,11 @@ For C++ PlatformIO libraries the release version is single-sourced from `library | Minor | New, backward-compatible features or capabilities | | Patch | Bug fixes and minor corrections with no new features | -### Step 4: Resolve the compatibility statement (sollertia only) +### Step 4: Resolve the compatibility statement (cross-dependent sets only) -For sollertia releases, the compatibility statement names the sibling-library versions this release is designed to +For cross-dependent releases, the compatibility statement names the sibling-library versions this release is designed to work with. You cannot reliably infer these — ask the user to confirm the compatible sibling-library versions and -include them verbatim. For ataraxis releases, skip this step entirely. +include them verbatim. For independent libraries, skip this step entirely. ### Step 5: Draft the release notes @@ -93,7 +93,7 @@ GitHub release manually. ```text ### {Major|Minor|Patch} Release -[sollertia only] This release is designed to work with vN, vM, ... +[cross-dependent sets only] This release is designed to work with vN, vM, ... **Major Changes:** @@ -104,8 +104,8 @@ GitHub release manually. ### Rules - The first line is `### {type} Release` using the user-confirmed type. -- For sollertia releases, follow the header with a single compatibility sentence naming the confirmed sibling-library - versions. Omit this line entirely for ataraxis releases. +- For cross-dependent releases, follow the header with a single compatibility sentence naming the confirmed sibling-library + versions. Omit this line entirely for independent libraries. - `**Major Changes:**` introduces a numbered list (`1.`, `2.`, …) of the most impactful changes, ordered from most to least impactful. - Each item is a complete, descriptive sentence in past tense (see the verb set in `/commit`) ending with a period. @@ -116,7 +116,7 @@ GitHub release manually. ### Examples -**Good (ataraxis — no compatibility statement):** +**Good (independent library — no compatibility statement):** ```text ### Major Release @@ -128,12 +128,12 @@ GitHub release manually. 3. Added a log processing (data extraction) pipeline. ``` -**Good (sollertia — compatibility statement included):** +**Good (cross-dependent set — compatibility statement included):** ```text ### Minor Release -This release remains compatible with sollertia-experiment v5, sollertia-unity-tasks v3, and sollertia-forgery v1. +This release remains compatible with `acquisition` v5, `behavior` v3, and `analysis` v1. **Major Changes:** @@ -182,8 +182,8 @@ Do NOT create tags or GitHub releases. Present the drafted notes for the user to Release Notes Compliance: - [ ] First line is `### {Major|Minor|Patch} Release` with the user-confirmed type - [ ] Release type was recommended AND confirmed by the user -- [ ] Compatibility statement included for sollertia releases, omitted for ataraxis releases -- [ ] Sibling-library versions confirmed by the user (sollertia only) +- [ ] Compatibility statement included for cross-dependent releases, omitted for independent libraries +- [ ] Sibling-library versions confirmed by the user (cross-dependent sets only) - [ ] `**Major Changes:**` numbered list ordered from most to least impactful - [ ] Each item is past tense and ends with a period - [ ] Condenses many pull requests into a few impactful themes (does not list every pull request) diff --git a/plugins/automation/skills/tox-config/SKILL.md b/plugins/automation/skills/tox-config/SKILL.md index 2920b2b..52c4107 100644 --- a/plugins/automation/skills/tox-config/SKILL.md +++ b/plugins/automation/skills/tox-config/SKILL.md @@ -50,12 +50,12 @@ You MUST follow these steps when this skill is invoked. Determine which pipeline applies: -| Archetype | Envlist pattern | Key indicator | -|----------------|------------------------------------------------------------------------------|-------------------------------------| -| Full Python | uninstall → export → lint → stubs → test → coverage → docs → build → install | `pyproject.toml` + `src/` layout | -| C++ extension | Same as full Python, with Doxygen in docs and cibuildwheel in build | `CMakeLists.txt` + `pyproject.toml` | -| Reduced Python | Full Python minus test and coverage | `sl-*` app with no unit tests | -| C++ docs-only | docs only | `platformio.ini`, no `pyproject` | +| Archetype | Envlist pattern | Key indicator | +|----------------|------------------------------------------------------------------------------|----------------------------------------| +| Full Python | uninstall → export → lint → stubs → test → coverage → docs → build → install | `pyproject.toml` + `src/` layout | +| C++ extension | Same as full Python, with Doxygen in docs and cibuildwheel in build | `CMakeLists.txt` + `pyproject.toml` | +| Reduced Python | Full Python minus test and coverage | Application project with no unit tests | +| C++ docs-only | docs only | `platformio.ini`, no `pyproject` | ### Step 2: Load reference templates @@ -226,7 +226,7 @@ envlist = ### Reduced Python pipeline -Used by application projects (`sl-*`) that do not have unit tests: +Used by application projects that do not have unit tests: ```ini envlist = @@ -321,12 +321,12 @@ envlist = docs Each project has a short abbreviation used for its mamba environment name: -| Pattern | Abbreviation rule | Example | -|--------------|------------------------------|------------------------------------| -| `ataraxis-*` | Initials of hyphenated parts | `ataraxis-base-utilities` → `axbu` | -| `sl-*` | Initials of hyphenated parts | `sl-shared-assets` → `slsa` | +| Project type | Abbreviation rule | Example | +|------------------------------------|-----------------------------------------------------------|------------------------------------| +| Multi-repository project component | Project abbreviation + the initial of each remaining word | `ataraxis-base-utilities` → `axbu` | +| Standalone project | The project name, used as-is | `harvester` → `harvester` | -The full environment name follows the pattern `{abbr}_dev` (e.g., `axbu_dev`). The OS suffix +The full environment name follows the pattern `{abbr}_dev` (e.g., `axbu_dev` or `harvester_dev`). The OS suffix (`_lin`, `_osx`, `_win`) is appended automatically by `automation-cli` at runtime — it does NOT appear in tox.ini. diff --git a/plugins/automation/skills/tox-config/references/environment-templates.md b/plugins/automation/skills/tox-config/references/environment-templates.md index c40709a..ad8f2f3 100644 --- a/plugins/automation/skills/tox-config/references/environment-templates.md +++ b/plugins/automation/skills/tox-config/references/environment-templates.md @@ -88,14 +88,14 @@ provider, its lint environment does not need `deps = ataraxis-automation==X.Y.Z` #### mypy parallelism (large projects only) `mypy ./src` runs single-threaded by default. This is correct for the overwhelming majority of -ataraxis and sollertia libraries: their `src/` is small enough that a warm, incremental `mypy` run +ataraxis libraries and application projects: their `src/` is small enough that a warm, incremental `mypy` run finishes in well under a second, and the binary + SQLite incremental caches (on by default since mypy 2.0) already make re-runs effectively free. You MUST NOT add parallelism to a project's lint command by default. mypy 2.x adds experimental parallel type checking via `-n N` / `--num-workers N` (config-file key `num_workers`; environment override `MYPY_NUM_WORKERS`). It only helps large codebases — those -where a *cold* `mypy ./src` takes more than a few seconds (e.g. `cindra`, `sollertia-experiment`). +where a *cold* `mypy ./src` takes more than a few seconds (large application projects). For those projects only, append the flag to the lint command: ```ini @@ -158,7 +158,7 @@ commands = **Parameterization:** - Python version matrix `{py312, py313, py314}`: Must match the `requires-python` range in - `pyproject.toml`. Core libraries (`ataraxis-*`) test 3 versions; applications (`sl-*`) may + `pyproject.toml`. Core libraries (`ataraxis-*`) test 3 versions; applications may test fewer. - `{package_name}` in `--cov`: The underscore-separated package name. - `package = wheel`: Forces the project to be built as a wheel before testing. @@ -421,7 +421,7 @@ commands = ## Reduced Python pipeline -Some Python application projects (`sl-*`) omit test and coverage environments from their envlist, +Some Python application projects omit test and coverage environments from their envlist, typically because the project is an application that integrates with hardware or external systems and cannot be meaningfully unit-tested in isolation. From f2b5979c436618da68557fe621ddf95cbc86331c Mon Sep 17 00:00:00 2001 From: Ivan Kondratyev Date: Thu, 18 Jun 2026 12:42:29 -0400 Subject: [PATCH 5/7] Standardized plugin skills for the pre-release agentic surface. -- Trimmed nine skill descriptions to five lines or fewer and codified the limit in skill-design. -- Unified source-ID terminology and added controller/system ID to source ID equivalence statements. -- Made cross-skill hand-off tables reciprocal across the four plugins. -- Added a platformio-config Proactive behavior section and standardized section ordering and casing. -- Relocated reference content to keep firmware-module and csharp-style under 500 lines. -- Corrected the video source ID range to 1-255 and the README MCP commands to axci/axvs mcp. -- Bumped all four plugin versions. --- README.md | 8 +-- plugins/automation/.claude-plugin/plugin.json | 2 +- .../automation/skills/audit-facts/SKILL.md | 11 ++-- .../automation/skills/audit-style/SKILL.md | 38 +++++++------- plugins/automation/skills/cpp-style/SKILL.md | 11 ++-- .../automation/skills/csharp-style/SKILL.md | 17 ++----- .../skills/explore-codebase/SKILL.md | 19 +++---- .../skills/explore-dependencies/SKILL.md | 7 ++- .../skills/platformio-config/SKILL.md | 43 +++++++++------- .../automation/skills/project-layout/SKILL.md | 11 ++-- plugins/automation/skills/release/SKILL.md | 19 +++---- .../automation/skills/skill-design/SKILL.md | 6 ++- plugins/automation/skills/tox-config/SKILL.md | 11 ++-- .../communication/.claude-plugin/plugin.json | 2 +- .../skills/extraction-configuration/SKILL.md | 19 +++---- .../skills/microcontroller-interface/SKILL.md | 18 +++---- .../skills/microcontroller-setup/SKILL.md | 21 ++++---- .../communication/skills/pipeline/SKILL.md | 5 ++ .../.claude-plugin/plugin.json | 2 +- .../skills/firmware-module/SKILL.md | 51 +++---------------- .../references/api-reference.md | 37 ++++++++++++++ plugins/video/.claude-plugin/plugin.json | 2 +- .../video/skills/log-input-format/SKILL.md | 2 +- plugins/video/skills/pipeline/SKILL.md | 11 +++- .../video-mcp-environment-setup/SKILL.md | 5 +- 25 files changed, 194 insertions(+), 184 deletions(-) diff --git a/README.md b/README.md index f406f63..61324b4 100644 --- a/README.md +++ b/README.md @@ -158,12 +158,12 @@ Add Ataraxis MCP servers to your Claude Code configuration (`~/.claude.json`): { "mcpServers": { "ataraxis-communication-interface": { - "command": "axci-mcp", - "args": [] + "command": "axci", + "args": ["mcp"] }, "ataraxis-video-system": { - "command": "python", - "args": ["-m", "ataraxis_video_system.mcp_server"] + "command": "axvs", + "args": ["mcp"] } } } diff --git a/plugins/automation/.claude-plugin/plugin.json b/plugins/automation/.claude-plugin/plugin.json index 19de7b2..8031c9d 100644 --- a/plugins/automation/.claude-plugin/plugin.json +++ b/plugins/automation/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "automation", - "version": "1.3.0", + "version": "1.3.1", "description": "Provides the shared software development skills that enforce conventions and code style in Ataraxis and derived projects.", "repository": "https://github.com/Sun-Lab-NBB/ataraxis", "license": "Apache-2.0", diff --git a/plugins/automation/skills/audit-facts/SKILL.md b/plugins/automation/skills/audit-facts/SKILL.md index 5304aa9..48cabb5 100644 --- a/plugins/automation/skills/audit-facts/SKILL.md +++ b/plugins/automation/skills/audit-facts/SKILL.md @@ -1,12 +1,11 @@ --- name: audit-facts description: >- - Performs a thorough fact-check audit of documentation files against their authoritative - source code. Verifies every concrete claim, surfaces drift, contradictions, and substantive - omissions, and produces a structured findings report with verbatim source citations. Use when - auditing README files, CLAUDE.md, SKILL.md, Sphinx documentation, or any project - documentation for factual accuracy against the codebase. Use when the user invokes - /audit-facts. + Performs a thorough fact-check audit of documentation files against their authoritative source + code. Verifies every concrete claim and surfaces drift, contradictions, and substantive omissions + in a structured findings report with verbatim source citations. Use when auditing README, + CLAUDE.md, SKILL.md, Sphinx, or any project documentation for factual accuracy, or when the user + invokes /audit-facts. user-invocable: true --- diff --git a/plugins/automation/skills/audit-style/SKILL.md b/plugins/automation/skills/audit-style/SKILL.md index 32312d4..493dc75 100644 --- a/plugins/automation/skills/audit-style/SKILL.md +++ b/plugins/automation/skills/audit-style/SKILL.md @@ -1,12 +1,11 @@ --- name: audit-style description: >- - Performs a thorough style-compliance audit of source code, configuration, or documentation - files against the applicable ataraxis framework style skill checklists. Walks every line of every file - in scope and reports only non-compliant findings with verbatim checklist citations. Use when - auditing a Python package, a config file, a README, or any project file for style, - formatting, naming, documentation quality, or convention compliance. Use when the user - invokes /audit-style. + Performs a thorough style-compliance audit of source code, configuration, or documentation files + against the applicable ataraxis framework style skill checklists. Walks every line in scope and + reports only non-compliant findings with verbatim checklist citations. Use when auditing a Python + package, config file, README, or any project file for style, formatting, naming, or convention + compliance, or when the user invokes /audit-style. user-invocable: true --- @@ -245,19 +244,20 @@ You MUST adhere to the following discipline during every audit. ## Related skills -| Skill | Relationship | -|---------------------|------------------------------------------------------------------------------------------| -| `/audit-facts` | Sibling audit for factual accuracy against source code | -| `/python-style` | Provides the Python style checklist; loaded when scope contains Python files | -| `/cpp-style` | Provides the C++ style checklist; loaded when scope contains C++ files | -| `/csharp-style` | Provides the C# style checklist; loaded when scope contains C# files | -| `/readme-style` | Provides the README style checklist; loaded when scope contains README files | -| `/pyproject-style` | Provides the pyproject.toml style checklist; loaded when scope contains pyproject.toml | -| `/tox-config` | Provides the tox.ini style checklist; loaded when scope contains tox.ini | -| `/api-docs` | Provides the Sphinx docs style checklist; loaded when scope contains docs files | -| `/skill-design` | Provides the skill and CLAUDE.md style checklist; loaded when scope contains skill files | -| `/project-layout` | Provides the project directory style checklist; loaded when target is a project root | -| `/explore-codebase` | Provides project structure context; invoke first when auditing an unfamiliar codebase | +| Skill | Relationship | +|----------------------|--------------------------------------------------------------------------------------------------| +| `/audit-facts` | Sibling audit for factual accuracy against source code | +| `/python-style` | Provides the Python style checklist; loaded when scope contains Python files | +| `/cpp-style` | Provides the C++ style checklist; loaded when scope contains C++ files | +| `/csharp-style` | Provides the C# style checklist; loaded when scope contains C# files | +| `/readme-style` | Provides the README style checklist; loaded when scope contains README files | +| `/pyproject-style` | Provides the pyproject.toml style checklist; loaded when scope contains pyproject.toml | +| `/tox-config` | Provides the tox.ini style checklist; loaded when scope contains tox.ini | +| `/platformio-config` | Provides the platformio.ini/library.json style checklist; loaded when scope contains those files | +| `/api-docs` | Provides the Sphinx docs style checklist; loaded when scope contains docs files | +| `/skill-design` | Provides the skill and CLAUDE.md style checklist; loaded when scope contains skill files | +| `/project-layout` | Provides the project directory style checklist; loaded when target is a project root | +| `/explore-codebase` | Provides project structure context; invoke first when auditing an unfamiliar codebase | --- diff --git a/plugins/automation/skills/cpp-style/SKILL.md b/plugins/automation/skills/cpp-style/SKILL.md index 8932a64..2811657 100644 --- a/plugins/automation/skills/cpp-style/SKILL.md +++ b/plugins/automation/skills/cpp-style/SKILL.md @@ -1,12 +1,11 @@ --- name: cpp-style description: >- - Applies C++ coding conventions when writing, reviewing, or refactoring code. Covers .h, - .hpp, and .cpp files, Doxygen documentation, naming, formatting, error handling, include - directives, file ordering, template patterns, embedded (Arduino/PlatformIO) conventions, and - Python C++ extension (nanobind/scikit-build-core) conventions. Use when writing new C++ code, - modifying existing code, reviewing pull requests, or when the user asks about C++ coding - standards. + Applies C++ coding conventions when writing, reviewing, or refactoring code. Covers .h, .hpp, and + .cpp files, Doxygen documentation, naming, formatting, error handling, includes, file ordering, + template patterns, embedded (Arduino/PlatformIO) conventions, and Python C++ extension + (nanobind/scikit-build-core) conventions. Use when writing or modifying C++ code, reviewing pull + requests, or when the user asks about C++ coding standards. user-invocable: false --- diff --git a/plugins/automation/skills/csharp-style/SKILL.md b/plugins/automation/skills/csharp-style/SKILL.md index 2eec0b5..54c0941 100644 --- a/plugins/automation/skills/csharp-style/SKILL.md +++ b/plugins/automation/skills/csharp-style/SKILL.md @@ -385,21 +385,10 @@ See [libraries-and-tools.md](references/libraries-and-tools.md) for guard clause See [libraries-and-tools.md](references/libraries-and-tools.md) for blank line conventions. -## Line length and formatting +## Formatting, tooling, and configuration files -See [libraries-and-tools.md](references/libraries-and-tools.md) for line length, formatting, and brace rules. - ---- - -## Tooling - -See [libraries-and-tools.md](references/libraries-and-tools.md) for CSharpier and EditorConfig tooling. - ---- - -## Configuration files - -See [libraries-and-tools.md](references/libraries-and-tools.md) for configuration file references. +See [libraries-and-tools.md](references/libraries-and-tools.md) for line length, formatting, and brace +rules; CSharpier and EditorConfig tooling; and configuration file references. --- diff --git a/plugins/automation/skills/explore-codebase/SKILL.md b/plugins/automation/skills/explore-codebase/SKILL.md index 5ddf8d5..3c525c4 100644 --- a/plugins/automation/skills/explore-codebase/SKILL.md +++ b/plugins/automation/skills/explore-codebase/SKILL.md @@ -262,15 +262,16 @@ Exported from `__init__.py` via `__all__`: ## Related skills -| Skill | Relationship | -|-------------------------|---------------------------------------------------------------------| -| `/explore-dependencies` | Explores ataraxis dependency APIs; invoke alongside this skill | -| `/python-style` | Provides Python coding conventions discovered during exploration | -| `/cpp-style` | Provides C++ coding conventions discovered during exploration | -| `/csharp-style` | Provides C# coding conventions discovered during exploration | -| `/readme-style` | Provides README conventions when exploration reveals README issues | -| `/commit` | Should be invoked after completing code changes informed by context | -| `/skill-design` | Provides skill conventions when exploration reveals skill files | +| Skill | Relationship | +|-------------------------|--------------------------------------------------------------------------------------| +| `/explore-dependencies` | Explores ataraxis dependency APIs; invoke alongside this skill | +| `/python-style` | Provides Python coding conventions discovered during exploration | +| `/cpp-style` | Provides C++ coding conventions discovered during exploration | +| `/csharp-style` | Provides C# coding conventions discovered during exploration | +| `/readme-style` | Provides README conventions when exploration reveals README issues | +| `/commit` | Should be invoked after completing code changes informed by context | +| `/skill-design` | Provides skill conventions when exploration reveals skill files | +| `/project-layout` | Provides project directory and test-naming conventions referenced during exploration | --- diff --git a/plugins/automation/skills/explore-dependencies/SKILL.md b/plugins/automation/skills/explore-dependencies/SKILL.md index f5133fa..02bbe41 100644 --- a/plugins/automation/skills/explore-dependencies/SKILL.md +++ b/plugins/automation/skills/explore-dependencies/SKILL.md @@ -1,10 +1,9 @@ --- name: explore-dependencies description: >- - Explores installed ataraxis dependency source code to build a live API snapshot. - Discovers public classes, functions, and constants exported by each dependency, identifies - replacement opportunities where project code reimplements existing library functionality, and - produces a structured dependency API snapshot. Use when starting a session on a project with + Explores installed ataraxis dependency source code to build a live API snapshot of the public + classes, functions, and constants each dependency exports, flagging where project code + reimplements existing library functionality. Use when starting a session on a project with ataraxis dependencies, before writing code that uses ataraxis library features, or when the user asks about available library APIs. user-invocable: true diff --git a/plugins/automation/skills/platformio-config/SKILL.md b/plugins/automation/skills/platformio-config/SKILL.md index 30a9a4d..688eca2 100644 --- a/plugins/automation/skills/platformio-config/SKILL.md +++ b/plugins/automation/skills/platformio-config/SKILL.md @@ -2,11 +2,10 @@ name: platformio-config description: >- Applies platformio.ini and library.json conventions when creating or modifying PlatformIO C++ - project and library configuration files. Covers per-board environment sections, build flags, - pinned lib_deps, library.json metadata, the lib_deps<->dependencies mirroring rule, the main.cpp - export exclusion, and library.json as the single source of the C++ library version. Use when - creating or modifying platformio.ini or library.json, adding a board or dependency, or when the - user asks about PlatformIO configuration conventions. + project and library configuration files. Covers per-board environments, build flags, pinned + lib_deps, library.json metadata, the lib_deps<->dependencies mirroring rule, the main.cpp export + exclusion, and library.json as the single source of the C++ library version. Use when creating or + modifying these files, adding a board or dependency, or when asked about PlatformIO conventions. user-invocable: false --- @@ -186,6 +185,28 @@ These are the PlatformIO development-automation commands (agent-runnable, the C+ --- +## Related skills + +| Skill | Relationship | +|-----------------------------------|----------------------------------------------------------------------| +| `/project-layout` | Owner of where platformio.ini/library.json sit in the C++ archetypes | +| `/cpp-style` | C++ source style (scopes out these config files) | +| `microcontroller:firmware-module` | The src/main.cpp harness that export excludes and the module sources | +| `/readme-style` | C++ PlatformIO README Installation/Developers sections | +| `/release` | Uses library.json version as the C++ library release version | + +--- + +## Proactive behavior + +You should proactively offer to invoke this skill when: +- Creating a new PlatformIO C++ library or firmware project that needs a platformio.ini or library.json +- Adding a board environment, or adding, removing, or re-pinning a lib_deps dependency +- Releasing a C++ library (library.json version is the single source of the release version) +- The user asks about PlatformIO configuration or the lib_deps<->dependencies mirroring rule + +--- + ## Verification checklist ```text @@ -201,15 +222,3 @@ PlatformIO configuration: - [ ] each library.json dependency's platforms array matches the boards that list it in lib_deps - [ ] library.json version is set (the single source of the C++ library version); platformio.ini has no version ``` - ---- - -## Related skills - -| Skill | Relationship | -|-----------------------------------|----------------------------------------------------------------------| -| `/project-layout` | Owner of where platformio.ini/library.json sit in the C++ archetypes | -| `/cpp-style` | C++ source style (scopes out these config files) | -| `microcontroller:firmware-module` | The src/main.cpp harness that export excludes and the module sources | -| `/readme-style` | C++ PlatformIO README Installation/Developers sections | -| `/release` | Uses library.json version as the C++ library release version | diff --git a/plugins/automation/skills/project-layout/SKILL.md b/plugins/automation/skills/project-layout/SKILL.md index da9bf27..3e6a20b 100644 --- a/plugins/automation/skills/project-layout/SKILL.md +++ b/plugins/automation/skills/project-layout/SKILL.md @@ -1,12 +1,11 @@ --- name: project-layout description: >- - Applies project directory structure conventions when creating new projects, adding - directories, or verifying project layout. Covers the five project archetypes (Python-only, - Python+C++ extension, C++ PlatformIO library, C++ PlatformIO firmware, C# Unity), common root - files, environment directories, test directories, and documentation directory placement. Use - when creating a new project, adding top-level directories, restructuring a project, or when the - user asks about project directory conventions. + Applies project directory structure conventions when creating new projects, adding directories, + or verifying project layout. Covers the five archetypes (Python-only, Python+C++ extension, C++ + PlatformIO library, C++ PlatformIO firmware, C# Unity), common root files, environment, test, and + documentation directories. Use when creating a new project, adding top-level directories, + restructuring a project, or when the user asks about project directory conventions. user-invocable: false --- diff --git a/plugins/automation/skills/release/SKILL.md b/plugins/automation/skills/release/SKILL.md index ec33168..9d78c23 100644 --- a/plugins/automation/skills/release/SKILL.md +++ b/plugins/automation/skills/release/SKILL.md @@ -1,10 +1,10 @@ --- name: release description: >- - Drafts style-compliant release notes by summarizing the pull requests merged since the previous release. Infers and - recommends the release type (major, minor, or patch) for the user to confirm, then produces a numbered list of the - most impactful changes. Includes a sibling-library compatibility statement for cross-dependent library sets only. Use when - preparing a release, drafting release notes, or when the user invokes /release. + Drafts style-compliant release notes by summarizing the pull requests merged since the previous release. Infers + and recommends the release type (major, minor, or patch) for the user to confirm, then produces a numbered list + of the most impactful changes. Includes a sibling-library compatibility statement for cross-dependent library + sets only. Use when preparing a release, drafting release notes, or when the user invokes /release. user-invocable: true --- @@ -157,11 +157,12 @@ This release remains compatible with `acquisition` v5, `behavior` v3, and `analy ## Related skills -| Skill | Relationship | -|---------------------|--------------------------------------------------------------------------| -| `/commit` | Provides the past tense verb set and punctuation conventions reused here | -| `/pr` | Drafts the per-branch pull request summaries that releases aggregate | -| `/explore-codebase` | Provides project context that helps write accurate summaries | +| Skill | Relationship | +|----------------------|--------------------------------------------------------------------------| +| `/commit` | Provides the past tense verb set and punctuation conventions reused here | +| `/pr` | Drafts the per-branch pull request summaries that releases aggregate | +| `/explore-codebase` | Provides project context that helps write accurate summaries | +| `/platformio-config` | Owns library.json whose version field is the C++ library release version | --- diff --git a/plugins/automation/skills/skill-design/SKILL.md b/plugins/automation/skills/skill-design/SKILL.md index c692642..fd76858 100644 --- a/plugins/automation/skills/skill-design/SKILL.md +++ b/plugins/automation/skills/skill-design/SKILL.md @@ -188,7 +188,9 @@ user-invocable: false only, max 64 characters. Examples: `explore-codebase`, `commit`, `skill-design`. **Description**: Third person. Include what the skill does AND when to use it. End with explicit -trigger conditions ("Use when..."). Max 1024 characters. +trigger conditions ("Use when..."). Max 1024 characters, and keep the folded description to 5 wrapped +lines or fewer — trim wordy descriptions to the essential coverage and triggers to avoid frontmatter +bloat. **`user-invocable`**: Set to `true` for skills invokable via `/skill-name`. Defaults to `true`. @@ -419,7 +421,7 @@ Skill File Compliance: - [ ] YAML frontmatter with `name` and `description` - [ ] `user-invocable: true` set if skill is directly invocable via slash command - [ ] Name matches parent directory name exactly -- [ ] Description in third person, includes what AND when to use (max 1024 chars) +- [ ] Description in third person, includes what AND when to use (max 1024 chars, ≤ 5 wrapped lines) - [ ] Scope declaration present (what skill covers and does not cover) - [ ] Degrees of freedom appropriate (low for reproducible, high for creative tasks) - [ ] All lines ≤ 120 characters (tables/code blocks may exceed for clarity) diff --git a/plugins/automation/skills/tox-config/SKILL.md b/plugins/automation/skills/tox-config/SKILL.md index 52c4107..32e4bab 100644 --- a/plugins/automation/skills/tox-config/SKILL.md +++ b/plugins/automation/skills/tox-config/SKILL.md @@ -1,12 +1,11 @@ --- name: tox-config description: >- - Applies tox.ini conventions when creating or modifying tox configuration files. Covers - the mamba + uv + tox toolchain architecture, envlist patterns, environment definitions, - dependency installation strategies, environment naming, and project archetype variations - (full Python, reduced Python, C++ extension, C++ docs-only). Use when creating a new tox.ini, - modifying an existing tox.ini, adding or changing tox environments, or when the user asks about - tox configuration, development automation, or the mamba/uv/tox toolchain. + Applies tox.ini conventions when creating or modifying tox configuration files. Covers the + mamba + uv + tox toolchain, envlist patterns, environment definitions, dependency installation + strategies, environment naming, and project archetype variations (full Python, reduced Python, + C++ extension, C++ docs-only). Use when creating or modifying a tox.ini, changing tox + environments, or when the user asks about tox configuration or the mamba/uv/tox toolchain. user-invocable: false --- diff --git a/plugins/communication/.claude-plugin/plugin.json b/plugins/communication/.claude-plugin/plugin.json index c5cbe4a..88f8065 100644 --- a/plugins/communication/.claude-plugin/plugin.json +++ b/plugins/communication/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "communication", - "version": "1.2.0", + "version": "1.2.1", "description": "Provides microcontroller discovery, extraction configuration, log processing, and pipeline orchestration skills for ataraxis-communication-interface. Includes MCP bindings for hardware discovery, manifest management, and batch data processing.", "repository": "https://github.com/Sun-Lab-NBB/ataraxis", "license": "Apache-2.0", diff --git a/plugins/communication/skills/extraction-configuration/SKILL.md b/plugins/communication/skills/extraction-configuration/SKILL.md index 683ebd5..4a79eaf 100644 --- a/plugins/communication/skills/extraction-configuration/SKILL.md +++ b/plugins/communication/skills/extraction-configuration/SKILL.md @@ -322,15 +322,16 @@ codes by design, so it must be filled in before processing. ## Related skills -| Skill | Relationship | -|----------------------------------------|------------------------------------------------------------------| -| `/microcontroller-setup` | Upstream: manifest creation and recording discovery | -| `/microcontroller-interface` | Upstream: code that produces the manifests used here | -| `/log-input-format` | Reference: archive format that extraction config targets | -| `/log-processing` | Downstream: consumes the validated extraction config | -| `/log-processing-results` | Downstream: output format depends on config targets | -| `/pipeline` | Context: extraction config is phase 3 of the end-to-end pipeline | -| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for config tools | +| Skill | Relationship | +|----------------------------------------|----------------------------------------------------------------------------| +| `/microcontroller-setup` | Upstream: manifest creation and recording discovery | +| `/microcontroller-interface` | Upstream: code that produces the manifests used here | +| `/microcontroller:firmware-module` | Upstream: firmware Module that defines the event codes this config targets | +| `/log-input-format` | Reference: archive format that extraction config targets | +| `/log-processing` | Downstream: consumes the validated extraction config | +| `/log-processing-results` | Downstream: output format depends on config targets | +| `/pipeline` | Context: extraction config is phase 3 of the end-to-end pipeline | +| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for config tools | --- diff --git a/plugins/communication/skills/microcontroller-interface/SKILL.md b/plugins/communication/skills/microcontroller-interface/SKILL.md index 065b578..0fbc320 100644 --- a/plugins/communication/skills/microcontroller-interface/SKILL.md +++ b/plugins/communication/skills/microcontroller-interface/SKILL.md @@ -1,12 +1,11 @@ --- name: microcontroller-interface description: >- - Guides creation and configuration of MicroControllerInterface, ModuleInterface, and MQTTCommunication - instances for microcontroller communication. Covers MicroControllerInterface initialization and - lifecycle, ModuleInterface subclassing with command and parameter sending, MQTTCommunication setup, - system ID allocation, and DataLogger integration. Use when writing code that creates - MicroControllerInterface or MQTTCommunication instances or needs to understand the - ataraxis-communication-interface API. + Guides creation and configuration of MicroControllerInterface, ModuleInterface, and + MQTTCommunication instances for microcontroller communication. Covers interface initialization + and lifecycle, ModuleInterface subclassing with command and parameter sending, MQTTCommunication + setup, controller ID allocation, and DataLogger integration. Use when writing code that creates + MicroControllerInterface or MQTTCommunication instances or needs the ataraxis-communication-interface API. user-invocable: false --- @@ -26,7 +25,7 @@ dataclasses, startup orchestration) is the responsibility of the consuming libra - MicroControllerInterface constructor parameters and lifecycle methods - ModuleInterface abstract base class and subclassing pattern - MQTTCommunication setup and lifecycle -- System ID allocation and naming conventions +- Controller ID allocation and naming conventions - DataLogger integration requirements **Does not cover:** @@ -414,10 +413,11 @@ communication cycle. Verification fails if: --- -## System ID allocation +## Controller ID allocation Each MicroControllerInterface instance requires a unique `controller_id` (`np.uint8`) for DataLogger -identification. The recommended allocation: +identification. A controller's `controller_id` IS its source ID at the DataLogger level (see +`/log-input-format`). The recommended allocation: | Range | Assignment | Notes | |---------|------------------------------------|---------------------------------------------------| diff --git a/plugins/communication/skills/microcontroller-setup/SKILL.md b/plugins/communication/skills/microcontroller-setup/SKILL.md index 35d820e..4e5f6e7 100644 --- a/plugins/communication/skills/microcontroller-setup/SKILL.md +++ b/plugins/communication/skills/microcontroller-setup/SKILL.md @@ -244,7 +244,7 @@ When transitioning from MCP-based discovery to writing MicroControllerInterface | Baudrate used in discovery | `baudrate` | Same value (default: 115200) | | MQTT broker host/port | `MQTTCommunication(ip, port)` | Pass to MQTTCommunication constructor | -### Source ID semantics +### Controller ID semantics | Range | Assignment | Notes | |---------|------------------------------------|---------------------------------------------------| @@ -288,15 +288,16 @@ advised ranges. ## Related skills -| Skill | Relationship | -|----------------------------------------|--------------------------------------------------------------------| -| `/microcontroller-interface` | Covers writing MicroControllerInterface code after testing via MCP | -| `/extraction-configuration` | Downstream: configure extraction parameters before processing | -| `/log-input-format` | Reference: documents the archive format produced by this workflow | -| `/log-processing` | Downstream: processes archives assembled by this skill | -| `/log-processing-results` | Downstream: analyzes output from processed archives | -| `/pipeline` | Context: end-to-end orchestration and multi-controller planning | -| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for all tool interactions | +| Skill | Relationship | +|----------------------------------------|---------------------------------------------------------------------------------| +| `/microcontroller-interface` | Covers writing MicroControllerInterface code after testing via MCP | +| `/microcontroller:firmware-module` | Firmware-side counterpart: C++ Module code that discovered controllers must run | +| `/extraction-configuration` | Downstream: configure extraction parameters before processing | +| `/log-input-format` | Reference: documents the archive format produced by this workflow | +| `/log-processing` | Downstream: processes archives assembled by this skill | +| `/log-processing-results` | Downstream: analyzes output from processed archives | +| `/pipeline` | Context: end-to-end orchestration and multi-controller planning | +| `/communication-mcp-environment-setup` | Prerequisite: MCP server connectivity for all tool interactions | --- diff --git a/plugins/communication/skills/pipeline/SKILL.md b/plugins/communication/skills/pipeline/SKILL.md index 23826b9..ecb3965 100644 --- a/plugins/communication/skills/pipeline/SKILL.md +++ b/plugins/communication/skills/pipeline/SKILL.md @@ -122,6 +122,11 @@ Python code that creates MicroControllerInterface and ModuleInterface instances. ### Controller ID allocation +A controller's `controller_id` IS its source ID at the DataLogger level: it is the value +MicroControllerInterface registers as the `source_id`, and it names the controller's +`{controller_id}_log.npz` archive (see `/log-input-format`). This skill uses "source ID" for the +shared DataLogger namespace and `controller_id` for the MicroControllerInterface constructor. + | Range | Assignment | Notes | |---------|------------------------------------|---------------------------------------------------| | 101-150 | MicroControllerInterface instances | Advised production range; not enforced | diff --git a/plugins/microcontroller/.claude-plugin/plugin.json b/plugins/microcontroller/.claude-plugin/plugin.json index cb62df0..22bd035 100644 --- a/plugins/microcontroller/.claude-plugin/plugin.json +++ b/plugins/microcontroller/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "microcontroller", - "version": "1.2.0", + "version": "1.2.1", "description": "Provides firmware module implementation skills for ataraxis-micro-controller.", "repository": "https://github.com/Sun-Lab-NBB/ataraxis", "license": "Apache-2.0", diff --git a/plugins/microcontroller/skills/firmware-module/SKILL.md b/plugins/microcontroller/skills/firmware-module/SKILL.md index cb02567..063d92b 100644 --- a/plugins/microcontroller/skills/firmware-module/SKILL.md +++ b/plugins/microcontroller/skills/firmware-module/SKILL.md @@ -3,10 +3,9 @@ name: firmware-module description: >- Guides creation of custom hardware Module subclasses in the ataraxis-micro-controller C++ firmware library. Covers SetupModule, SetCustomParameters, and RunActiveCommand implementation, stage-based - command execution, parameter structures with PACKED_STRUCT, event codes, SendData patterns, and - main.cpp integration with Kernel and Communication. Use when writing or modifying firmware module - classes for microcontrollers, when the user asks about Module subclassing, or when implementing - new hardware interfaces on the microcontroller side of ataraxis-communication-interface. + command execution, PACKED_STRUCT parameter structures, event codes, SendData patterns, and main.cpp + integration with Kernel and Communication. Use when writing or modifying firmware Module + subclasses, or when implementing the microcontroller side of an ataraxis-communication-interface module. user-invocable: false --- @@ -436,48 +435,11 @@ void loop() --- -## Template parameter guidelines - -| Type | Use Case | Example | -|------------|-----------------------------------|--------------------------------| -| `uint8_t` | Pin numbers, counts | `kPin`, `kEncoderPinA` | -| `bool` | Hardware polarity, default states | `kNormallyClosed`, `kStartOff` | -| `uint16_t` | Larger constants (calibration) | `kDefaultThreshold` | - -Use `255` as a sentinel for optional pins: - -```cpp -template -// In implementation: -if constexpr (kTonePin != 255) { pinMode(kTonePin, OUTPUT); } -``` - ---- - -## Static assertions - -Place static assertions at the **top of the class body**, before `public:`: - -```cpp -template -class EncoderModule final : public Module -{ - static_assert(kPinA != kPinB, "Channel A and Channel B pins cannot be the same."); - static_assert(kPinA != LED_BUILTIN, "Select a different Channel A pin."); - static_assert(kPinB != LED_BUILTIN, "Select a different Channel B pin."); - - public: - // ... -}; -``` - ---- - ## Implementation hints -See [references/api-reference.md](references/api-reference.md) for optional efficiency patterns, -including constexpr pin logic for polarity-configurable modules and sensor hysteresis for polling -commands. +See [references/api-reference.md](references/api-reference.md) for template parameter type guidelines, +static-assertion placement, and optional efficiency patterns (constexpr pin logic for +polarity-configurable modules and sensor hysteresis for polling commands). --- @@ -490,6 +452,7 @@ commands. | `/communication:extraction-configuration` | Downstream: configure extraction for this module's event codes | | `/cpp-style` | C++ coding conventions for firmware code | | `/project-layout` | Project directory structure for PlatformIO firmware projects | +| `/platformio-config` | PlatformIO config (platformio.ini / library.json) conventions for the firmware project | --- diff --git a/plugins/microcontroller/skills/firmware-module/references/api-reference.md b/plugins/microcontroller/skills/firmware-module/references/api-reference.md index fc004b6..f291536 100644 --- a/plugins/microcontroller/skills/firmware-module/references/api-reference.md +++ b/plugins/microcontroller/skills/firmware-module/references/api-reference.md @@ -389,3 +389,40 @@ void CheckSensor() ``` This reduces serial bandwidth and log archive size without losing transition information. + +--- + +## Template parameter guidelines + +| Type | Use Case | Example | +|------------|-----------------------------------|--------------------------------| +| `uint8_t` | Pin numbers, counts | `kPin`, `kEncoderPinA` | +| `bool` | Hardware polarity, default states | `kNormallyClosed`, `kStartOff` | +| `uint16_t` | Larger constants (calibration) | `kDefaultThreshold` | + +Use `255` as a sentinel for optional pins: + +```cpp +template +// In implementation: +if constexpr (kTonePin != 255) { pinMode(kTonePin, OUTPUT); } +``` + +--- + +## Static assertions + +Place static assertions at the **top of the class body**, before `public:`: + +```cpp +template +class EncoderModule final : public Module +{ + static_assert(kPinA != kPinB, "Channel A and Channel B pins cannot be the same."); + static_assert(kPinA != LED_BUILTIN, "Select a different Channel A pin."); + static_assert(kPinB != LED_BUILTIN, "Select a different Channel B pin."); + + public: + // ... +}; +``` diff --git a/plugins/video/.claude-plugin/plugin.json b/plugins/video/.claude-plugin/plugin.json index 627551c..8127b3f 100644 --- a/plugins/video/.claude-plugin/plugin.json +++ b/plugins/video/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "video", - "version": "1.2.0", + "version": "1.2.1", "description": "Provides camera acquisition, video recording, log processing, and pipeline orchestration skills for ataraxis-video-system. Includes MCP bindings for interactive camera discovery, testing, and session management.", "repository": "https://github.com/Sun-Lab-NBB/ataraxis", "license": "Apache-2.0", diff --git a/plugins/video/skills/log-input-format/SKILL.md b/plugins/video/skills/log-input-format/SKILL.md index 7cb9d1f..86bac6f 100644 --- a/plugins/video/skills/log-input-format/SKILL.md +++ b/plugins/video/skills/log-input-format/SKILL.md @@ -106,7 +106,7 @@ corresponding video files by camera name. ### What source IDs represent -A source ID is a `np.uint8` value (0–255) that identifies the hardware system that produced log data. +A source ID is a `np.uint8` value (1-255) that identifies the hardware system that produced log data. In ataraxis-video-system, each `VideoSystem` instance has a `system_id` that becomes the `source_id` in all log entries sent to the `DataLogger`. diff --git a/plugins/video/skills/pipeline/SKILL.md b/plugins/video/skills/pipeline/SKILL.md index 345cee8..00a95b1 100644 --- a/plugins/video/skills/pipeline/SKILL.md +++ b/plugins/video/skills/pipeline/SKILL.md @@ -137,14 +137,21 @@ for MCP encoding parameter reference. ### System ID allocation +A camera's `system_id` IS its source ID at the DataLogger level: it is the value VideoSystem +registers as the `source_id`, and it names the camera's `{system_id}_log.npz` archive (see +`/log-input-format`). This skill uses "source ID" for the shared DataLogger namespace and `system_id` +for the VideoSystem constructor. + | Range | Assignment | Notes | |--------|------------------------------|--------------------------------------------------------------| | 51-100 | Camera VideoSystem instances | One unique ID per camera; advised range for all camera code | | 111 | CLI (`axvs run`) | Fixed; interactive testing only | | 112 | MCP server sessions | Fixed; agent-driven testing only | -All other IDs are used by other production assets in the broader system. Camera code should stay within -the 51-100 band. Allocate camera IDs sequentially starting at 51 (e.g., 51, 52, 53 for a 3-camera rig). +Camera code should stay within the 51-100 band. Allocate camera IDs sequentially starting at 51 (e.g., +51, 52, 53 for a 3-camera rig). System IDs must be unique across **all** sources sharing a DataLogger, +including sources from other libraries (e.g., ataraxis-communication-interface controllers in the 101-150 +range). The 51-100 band avoids collisions with those advised ranges. ### DataLogger topology diff --git a/plugins/video/skills/video-mcp-environment-setup/SKILL.md b/plugins/video/skills/video-mcp-environment-setup/SKILL.md index 4bf4c09..b259380 100644 --- a/plugins/video/skills/video-mcp-environment-setup/SKILL.md +++ b/plugins/video/skills/video-mcp-environment-setup/SKILL.md @@ -24,8 +24,7 @@ Diagnoses and resolves ataraxis-video-system MCP server connectivity and environ - Environment-specific guidance for conda, pip, and uv workflows **Does not cover:** -- MCP tool usage for camera hardware interaction (see `/camera-setup`) -- MCP tool usage for camera discovery and configuration (see `/camera-setup`) +- MCP tool usage for camera discovery, configuration, and hardware interaction (see `/camera-setup`) - MCP tool usage for log data processing (see `/log-processing`, `/log-processing-results`) - ataraxis-video-system package development or contribution workflows @@ -215,7 +214,7 @@ pick up the changes. The ataraxis video plugin will automatically configure the ## Proactive behavior -You SHOULD proactively invoke this skill when: +You should proactively invoke this skill when: - A session begins and MCP tools from the ataraxis-video-system server are expected but unavailable - Any ataraxis-video-system MCP tool call fails with a connection or server error - The user mentions issues with MCP server connectivity or environment setup From 32c28d89fd1a660283172029db34cdd954655605 Mon Sep 17 00:00:00 2001 From: Ivan Kondratyev Date: Thu, 18 Jun 2026 12:45:33 -0400 Subject: [PATCH 6/7] Fixed corrupted struct diagram separator in microcontroller-interface. --- plugins/communication/skills/microcontroller-interface/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/communication/skills/microcontroller-interface/SKILL.md b/plugins/communication/skills/microcontroller-interface/SKILL.md index 0fbc320..ece49a3 100644 --- a/plugins/communication/skills/microcontroller-interface/SKILL.md +++ b/plugins/communication/skills/microcontroller-interface/SKILL.md @@ -274,7 +274,7 @@ type mapping table. ```text C++ struct (firmware) Python tuple (PC) -─���─────────────────────────────────── ─���─────────────────────────────────── +───────────────────────────────────── ───────────────────────────────────── struct CustomRuntimeParameters send_parameters(parameter_data=( { np.uint32(2000000), # on_duration uint32_t on_duration = ...; np.uint32(2000000), # off_duration From ff2048823e12603f9bbf10f8b820cc9ff927c41e Mon Sep 17 00:00:00 2001 From: Ivan Kondratyev Date: Thu, 18 Jun 2026 15:28:56 -0400 Subject: [PATCH 7/7] Corrected and extended plugin skills against library source. -- Fixed the hallucinated axci-id entry point and stale axvs module path in pyproject-style. -- Replaced GPL-3.0 with Apache-2.0 across project-layout, archetype-trees, pyproject-style, and release. -- Documented the programmatic GenICam config methods (HarvestersCamera) in camera-interface. -- Added a post-hoc microcontroller message-loss caveat to log-processing-results and pipeline. -- Scoped build-system pinning in cpp-style to Python ranges versus PlatformIO exact pins. -- Added a PlatformIO build/upload section and an output-device note to firmware-module. -- Disambiguated the duplicate log-input-format and mcp-environment-setup skill triggers. -- Removed the stale motor-controller claim and added an active-buzzer note to the README. --- README.md | 8 +++- .../cpp-style/references/anti-patterns.md | 2 +- .../references/libraries-and-tools.md | 9 +++-- .../automation/skills/project-layout/SKILL.md | 4 +- .../references/archetype-trees.md | 10 ++--- .../references/project-metadata.md | 21 +++------- plugins/automation/skills/release/SKILL.md | 2 +- .../SKILL.md | 5 ++- .../skills/log-input-format/SKILL.md | 5 ++- .../skills/log-processing-results/SKILL.md | 13 ++++++ .../communication/skills/pipeline/SKILL.md | 2 + .../skills/firmware-module/SKILL.md | 33 +++++++++++++++ .../video/skills/camera-interface/SKILL.md | 8 +++- .../references/api-reference.md | 40 +++++++++++++++++++ .../video/skills/log-input-format/SKILL.md | 4 +- .../video-mcp-environment-setup/SKILL.md | 5 ++- 16 files changed, 132 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 61324b4..85f8664 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ Copyright: 2026, NeuroAI Lab, Cornell University. ## Features ### Hardware Discovery & Validation -- **MCP-based device enumeration**: AI agents can query connected cameras, microcontrollers, and - motor controllers through structured tool interfaces. +- **MCP-based device enumeration**: AI agents can query connected cameras and microcontrollers + through structured tool interfaces. - **Pre-session diagnostics**: Validate hardware connectivity and configuration through natural language queries. - **Real-time status checking**: Query device responsiveness, serial port status, and camera @@ -267,6 +267,10 @@ AI: Created buzzer module with pulse, toggle on, and toggle off commands. Upload the firmware and update the dependency version. ``` +The generated handler drives the pin with `digitalWrite`, which suits an **active** buzzer (pin HIGH = +sound, LOW = silent). A **passive** piezo element produces no tone from a steady HIGH and would instead +need a `tone()`/PWM-driven handler. + --- ## Adoption Roadmap diff --git a/plugins/automation/skills/cpp-style/references/anti-patterns.md b/plugins/automation/skills/cpp-style/references/anti-patterns.md index 9c43466..16d6448 100644 --- a/plugins/automation/skills/cpp-style/references/anti-patterns.md +++ b/plugins/automation/skills/cpp-style/references/anti-patterns.md @@ -179,4 +179,4 @@ Common violations in Python C++ extension (nanobind) code: | Accessing Python objects with GIL released | Only access C++ state while GIL is released | Thread safety | | `#include "nanobind/nanobind.h"` | `#include ` | Angle brackets for library headers | | Inline binding code mixed with class implementation | NB_MODULE block at end of file, after class | Separation of concerns | -| Unpinned nanobind/scikit-build-core versions | Pin exact versions in pyproject.toml build-system.requires | Reproducible builds | +| Exact-pinned nanobind/scikit-build-core in pyproject | Major-version ranges in build-system.requires (see /pyproject-style) | Python deps track major versions | diff --git a/plugins/automation/skills/cpp-style/references/libraries-and-tools.md b/plugins/automation/skills/cpp-style/references/libraries-and-tools.md index 8e6d559..3a99238 100644 --- a/plugins/automation/skills/cpp-style/references/libraries-and-tools.md +++ b/plugins/automation/skills/cpp-style/references/libraries-and-tools.md @@ -528,12 +528,15 @@ The build system section declares scikit-build-core and nanobind as build depend ```toml [build-system] -requires = ["scikit-build-core==0.11.6", "nanobind==2.9.2"] +requires = ["scikit-build-core>=0,<1", "nanobind>=2,<3"] build-backend = "scikit_build_core.build" ``` -Pin exact versions for reproducible builds. The `scikit_build_core.build` backend handles CMake -invocation automatically during `pip install`. +Constrain these Python build dependencies with major-version ranges (see `/pyproject-style`), not exact +pins — Python dependencies track major versions, so compatible minor/patch updates are adopted +automatically. Exact pinning is reserved for microcontroller/PlatformIO dependencies (see +`/platformio-config`), where stringent hardware requirements make silent minor/patch bumps undesirable. +The `scikit_build_core.build` backend handles CMake invocation automatically during `pip install`. ### `__repr__` for extension classes diff --git a/plugins/automation/skills/project-layout/SKILL.md b/plugins/automation/skills/project-layout/SKILL.md index 3e6a20b..87ef52a 100644 --- a/plugins/automation/skills/project-layout/SKILL.md +++ b/plugins/automation/skills/project-layout/SKILL.md @@ -78,7 +78,7 @@ These files appear at the root of all (or most) projects: | File | All archetypes | Purpose | |--------------|----------------|---------------------------------------------------| -| `LICENSE` | Yes | GPL-3.0 license | +| `LICENSE` | Yes | Apache-2.0 license | | `README.md` | Yes | Project documentation (see `/readme-style`) | | `.gitignore` | Yes | Git ignore patterns | | `CLAUDE.md` | Yes | Claude Code project instructions | @@ -301,7 +301,7 @@ Archetype Identification: - [ ] Reference tree loaded from archetype-trees.md Common Root Files: -- [ ] LICENSE present (GPL-3.0) +- [ ] LICENSE present (Apache-2.0) - [ ] README.md present - [ ] .gitignore present - [ ] CLAUDE.md present diff --git a/plugins/automation/skills/project-layout/references/archetype-trees.md b/plugins/automation/skills/project-layout/references/archetype-trees.md index 9d111de..91928ef 100644 --- a/plugins/automation/skills/project-layout/references/archetype-trees.md +++ b/plugins/automation/skills/project-layout/references/archetype-trees.md @@ -45,7 +45,7 @@ project-root/ │ └── module_test.py # Test files use _test.py suffix ├── .gitignore ├── CLAUDE.md # Claude Code project instructions -├── LICENSE # GPL-3.0 license +├── LICENSE # Apache-2.0 license ├── pyproject.toml # Build config, metadata, tool settings ├── README.md # Project documentation └── tox.ini # Automation orchestration (lint, type, test, docs) @@ -119,7 +119,7 @@ project-root/ ├── CLAUDE.md # Claude Code project instructions ├── CMakeLists.txt # CMake build config for nanobind extension ├── Doxyfile # Doxygen documentation configuration -├── LICENSE # GPL-3.0 license +├── LICENSE # Apache-2.0 license ├── pyproject.toml # scikit-build-core backend + metadata ├── README.md # Project documentation └── tox.ini # Automation orchestration @@ -166,7 +166,7 @@ project-root/ ├── CLAUDE.md # Claude Code project instructions ├── Doxyfile # Doxygen documentation configuration ├── library.json # PlatformIO library manifest -├── LICENSE # GPL-3.0 license +├── LICENSE # Apache-2.0 license ├── platformio.ini # PlatformIO build configuration ├── README.md # Project documentation └── tox.ini # Documentation build automation @@ -209,7 +209,7 @@ project-root/ ├── .gitignore ├── CLAUDE.md # Claude Code project instructions ├── Doxyfile # Doxygen documentation configuration -├── LICENSE # GPL-3.0 license +├── LICENSE # Apache-2.0 license ├── platformio.ini # PlatformIO build configuration ├── README.md # Project documentation └── tox.ini # Documentation build automation @@ -261,7 +261,7 @@ project-root/ ├── .editorconfig # Editor configuration (indentation, encoding) ├── .gitignore ├── CLAUDE.md # Claude Code project instructions -├── LICENSE # GPL-3.0 license +├── LICENSE # Apache-2.0 license ├── README.md # Project documentation └── *.slnx # Unity solution file ``` diff --git a/plugins/automation/skills/pyproject-style/references/project-metadata.md b/plugins/automation/skills/pyproject-style/references/project-metadata.md index c8faad2..ebca719 100644 --- a/plugins/automation/skills/pyproject-style/references/project-metadata.md +++ b/plugins/automation/skills/pyproject-style/references/project-metadata.md @@ -65,17 +65,8 @@ readme = "README.md" Uses an SPDX license expression string. The `license-files` field specifies the license file: ```toml -# GPL (most projects) -license = "GPL-3.0-or-later" -license-files = ["LICENSE"] - -# Apache (ataraxis-automation) license = "Apache-2.0" license-files = ["LICENSE"] - -# BSD -license = "BSD-3-Clause" -license-files = ["LICENSE"] ``` Do NOT use the deprecated table format (`license = { file = "LICENSE" }`). When using SPDX @@ -363,15 +354,15 @@ command-name = "package_name.module:function" - Use short, memorable command names - Use hyphens for multi-word commands -- Prefix with project abbreviation for namespacing (e.g., `axci-id`, `axvs`) +- Prefix with project abbreviation for namespacing (e.g., `axci`, `axvs`) ### Examples from projects -| Project | Command | Entry point | -|----------------------------------|------------------|----------------------------------------------------| -| ataraxis-automation | `automation-cli` | `ataraxis_automation.cli:cli` | -| ataraxis-video-system | `axvs` | `ataraxis_video_system.cli:axvs_cli` | -| ataraxis-communication-interface | `axci-id` | `...microcontroller_interface:identify_interfaces` | +| Project | Command | Entry point | +|----------------------------------|------------------|------------------------------------------------------------| +| ataraxis-automation | `automation-cli` | `ataraxis_automation.cli:cli` | +| ataraxis-video-system | `axvs` | `ataraxis_video_system.interfaces.cli:axvs_cli` | +| ataraxis-communication-interface | `axci` | `ataraxis_communication_interface.interfaces.cli:axci_cli` | For Click-based CLIs, point to the Click group or command object directly. diff --git a/plugins/automation/skills/release/SKILL.md b/plugins/automation/skills/release/SKILL.md index 9d78c23..230e99e 100644 --- a/plugins/automation/skills/release/SKILL.md +++ b/plugins/automation/skills/release/SKILL.md @@ -123,7 +123,7 @@ GitHub release manually. **Major Changes:** -1. Re-licensed the library to Apache 2.0 from GPL 3. +1. Re-licensed the library to Apache 2.0. 2. Added MCP assets and a companion plugin that enables AI agent interfacing with all library components. 3. Added a log processing (data extraction) pipeline. ``` diff --git a/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md b/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md index c1e54d6..9cd4fcc 100644 --- a/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md +++ b/plugins/communication/skills/communication-mcp-environment-setup/SKILL.md @@ -3,8 +3,9 @@ name: communication-mcp-environment-setup description: >- Diagnoses and resolves ataraxis-communication-interface MCP server connectivity issues. Covers environment verification, command availability, Python version checks, dependency validation, and conda/pip/uv - environment configuration. Use when MCP tools are unavailable, when the server fails to start, - when the user reports connection issues, or when starting a session that requires MCP tools. + environment configuration. Use when the axci (communication-interface) MCP tools are unavailable, when the + axci server fails to start, when the user reports communication-interface connection issues, or when + starting a session that requires the axci MCP tools. user-invocable: false --- diff --git a/plugins/communication/skills/log-input-format/SKILL.md b/plugins/communication/skills/log-input-format/SKILL.md index 7376778..03b1360 100644 --- a/plugins/communication/skills/log-input-format/SKILL.md +++ b/plugins/communication/skills/log-input-format/SKILL.md @@ -3,8 +3,9 @@ name: log-input-format description: >- Documents the input data format required by the log processing pipeline: NPZ log archives produced by DataLogger, source ID semantics, microcontroller manifest system, archive internal message layout, and - communication protocol. Use when the user asks about log archive format, source IDs, DataLogger output, - or why processing fails due to missing or malformed archives. + communication protocol. Use when the user asks about microcontroller (serial) log archive format, source + IDs, the manifest system, DataLogger output, or why microcontroller log processing fails due to missing or + malformed archives. user-invocable: false --- diff --git a/plugins/communication/skills/log-processing-results/SKILL.md b/plugins/communication/skills/log-processing-results/SKILL.md index a7841cf..3aa098c 100644 --- a/plugins/communication/skills/log-processing-results/SKILL.md +++ b/plugins/communication/skills/log-processing-results/SKILL.md @@ -210,6 +210,19 @@ The `microcontroller_processing_tracker.yaml` file tracks job lifecycle per outp contention, buffering, or competing processes - **Very long gaps** (`max_us` >> `mean_us`) suggest intermittent communication interruptions +### Message loss is not measurable post-hoc + +Per-message loss **cannot** be computed from extracted archives. The serial wire format carries no sequence +or counter field, so there is no expected-vs-received count, and extraction keeps only the configured event +codes — so a sparse `event_distribution` reflects the config, not dropped data. Do **not** report inter-event +gaps (a large `max_us`) as "lost messages": a long gap is a timing observation, not a quantified loss. + +The only after-the-fact signal of a communication interruption is the Kernel keepalive-timeout status event +(`kKeepAliveTimeout`, kernel status code 10), emitted when the Kernel stops receiving keepalive messages from +the PC — and it appears in the kernel feather **only if that kernel event code was included in the extraction +config**. If a run needs guaranteed-delivery accounting, that guarantee comes from the transport layer's +runtime CRC/COBS verification during acquisition, not from post-hoc log analysis. + ### Data payload reconstruction For rows where `dtype` and `data` are non-null, the original data value can be reconstructed: diff --git a/plugins/communication/skills/pipeline/SKILL.md b/plugins/communication/skills/pipeline/SKILL.md index ecb3965..80b2ccd 100644 --- a/plugins/communication/skills/pipeline/SKILL.md +++ b/plugins/communication/skills/pipeline/SKILL.md @@ -87,6 +87,8 @@ Setup → Discovery → Config → → Processing - **Skill:** `/log-processing-results` - **Actions:** Verify output, analyze event distributions, interpret timing statistics +- **Caveat:** Per-message loss is not measurable post-hoc (the wire format has no sequence field); never + report inter-event gaps as lost messages. See `/log-processing-results`. --- diff --git a/plugins/microcontroller/skills/firmware-module/SKILL.md b/plugins/microcontroller/skills/firmware-module/SKILL.md index 063d92b..fa01721 100644 --- a/plugins/microcontroller/skills/firmware-module/SKILL.md +++ b/plugins/microcontroller/skills/firmware-module/SKILL.md @@ -336,6 +336,11 @@ the multi-stage non-blocking-delay / sensor-polling patterns to avoid flooding t recurrence interval via `send_command(repetition_delay=...)` — see `communication:microcontroller-interface`. +**Output-device note:** handlers that drive a pin with `digitalWrite(HIGH/LOW)` control level-driven +(active) devices — an active buzzer sounds at HIGH and is silent at LOW, a valve or LED switches on/off. +A device that needs a generated waveform (a **passive** piezo, a servo) needs a `tone()` / `analogWrite` +(PWM) handler instead; `digitalWrite` alone leaves it silent or unmoving. + --- ## Sending data to PC @@ -435,6 +440,34 @@ void loop() --- +## Build and upload + +Build, upload, and monitor the firmware with PlatformIO. The board environment(s) are defined in +`platformio.ini` (see `/platformio-config`). + +```bash +# Build only (compile, no upload) +pio run + +# Build and upload to the board (uses the default environment) +pio run --target upload + +# Target a specific board environment (e.g. teensy41) when platformio.ini defines several +pio run --environment teensy41 --target upload + +# List the environments defined in platformio.ini +pio project config + +# Open the serial monitor after upload (match the Serial.begin() baudrate) +pio device monitor --baud 115200 +``` + +After uploading, the controller runs the deterministic `RuntimeCycle()` loop and is ready for the PC-side +`MicroControllerInterface` to connect (see `/microcontroller-interface`). Re-upload whenever the firmware +module, its command/event codes, or its parameter struct change. + +--- + ## Implementation hints See [references/api-reference.md](references/api-reference.md) for template parameter type guidelines, diff --git a/plugins/video/skills/camera-interface/SKILL.md b/plugins/video/skills/camera-interface/SKILL.md index 9c20432..6ab935c 100644 --- a/plugins/video/skills/camera-interface/SKILL.md +++ b/plugins/video/skills/camera-interface/SKILL.md @@ -64,7 +64,8 @@ See [references/api-reference.md](references/api-reference.md) for the complete - Properties (video_file_path, started, system_id) - All enumerations (CameraInterfaces, VideoEncoders, EncoderSpeedPresets, OutputPixelFormats, InputPixelFormats) - Discovery functions (discover_camera_ids, check_cti_file, add_cti_file) -- GenICam configuration classes (GenicamNodeInfo, GenicamConfiguration) +- GenICam configuration classes (GenicamNodeInfo, GenicamConfiguration) and the programmatic config methods + (set_node_value, get_configuration, apply_configuration) that back the `/camera-setup` tools - Utility functions (check_ffmpeg_availability, check_gpu_availability, extract_logged_camera_timestamps) --- @@ -100,7 +101,10 @@ Key constructor notes: - `frame_width`, `frame_height`, `frame_rate` default to `None` (use camera native settings). For Harvesters cameras, set resolution and frame rate via GenICam configuration (see `/camera-setup`) rather than overriding through these parameters. The VideoSystem overrides are primarily intended - for OpenCV cameras that lack GenICam node control. + for OpenCV cameras that lack GenICam node control. Exposure, gain, and other GenICam nodes are applied at + configuration time via the `/camera-setup` tools or, in code, via the `HarvestersCamera` config methods + (`set_node_value`, `get_configuration`, `apply_configuration`); see the API reference. The deterministic + acquisition script does not reconfigure nodes at runtime. - `display_frame_rate` defaults to `None` (preview disabled). Set to a positive integer FPS not exceeding the camera's acquisition frame rate to enable, else `__init__` raises `TypeError`. Frame display is unsupported on macOS: it is auto-disabled (a warning is emitted), so the value has no effect there. diff --git a/plugins/video/skills/camera-interface/references/api-reference.md b/plugins/video/skills/camera-interface/references/api-reference.md index 3ab88fc..495c570 100644 --- a/plugins/video/skills/camera-interface/references/api-reference.md +++ b/plugins/video/skills/camera-interface/references/api-reference.md @@ -242,6 +242,46 @@ config.to_yaml(file_path=Path("camera_config.yaml")) config = GenicamConfiguration.from_yaml(file_path=Path("camera_config.yaml")) ``` +### Programmatic GenICam configuration + +GenICam state is applied in code through the `HarvestersCamera` interface — the same operations the +`/camera-setup` MCP tools (`read_genicam_node_tool`, `write_genicam_node_tool`, `dump_genicam_config_tool`, +`load_genicam_config_tool`) perform. Two supply modes are supported: + +```python +# Per-parameter targeting: write a single ReadWrite node (value is coerced to the node's native type) +camera.set_node_value(name="ExposureTime", value="4000") +camera.set_node_value(name="Gain", value="2.0") +info = camera.get_node_info(name="AcquisitionFrameRate") # -> GenicamNodeInfo(name, value) + +# Full-config restoration: dump every ReadWrite node, persist to YAML, re-apply later +config = camera.get_configuration() # -> GenicamConfiguration +config.to_yaml(file_path=Path("camera_config.yaml")) +camera.apply_configuration(config=config, strict_identity=False) # strict_identity/blacklisted_nodes are keyword-only +``` + +`HarvestersCamera` config method signatures: + +```python +def get_node_info(self, name: str) -> GenicamNodeInfo: ... +def get_node_description(self, name: str) -> str: ... +def set_node_value(self, name: str, value: str) -> None: ... +def get_configuration(self, blacklisted_nodes: frozenset[str] = DEFAULT_BLACKLISTED_NODES) -> GenicamConfiguration: ... +def apply_configuration(self, config: GenicamConfiguration, *, strict_identity: bool = False, + blacklisted_nodes: frozenset[str] = DEFAULT_BLACKLISTED_NODES) -> None: ... +``` + +`strict_identity=False` warns (rather than aborts) on a camera model/serial mismatch. The default +`blacklisted_nodes` (`{CustomerIDKey, CustomerValueKey, TestPattern}`) skips vendor nodes that report +ReadWrite access but reject writes. A connected `HarvestersCamera` is normally obtained at configuration +time via the `/camera-setup` tools (which wrap these calls); these methods exist for advanced in-process use. + +The `VideoSystem` constructor accepts **no** GenICam config object: resolution and frame rate are applied +from its `frame_width`/`frame_height`/`frame_rate` arguments at `connect()`, while exposure, gain, and other +nodes are configured through the methods above. Because the deterministic acquisition script does not +reconfigure nodes at runtime, apply GenICam state at configuration time and either persist it on the camera +(save a UserSet) or re-apply a saved `GenicamConfiguration` before starting acquisition. + ### CameraSourceData Stores identification data for a single camera source in a log manifest: diff --git a/plugins/video/skills/log-input-format/SKILL.md b/plugins/video/skills/log-input-format/SKILL.md index 86bac6f..a3cfe79 100644 --- a/plugins/video/skills/log-input-format/SKILL.md +++ b/plugins/video/skills/log-input-format/SKILL.md @@ -3,8 +3,8 @@ name: log-input-format description: >- Documents the input data format required by the log processing pipeline: NPZ log archives produced by DataLogger and assemble_log_archives, source ID semantics, multi-logger recording structures, and - archive internal layout. Use when the user asks about log archive format, source IDs, DataLogger output, - or why processing fails due to missing or malformed archives. + archive internal layout. Use when the user asks about camera (video-system) log archive format, source IDs, + DataLogger output, or why video log processing fails due to missing or malformed archives. user-invocable: false --- diff --git a/plugins/video/skills/video-mcp-environment-setup/SKILL.md b/plugins/video/skills/video-mcp-environment-setup/SKILL.md index b259380..d4745c0 100644 --- a/plugins/video/skills/video-mcp-environment-setup/SKILL.md +++ b/plugins/video/skills/video-mcp-environment-setup/SKILL.md @@ -3,8 +3,9 @@ name: video-mcp-environment-setup description: >- Diagnoses and resolves ataraxis-video-system MCP server connectivity issues. Covers environment verification, command availability, Python version checks, dependency validation, and conda/pip/uv - environment configuration. Use when MCP tools are unavailable, when the server fails to start, - when the user reports connection issues, or when starting a session that requires MCP tools. + environment configuration. Use when the axvs (video-system) MCP tools are unavailable, when the axvs server + fails to start, when the user reports video-system connection issues, or when starting a session that + requires the axvs MCP tools. user-invocable: false ---