diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..a50d2e1fd --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,92 @@ +## SDRangel — Copilot instructions + +Goal: help an AI coding agent become productive quickly in the SDRangel repo by summarizing the architecture, developer workflows, project conventions and integration points with concrete file references and examples. + +- Big picture + - SDRangel is a Qt-based (Qt5/Qt6 optional) GUI and server frontend for software-defined radio devices. It processes I/Q samples from various SDR hardware, applies signal processing and demodulation/modulation plugins, and exposes a WebAPI for remote control. The interface with hardware is done via "device" plugins. The modulation/demodulation is done via "channel" plugins. Another kind of plugins provide additional features not necessarily depending on the I/Q stream(s) (e.g., rotator control, map display). SDRangel can run as a desktop GUI application or as a headless server exposing a WebAPI. + Key top-level directories: + - `app/`, `appbench/`, `appsrv/` — application entry points + - `sdrbase/` — core application framework shared by app, appsrv, appbench and plugins + - `sdrgui/` — shared GUI components used by the main app and plugins + - `sdrsrv/` — shared server components used by appsrv and plugins + - `settings/` — application settings management + - `plugins/` — channel, device and feature plugins (primary extension mechanism) + - `plugins/channelmimo/` — MIMO channel plugins for channels processing multiple synchronized streams in both transmit and receive directions + - `plugins/channelrx/` — receive channel plugins for channels processing single streams in receive direction + - `plugins/channeltx/` — transmit channel plugins for channels processing single streams in transmit direction + - `plugins/feature/` — feature plugins providing additional functionalities not directly related to I/Q stream processing + - `plugins/samplemimo/` — device plugins for SDR hardware supporting multiple synchronized streams in both transmit and receive directions + - `plugins/samplesource/` — device plugins for SDR hardware receivers (sources) with single I/Q stream + - `plugins/samplesink/` — device plugins for SDR hardware transmitters (sinks) with single I/Q stream + - `httpserver/` — HTTP server implementation for the WebAPI + - `logging/` — logging framework used by the application and plugins + - `ft8/` — FT8 modem implementation as a separate module + - `modemm17/` — M17 modem implementation as a separate module + - `qrtplib/` — QRTPLib library for RTP protocol used by some modem plugins + - `wdsp/` — signal processing library used by demod/modem plugins + - `swagger/` — OpenAPI specs and generated client/server code (used to expose and consume the WebAPI) + - `scriptsapi/` — Scripts written in Python to interact with the WebAPI + - `doc/img/` — images used in the documentation + - `doc/model/` — architecture diagrams and models +- Architecture notes (why things are organized this way) + - Plugin-first design: features, device drivers and channel implementations are implemented as plugins under `plugins/`. Inspect `plugins/*/*plugin.h` and `*worker` classes for lifecycle and messaging patterns. + - Core real-time DSP lives in `wdsp/`. Plugins call into WDSP classes (e.g. `wdsp/wcpAGC.*`, `wdsp/fmd.*`) for audio/DSP routines. + - Swagger/OpenAPI under `swagger/` drives a generated client and server API. The code generator output for Qt lives under `swagger/sdrangel/code/qt5/` and is not meant to be hand-edited. + +- Build & developer flows (concrete commands) + - Preferred build: CMake. Preconfigured presets in `CMakePresets.json`. Typical Linux flow: + - Configure: `cmake --preset default` (uses `build-default` and local cache variables) + - Build: `cmake --build --preset default` or `cmake --build build-default -j$(nproc)` + - Install (optional): `cmake --install build-default --prefix /opt/install/sdrangel` + - For Qt6 builds use preset `default-qt6` or `default-qt6-windows` for Windows. + - Notes: presets contain many cache variables pointing to external dependencies (`UHD_DIR`, `SoapySDR`, `LimeSuite`, `MBE_DIR`, etc.). When reproducing CI or a developer environment, set those to installed dependencies or use Docker (there is a separate `sdrangel-docker` project). + +- Tests & verification + - There are no central unit-test runners in the top-level; run small tests by building the relevant plugin or running example programs. Use `build/Makefile` targets produced by CMake. + +- Common conventions and patterns + - Message passing: many subsystems use `util/message.h` derived `Message` classes and `Msg*` naming (see `plugins/*/*plugin.h`). When adding a command or event, follow that pattern. + - Worker threads: long-running hardware or DSP tasks are implemented as `*worker` classes and often use Qt threads (see `plugins/*/*worker.h`). + - Generated code: files under `swagger/sdrangel/code/*` are generated by swagger-codegen; do not edit them manually. To regenerate see `swagger/sdrangel/README.md` and start the include HTTP server for includes. + +- Integration points & external deps + - Hardware/backends: plugins interface to external SDKs. Look in `CMakePresets.json` for common dependency variables (e.g., `AIRSPY_DIR`, `LIMESUITE_DIR`, `UHD_DIR`). + - Web API: OpenAPI spec lives at `swagger/sdrangel/api/swagger/swagger.yaml`. Many plugins expose a WebAPI adapter class `*webapiadapter.cpp` which uses generated SWG classes under `swagger/sdrangel/code/qt5/client/`. + - Scripts: automation and API helpers live in `scriptsapi/` (examples: `dump.py`, `config.py`). They show how to call the WebAPI. + +- Files to inspect for common tasks (examples) + - Add a new plugin: inspect existing `plugins/channelrx/wdsprx/` and `plugins/samplesource/*` for the plugin lifecycle, settings classes and `readme.md` documentation. + - Debug audio/DSP: `wdsp/` (e.g., `wcpAGC.cpp`, `fmd.*`) and plugin readmes `plugins/channelrx/wdsprx/readme.md` explain AGC behavior and parameters. + - Work with WebAPI: `swagger/sdrangel/api/swagger/swagger.yaml` + `scriptsapi/Readme.md` + `swagger/sdrangel/README.md` for generation and usage. + +- Quick examples (copyable snippets agents may use) + - Configure + build (Linux): `cmake --preset default && cmake --build --preset default -j$(nproc)` + - Regenerate swagger Qt client (developer machine with swagger-codegen): follow `swagger/sdrangel/README.md` and run `/opt/install/swagger/swagger-codegen generate -i api/swagger/swagger.yaml -l qt5cpp -c qt5cpp-config.json -o code/qt5` + +- Keep in mind + - Do not edit generated code under `swagger/.../code/` — change the OpenAPI spec or generator configuration instead. + - Respect plugin message naming and settings classes (`*settings.h/.cpp`) for backwards compatibility with saved session files. + - Many device-specific behaviors are documented in `plugins/*/*/readme.md` — use them as primary references for device behavior and configuration. + +If anything above is unclear or you need a different focus (for example: test harness, CI, or contribution guidelines), tell me which area to expand and I'll iterate. + +## Short additions: CI, Docker, Swagger tips + +- CI / reproducible builds + - There is no single top-level CI config in the repo root — check `cmake/ci/` for CI helper scripts and the `build/` or `build-default/` directories produced by CMake to inspect test/run artifacts. + - Use `cmake --preset default` on Linux; ensure the various *_DIR cache vars in `CMakePresets.json` are set to installed dependency locations or point to Docker images that provide them. + +- Docker + - The repo references `sdrangel-docker` in the README. For reproducible environments prefer using that project which pre-installs SDKs listed in presets. + +- Swagger codegen + - The OpenAPI spec is at `swagger/sdrangel/api/swagger/swagger.yaml`. Regenerate Qt client with the command (developer machine with generator installed): + - `/opt/install/swagger/swagger-codegen generate -i api/swagger/swagger.yaml -l qt5cpp -c qt5cpp-config.json -o code/qt5` + - Do not edit generated files under `swagger/sdrangel/code/*` — change the spec or generator config instead (`swagger/sdrangel/config/`). + +## Where to look next (fast open targets) +- `plugins/channelrx/wdsprx/` — canonical receive channel plugin and `readme.md` explaining many signal chain choices +- `wdsp/` — DSP implementations (AGC, filters, demodulators) referenced by many plugins +- `scriptsapi/` — example scripts showing how to call the WebAPI for automation + +Please review these additions and tell me if you want me to: (A) expand CI/Docker commands with example Dockerfile and Compose, (B) add a short checklist for contributing patches, or (C) generate quick search shortcuts for common code patterns. diff --git a/.github/instructions/cpp.instructions.md b/.github/instructions/cpp.instructions.md new file mode 100644 index 000000000..0a3bf309e --- /dev/null +++ b/.github/instructions/cpp.instructions.md @@ -0,0 +1,139 @@ +--- +applyTo: '**/*.cpp, **/*.h, **/*.hpp, **/*.cxx, **/*.cc' +--- +# Qt C++ & SDRangel App coding conventions and guidelines + +These instructions guide Copilot to generate code that aligns with modern Qt C++ standards, C++20/23 features, software engineering principles, and industry best practices to improve software quality, maintainability, and performance for the SDRangel application. + +## ✅ General C++ Coding Standards + +- Follow **Google C++ Style Guide** or **Core Guidelines** for consistent code structure +- Use **meaningful, descriptive variable, function, class, and file names** +- Apply proper Doxygen comments for classes, methods, and complex logic +- Organize code into small, reusable functions or classes with single responsibility +- Avoid magic numbers or hard-coded strings; use constants, enums, or configuration +- Use **RAII** (Resource Acquisition Is Initialization) for all resource management +- Prefer **const correctness** throughout the codebase + +## ✅ Modern C++20/23 Best Practices + +- Use **auto** for type deduction when it improves readability +- Utilize **smart pointers** (`std::unique_ptr`, `std::shared_ptr`) over raw pointers +- Apply **range-based for loops** instead of traditional iterator loops +- Use **constexpr** for compile-time constants and functions +- Leverage **structured bindings** for tuple/pair unpacking +- Use **std::optional** for optional values instead of null pointers +- Apply **concepts** for template constraints where applicable +- Use **std::span** for safe array/container views +- Utilize **std::string_view** for read-only string parameters +- Apply **designated initializers** for struct initialization +- Use **[[nodiscard]]** attribute for functions whose return values shouldn't be ignored + +## ✅ Qt Framework Standards & Conventions + +- Follow Qt's **CamelCase** naming convention for classes and **camelCase** for methods/variables +- Use Qt's **parent-child ownership model** for automatic memory management +- Apply **Q_OBJECT** macro for classes that need signals/slots or meta-object features +- Use **signals and slots** for loose coupling between components +- Prefer **Qt containers** (`QVector`, `QHash`, `QSet`) over STL containers when integrating with Qt APIs +- Use **Qt's foreach** or range-based for loops with Qt containers +- Apply **Qt's string handling** (`QString`, `QStringView`) for Unicode support +- Use **QPointer** for safe weak references to QObjects + +## ✅ Project Structure & File Organization + +- Header files should: + - Use include guards + - Forward declare classes when possible + - Separate public, protected, and private sections clearly +- Source files should: + - Include corresponding header files first + - Group includes: standard library, Qt headers, project headers +- Organize classes into namespaces when necessary to avoid name collisions +- Maintain a clear separation between interface (header) and implementation (source) files + +## ✅ Qt-Specific Patterns for SDRangel + +- **Main Application Structure**: + + - Implement proper application lifecycle management + - Use `QSettings` for persistent configuration storage + +- **Data Collection & Monitoring**: + + - Use `QTimer` for periodic data collection + - Apply `QThread` or `QRunnable` for background processing + - Use `QMutex` or `QReadWriteLock` for thread synchronization + - Implement `QFileSystemWatcher` for file monitoring + +- **UI Components**: + + - Use `QMainWindow` as the primary window class + - Apply `QWidget` customization for specialized displays + - Use `QCharts` for data visualization + - Implement `QSystemTrayIcon` for background operation + - Use `QDialog` for settings and configuration windows + +- **Networking & API Integration**: + - Use `QNetworkAccessManager` for HTTP requests + - Apply `QNetworkReply` for handling responses + - Use `QJsonDocument` and `QJsonObject` for JSON parsing + - Implement proper SSL/TLS handling with `QSslConfiguration` + +## ✅ Performance & Memory Management + +- Use **Qt's object ownership** system to prevent memory leaks +- Apply **lazy initialization** for expensive resources +- Use **QObject::deleteLater()** for safe object deletion +- Implement **efficient string operations** with `QStringBuilder` +- Use **QCache** for frequently accessed data +- Apply **QPixmapCache** for image caching +- Optimize **paint events** with proper clipping and caching + +## ✅ Cross-Platform Development + +- Use **Qt's platform abstraction** instead of platform-specific code +- Apply **conditional compilation** sparingly with `Q_OS_*` macros +- Use **QStandardPaths** for platform-appropriate file locations +- Implement **platform-specific features** through Qt's platform plugins +- Apply **High DPI scaling** support with `Qt::AA_EnableHighDpiScaling` + +## ✅ Modern Qt Features to Leverage + +- Use **Qt Quick** for modern, fluid UIs where appropriate +- Apply **Qt Concurrent** for parallel processing +- Use **Qt State Machine** for complex state management +- Apply **Qt's logging framework** with categories +- Use **Qt's property system** for dynamic behavior +- Apply **Qt's animation framework** for smooth transitions + +## ✅ Code Quality & Maintainability + +- Follow **SOLID Principles** adapted for Qt: + + - Single Responsibility: Each class has one clear purpose + - Open/Closed: Use Qt's plugin system for extensions + - Liskov Substitution: Proper inheritance hierarchies + - Interface Segregation: Use Qt's abstract base classes + - Dependency Inversion: Use Qt's dependency injection patterns + +- Apply **Qt's Model-View patterns** for data presentation +- Use **Qt's undo framework** for user actions +- Implement **proper error handling** with Qt's exception safety +- Apply **const correctness** especially with Qt's implicit sharing + +## ✅ Additional Copilot Behavior Preferences + +- Generate **const-correct**, modern C++ code using Qt idioms +- Prioritize **readable, maintainable** code over premature optimization +- Avoid deprecated Qt APIs; use modern alternatives +- Suggest proper class placement based on Qt application structure +- Default to **Qt's memory management** and **RAII** patterns +- Include **thread safety considerations** for multi-threaded operations +- Consider **platform differences** when suggesting system-level code +- Provide **Doxygen-style documentation** for complex functions +- Suggest **unit tests** alongside new features where applicable +- Use **Qt's internationalization** support for user-facing strings +- Be direct and concise in code comments; avoid unnecessary verbosity +- Avoid starting responses with "Sure!", "You're right!" or similar phrases; be direct and concise. +- When writing text that'll be visible to users, use **clear, professional language** without unnecessary exclamations or informalities. Also use Sentence case for titles and headings. diff --git a/.github/instructions/python.instructions.md b/.github/instructions/python.instructions.md new file mode 100644 index 000000000..eda822c08 --- /dev/null +++ b/.github/instructions/python.instructions.md @@ -0,0 +1,56 @@ +--- +description: 'Python coding conventions and guidelines' +applyTo: '**/*.py' +--- + +# Python Coding Conventions + +## Python Instructions + +- Write clear and concise comments for each function. +- Ensure functions have descriptive names and include type hints. +- Provide docstrings following PEP 257 conventions. +- Use the `typing` module for type annotations (e.g., `List[str]`, `Dict[str, int]`). +- Break down complex functions into smaller, more manageable functions. + +## General Instructions + +- Always prioritize readability and clarity. +- For algorithm-related code, include explanations of the approach used. +- Write code with good maintainability practices, including comments on why certain design decisions were made. +- Handle edge cases and write clear exception handling. +- For libraries or external dependencies, mention their usage and purpose in comments. +- Use consistent naming conventions and follow language-specific best practices. +- Write concise, efficient, and idiomatic code that is also easily understandable. + +## Code Style and Formatting + +- Follow the **PEP 8** style guide for Python. +- Maintain proper indentation (use 4 spaces for each level of indentation). +- Ensure lines do not exceed 140 characters. +- Place function and class docstrings immediately after the `def` or `class` keyword. +- Use blank lines to separate functions, classes, and code blocks where appropriate. + +## Edge Cases and Testing + +- Always include test cases for critical paths of the application. +- Account for common edge cases like empty inputs, invalid data types, and large datasets. +- Include comments for edge cases and the expected behavior in those cases. +- Write unit tests for functions and document them with docstrings explaining the test cases. + +## Example of Proper Documentation + +```python +def calculate_area(radius: float) -> float: + """ + Calculate the area of a circle given the radius. + + Parameters: + radius (float): The radius of the circle. + + Returns: + float: The area of the circle, calculated as π * radius^2. + """ + import math + return math.pi * radius ** 2 +```