Code of Conduct
This project follows the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.Getting Started
- Fork the repository on GitHub
- Clone your fork:
- Create a branch for your change:
- Make your changes (see Development Setup)
- Write or update tests (see Testing Guide)
- Add a changeset (see Changesets below)
- Open a pull request against
main
Development Workflow
1. Branch Naming
Use descriptive branch names:feature/add-token-usage-export— New featurefix/dashboard-crash-on-empty-data— Bug fixrefactor/simplify-routing-logic— Refactoringdocs/improve-setup-guide— Documentationchore/update-dependencies— Maintenance
2. Make Changes
Follow the project structure and conventions:- Backend: NestJS services, controllers, entities, guards
- Frontend: SolidJS components, pages, services
- Plugin: TypeScript modules with zero runtime dependencies
3. Write Tests
- Backend unit tests:
*.spec.tsnext to source files - Backend E2E tests:
packages/backend/test/*.e2e-spec.ts - Frontend tests:
*.test.tsxusing Vitest - Plugin tests:
*.spec.tsusing Jest
4. Add a Changeset
Run the changeset CLI:- Select packages: Choose the packages your change affects
- Select bump type:
patch(bug fix),minor(new feature), ormajor(breaking change) - Write summary: Describe the change in 1-2 sentences
.changeset/ — commit it with your code.
Which Packages Need Changesets?
| Package | npm name | Needs changeset? |
|---|---|---|
packages/openclaw-plugin | manifest | Yes (published to npm) |
packages/backend | — | No (private, but requires manifest changeset) |
packages/frontend | — | No (private, but requires manifest changeset) |
Backend or frontend changes always need a
manifest changeset. These packages compile into the manifest plugin, so any change to packages/backend/ or packages/frontend/ must include a changeset bumping manifest. CI enforces this.Empty Changesets
If your change doesn’t affect any publishable package (e.g., CI config, docs, tooling):5. Verify the Build
Before opening a PR, ensure the production build works:Code Standards
TypeScript
- Strict mode: Enabled across all packages
- Type safety: Avoid
any— use proper types orunknown - Null safety: Use optional chaining (
?.) and nullish coalescing (??)
Formatting
- Prettier: Automatic formatting via
npm run format - ESLint: Linting via
npm run lint
Naming Conventions
- Files:
kebab-case.ts(e.g.,user-cache.interceptor.ts) - Classes:
PascalCase(e.g.,UserCacheInterceptor) - Functions:
camelCase(e.g.,getUserSession) - Constants:
UPPER_SNAKE_CASE(e.g.,API_KEY_PREFIX) - Interfaces:
PascalCase(noIprefix — e.g.,CreateAgentDto, notICreateAgentDto)
Commit Messages
Write clear, concise commit messages:- Use present tense (“Add feature” not “Added feature”)
- Explain why the change was made, not just what changed
- Reference issues when applicable (e.g., “Fix dashboard crash (#123)”)
Add token cost breakdown to overview pageFix race condition in OTLP ingestion pipelineRefactor routing logic to use QueryBuilder API
Update filesFix bugWIP
Backend Standards
Services
- Use dependency injection via constructor
- Inject repositories using
@InjectRepository(Entity) - Use TypeORM QueryBuilder instead of raw SQL
- Apply multi-tenancy via
addTenantFilter(qb, userId)
Controllers
- Use DTOs for request validation
- Use @CurrentUser() decorator for user context
- Mark public routes with @Public()
- Return appropriate HTTP status codes
DTOs
- Use class-validator decorators
- Use class-transformer for type coercion
- Validate all inputs
Frontend Standards
Components
- Use SolidJS functional components
- Use signals for reactive state
- Use createResource for async data fetching
- Keep components small and focused
Styling
- Use custom CSS (no CSS-in-JS)
- Follow existing naming conventions (BEM-like)
- Avoid inline styles
Pull Request Process
Before Opening a PR
-
Run tests locally:
-
Run linter:
-
Verify build:
-
Ensure changeset is added:
PR Template
Include the following in your PR description:- Summary: What does this PR do?
- Motivation: Why is this change needed?
- Changes: List key changes (bullet points)
- Testing: How did you test this?
- Breaking changes: Any breaking changes? (if yes, explain migration path)
- Related issues: Link to related issues (e.g., “Fixes #123”)
PR Guidelines
- Keep PRs focused: One concern per PR
- Small PRs: Easier to review and merge
- Clear title: Summarize the change in the title
- Screenshots: Include screenshots for UI changes
- Documentation: Update docs if needed
CI Checks
Your PR must pass these CI checks:- Lint: ESLint across all packages
- Backend (PostgreSQL): Unit + E2E tests with coverage
- Backend (sql.js): Unit + E2E tests (Linux + macOS)
- Frontend: Unit tests + Vite build with coverage
- Plugin: Unit tests with coverage
- Changeset check: Validates changeset presence
- Codecov: Patch coverage must be >90%
Review Process
- A maintainer will review your PR
- Address feedback by pushing new commits
- Once approved, a maintainer will merge your PR
Release Process
Releases are automated via Changesets.Workflow
- PR merged with changeset → Release workflow detects changesets
- “Version Packages” PR created → Bumps versions in
package.json, updatesCHANGELOG.md - Version PR merged → Workflow publishes to npm automatically
Commands
Only maintainers can publish releases. Contributors only need to add changesets to their PRs.
Reporting Issues
Found a bug or have a feature request?- Check existing issues to avoid duplicates
- Open a new issue on GitHub
- Provide details:
- Steps to reproduce (for bugs)
- Expected behavior vs actual behavior
- Environment (OS, Node version, etc.)
- Screenshots or logs (if applicable)
Getting Help
- Documentation: Check the docs at manifest.build/docs
- GitHub Issues: Ask questions via GitHub Issues
- Discord: Join the community (link in README)
License
By contributing, you agree that your contributions will be licensed under the MIT License.Recognition
All contributors are recognized in:- GitHub contributors list
- Release notes (when your PR is included in a release)
- Community shoutouts