Contributing to sqi¶
Thank you for your interest in contributing to sqi. We welcome contributions across multiple dimensions: code, preset definitions, documentation, bug reports, and design discussion.
How to Contribute¶
Code¶
We maintain a roadmap and architecture guide organized by development phases. Code contributions are welcome at all stages.
Setting up for development:
# Clone the repository
git clone https://github.com/Uberware/sqi.git
cd sqi
# Go development (server and workers)
cd cmd/sqi-server
go mod download
go build
# Python development (client SDK and DCC submitters)
cd clients/python
pip install -e .
# Web UI development (TypeScript + React)
cd web
npm install
npm run dev
Before starting work:
- Check the issues and discussions to avoid duplicating effort
- For substantial changes, open a discussion first to get feedback on the approach
- Read ROADMAP.md to understand the architecture, deployment modes, and job model
Code style and conventions:
- Go: Follow Effective Go. Run
make fmt(gofumpt + goimports) andmake lint(golangci-lint) before submitting - Python: Follow PEP 8. Use type hints for all function signatures. Format and lint with ruff:
ruff format && ruff check --fix— this handles style consistency automatically - TypeScript/React: Use ESLint and Prettier with the project configuration. Functional components and hooks preferred
- Commit messages: Be clear and specific. Reference issue numbers where relevant (e.g., "Fix scheduler race condition in Phase 1 (#42)")
Testing:
- Unit tests are required for code changes. The enforced coverage floor is 70% (
COVERAGE_MINin the Makefile); aim higher on new code - Integration tests are encouraged for complex features
- Run
make test(ormake ci) before submitting a PR — do not run barego test ./...from the repo root, sinceweb/node_modules/contains third-party Go files the Makefile filters out
Submitting a PR:
- Make your changes with clear commits
- Run tests and linting locally
- Open a pull request with a clear description of what you're doing and why
- Respond to review feedback promptly
(If you're new to open source, see GitHub's guide to forking repositories.)
Web UI contributions¶
The web UI (web/) is React + TypeScript + Vite, built into a bundle that is
embedded in the sqi-server binary. Start with web/README.md
for the layout and docs/web-development.md for the
dev-server workflow (run sqi-server, optionally a worker, then npm run dev
with its API proxy).
Before opening a PR, run the same gate CI does, from web/:
npm run format:check && npm run typecheck && npm run lint && npm run test:coverage
Storybook. The project does not ship Storybook yet. Components are developed
and reviewed through their tests and the running app rather than an isolated
component explorer. If Storybook is added later, document its npm run storybook
entry point here.
Component testing approach. Tests use Vitest with
React Testing Library in a jsdom environment.
Conventions:
- Co-locate each test next to its subject as
Name.test.tsx(or.test.ts). - Test behavior through the rendered DOM the way a user experiences it — query
by role, label, and text; drive interaction with
@testing-library/user-event; assert with@testing-library/jest-dommatchers. Avoid asserting on internal state or implementation details. - Mock at the network boundary (the
apiFetch/query layer), not at the component internals, so tests exercise real component wiring. - New components and hooks ship with tests; coverage is enforced against the
threshold in
web/vite.config.ts. See the existingDataTable.test.tsx,StatusBadge.test.tsx, and thesrc/api/src/hookstests for the patterns.
API client pattern. All server access goes through src/api/ — never call
fetch directly from a component.
src/api/client.tsexposesapiFetch<T>, which sets JSON headers, prefixes/api/v1, and throws a typedApiError({ status, title, detail, … }) on non-2xx responses. SurfaceApiError.detailto users.- Read endpoints: add the wire type to
src/api/types.ts, a raw fetch function and query key tosrc/api/queries.ts, then auseQueryhook. Write endpoints: add auseMutationhook insrc/api/mutations.tsthat invalidates the affected query keys inonSuccess. src/api/types.tsmirrors the REST wire format; keep it in sync with the OpenAPI spec atGET /api/v1/openapi.yaml(the spec is authoritative when they diverge). Live updates use the WebSocket layer insrc/ws/via theuseWebSockethook. Exported functions and types insrc/api/andsrc/ws/carry JSDoc — keep that up as you add to them.
Styling conventions.
- Use CSS Modules (
Component.module.css) co-located with each component; no global class names or inline style objects for layout. - Pull every color, spacing, radius, font, and shadow value from the design
tokens in
src/styles/tokens.css. Do not hard-code colors — new pairings must meet the contrast baseline indocs/web-accessibility.md. - Functional components and hooks only. Import with the
@/path alias, not relative../../chains. - Honor the accessibility baseline (
docs/web-accessibility.md): semantic HTML, keyboard-operable controls, and text alternatives for any color-only or icon-only indicator.
Community Preset Library¶
The community preset library is the easiest way to contribute and benefits the whole community. Presets are YAML or JSON files defining how to run a specific tool — no programming required.
Preset structure:
Presets define a product (product name, description, parameters, command mapping) for a DCC or tool. A simple example:
name: Arnold CPU Render
description: Render a scene using Arnold (CPU)
version: 1.0
software_required: [ Arnold ]
parameters:
scene_file:
type: path
required: true
description: Arnold scene file (.ass)
output_path:
type: path
required: true
description: Output directory for EXR files
samples:
type: integer
default: 100
description: Camera samples per pixel
command:
template: |
kick -r {{ params.output_path }} \
-samples {{ params.samples }} \
"{{ params.scene_file }}"
Contributing a preset:
- Test your preset locally — submit a job through
sqiand verify output - Document the preset's assumptions (required plugins, environment setup, file paths)
- Submit a PR to the sqi-presets repository with:
- A descriptive name for the preset file
- Detailed description in the YAML/JSON
- An optional README explaining any setup or quirks
- Include a rendered example (frame, output file) in the PR description if possible
Presets for major DCCs (Arnold, Blender, Houdini, Maya, Nuke, After Effects, Cinema 4D) are especially welcome. Custom tool presets are also valuable — if your studio has a proprietary pipeline tool, sharing the preset helps others.
Documentation¶
Documentation contributions help the project significantly:
- README improvements: Clearer setup instructions, getting-started guides, use case examples
- API documentation: Docstrings in code, generated API reference, Python client examples
- Architecture guides: Explaining design decisions, system interaction diagrams, deployment patterns
- Troubleshooting: Common issues, diagnostics, logs interpretation
To contribute documentation:
- Fork the repository
- Edit
.mdfiles or code docstrings directly - Submit a PR describing what you clarified and why
Bug Reports¶
Found an issue? Open a GitHub issue with:
- A clear title describing the problem
- Steps to reproduce (if applicable)
- Observed behavior vs. expected behavior
- Relevant logs or error messages
- Your environment (OS, Go version, deployment mode)
Design Discussion¶
Have ideas for a feature, architectural improvement, or design change? Open a GitHub discussion. These are less formal than issues and are a good place to explore ideas before committing to implementation.
Development Phases and Priorities¶
The ROADMAP.md document outlines development phases. Current priorities:
- Phase 1 (v0.1 — released): Core scheduler, pull-based workers, basic web UI, OpenJD execution
- Phase 2 (v0.2 — released): Product system, preset library, DCC submitters
- Phase 3 (next): Auth (LDAP, OAuth2), multi-user role model
- Phase 4 (planned): Production hardening, PostgreSQL, HA, auto-scaling
Code contributions aligned with the current phase are most likely to be accepted quickly. Contributions targeting later phases are welcome but may take longer to review if they require design discussion.
Code of Conduct¶
We are committed to providing a welcoming and inclusive environment for all contributors.
- Be respectful of different perspectives and experience levels
- Provide constructive feedback
- Assume good intent
- Report violations to robin@uberware.net
Licensing¶
sqi is dual-licensed under:
- GNU Affero General Public License v3.0 (AGPL-3.0) — Open source, self-hosted
- Commercial license — For organizations requiring it
By contributing code, you agree that your contribution will be made available under both licenses. See LICENSE for details.
If you have questions about licensing compatibility, open a discussion or contact robin@uberware.net.
Getting Help¶
- Questions about contributing? Open a discussion
- Questions about the architecture? Read ROADMAP.md
- Need a development environment tip? Ask in discussions or open an issue
- Direct contact: robin@uberware.net
Thank You¶
We appreciate all contributions, large and small. Every preset shared, bug report filed, and piece of code submitted makes sqi better for everyone.
Happy coding.