Thank you for your interest in contributing to Preference Injector! This document provides guidelines and instructions for contributing.
Please read CODE_OF_CONDUCT.md before contributing.
This project prioritizes emotional safety and uses the Tri-Perimeter Contribution Framework (TPCF) to reduce anxiety and encourage experimentation.
- ✅ Fork, clone, experiment freely
- ✅ Open issues and submit PRs
- ✅ Low anxiety - all changes are reversible via Git
- ✅ High experimentation - breaking things is learning!
⚠️ Cannot commit directly to main branch (protection)
After 3+ merged PRs and 30+ days of contribution:
- ✅ Direct commits to feature branches
- ✅ Triage and label issues
- ✅ Review PRs from Perimeter 3
- 🔄 Automatic promotion (no vote required)
Demonstrated leadership + nomination + 2/3 vote:
- ✅ Merge to main branch
- ✅ Release management
- ✅ Security triage
- 👥 See MAINTAINERS.md for details
- Deno 1.x or higher (we migrated from Node.js!)
- Just command runner (replaces npm scripts)
- Git
- (Optional) Nix for reproducible builds
- (Optional) ReScript for functional programming modules
-
Fork and clone the repository:
git clone https://github.com/YOUR_USERNAME/preference-injector.git cd preference-injector -
Install dependencies:
just install # or manually: deno cache src/deps.ts -
Verify RSR compliance (optional but recommended):
just rsr-verify
-
Start developing:
just dev
# Enter development shell with all dependencies
nix develop
# Build the project
nix build
# Run checks
nix flake checkWe use Just as our command runner. See all available commands:
just --list# Run all tests
just test
# Run tests in watch mode
just test-watch
# Generate coverage report
just test-coverage# Build TypeScript
just build
# Build ReScript
just build-rescript
# Build everything
just build-all
# Clean build artifacts
just clean# Run linter
just lint
# Auto-fix linting issues
just lint-fix
# Format code
just fmt
# Check formatting
just fmt-check
# Run all checks (lint + format + types)
just check-allThis project follows the Rhodium Standard Repository (RSR) Framework. Before submitting PRs, please verify compliance:
# Check RSR compliance
just rsr-verify
# Calculate compliance score
just rsr-scoreEnsure these files exist and are up-to-date:
- ✅
SECURITY.md- Security policies - ✅
CODE_OF_CONDUCT.md- Community guidelines - ✅
MAINTAINERS.md- Governance and TPCF - ✅
.well-known/security.txt- RFC 9116 security contact - ✅
.well-known/ai.txt- AI training policies - ✅
.well-known/humans.txt- Human contributors - ✅
PALIMPSEST-LICENSE.txt- Dual licensing
- Use strict TypeScript configuration
- Prefer interfaces over types for object shapes
- Use explicit return types for functions
- Avoid
anytype; useunknownwhen type is truly unknown
- Files:
kebab-case.ts - Classes:
PascalCase - Functions/Variables:
camelCase - Constants:
UPPER_SNAKE_CASE - Interfaces:
PascalCase
- Use 2 spaces for indentation
- Use single quotes for strings
- Add semicolons
- Use async/await over raw Promises
- Prefer const over let; avoid var
- Add JSDoc comments for public APIs
- Document complex logic with inline comments
- Keep comments up-to-date with code changes
- Use TypeDoc-compatible documentation
- Unit Tests: Test individual components in isolation (
*.test.ts) - Integration Tests: Test component interactions (
*.integration.test.ts) - E2E Tests: Test complete workflows (
*.e2e.test.ts)
- Follow AAA pattern (Arrange, Act, Assert)
- Use descriptive test names
- Test both success and failure cases
- Aim for >80% code coverage
- Mock external dependencies
Example:
describe('ComponentName', () => {
describe('methodName', () => {
test('should do something when condition', () => {
// Arrange
const input = 'test';
// Act
const result = method(input);
// Assert
expect(result).toBe(expected);
});
});
});- Ensure all tests pass
- Add tests for new features
- Update documentation
- Run linter and formatter
- Update CHANGELOG.md
- Create a descriptive title
- Reference related issues
- Provide a clear description of changes
- Include screenshots for UI changes
- Keep PRs focused and atomic
## Description
[Describe your changes]
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Tests added/updated
- [ ] All tests passing
- [ ] Manual testing completed
## Checklist
- [ ] Code follows project style
- [ ] Self-review completed
- [ ] Comments added for complex logic
- [ ] Documentation updated
- [ ] No new warnings generated
- [ ] CHANGELOG.md updated- Design documented
- Implementation follows coding standards
- Unit tests added
- Integration tests added (if applicable)
- Documentation updated
- Examples added
- TypeScript types exported
- Backward compatibility maintained
When adding a new provider:
- Implement
PreferenceProviderinterface - Add comprehensive error handling
- Include validation and sanitization
- Add unit and integration tests
- Update documentation
- Add usage example
When adding framework integration:
- Follow framework conventions
- Provide TypeScript types
- Add comprehensive examples
- Include integration tests
- Update documentation
- Keep examples current
- Update feature list
- Add new sections as needed
- Include screenshots if helpful
- Use JSDoc comments
- Document parameters and return types
- Include usage examples
- Generate with TypeDoc
- Keep examples simple and focused
- Use realistic scenarios
- Include error handling
- Add comments explaining key concepts
- Update version in package.json
- Update CHANGELOG.md
- Create git tag
- Push to GitHub
- Create GitHub release
- Publish to npm (maintainers only)
- Issues: For bugs and feature requests
- Discussions: For questions and ideas
- Email: For security issues
Contributors will be recognized in:
- README contributors section
- CHANGELOG for significant contributions
- GitHub contributors page
By contributing, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing to Preference Injector!