Skip to content

Latest commit

 

History

History
160 lines (124 loc) · 5.31 KB

CONTRIBUTING.md

File metadata and controls

160 lines (124 loc) · 5.31 KB

Contributing to Kenafold

Thanks for the interest. This document covers how to set up a dev environment, run the test suite, and submit a pull request.

Code of conduct

Be kind. This is a file manager, not a kernel — there's no need for intensity. Disagreements about design are resolved in code review, not in commit messages.

Development setup

Prerequisites

  • Bun ≥ 1.3 (the project pins bun@1.3.5 in packageManager).
  • Rust stable (the project uses Tauri 2.11, which requires rustc ≥ 1.77).
  • Tauri system deps — see https://tauri.app/start/prerequisites/. On Debian / Ubuntu:
    sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev \
      libayatana-appindicator3-dev librsvg2-dev \
      build-essential curl wget file libssl-dev
  • macOS: Xcode Command Line Tools (xcode-select --install).
  • Windows (Sprint 7): Visual Studio Build Tools 2022 with the "Desktop development with C++" workload.

First run

# Install JS deps.
bun install

# Run the frontend dev server on http://localhost:1420.
bun --filter @kenafold/app run dev

# In a second terminal, run the full Tauri app (frontend + Rust backend).
bun --filter @kenafold/app run tauri dev

The first tauri dev invocation downloads and compiles a few hundred Rust crates — go grab a coffee. Subsequent runs are incremental.

Tests

# Frontend (Vitest + Testing Library).
bun run test

# Rust (cargo test on every target the runner supports).
cd apps/app/src-tauri && cargo test --all

# Typecheck (TypeScript).
bun run typecheck

# Lint (ESLint flat config + react-hooks).
bun run lint

Before opening a PR, make sure all four pass. The CI workflow in .github/workflows/ci.yml runs the same checks.

Code style

  • TypeScript is the project's primary frontend language. The codebase uses strict: true and "noUncheckedIndexedAccess": true.
  • Prettier is configured at the repo root — run bun run format before committing.
  • ESLint flat config (apps/app/eslint.config.js) flags react-hooks/set-state-in-effect, react-hooks/refs, and react-refresh/only-export-components. When you genuinely need one of these patterns, silence the rule with a comment explaining why.
  • Rust uses cargo fmt and cargo clippy with -D warnings (set up in the CI workflow). New public items should carry doc comments (///).

Architecture

The codebase is a Tauri 2 monorepo with two apps and a shared UI package:

apps/
  app/         # The Kenafold desktop app (frontend + Rust backend).
  web/         # Marketing landing page (TanStack Start).
packages/
  ui/          # Shared shadcn/ui components + Tailwind 4 theme.

Inside apps/app, the frontend follows "Screaming Architecture" — each feature owns its own layers under src/features/<feature>/:

src/features/<feature>/
  api/         # React hooks = use-cases (call infra, expose state)
  domain/      # Pure TS: types, logic, no framework deps
  infra/       # Tauri invoke adapters (gateway pattern)
  components/  # UI components
  hooks/       # Feature-specific hooks (not use-cases)

Tauri commands live in apps/app/src-tauri/src/, one Rust file per feature (fs.rs, commands.rs, git_status.rs, …). Commands are exposed to the renderer via the fs.gateway.ts thin wrapper.

Pull request process

  1. Open an issue first for anything beyond a one-line fix. The issue should describe the user-visible problem and the proposed solution. Use the templates if they exist.
  2. Branch from main. Use a descriptive name: feat/grid-thumbnails, fix/trash-leak-on-cancel, docs/translate-pt-br.
  3. Write tests for the change. Bug fixes should add a regression test; features should add coverage for the new behavior.
  4. Run the test suite locally before pushing. CI is the source of truth, but a green local run saves a round-trip.
  5. One logical change per PR. If you find yourself mixing a refactor with a feature, split it into two PRs.
  6. Update docs if the change is user-visible: README, docs/, CHANGELOG.md "Unreleased" section, i18n keys in both en.ts and es.ts.

Release process

We use a manual tag-driven release:

  1. Move the "Unreleased" section in CHANGELOG.md into a dated versioned entry.
  2. Bump version in apps/app/src-tauri/tauri.conf.json and apps/app/package.json.
  3. git tag v0.x.y && git push --tags.
  4. The release.yml workflow builds the macOS, Linux .deb, and Linux arm64 artefacts and attaches them to the GitHub release.

Translations

Kenafold ships with English (en) and Spanish (es) locales. To add a new language:

  1. Copy apps/app/src/shared/i18n/locales/en.ts to apps/app/src/shared/i18n/locales/<code>.ts.
  2. Translate the strings. Keep the keys (the part before the colon) exactly as in en.ts — the type system enforces that the locale file's keys match.
  3. Add the new code to SUPPORTED_LANGUAGES in apps/app/src/shared/i18n/i18n.ts.
  4. The LanguagePicker in the settings panel will surface the new locale automatically.

The locale files are type-checked (as const) — TypeScript will catch any missing or extra key.

Reporting bugs

Use the issue templates (when present). For security issues, follow SECURITY.md instead of opening a public issue.