Thank you for your interest in contributing to Open-Inspect! This document provides guidelines for contributing to the project.
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR-USERNAME/background-agents.git - Run the setup script:
bash .openinspect/setup.sh - Create a branch for your changes:
git checkout -b feature/your-feature-name
The quickest way to get a working environment:
bash .openinspect/setup.shThis handles npm dependencies, builds the shared package, configures git hooks (husky +
lint-staged), and optionally sets up a Python virtualenv for packages/modal-infra.
See docs/GETTING_STARTED.md for full deployment instructions. See docs/SETUP_GUIDE.md for local setup and day-to-day development paths. To run OpenCode itself on a checkout of this repo, see docs/OPENCODE_LOCAL.md.
For manual setup or individual steps:
# Install dependencies
npm install
# Build shared package
npm run build -w @open-inspect/shared
# Run type checking
npm run typecheck
# Run linting
npm run lint
# Run tests
npm test| Package | Description |
|---|---|
packages/control-plane |
Cloudflare Workers + Durable Objects |
packages/web |
Next.js web application |
packages/sandbox-runtime |
Shared in-sandbox agent runtime |
packages/modal-infra |
Modal sandbox infrastructure |
packages/daytona-infra |
Daytona snapshot infrastructure |
packages/shared |
Shared types and utilities |
- Run
npm run lintbefore committing - Run
npm run typecheckto ensure type safety - Follow existing code patterns in the codebase
Run heavyweight validation commands (lint, typecheck, and full test suites) sequentially on a shared
development host. Each Vitest invocation sizes its own worker pool independently; running multiple
full suites together can exhaust a test's elapsed-time budget even when its assertions are correct.
If you intentionally overlap suites, pass an explicit --maxWorkers budget to each invocation,
accounting for the other work on the host.
In DOM tests, scope queries to the relevant form section or open listbox. For example,
within(screen.getByRole("listbox")).getByRole("option", { name }) avoids scanning unrelated
options, including Radix's hidden native selects, while preserving accessibility checks. Prefer
label queries when selecting labeled inputs. Investigate slow operations before increasing test
timeouts or adding retries.
For coverage commands, the recorded baseline, and test-reduction tradeoffs, see
Coverage-Guided Test Reduction. Control-plane coverage combines the Node
and workerd suites; unit-only coverage is not the measure of retained integration coverage. The
unfiltered Coverage workflow enforces production-only TypeScript and separate Python
statement/branch floors. Repository administrators should require its Coverage check in main
rules.
Use clear, descriptive commit messages:
feat: add new featurefix: resolve issue with Xdocs: update documentationrefactor: restructure module
- Ensure all tests pass:
npm test - Ensure linting passes:
npm run lint - Ensure type checking passes:
npm run typecheck - Update documentation if needed
- Provide a clear description of your changes
SQL in the control plane must stay inside the portable subset — see
docs/PORTABLE_SQL.md. npm run lint:sql-portability checks it.
For SCM/provider changes, follow:
docs/adr/0001-single-provider-scm-boundaries.mddocs/provider-contribution-checklist.md
When reporting issues, please include:
- A clear description of the problem
- Steps to reproduce
- Expected vs actual behavior
- Environment details (OS, Node version, etc.)
If you have questions, please open a GitHub issue with the "question" label.
By contributing, you agree that your contributions will be licensed under the MIT License.