Thank you for your interest in contributing to PrismGB! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Setup
- Development Workflow
- Project Structure
- Documentation
- Commit Guidelines
- Pull Request Process
- Code Style
- Naming Conventions
- Testing
Please be respectful and constructive in all interactions. We aim to foster a welcoming environment for all contributors.
- Fork the repository
- Clone your fork locally
- Set up the development environment (see below)
- Create a feature branch from
main - Make your changes
- Submit a pull request
- Node.js v22 LTS or higher
- npm (included with Node.js)
- Git
Native modules (like usb-detection) require build tools and development libraries:
# Debian/Ubuntu
sudo apt-get install build-essential python3 libusb-1.0-0-dev libudev-dev
# Fedora
sudo dnf install gcc gcc-c++ make python3 libusb-devel systemd-devel
# Arch
sudo pacman -S base-devel python libusbbrew install libusb# Clone your fork
git clone https://github.com/YOUR_USERNAME/prismgb-app.git
cd prismgb-app
# Install dependencies
npm install
# Start development server
npm run devnpm run dev # Start Vite dev server with Electron
npm run build # Build and package for current platform
npm run lint # Check for linting errors
npm run test:coverage # Run tests with coverage report
npm run test:integration # Run integration tests
npm run test:smoke # Run smoke test against built appSee DEVELOPMENT.md for the full script list and local setup notes.
src/
├── main/ # Electron main process
├── preload/ # Context bridge APIs
├── renderer/ # Renderer process and UI
│ ├── application/ # App orchestrators and state
│ ├── assets/ # Styles, fonts, images
│ ├── features/ # Domain features (capture, devices, notes, settings, streaming, updates)
│ ├── infrastructure/ # Event bus, logging, adapters
│ ├── ui/ # Templates, components, orchestration
│ └── lib/ # Renderer-only utilities
├── shared/ # Shared utilities and config
tests/ # Unit and integration tests
docs/ # Architecture and feature docs
scripts/ # Build and tooling scripts
- Development guide:
DEVELOPMENT.md - Feature map:
docs/feature-map.md - Naming conventions:
docs/naming-conventions.md - Architecture diagrams:
docs/architecture-diagrams.md - Architecture onboarding:
docs/architecture-diagrams-onboarding.md
We use Conventional Commits for commit messages. This enables automated changelog generation and semantic versioning.
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
| Type | Description |
|---|---|
feat |
A new feature |
fix |
A bug fix |
docs |
Documentation changes |
style |
Code style changes (formatting, semicolons, etc.) |
refactor |
Code changes that neither fix bugs nor add features |
perf |
Performance improvements |
test |
Adding or updating tests |
build |
Build system or dependency changes |
ci |
CI/CD configuration changes |
chore |
Other changes that don't modify src or test files |
revert |
Reverts a previous commit |
feat(streaming): add support for custom resolutions
fix(devices): resolve USB detection on Linux
docs: update installation instructions
ci: add security scanning to PR workflowThis project uses Husky to enforce commit conventions:
- pre-commit: Runs
npm test(Vitest watch mode) - commit-msg: Validates commit message format via commitlint
If commits fail validation, check your commit message format against the guidelines above.
-
Create a feature branch from
main:git checkout -b feat/my-feature
-
Make your changes following our code style and commit guidelines
-
Run quality checks before pushing:
npm run lint npm run test:coverage npm run test:integration
-
Push your branch and open a pull request
-
Fill out the PR template with all relevant information
-
Address review feedback promptly
All PRs must pass:
- Linting (
npm run lint) - Tests with coverage (
npm run test:coverage) - Integration tests (
npm run test:integration) - Build smoke check (
npm run build:vite) - Conventional commit validation (PR title and commits)
Optional: add the full-ci label on a PR to run macOS and Windows validation.
We use ESLint for code style enforcement:
- 2-space indentation
- Single quotes for strings
- Semicolons required
- Unix line endings (LF)
- Services extend
BaseServicefor business logic - Orchestrators extend
BaseOrchestratorfor coordination - Use
EventBusfor cross-service communication - Use dependency injection via the container
See docs/naming-conventions.md for the full guide. Highlights are below.
All JavaScript files follow the pattern: {name}.{type}.js
| Suffix | Purpose |
|---|---|
.service.js |
Business logic (extends BaseService) |
.orchestrator.js |
Lifecycle coordination (extends BaseOrchestrator) |
.adapter.js |
External API wrappers |
.component.js |
UI components |
.handler.js |
IPC handlers |
.factory.js |
Instance creation |
.bridge.js |
Cross-module coordination |
.registry.js |
Collection management |
.interface.js |
Interface definitions |
.worker.js |
Web Workers |
.state.js |
State management |
.config.js |
Configuration constants |
.profile.js |
Device profiles |
.utils.js |
Pure utility functions |
.class.js |
Plain classes (no DI) |
.base.js |
Abstract base classes |
Rules:
- Use kebab-case for filenames
- Type suffix uses dot separator:
device-profile.registry.js,streaming-worker-protocol.config.js - Abstract base classes use
{type}.base.jspattern:service.base.js,orchestrator.base.js - Entry points (
index.js) and DI containers (container.js) are exceptions
import { BaseService } from '@shared/base/service.base.js';
export class MyService extends BaseService {
constructor(dependencies) {
super(dependencies, ['eventBus', 'loggerFactory', 'requiredDep'], 'MyService');
}
myMethod() {
this.logger.info('Doing something');
this.eventBus.publish('my:event', { data: 'value' });
}
}We use Vitest for testing.
npm test # Watch mode
npm run test:ui # Vitest UI
npm run test:run # Single run
npm run test:unit # Unit tests only
npm run test:integration # Integration tests only
npm run test:integration:watch # Watch integration tests
npm run test:coverage # With coverage report
npm run test:smoke # Smoke test (requires build)- Lines: 80%
- Functions: 80%
- Statements: 80%
- Branches: 75%
Tests should be placed in:
tests/unit/for unit teststests/integration/for integration tests- Or co-located with source files as
*.test.js
import { describe, it, expect, vi } from 'vitest';
import { MyService } from './MyService.js';
describe('MyService', () => {
it('should do something', () => {
const mockDeps = {
eventBus: { publish: vi.fn(), subscribe: vi.fn() },
loggerFactory: { createLogger: () => ({ info: vi.fn() }) }
};
const service = new MyService(mockDeps);
expect(service).toBeDefined();
});
});If you have questions about contributing, please open an issue for discussion.
Thank you for contributing to PrismGB!