Skip to content

Latest commit

 

History

History
199 lines (136 loc) · 11.4 KB

File metadata and controls

199 lines (136 loc) · 11.4 KB

Contributing to ORGII

Thank you for helping improve ORGII. This project is a Tauri v2 desktop app built with React, TypeScript, webpack, and Rust.

Unless otherwise noted, paths and shell commands are relative to the repository root.

Quick path

  1. Search existing issues and pull requests first.
  2. For larger changes, open an issue or discussion before implementing.
  3. Set up the app, make a small focused change, and run the checks that match your files.
  4. Open a pull request with a clear summary, test plan, and passing CLA check.

Keep secrets, private data, generated artifacts, and unrelated formatting changes out of your PR. If you use AI assistance, a human must actively review the design and implementation before submission.

Development setup

Install the required tools:

Tool Version Notes
Node.js 20 or current LTS Use nvm install --lts or the Node.js installer.
pnpm 9.15 Install with npm install -g pnpm@9.15.
Rust toolchain 1.85.0 or later Use rustup toolchain install stable.
Tauri system dependencies Tauri v2 Follow the Tauri prerequisites guide for your OS.
Python 3 Any 3.x Only needed for optional asset download scripts.

From the repository root:

pnpm install
pnpm run tauri:dev

Tauri starts the webpack dev server through its beforeDevCommand, so use the Tauri scripts for normal desktop development.

To try Mobile Remote in production (phone PWA + Cloudflare Relay), see the colleague experience guide. For local relay / Workers deployment, see Mobile Remote dev & production guide.

Copy config/env.example to the repository-root .env only when you need local configuration. .env is gitignored; never commit real secrets.

Build, test, CSS, and commit-message configuration lives in config/. The package scripts and Git hooks select these files explicitly. Use pnpm build, pnpm test, and pnpm test:watch; direct webpack or Vitest commands need --config config/webpack.config.js or --config config/vitest.config.ts, respectively. Editor integrations that ask for a config path should use the files in config/ as well.

ESLint, Prettier, and unimported settings live in package.json so editors and CLI tools can discover them automatically. See linting conventions for the reasoning behind the lint rules.

Restart a running dev server after changing or relocating build configuration. The webpack wrapper loads its config only at startup, so an existing process can keep using old loader paths even after source hot reloads.

For fast desktop iteration against a built app bundle:

pnpm run tauri:build:fast

Run the right checks

Run the checks that match the files you changed. If you cannot run a relevant check locally, explain why in the PR and include any partial verification you performed.

Change area Recommended checks
Frontend / TypeScript pnpm run lint, pnpm run test, pnpm run check:circular
Rust / Tauri pnpm run cargo:check, pnpm run cargo:clippy, pnpm run cargo:test
Targeted Rust modules pnpm run cargo:test:lib (root-package unit tests only), pnpm run cargo:test:agent_core, pnpm run cargo:test:agent_sessions, pnpm run cargo:test:api
Chat, session, or UI behavior E2E tests in tests/e2e; see tests/e2e/README.md

Core UI end-to-end tests use WebDriverIO with tauri-webdriver-automation:

cargo install tauri-webdriver-automation --locked
cd tests/e2e
pnpm install
pnpm test

Where tests live

One style per directory — never mix. A directory either colocates its tests beside the source or keeps them in a __tests__/ subdirectory. Both are fine; both are discovered. What is not fine is a directory that does both, because then nobody can tell where a new test belongs.

  • New directory? Colocate: foo.ts and foo.test.ts side by side.
  • Existing directory? Match whatever is already there. pnpm run check:test-placement enforces this and runs in CI — it names the offending directory and which file to move.
  • Name a test after the file it covers: foo.ts -> foo.test.ts. A component whose source is Foo/index.tsx takes Foo/Foo.test.ts.
  • When one source file needs several test files, add a facet: syncEngine.journal.test.ts, syncEngine.retention.test.ts.
  • A test that covers an invariant rather than a file may be named for the invariant (rustTsContract.test.ts, visibilityParity.test.ts). Keep these rare and obvious.

Vitest discovers src/**/*.test.ts only. Two consequences worth knowing:

  • A test outside src/ is not run by pnpm test. The e2e suite under tests/e2e/ is a separate WebdriverIO run with its own config.
  • Only .test.ts is collected — not .test.tsx. Keep test files as .ts and import the component under test, rather than renaming the test to .tsx.

Import the module under test with a relative path (../foo, ./foo) and pull anything cross-module through the @src/ alias. Most test files use both, and that is the intended split — not drift.

describe.only / it.only are a lint error in test files. A focused test makes every other test in its file silently not run while the suite still exits 0, which is indistinguishable from passing. .skip and .todo are allowed: those show up in the reporter's skipped count, so they are visible rather than invisible.

On the Rust side, unit tests are inline #[cfg(test)] mod tests in the source file. Large modules may extract them to a tests/ subdirectory or a sibling tests.rs. Cross-cutting integration tests live in a crate's top-level tests/. pnpm run cargo:test runs the whole workspace, including those integration targets.

Project map

Path Purpose
src/ React, TypeScript, UI, stores, hooks, and frontend services
src-tauri/ Tauri shell and Rust backend
docs/ Living architecture and feature documentation
scripts/ Development, setup, maintenance, and build scripts
tests/ Repository-level tests and test helpers

Add or update docs when behavior, architecture, setup, or user-visible behavior changes in a way that is not obvious from the code.

Coding expectations

Use the repository rules in .cursor/rules/ as the source of truth. The most common expectations are:

  • Keep changes focused and remove dead code immediately.
  • Use existing shared components, hooks, stores, and design tokens.
  • Prefer typed constants and enums over hardcoded domain strings.
  • Let errors propagate instead of silently returning empty fallback data.
  • Update all supported locales when changing user-facing UI text.
  • Follow frontend/backend contract rules when a setting, command, or wire type crosses the TypeScript and Rust boundary.

For deeper guidance, read:

  • .cursor/rules/orgii-frontend.mdc
  • .cursor/rules/frontend-backend-alignment.mdc
  • .cursor/rules/rust-resource-lifecycle.mdc
  • .cursor/rules/cargo-cleanup.mdc

Commits and pull requests

The complete, repository-wide pull request contract is in PR_RULES.md. It applies to human contributors and coding agents. GitHub automation enforces its machine-checkable title, description, and label rules.

Commit messages and PR titles must use scoped Conventional Commits:

feat(scope): short imperative summary
fix(scope): short imperative summary

Use lowercase kebab-case scopes such as git, settings, workstation, slash-menu, or contributing. Common types include feat, fix, chore, docs, style, test, refactor, perf, build, ci, and revert.

Every non-trivial commit needs a body that explains why the change exists, summarizes important behavior or architecture changes, and mentions notable verification or migration details.

A commit-msg hook runs commitlint, and the pre-commit hook appends a tamper-evidence trailer:

Pre-commit hook ran. Total eslint: N, total circular: N

Do not remove this trailer, and do not bypass hooks with --no-verify, HUSKY=0, or similar unless a maintainer explicitly asks you to do so for emergency recovery. If a hook fails, fix the issue and rerun the command normally.

Pull request checklist

Before requesting review, make sure the PR has:

  • A title, description, and labels that comply with PR_RULES.md.
  • One focused issue, feature, or fix.
  • Relevant checks passing, or a note explaining what could not be run.
  • CLA Assistant passing, plus screenshots or docs when the change needs them.

Also confirm that no secrets, local configuration, generated build output, or unrelated files are included.

Contributor License Agreement

ORGII requires contributors to sign the repository Contributor License Agreement before a pull request can be merged. The agreement text is in docs/contributing/CLA.md.

GitHub CLA Assistant will comment with a signing link on your first PR if your GitHub account has not signed the current agreement.

  • Sign as an individual when the contribution is your own work and you are legally allowed to submit it.
  • Sign as a company only if you are authorized to bind that organization to the CLA.

Maintainers will not merge PRs until the CLA check passes.

Security

Do not report security vulnerabilities in public issues. Use the repository's private security advisory flow when available, or contact the maintainers privately.

Never commit API keys, signing keys, OAuth secrets, personal tokens, private logs, or user data. If you accidentally expose a secret, revoke it immediately and notify maintainers.

Code of conduct and license

Be respectful, constructive, and specific. Keep issue and pull request discussions focused on the work.

By contributing, you agree that your contributions are licensed under AGPL-3.0-or-later and submitted under the Contributor License Agreement in docs/contributing/CLA.md. See LICENSE for the full license text.