CONTRIBUTING
Thank you for your interest in contributing to Inklings. This guide covers everything you need to get started.
Getting Started
For prerequisites (Node.js, pnpm, Rust, gitleaks, platform-specific dependencies) and initial setup, see Getting Started.
Additional dev tools:
- git-cliff (
brew install git-cliff) — changelog generator, used bytools/release.sh - dprint (
brew install dprint) — markdown formatter - uv (
brew install uvon macOS, or https://docs.astral.sh/uv/) — Python package manager, required forapps/python-sidecar/
Finding Work
- Browse open issues for tasks
- Issues labeled
good first issueare suitable for new contributors - Comment on an issue to claim it before starting work
- If you want to work on something not yet tracked, open an issue first to discuss the approach
Architecture Overview
Inklings is a polyglot modular monolith with Clean Architecture. Compile-time enforcement is achieved via separate Rust crates with a strict dependency direction:
Framework → Infrastructure → Application → DomainSee the Development Guide for full details.
Layer Organization
| Layer | Path | Responsibility |
|---|---|---|
| Domain | crates/domain/ | Pure business entities, no external deps |
| Application | crates/application/ | Use cases + service traits |
| Infrastructure | crates/infrastructure/ | Storage, import, embedding, sync, etc. |
| Commands | crates/commands/ | Transport-agnostic validation + error sanitization |
| Framework | apps/desktop/src-tauri/ | Tauri commands wiring everything together |
| Frontend | apps/desktop/src-react/ | React UI (TypeScript) |
Development Methodology
All features are implemented end-to-end through all layers (vertical slicing), not layer-by-layer:
- Domain (Rust entity/validation)
- Application (Rust use case + service traits)
- Infrastructure (storage implementation)
- Framework (Tauri command)
- Frontend (React component)
Rule: If you can’t demo it, you haven’t finished it.
Each use case gets its own file. See the Development Guide for full details and the file-per-use-case pattern.
Testing Strategy
| Layer | Approach | Coverage Target |
|---|---|---|
| Domain | Pure unit tests | 100% |
| Application | Unit tests with mocked repos | >90% |
| Infrastructure | Unit tests with temp dirs | >80% |
| Integration | Real SQLite (tests/core/) | Key scenarios |
| Frontend | Playwright with mocked backend | Critical paths |
Test naming convention: test_[what]_[condition]_[expected]
cargo test # Rust unit + integration testscargo test -p core-tests # Rust integration tests (real SQLite, in tests/core/)pnpm test # All tests via Turbo (Playwright frontend integration tests in apps/desktop/tests/)Code Conventions
Rust
- Linting:
cargo clippy— all warnings must be resolved before committing - Formatting:
cargo fmt
TypeScript
- Linting:
pnpm lint(oxlint) - Type checking:
pnpm typecheck
Commit Messages
Follow Conventional Commits format:
<type>(<scope>): <description>| Type | When to use |
|---|---|
feat | New feature or capability |
fix | Bug fix |
refactor | Code restructuring without behavior change |
chore | Build, tooling, dependency changes |
docs | Documentation changes |
test | Adding or fixing tests |
perf | Performance improvements |
Examples:
feat(editor): add image block drag-and-dropfix(sync): advance cursor only after successful mergerefactor(application): extract shared loop driverchore(ci): exclude http-bridge from CI compilationdocs(contributing): rewrite with updated pathstest(integration): add page lifecycle smoke test
Pre-commit Hook
The pre-commit hook runs gitleaks (secret scanning) only. Formatting and linting are not enforced at commit time.
Before submitting a PR, run the quality gate:
./tools/precheck.sh --fix # auto-fix formatting/linting, then validatePull Request Process
- Create a feature branch from
main - Implement your changes following the vertical slicing approach
- Ensure tests pass:
cargo testandpnpm test - Ensure linting passes:
cargo clippy,cargo fmt --check,pnpm lint - Write a clear PR description explaining what changed and why
- Request review from a maintainer
Infrastructure Provisioning (release managers only)
The tools/provision/ directory contains scripts that automate deployment configuration (GitHub secrets, Supabase
auth/SMTP, Sentry, Cloudflare, signing, distribution).
Quick Start
# Bootstrap will auto-install missing CLI tools (gh, jq, curl) via your package manager./tools/provision/bootstrap.sh --environment staging --dry-runAuto-Installed Prerequisites
The bootstrap script detects your OS and package manager, then offers to install missing tools:
| Tool | macOS (brew) | Linux (apt/dnf/pacman) | Windows (winget/choco/scoop) |
|---|---|---|---|
gh | gh | gh | GitHub.cli |
jq | jq | jq | jqlang.jq |
curl | curl | curl | cURL.cURL |
Manual Prerequisites (cannot be scripted)
These require interactive setup or access to external dashboards:
| Prerequisite | How to set up |
|---|---|
| GitHub CLI auth | gh auth login — requires browser-based OAuth flow |
| Supabase access token | supabase.com/dashboard/account/tokens → Generate new token |
| Sentry auth token | sentry.io → Settings → Auth Tokens → Create New Token (scopes: project:read, org:read) |
| Cloudflare API token | dash.cloudflare.com/profile/api-tokens → Create Token → Edit Cloudflare Workers |
| Resend API key | resend.com/api-keys → Create API Key (domain must be verified first) |
| Google OAuth credentials | console.cloud.google.com → APIs & Services → Credentials → OAuth 2.0 Client IDs |
| Apple OAuth credentials | developer.apple.com → Certificates, Identifiers & Profiles → Service IDs |
| Apple Developer enrollment | developer.apple.com/programs — required for code signing (INK-161) |
| Apple code signing certificate | Xcode → Settings → Accounts → Manage Certificates → export .p12 |
| Windows signing provider | Choose one: SignPath, SSL.com eSigner, or Azure Trusted Signing |
| CrabNebula account | crabnebula.dev — for desktop app distribution |
| Tauri updater key password | You choose this — used when running tools/provision/signing/generate-tauri-keys.sh |
All manual credentials go into tools/provision/.env.provision (gitignored). See
tools/provision/.env.provision.example for the full template.
Validation
After provisioning, verify everything is in place:
./tools/provision/validate.sh --environment stagingThis prints a pass/fail report card for all services without making any changes.
Releasing
Releases are managed by tools/release.sh, which automates version bumping, changelog generation, tagging, and
production deployment:
./tools/release.sh # Full release (tests + version bump + tag + deploy)./tools/release.sh --dry-run # Preview version + changelog without changes./tools/release.sh --skip-tests # Skip quality gate./tools/release.sh --skip-deploy # Version + tag only, no production promotionThe script uses git-cliff to calculate the next semantic version from conventional commit messages and generate categorized release notes (Features, Bug Fixes, Performance, Breaking Changes).
Version is synced across three files: Cargo.toml (workspace), tauri.conf.json, and pyproject.toml.
Documentation
- Development Guide — methodology, patterns, testing strategy
- Domain Rules — business rules enforced in Rust
- Architecture Decisions — ADRs for key technical choices
- System Documentation — in-depth system documentation
License
This project is proprietary software. See LICENSE for details.
Was this page helpful?
Thanks for your feedback!