Files
networkSetup/.claude/skills/add-tauri-command/SKILL.md
T
jychoi4andClaude Opus 5.5 905e6d4eaa 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>
2026-11-11 11:09:05 +09:00

2.8 KiB

name, description
name description
add-tauri-command 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 명령
#[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)?
}
  1. main.rs 하단 tauri::generate_handler![ ... ] 목록에 example_action 추가.
  2. cargo build --locked -p msix-studio --features custom-protocol 실행. permissions/autogenerated/example_action.toml이 생긴다. 이 파일은 수정하지 않는다.
  3. capabilities/main.json의 permissions 배열에 "allow-example-action" 추가(snake → kebab). 기존 순서를 따라 명령 그룹 근처에 넣는다.
  4. TypeScript: main.ts(또는 담당 모듈)에 반환 type 선언 후 await invoke<ExampleView>('example_action', { id }). 호출은 action() 분기 안에서 busy 보호를 받게 한다.
  5. 순수 로직이 생겼으면 별도 모듈로 빼고 tests/<module>.test.mjs에 테스트 추가.
  6. src/README.md에서 해당 화면·CLI 절을 갱신한다. 새 오류 코드가 있으면 적는다.
  7. check 스킬로 전체 검사.

자주 나는 오류

  • 런타임 example_action not allowed by ACL: 4단계 누락.
  • permissions/autogenerated에 파일이 없음: 2단계 누락 또는 빌드 미실행.
  • TS에서 undefined 필드: Rust snake_case ↔ TS camelCase 불일치. rename_all 확인.
  • 빌드 중 명령이 실행됨: 1단계 idle 누락.