# Oleafly에 기여하기

Oleafly를 더 좋게 만들고 싶어 해 주셔서 감사합니다! 이 가이드는 새로 클론한 저장소에서 동작하는 개발 빌드까지 안내하고, 변경을 검토하고 반영하는 방식을 설명합니다.

Oleafly를 더 좋게 만들고 싶어 해 주셔서 감사합니다! 이 가이드는 새로 클론한 저장소에서
동작하는 개발 빌드까지 안내하고, 변경을 검토하고 반영하는 방식을 설명합니다.

## 기여하는 방법

- 버그 신고: [버그 리포트](https://github.com/Oleafly/Oleafly/issues/new/choose)를 여세요.
- 기능 요청: [기능 요청](https://github.com/Oleafly/Oleafly/issues/new/choose)을 여세요.
- 취약점은 [SECURITY.md](https://github.com/Oleafly/Oleafly/blob/main/SECURITY.md)에 따라 비공개로 신고하세요.
- 풀 리퀘스트 보내기: 아래를 참고하세요.

작은 수정보다 큰 변경이라면, 시간을 들이기 전에 접근 방식을 합의할 수 있도록 먼저
이슈를 여세요.

## 사전 요구 사항

| 도구 | 버전 | 참고 |
| --- | --- | --- |
| [Node.js](https://nodejs.org) | 22.13+ | pnpm 11에 필요합니다 |
| [pnpm](https://pnpm.io) | 11.9+ | Corepack을 켜거나 `package.json`에 선언된 버전을 설치하세요 |
| [Rust](https://rustup.rs) | stable (1.77+) | `cargo`가 포함됩니다 |
| 플랫폼 의존성 | - | 사용하는 OS의 [Tauri v2 사전 요구 사항](https://v2.tauri.app/start/prerequisites/)을 참고하세요(Linux에서는 `libwebkit2gtk-4.1-dev`, `librsvg2-dev`, `patchelf`, …) |

## 시작하기

```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
```

> Tectonic, Biber, Typst 바이너리는 의도적으로 **git에서 제외**되어 있습니다.
> 절대 커밋하지 마세요. 가져오기 스크립트가 이 파일들을
> `bundle.externalBin`이 기대하는 위치인 `src-tauri/binaries/`에 둡니다.

### 프로덕션 번들을 로컬에서 빌드하기

```bash
pnpm tauri build
```

설치 프로그램은 `src-tauri/target/release/bundle/`에 생성됩니다.

## 프로젝트 구조

```
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
```

## 테스트

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

파일 시스템, git, 사용자 경로를 건드리는 백엔드 로직에는 반드시 테스트가 있어야
합니다. 경로 샌드박싱 도우미(`resolve_within`, `validate_project_id`)와 로그/URL
파서는 `#[cfg(test)]` 모듈에서 다루고 있으니, 해당 코드를 바꿀 때 이 테스트를 확장하세요.
프런트엔드에서는 맞춤법/문법 검사기가 무엇을 볼지 정하는 LaTeX 마스킹이 순수 로직이며
`src/components/editor/cm/latex-mask.test.ts`에서 단위 테스트됩니다. 무엇을 본문으로
볼지 바꿀 때는 거기에 케이스를 추가하세요.

## 코드 스타일

- **TypeScript** - 프런트엔드는 타입 검사와 빌드를 통과해야 하며 `pnpm build`,
  Biome 린트 관문 `pnpm lint`(안전한 것은 `pnpm lint:fix`로 자동 수정)도
  통과해야 합니다. 이 관문은 정확성 오류가 있으면 **차단**합니다. 기존의
  접근성/스타일 잔여 항목은 차단하지 않는 경고로 보고됩니다(`biome.json`
  참고). 새 경고는 되도록 추가하지 마세요.
- **Rust** - 백엔드는 `cargo fmt`와 `cargo clippy`에 깨끗해야 합니다. 둘 다 CI에서
  **차단** 항목입니다(`clippy`는 `-D warnings`로 실행됩니다). 푸시하기 전에
  `cargo fmt`와 `cargo clippy --all-targets --fix`를 실행하세요.
- 주변 코드에 맞추세요. 주석 밀도, 이름 짓기, 관용구가 해당합니다.

## 풀 리퀘스트

1. 포크하고 `main`에서 브랜치를 만듭니다(`git checkout -b fix/short-description`).
2. 변경은 한 가지에 집중하세요. 관련 없는 리팩터링은 별도의 PR로 올리세요.
3. 로컬에서 `pnpm lint`, `pnpm build`, `cargo test --lib`가 통과하는지 확인하세요.
4. PR 템플릿을 채우세요. 이슈를 연결하고, 변경 내용을 설명하고, 어떻게
   테스트했는지 적으세요.
5. CI가 초록색이어야 합니다(프런트엔드 빌드와 Rust 테스트가 필수 검사입니다).

스쿼시 병합을 하므로 깔끔한 PR 제목이 곧 커밋 메시지가 됩니다. 컨벤셔널 커밋
스타일을 쓰면 좋지만 필수는 아닙니다(예: `fix: reject absolute paths in resolve`).

## 릴리스(메인테이너용)

릴리스는 버전 태그를 푸시해서 만듭니다.
[`Release` 워크플로](https://github.com/Oleafly/Oleafly/blob/main/.github/workflows/release.yml)가 macOS Apple Silicon, Windows x64, Linux x64, Linux ARM64 설치 프로그램을 빌드하고, 검토용 초안에 첨부합니다. 게시하려면 같은 태그에 대해 보호된 두 번째 워크플로를 실행해야 합니다.

```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
```

기여함으로써 여러분의 기여물이 프로젝트의
[GNU Affero General Public License v3.0 이상](https://github.com/Oleafly/Oleafly/blob/main/LICENSE)에 따라 라이선스됨에 동의하는 것으로 봅니다.
