chore: add Claude Code guidelines, rules and skills
- CLAUDE.md: product principles, crate layering, common commands, commits. - .claude/rules: common, Rust, frontend, Tauri IPC, docs and security rules. - .claude/skills: check, add-tauri-command, project-model-change, change-record, msix-integration-test, backlog-status. Refs #16 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7f5540f148
commit
905e6d4eaa
13 files changed
+654
No files matched your search
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: add-tauri-command
|
||||
description: Installer Studio 데스크톱에 Tauri IPC 명령을 추가하거나 바꾼다. Rust 명령 작성, generate_handler 등록, 자동 생성 권한, capabilities/main.json 허용, TypeScript invoke 타입, README 갱신까지 한 번에 끝낸다. "명령 추가", "IPC", "프런트에서 호출", "capability", "not allowed 오류"에 사용한다.
|
||||
---
|
||||
|
||||
# Tauri 명령 추가
|
||||
|
||||
파일 위치: `src/apps/desktop/src-tauri/src/main.rs`, `src/apps/desktop/src-tauri/capabilities/main.json`, `src/apps/desktop/src/main.ts`.
|
||||
|
||||
## 설계 먼저 결정
|
||||
|
||||
- 비즈니스 로직은 `package-infra`에 함수로 두고 명령은 그 함수를 호출만 한다. CLI(`apps/cli/src/main.rs`)에서도 같은 함수를 쓸 수 있어야 한다.
|
||||
- 인자로 받을 것은 ID·선택지·사용자 입력값이다. 파일 경로를 프런트엔드에서 받지 않는다. 경로가 필요하면 `rfd` 대화상자 또는 세션 문서에서 얻는다.
|
||||
- 세션을 바꾸는가? → `idle(&session)?`를 첫 줄에.
|
||||
- 파일 IO·해시·외부 도구를 실행하는가? → `async fn` + `spawn_blocking`.
|
||||
- 반환 DTO가 새 타입이면 `#[derive(serde::Serialize)]` + `#[serde(rename_all = "camelCase")]`. 바이트 수는 문자열.
|
||||
|
||||
## 절차
|
||||
|
||||
1. **Rust 명령**
|
||||
|
||||
```rust
|
||||
#[tauri::command]
|
||||
async fn example_action(id: String, session: State<'_, Session>) -> Result<ExampleView, String> {
|
||||
idle(&session)?; // 세션을 바꾸는 경우만
|
||||
let doc = document(&session)?;
|
||||
tauri::async_runtime::spawn_blocking(move || infra::example(&doc, &id).map_err(error))
|
||||
.await
|
||||
.map_err(error)?
|
||||
}
|
||||
```
|
||||
|
||||
2. `main.rs` 하단 `tauri::generate_handler![ ... ]` 목록에 `example_action` 추가.
|
||||
3. `cargo build --locked -p msix-studio --features custom-protocol` 실행. `permissions/autogenerated/example_action.toml`이 생긴다. 이 파일은 수정하지 않는다.
|
||||
4. `capabilities/main.json`의 `permissions` 배열에 `"allow-example-action"` 추가(snake → kebab). 기존 순서를 따라 명령 그룹 근처에 넣는다.
|
||||
5. **TypeScript**: `main.ts`(또는 담당 모듈)에 반환 `type` 선언 후 `await invoke<ExampleView>('example_action', { id })`. 호출은 `action()` 분기 안에서 `busy` 보호를 받게 한다.
|
||||
6. 순수 로직이 생겼으면 별도 모듈로 빼고 `tests/<module>.test.mjs`에 테스트 추가.
|
||||
7. `src/README.md`에서 해당 화면·CLI 절을 갱신한다. 새 오류 코드가 있으면 적는다.
|
||||
8. `check` 스킬로 전체 검사.
|
||||
|
||||
## 자주 나는 오류
|
||||
|
||||
- 런타임 `example_action not allowed by ACL`: 4단계 누락.
|
||||
- `permissions/autogenerated`에 파일이 없음: 2단계 누락 또는 빌드 미실행.
|
||||
- TS에서 `undefined` 필드: Rust `snake_case` ↔ TS `camelCase` 불일치. `rename_all` 확인.
|
||||
- 빌드 중 명령이 실행됨: 1단계 `idle` 누락.
|
||||
Reference in new issue
Block a user