소스 정보
- 저장소
- publieople/hermes-config-kit
- 최근 소스 활동
- 2026년 8월 8일 22:00
- 감지된 SKILL.md 언어
- 중국어
- 스타
- 0
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/publieople/hermes-config-kit --skill tauri-desktop-app명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
SOC 직업 분류 기준
| name | tauri-desktop-app |
| description | Tauri v2 桌面/移动应用开发 — 项目搭建、插件配置、架构模式、跨平台适配 |
| tags | ["tauri","rust","desktop","android","pwa","cross-platform"] |
| trigger | tauri|tauri v2|桌面应用|Tauri plugin|system tray|global shortcut|clipboard |
| category | software-development |
pnpm create tauri-app # 选 vanilla JS + Vite
cd <project>
cargo install tauri-cli --locked # Tauri CLI(如未安装)
复杂度评估
├── 单页面 + 少量交互 → Vanilla JS + Vite(本 Skill 默认)
├── 多页面 + 状态管理 → React/Preact
├── 响应式优先 → Solid/Svelte
└── 用户已有 React 栈 → React + Vite
对 Markdown 预览器这类"一个 textarea + 一个渲染 div"的应用,框架是过度工程。
| 插件 | Cargo Crate | npm Package | 用途 | 备注 |
|---|---|---|---|---|
| clipboard-manager | tauri-plugin-clipboard-manager | @tauri-apps/plugin-clipboard-manager | 读写剪贴板 | readText() / writeText() |
| global-shortcut | tauri-plugin-global-shortcut | @tauri-apps/plugin-global-shortcut | 全局热键 | register('Ctrl+Shift+M', handler) |
| single-instance | tauri-plugin-single-instance | — (Rust only) | 单实例 | 重复启动 → 聚焦已有窗口 |
| autostart | tauri-plugin-autostart | @tauri-apps/plugin-autostart | 开机自启 | enable() / disable() / isEnabled() |
用 Tauri 内置 TrayIcon API(不需要插件):
use tauri::tray::{TrayIconBuilder, TrayIconEvent};
use tauri::menu::{Menu, MenuItem};
let menu = Menu::with_items(app, &[
&MenuItem::with_id(app, "show", "显示/隐藏", true, None::<&str>)?,
&MenuItem::with_id(app, "settings", "设置", true, None::<&str>)?,
&MenuItem::with_id(app, "quit", "退出", true, None::<&str>)?,
])?;
TrayIconBuilder::new()
.icon(app.default_window_icon().unwrap().clone())
.tooltip("App Title")
.menu(&menu)
.on_menu_event(|app, event| match event.id.as_ref() {
"show" => { /* toggle window */ }
"settings" => { /* open settings */ }
"quit" => app.exit(0),
_ => {}
})
.on_tray_icon_event(|tray, event| {
if let TrayIconEvent::Click { .. } = event {
// toggle window visibility
}
})
.build(app)?;
// 获取窗口
let window = app.get_webview_window("main").unwrap();
// 显隐切换
if window.is_visible().unwrap_or(false) {
window.hide().unwrap();
} else {
window.show().unwrap();
window.set_focus().unwrap();
}
# Rust 侧
cd src-tauri
cargo add tauri-plugin-clipboard-manager
cargo add tauri-plugin-global-shortcut
cargo add tauri-plugin-single-instance
cargo add tauri-plugin-autostart
# JS 侧
pnpm add @tauri-apps/plugin-clipboard-manager
pnpm add @tauri-apps/plugin-global-shortcut
pnpm add @tauri-apps/plugin-autostart
{
"identifier": "default",
"windows": ["main"],
"permissions": [
"core:default",
"clipboard-manager:allow-read-text",
"clipboard-manager:allow-write-text",
"global-shortcut:allow-register",
"global-shortcut:allow-unregister",
"autostart:allow-enable",
"autostart:allow-disable",
"autostart:allow-is-enabled"
]
}
📚 完整研究见
references/android-clipboard-research.md
参见 references/android-clipboard-research.md。
关键结论:
ClipboardManager.OnPrimaryClipChangedListener 正常工作,不需要 Shizukuvisibilitychange 事件 + navigator.clipboard.readText()rustup target add aarch64-linux-android
# 需要 Android Studio + SDK + NDK 27+
pnpm tauri android init
pnpm tauri android dev
pnpm tauri android build
项目根/
├── src/ # 共享前端(Vanilla JS + Vite)
│ ├── index.html
│ ├── main.js # Tauri API → 桌面/Android 自动注入
│ ├── renderer.js # Markdown 渲染(marked.js + highlight.js)
│ └── style.css
├── src-tauri/ # Rust 后端(桌面 + Android 共用)
│ ├── src/
│ │ ├── main.rs # 插件注册、setup hook
│ │ ├── tray.rs # 系统托盘(#[cfg(desktop)])
│ │ ├── commands.rs
│ │ └── config.rs
│ └── tauri.conf.json
├── manifest.json # PWA manifest(独立于 Tauri)
└── sw.js # Service Worker(PWA 专属)
关键:前端代码完全不区分平台。window.__TAURI__ 存在时走 Tauri API,否则走 Web Clipboard API。
navigator.clipboard 需要 HTTPS 或 localhost — GitHub Pages 天然 HTTPSsudo pacman -S xdotool webkit2gtk-4.1version 写死不跟 tag 走。解决方案:release workflow 用 python3 从 ${{ github.ref_name }} 提取版本号(${TAG#v} → 0.1.1)替换 Cargo.toml 的 workspace version 和 tauri.conf.json 的 version 字段。产物上传用 *.exe/*.msi 通配符。bundle.resources 映射是 源路径 -> 安装目录文件名(扁平)。CI gui job 的 cargo check 会校验 resources 存在性 → 必须先构建 CLI+helper。beforeBuildCommand 用 --manifest-path ../Cargo.toml 跨独立 workspace 共享 target。gh release create 必须 checkout — publish job 需要 actions/checkout@v4(fetch-depth: 0)提供 git 仓库上下文,否则 gh release create 报 fatal: not a git repository。actions/download-artifact 下载后文件名不是扁平的(installer/gui/src-tauri/...),用 find installer -type f 收集文件,不要用 glob 猜 installer/*.exe。<div> 上无法被 html/body 继承(body 在 div 外层)。必须挂到 :root(document.documentElement.style.setProperty),用 watch + immediate: true 同步。version 写死不跟 tag 走。解决方案:release workflow 用 python3 从 ${{ github.ref_name }} 提取版本号替换两个文件的 version 字段。产物上传用 *.exe/*.msi 通配符。use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Clone)]
struct Settings {
hotkey: String,
theme: String,
auto_start: bool,
}
// 存储路径
let config_dir = dirs::config_dir().unwrap().join("app-name");
let config_path = config_dir.join("config.json");
pnpm tauri dev 桌面端可运行bundle.resources源路径 -> 安装目录文件名cargo checkbeforeBuildCommand--manifest-path ../Cargo.toml