# Đóng góp cho Oleafly

Cảm ơn bạn vì muốn làm Oleafly tốt hơn! Hướng dẫn này đưa bạn từ một bản clone mới về máy đến một bản build dev chạy được, đồng thời trình bày cách chúng tôi xem xét và hợp nhất các thay đổi.

Cảm ơn bạn vì muốn làm Oleafly tốt hơn! Hướng dẫn này đưa bạn từ một bản clone mới về máy đến một bản build dev chạy được, đồng thời trình bày cách chúng tôi xem xét và hợp nhất các thay đổi.

## Các cách đóng góp

- Báo cáo lỗi: mở một [báo cáo lỗi](https://github.com/Oleafly/Oleafly/issues/new/choose).
- Đề xuất tính năng: mở một [yêu cầu tính năng](https://github.com/Oleafly/Oleafly/issues/new/choose).
- Báo cáo lỗ hổng bảo mật một cách riêng tư bằng cách làm theo [SECURITY.md](https://github.com/Oleafly/Oleafly/blob/main/SECURITY.md).
- Gửi pull request: xem bên dưới.

Với bất cứ thứ gì lớn hơn một bản vá nhỏ, hãy mở issue trước để chúng tôi cùng thống nhất hướng tiếp cận trước khi bạn bỏ thời gian.

## Điều kiện trước

| Công cụ | Phiên bản | Ghi chú |
| --- | --- | --- |
| [Node.js](https://nodejs.org) | 22.13+ | Được pnpm 11 yêu cầu |
| [pnpm](https://pnpm.io) | 11.9+ | Bật Corepack hoặc cài phiên bản được khai báo trong `package.json` |
| [Rust](https://rustup.rs) | stable (1.77+) | bao gồm `cargo` |
| Dependency nền tảng | - | Xem [điều kiện trước của Tauri v2](https://v2.tauri.app/start/prerequisites/) cho hệ điều hành của bạn (trên Linux: `libwebkit2gtk-4.1-dev`, `librsvg2-dev`, `patchelf`, …) |

## Bắt đầu

```bash
git clone https://github.com/Oleafly/Oleafly.git
cd Oleafly
pnpm install

# Find your target with `rustc -vV | grep host`.
bash scripts/fetch-tectonic.sh aarch64-apple-darwin   # or your host triple
bash scripts/fetch-typst.sh aarch64-apple-darwin

# Run the app in dev mode (hot-reloads the frontend, rebuilds Rust on change):
pnpm tauri dev
```

> Các tệp nhị phân Tectonic, Biber và Typst bị **git-ignored** một cách có chủ đích: đừng bao giờ commit chúng. Script tải về đặt chúng vào `src-tauri/binaries/`, đúng nơi `bundle.externalBin` chờ chúng.

### Dự dựng gói production cục bộ

```bash
pnpm tauri build
```

Các bản cài đặt nằm trong `src-tauri/target/release/bundle/`.

## Bố cục dự án

```
src/                 React + TypeScript app shell
  components/         UI (editor, pdf, ai, layout, files, …)
  lib/               framework-agnostic helpers (ai-providers, github, …)
  store/             Zustand state slices
packages/            @oleafly/* engine packages, consumed as TypeScript source
src-tauri/src/       Rust backend (Tauri commands)
  commands.rs        Tauri command handlers and compile entry points
  latex_engine.rs    Tectonic and latexmk selection
  mcp/               local MCP server, routing, and native tools
  project.rs         project/file CRUD (path-sandboxed - see `resolve`)
  git.rs             git integration
  github.rs          GitHub OAuth device flow
  paths.rs           path helpers + project-id validation
docs/                user-facing documentation
scripts/             sidecar fetchers, language servers, release checks, icon generation
```

## Kiểm thử

```bash
pnpm test                    # frontend unit tests (Vitest)
cd src-tauri && cargo test --lib   # Rust backend tests
```

Logic backend chạm tới hệ thống tệp, git hay đường dẫn của người dùng **bắt buộc** phải có bài kiểm thử. Các hàm hỗ trợ giới hạn đường dẫn (`resolve_within`, `validate_project_id`) và các bộ phân tích nhật ký/URL được phủ trong các module `#[cfg(test)]`, hãy mở rộng chúng khi bạn thay đổi mã đó. Ở frontend, phần che LaTeX quyết định trình kiểm tra chính tả/ngữ pháp nhìn thấy gì là thuần khiết và được kiểm thử đơn vị trong `src/components/editor/cm/latex-mask.test.ts`, hãy thêm một trường hợp ở đó khi bạn thay đổi định nghĩa thế nào là văn xuôi.

## Phong cách mã

- **TypeScript**: frontend phải vượt qua kiểm tra kiểu và dựng được bằng `pnpm build`, và qua cổng lint Biome: `pnpm lint` (tự sửa phần an toàn bằng `pnpm lint:fix`). Cổng này **chặn** khi có lỗi tính đúng đắn. Phần tồn đọng cũ về khả năng tiếp cận và phong cách được báo cáo thành cảnh báo không chặn (xem `biome.json`). Hãy tránh thêm cảnh báo mới.
- **Rust**: backend phải sạch `cargo fmt` và sạch `cargo clippy`. Cả hai đều **chặn** trong CI (`clippy` chạy với `-D warnings`). Hãy chạy `cargo fmt` và `cargo clippy --all-targets --fix` trước khi đẩy mã.
- Phù hợp với mã xung quanh về mật độ chú thích, cách đặt tên và thành ngữ.

## Pull request

1. Fork và tạo nhánh từ `main` (`git checkout -b fix/short-description`).
2. Giữ thay đổi tập trung. Đặt các refactor không liên quan vào PR riêng.
3. Chắc chắn `pnpm lint`, `pnpm build` và `cargo test --lib` chạy qua trên máy bạn.
4. Điền vào mẫu PR: liên kết issue, mô tả thay đổi, ghi chú cách bạn đã kiểm thử.
5. CI phải xanh (bản dựng frontend và bài kiểm thử Rust là các kiểm tra bắt buộc).

Chúng tôi hợp nhất kiểu squash, nên tiêu đề PR gọn gàng chính là thông điệp commit. Phong cách conventional-commit được hoan nghênh nhưng không bắt buộc (ví dụ `fix: reject absolute paths in resolve`).

## Phát hành (dành cho người bảo trì)

Bản phát hành được cắt bằng cách đẩy một thẻ phiên bản. [`Release` workflow](https://github.com/Oleafly/Oleafly/blob/main/.github/workflows/release.yml) dựng các bản cài đặt macOS Apple Silicon, Windows x64, Linux x64 và Linux ARM64, rồi đính kèm chúng vào một bản nháp để xem xét. Việc xuất bản yêu cầu một lượt chạy workflow được bảo vệ thứ hai cho cùng thẻ đó.

```bash
# Bump the version everywhere it's declared (package.json, Cargo.toml,
# Cargo.lock, tauri.conf.json) in one shot, so the tag can't drift:
./scripts/bump-version.sh 0.3.6

git commit -am "chore: release v0.2.0"
git tag v0.2.0 && git push origin v0.2.0
```

Bằng cách đóng góp, bạn đồng ý rằng các đóng góp của mình được cấp phép theo [GNU Affero General Public License v3.0 hoặc mới hơn](https://github.com/Oleafly/Oleafly/blob/main/LICENSE) của dự án.
