Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

Commit 09cb716

Browse files
authored
Merge pull request #642 from mangelajo/cursor-rules
Add some cursor rules to help our AI assistants
2 parents 6f78e5c + 55bcb81 commit 09cb716

4 files changed

Lines changed: 293 additions & 4 deletions

File tree

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
---
2+
description: when the user is requesting to create, improve or document a new driver
3+
alwaysApply: false
4+
---
5+
# Creating New Drivers
6+
7+
When asked to create a new driver, follow these steps:
8+
9+
## 1. Use the Driver Creation Script
10+
Always use the provided script: `./__templates__/create_driver.sh`
11+
12+
## 2. Required Information
13+
Before creating a driver, ask the user for:
14+
- **Driver Package Name**: The package name (e.g., `mydriver`, `custom-power`, `device-controller`)
15+
- Should be lowercase with hyphens for multi-word names
16+
- Examples from existing drivers: `network`, `iscsi`, `ridesx`, `opendal`, `shell`, `gpiod`, `http-power`, `tasmota`, `tftp`, `uboot`, `snmp`, `sdwire`, `probe-rs`, `can`, `composite`, `corellium`, `dutlink`, `energenie`, `flashers`, `http`, `power`, `pyserial`, `qemu`, `ustreamer`, `yepkit`
17+
- **Driver Class Name**: The main driver class in CamelCase (e.g., `MyDriver`, `CustomPower`, `DeviceController`)
18+
- Should be descriptive and end with appropriate suffix based on functionality
19+
- Examples: `TcpNetwork`, `ISCSI`, `RideSXDriver`, `Opendal`, `Shell`, `HttpPower`, `TasmotaPower`, `Tftp`, `UbootConsole`, `SNMPServer`, `SDWire`, `ProbeRs`, `Can`, `Composite`, `Corellium`, `Dutlink`, `EnerGenie`, `QemuFlasher`, `UStreamer`, `Ykush`
20+
- **Author Name**: Full name of the author
21+
- **Author Email**: Email address of the author
22+
23+
## 3. Command Format
24+
```bash
25+
./__templates__/create_driver.sh <driver_package> <DriverClass> "<Author Name>" "<author@email.com>"
26+
```
27+
Always try to obtain the Author Name and Email from git, by checking the git configuration.
28+
## 4. Examples
29+
```bash
30+
# Network driver
31+
./__templates__/create_driver.sh network TcpNetwork "John Doe" "john@example.com"
32+
33+
# Power management driver
34+
./__templates__/create_driver.sh custom-power CustomPowerDriver "Jane Smith" "jane@example.com"
35+
36+
# Device control driver
37+
./__templates__/create_driver.sh device-controller DeviceController "Bob Wilson" "bob@example.com"
38+
```
39+
40+
## 5. After Creation
41+
Once the driver is created:
42+
1. Navigate to the new driver directory: `packages/jumpstarter-driver-<driver_package>/`
43+
2. Review the generated files and customize as needed
44+
3. Implement the driver logic in `driver.py`
45+
4. Add tests in `driver_test.py`
46+
5. Update the README.md with specific documentation
47+
6. Test the driver: `make pkg-test-<driver_package>`
48+
49+
## 6. Driver Naming Conventions
50+
- **Package names**: lowercase with hyphens (e.g., `my-driver`)
51+
- **Class names**: CamelCase with descriptive suffixes:
52+
- Power drivers: `*Power` (e.g., `TasmotaPower`, `HttpPower`)
53+
- Network drivers: `*Network` (e.g., `TcpNetwork`, `UdpNetwork`)
54+
- Flasher drivers: `*Flasher` (e.g., `QemuFlasher`)
55+
- Console drivers: `*Console` (e.g., `UbootConsole`)
56+
- Server drivers: `*Server` (e.g., `HttpServer`, `SNMPServer`)
57+
- Generic drivers: descriptive name (e.g., `ISCSI`, `Shell`, `Tftp`)
58+
59+
## 7. Directory Structure
60+
The script creates:
61+
```
62+
packages/jumpstarter-driver-<driver_package>/
63+
├── jumpstarter_driver_<driver_package>/
64+
│ ├── __init__.py
65+
│ ├── client.py
66+
│ ├── driver.py
67+
│ └── driver_test.py
68+
├── examples/
69+
│ └── exporter.yaml
70+
├── .gitignore
71+
├── pyproject.toml
72+
└── README.md
73+
```
74+
75+
## 8. Documentation
76+
The script automatically creates:
77+
- A README.md with basic documentation
78+
- A symlink in `docs/source/reference/package-apis/drivers/` pointing to the README
79+
- Template files for all necessary components
80+
- A good example of documentation is in `docs/source/reference/package-apis/drivers/gpiod.md` and also `docs/source/reference/package-apis/drivers/pyserial.md`
81+
82+
## Code Style and Testing
83+
84+
- Follow existing code style (validate with `make lint`, fix with `make lint-fix`)
85+
- Perform static type checking with `make ty-pkg-${package_name}`
86+
- Add comprehensive tests and update documentation
87+
- Verify all tests pass (`make test-pkg-${package_name}` or `make test`)
88+
89+
## Contributing Guidelines
90+
91+
- Focus on a single issue per driver
92+
- Use clear, descriptive commit messages
93+
- Reference issue numbers when applicable
94+
- Follow conventional commit format when possible
95+
- Ensure all tests pass before submitting PRs
96+
97+
# Driver client CLIs
98+
99+
Some drivers implement known classes that provide a CLI interface for the driver, but other
100+
clients implement their own CLI interface that will appear in the `j` command inside a `jmp shell`.
101+
102+
Good examples can be found in `packages/jumpstarter-driver-shell/jumpstarter_driver_shell/client.py`, `packages/jumpstarter-driver-pyserial/jumpstarter_driver_pyserial/client.py` or `packages/jumpstarter-driver-probe-rs/jumpstarter_driver_probe_rs/client.py`.
103+
104+
# Composite drivers
105+
106+
Drives which have children drivers should be composite drivers, and the client interface should
107+
inherit from `CompositeClient` in jumpstarter_driver_composite.client, also the pyproject.toml should
108+
have a dependency on `jumpstarter-driver-composite`.
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
---
2+
alwaysApply: true
3+
---
4+
5+
# Project Structure
6+
7+
This project follows a monorepo structure with a top-level `pyproject.toml` that manages all packages using UV workspace.
8+
9+
## Top-Level Structure
10+
11+
```
12+
jumpstarter/
13+
├── pyproject.toml # Main workspace configuration
14+
├── packages/ # All Python packages
15+
├── examples/ # Example applications
16+
├── docs/ # Documentation
17+
├── __templates__/ # Templates for creating new drivers
18+
└── .cursor/ # Cursor AI rules
19+
```
20+
21+
## Workspace Configuration
22+
23+
The project uses **UV workspace** for dependency management:
24+
25+
- **Top-level `pyproject.toml`**: Defines the workspace and includes all packages
26+
- **Workspace members**: All packages in `packages/*` and `examples/*` are included
27+
- **Dependency groups**: Shared development dependencies (docs, dev)
28+
- **Tool configuration**: Ruff, typos, coverage, pytest settings
29+
30+
## Package Structure
31+
32+
### Core Packages
33+
34+
- **`jumpstarter/`**: Main library with client, config, and common functionality
35+
- **`jumpstarter-protocol/`**: gRPC protocol definitions (excluded from linting)
36+
- **`jumpstarter-kubernetes/`**: Kubernetes integration
37+
- **`jumpstarter-testing/`**: Testing utilities
38+
- **`jumpstarter-imagehash/`**: Image hashing utilities
39+
40+
### CLI Packages
41+
42+
- **`jumpstarter-cli/`**: Main CLI application
43+
- **`jumpstarter-cli-admin/`**: Administrative CLI commands
44+
- **`jumpstarter-cli-common/`**: Shared CLI utilities
45+
- **`jumpstarter-cli-driver/`**: Driver-specific CLI commands
46+
47+
### Driver Packages
48+
49+
All driver packages follow the pattern `jumpstarter-driver-<name>/`:
50+
51+
- **`jumpstarter-driver-network/`**: Network interface drivers (TCP, UDP, Unix, etc.)
52+
- **`jumpstarter-driver-power/`**: Power management drivers
53+
- **`jumpstarter-driver-*`**: Various hardware-specific drivers
54+
55+
### Utility Packages
56+
57+
- **`jumpstarter-all/`**: Meta-package that includes all components
58+
- **`hatch-pin-jumpstarter/`**: Custom Hatch build hook
59+
60+
## Package Structure
61+
62+
Each package follows this structure:
63+
64+
```
65+
packages/jumpstarter-driver-<name>/
66+
├── jumpstarter_driver_<name>/ # Main Python package
67+
│ ├── __init__.py
68+
│ ├── driver.py # Driver implementation
69+
│ ├── client.py # Client implementation
70+
│ └── driver_test.py # Tests
71+
├── examples/ # Example configurations
72+
│ └── exporter.yaml
73+
├── pyproject.toml # Package configuration
74+
├── README.md # Package documentation
75+
└── .gitignore
76+
```
77+
78+
## Package Configuration
79+
80+
Each package's `pyproject.toml` includes:
81+
82+
- **Project metadata**: Name, description, authors, license, please note that this repo only accepts Apache-2.0 license.
83+
- **Dependencies**: Runtime and development dependencies
84+
- **Entry points**: Driver and adapter registrations
85+
- **Build system**: Hatch with custom hooks
86+
- **Version management**: VCS-based versioning from root
87+
88+
## Examples Structure
89+
90+
```
91+
examples/
92+
├── automotive/ # Automotive testing example
93+
│ ├── jumpstarter_example_automotive/
94+
│ ├── pyproject.toml
95+
│ └── README.md
96+
└── soc-pytest/ # SoC testing example
97+
├── jumpstarter_example_soc_pytest/
98+
├── pyproject.toml
99+
└── README.md
100+
```
101+
102+
## Development Workflow
103+
104+
### Creating New Packages
105+
106+
1. **Drivers**: Use `./__templates__/create_driver.sh` (see creating-new-drivers.mdc)
107+
2. **Other packages**: Create manually following existing patterns
108+
109+
### Package Dependencies
110+
111+
- **Core packages**: Depend on `jumpstarter-protocol`
112+
- **Driver packages**: Depend on `jumpstarter` and specific hardware libraries
113+
- **CLI packages**: Depend on `jumpstarter` and `jumpstarter-cli-common`
114+
- **Examples**: Depend on relevant driver packages
115+
116+
### Testing
117+
118+
- **Package tests**: `make test-pkg-<package_name>`
119+
- **All tests**: `make test`
120+
- **Coverage**: Configured per package with HTML and XML reports
121+
122+
### Linting and Formatting
123+
124+
- **Ruff**: Code formatting and linting (excludes `jumpstarter-protocol`), `make lint` and `make lint-fix` are available.
125+
- **Typos**: Spell checking
126+
- **Pre-commit**: Automated checks
127+
128+
## Key Conventions
129+
130+
1. **Naming**: Package names use hyphens, module names use underscores
131+
2. **Entry points**: Drivers register via `jumpstarter.drivers` entry point
132+
3. **Versioning**: All packages share the same version from VCS
133+
4. **Documentation**: Each package has its own README.md, and when it's a driver we make a symlink in `docs/source/reference/package-apis/drivers/` pointing to the README.md for the driver.
134+
5. **Testing**: Comprehensive test coverage required, but always try to focus on starting a server and client to test it e2e. Mock sometimes when there is too much dependency on system tools/services/compatibility issues between MacOs/Linux.
135+
6. **Dependencies**: Minimal, focused dependencies per package
136+
137+
## Build and Distribution
138+
139+
- **Build system**: Hatch with custom `hatch-pin-jumpstarter` hook
140+
- **Version source**: VCS (Git) with root-level version management
141+
- **Distribution**: Individual packages published separately
142+
- **Workspace**: UV manages dependencies across all packages
143+
144+
## Running tests
145+
146+
When running tests you should use the `make pkg-test-<package_name>` command.
147+
148+
## Running type checking
149+
150+
When running type checking you should use the `make pkg-ty-<package_name>` command,
151+
never invoke pytest manually. Use this because it will be more reliable and
152+
install the right dependencies.
153+
154+
## Running linting
155+
156+
When running linting you should use the `make lint-fix`command.
157+
158+
## Running python manually
159+
160+
If you need to run python code manually to check if it works, you should use `uv run python3`
161+
to make sure you get the venv from uv, you may need to run `make sync` first to get all
162+
the dependencies in place.

__templates__/create_driver.sh

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ set -euxv
1111
if [ "$#" -ne 4 ]; then
1212
echo "Illegal number of parameters"
1313
echo "Usage: create_driver.sh <driver_name> <driver_class> <author_name> <author_email>"
14-
echo "Example: create_driver.sh mydriver MyDriver \"John Something\" john@somewhere.com"
14+
echo "Example: create_driver.sh my-driver MyDriver \"John Something\" john@somewhere.com"
1515
exit 1
1616
fi
1717

@@ -20,6 +20,9 @@ export DRIVER_CLASS=$2
2020
export AUTHOR_NAME=$3
2121
export AUTHOR_EMAIL=$4
2222

23+
# Convert hyphens to underscores for Python module name
24+
export DRIVER_MODULE_NAME=$(echo "${DRIVER_NAME}" | sed 's/-/_/g')
25+
2326
# MacOS has a different syntax for sed -i, we either use gsed (GNU sed) or apply the right -i syntax
2427
if command -v gsed &> /dev/null; then
2528
sed_cmd="gsed"
@@ -31,7 +34,7 @@ fi
3134

3235
# create the driver directory
3336
DRIVER_DIRECTORY=packages/jumpstarter-driver-${DRIVER_NAME}
34-
MODULE_DIRECTORY=${DRIVER_DIRECTORY}/jumpstarter_driver_${DRIVER_NAME}
37+
MODULE_DIRECTORY=${DRIVER_DIRECTORY}/jumpstarter_driver_${DRIVER_MODULE_NAME}
3538
# create the module directories
3639
mkdir -p ${MODULE_DIRECTORY}
3740
mkdir -p ${DRIVER_DIRECTORY}/examples
@@ -61,7 +64,7 @@ Example configuration:
6164
```yaml
6265
export:
6366
${DRIVER_NAME}:
64-
type: jumpstarter_driver_${DRIVER_NAME}.driver.${DRIVER_CLASS}
67+
type: jumpstarter_driver_${DRIVER_MODULE_NAME}.driver.${DRIVER_CLASS}
6568
config:
6669
# Add required config parameters here
6770
```
@@ -71,7 +74,7 @@ export:
7174
Add API documentation here.
7275
EOF
7376
# Need to expand variables after EOF to prevent early expansion
74-
$sed_cmd "s/\${DRIVER_CLASS}/${DRIVER_CLASS}/g; s/\${DRIVER_NAME}/${DRIVER_NAME}/g" "${README_FILE}"
77+
$sed_cmd "s/\${DRIVER_CLASS}/${DRIVER_CLASS}/g; s/\${DRIVER_NAME}/${DRIVER_NAME}/g; s/\${DRIVER_MODULE_NAME}/${DRIVER_MODULE_NAME}/g" "${README_FILE}"
7578
echo "README.md file content:"
7679
cat "${README_FILE}"
7780

docs/source/contributing.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,22 @@ If you have questions, reach out in our Matrix chat or open an issue on GitHub.
4949

5050
We welcome bug fixes, features, and improvements to the core codebase.
5151

52+
53+
## AI Assistants
54+
55+
This project accepts contributions from AI assistants, although you should be careful when creating code from AI assistants,
56+
and figure out if the code you are submitting could infringe any licensing, for example, reusing code from other incompatible
57+
GPL licenses, you should do your due diligence.
58+
59+
This project includes cursor rules to help Cursor AI understand our codebase and development patterns. When working with Cursor AI:
60+
61+
- **Driver Creation**: If asked to create a new driver, Cursor will guide you through the process using our `create_driver.sh` script
62+
- **Code Style**: Cursor will follow our established patterns and conventions
63+
- **Testing**: Cursor will remind you to add tests and run our test suite
64+
65+
The cursor rules are located in `.cursor/rules/` directory, with specific guidance for driver creation in `.cursor/rules/creating-new-drivers.mdc`.
66+
67+
5268
### Contributing Drivers
5369

5470
To create a new driver scaffold:

0 commit comments

Comments
 (0)