OpenHuman 日常开发实战:从 dev-agent 看 React 组件、Tauri 命令与插件接入规范
OpenHuman 仓库在 .claude/agents/dev-agent.md 中定义了一个面向日常开发的子 Agent(dev-agent),它把"创建 React 组件、编写 Tauri 命令、添加插件、配置开发环境"这四类高频任务固化成了可复制的模板与命令。读懂这份文档,再对照仓库中 app/src-tauri/src/lib.rs 的真实命令实现与 app/src/utils/tauriCommands/core.ts 的前端调用约定,你就能完整掌握在这个 Tauri + React + Rust 代码库里新增功能的标准路径:声明命令、注册 handler、前端 invoke、跑测试与 lint。
dev-agent 是什么:一份固化的开发 SOP
dev-agent 是 Claude Code 的 subagent 定义文件,采用 YAML frontmatter + Markdown 正文的结构:
---
name: dev-agent
description: Assists with day-to-day development tasks, code generation, and feature implementation
model: model-sonnet
color: teal
---
frontmatter 中的 name 用于在 .claude/agents/ 目录下标识该 Agent,description 描述其职责边界,model 指定使用的模型。它的定位是"日常开发任务、代码生成、功能实现",核心能力被明确限定为四项:
- 生成 React 组件(Generate React components)
- 创建 Tauri 命令(Create Tauri commands)
- 安装配置插件(Set up plugins)
- 配置开发环境(Configure development environment)
从源码结构看,这个目录还并列存放了 test-agent、pr-reviewer、mobile-agent 等按职责拆分的子 Agent,dev-agent 是其中专注"写功能"的一个。以下各节按文档的四大能力展开,并用仓库真实代码印证每一步。
创建新的 React 组件
文档给出的模板
dev-agent 文档中"Create New Component"一节给出两步操作:
# Create component file
touch src/components/MyComponent.tsx
然后套入如下函数式组件模板:
import { FC } from 'react';
import './MyComponent.css';
interface MyComponentProps {
title: string;
}
export const MyComponent: FC<MyComponentProps> = ({ title }) => {
return (
<div className="my-component">
<h2>{title}</h2>
</div>
);
};
模板体现了文档"Code Style / TypeScript"一节的四条规范:函数式组件 + hooks、所有 props 和 state 必须有类型(interface MyComponentProps)、通过 invoke 调用 Tauri 命令、错误处理用 try/catch。
在本仓库中的落点
需要注意仓库目录布局:前端代码位于 app/ 工作区下,因此文档中的相对路径在本仓库对应 app/src/components/(该目录下有数百个 .tsx 组件)。命令实际在 app/ 目录执行时写作:
touch app/src/components/MyComponent.tsx
组件创建完成后,验证手段在 app/package.json 中已经就绪:pnpm lint(ESLint)、pnpm compile(tsc --noEmit 类型检查)、pnpm test(Vitest)。仓库还配有 knip 做未使用代码检测,新增组件若未被引用会被这类工具捕获。
创建 Tauri 命令:声明、注册、调用三步走
这是 dev-agent 文档中技术含量最高的部分,对应仓库中"前端 ⇄ Rust 内核"通信的核心机制。文档给出的三步流程如下。
第一步:在 lib.rs 中声明命令
文档要求在 src-tauri/src/lib.rs 中添加:
#[tauri::command]
fn my_command(arg: String) -> Result<String, String> {
Ok(format!("Received: {}", arg))
}
在真实仓库中,该文件是 app/src-tauri/src/lib.rs(约 3700 行,是整个桌面 shell 的命令层)。一个真实的同步 + 异步混合命令例子是 core_rpc_url:
/// Tauri command: where the renderer should send core JSON-RPC.
#[tauri::command]
async fn core_rpc_url(
desktop: tauri::State<'_, core_process::CoreProcessHandle>,
) -> Result<String, String> {
Ok(active_rpc_endpoint(desktop.inner()).await.0)
}
(见 app/src-tauri/src/lib.rs#L113-L124)
对照文档"Code Style / Rust"一节的四条规则,这段真实代码恰好全部命中:
- 命令用
#[tauri::command]宏标注; - 可失败操作返回
Result<T, E>; - 共享状态通过
State<CoreProcessHandle>注入(Tauri 的依赖注入点,由 builder 在启动时manage); - 涉及 I/O 的命令(这里要查询 active gateway)声明为
async。
第二步:在 builder 中注册 handler
文档要求把命令加入 builder:
.invoke_handler(tauri::generate_handler![my_command])
在 app/src-tauri/src/lib.rs#L3369 可以看到真实的注册点,tauri::generate_handler![...] 宏内是一个显式清单:
.invoke_handler(tauri::generate_handler![
core_rpc_url,
core_rpc_token,
core_rpc_endpoint,
// ...
check_core_update,
apply_core_update,
check_app_update,
apply_app_update,
restart_core_process,
recover_port_conflict,
force_quit_port_owner,
start_core_process,
// ...
])
值得注意的工程细节:清单里部分命令带条件编译,例如 gateway 相关命令写作 #[cfg(feature = "gateways")] gateway::commands::gateway_list。注释解释了设计意图——feature 关闭时命令"absent, not stubbed"(干脆不注册,而不是注册一个运行时才报错的桩函数),让前端可以做特性探测。新增命令时若依赖某个 cargo feature,应照此模式处理。
第三步:前端 invoke
文档给出的前端调用:
import { invoke } from '@tauri-apps/api/core';
const result = await invoke<string>('my_command', { arg: 'test' });
仓库中前端对 invoke 做了集中封装,位于 app/src/utils/tauriCommands/core.ts,restartCoreProcess 展示了比文档模板更完整的防御式写法:
export async function restartCoreProcess(): Promise<void> {
if (!isTauri()) {
console.debug('[core] restartCoreProcess: skipped — not running in Tauri');
return;
}
console.debug('[core] restartCoreProcess: invoking restart_core_process');
await invoke<void>('restart_core_process');
clearCoreRpcTokenCache();
console.debug('[core] restartCoreProcess: done');
}
两个约定超出文档模板但属于本仓库的硬性实践:
isTauri()前置守卫——同一套 React 代码也运行在纯 Web 模式(pnpm dev的 vite 开发模式)下,此时@tauri-apps/api的invoke不可用,所有命令封装都要在入口处判断并优雅降级;- 类型参数显式化——
invoke<void>/invoke<string>的泛型保证返回值在编译期就是前端预期的类型。
命令名与 Rust 函数名一一对应(restart_core_process),参数名同样保持 snake_case 与 Rust 侧签名一致,这是 invoke 序列化匹配的前提。
插件安装与开发服务器
插件
文档给出的插件安装命令:
# Add plugin via CLI
npm run tauri add <plugin-name>
# Common plugins:
npm run tauri add fs
npm run tauri add dialog
npm run tauri add http
npm run tauri add notification
npm run tauri add store
在本仓库中,app/package.json 已定义 "tauri": "tauri" 脚本,且依赖锁定在 pnpm 工作区(packageManager 字段与 gitbooks/developing/getting-set-up.md 要求 pnpm@10.10.0),因此实际执行时建议写作:
pnpm tauri add fs
仓库当前已在依赖中使用了多个官方插件,如 @tauri-apps/plugin-opener、@tauri-apps/plugin-os、@tauri-apps/plugin-deep-link、@tauri-apps/plugin-barcode-scanner(见 app/package.json 的 dependencies 段),可作为"常用插件"清单的实证参考。
开发服务器
文档列出的三条命令:
# Start with hot reload
npm run tauri dev
# Frontend only
npm run dev
# Check for issues
npm run tauri info
对照 app/package.json 的实际 scripts,本仓库的对应关系是:
| 文档命令 | 仓库实际脚本 | 说明 |
|---|---|---|
npm run dev |
pnpm dev |
纯前端 Vite 开发服务器,适合快速迭代 UI |
npm run tauri dev |
pnpm dev:app |
完整桌面端热重载开发(内部调用 scripts/run-dev-macos.sh 等平台脚本) |
npm run tauri info |
pnpm tauri info |
打印工具链诊断信息 |
开发环境的前置条件(以 gitbooks/developing/getting-set-up.md 与 rust-toolchain.toml 为准):
- Node.js 24+(
app/package.json的engines字段要求>=24.0.0) - pnpm 10.10.0
- Rust 1.93.0(经 rustup 安装,含
rustfmt与clippy) - CMake(原生 Rust 依赖需要)
app/src-tauri/vendor/下的 git submodule(vendored CEF 版 Tauri CLI)
首次克隆后按该指南初始化:
git submodule update --init --recursive
pnpm install
代码风格规范:TypeScript 与 Rust 双侧约定
文档"Code Style"一节是两侧语言的硬性约定汇总,可作为 Code Review 的检查清单。
TypeScript 侧:
- 函数式组件 + hooks,不写类组件;
- 所有 props 和 state 必须有类型;
- 调用 Tauri 命令统一走
invoke(在仓库实践中即走app/src/utils/tauriCommands/下的封装函数,而非散落各组件的直接 invoke); - 错误处理用 try/catch。
Rust 侧:
- 命令一律用
#[tauri::command]标注; - 可失败操作返回
Result<T, E>,禁止在命令体内unwrap导致进程级 panic; - 共享状态用
State<>注入; - 做 I/O 的命令保持 async。
仓库为这些风格配备了可执行的守门脚本(见 app/package.json):pnpm lint(ESLint 9)、pnpm rust:clippy(cargo clippy -- -D warnings,警告即失败)、pnpm rust:format:check(cargo fmt --check)、pnpm format:check(prettier 校验)。新增代码提交前跑一遍 pnpm format:check && pnpm lint 是低成本的一致性保障。
测试:前后端双栈验证
文档"Testing"一节给出两条命令:
# Frontend tests
npm test
# Rust tests
cd src-tauri && cargo test
在本仓库中对应(注意 shell 工程位于 app/ 下):
cd app
pnpm test # vitest run --config test/vitest.config.ts
cd src-tauri && cargo test # Rust 侧单元测试
仓库实际测试面比文档更宽:
- 前端单测/组件测试:
pnpm test、pnpm test:coverage(v8 覆盖率),测试入口配置在 app/test/vitest.config.ts; - 桌面 shell 的 Rust 测试除
cargo test外,还有pnpm test:rust(即scripts/test-rust-with-mock.sh,带 mock 服务); - 端到端:
pnpm test:e2e(Playwright,含 web 与 mega-flow 两条线); - 一键全量:
pnpm test:all= 前端覆盖率 + Rust 测试 + E2E。
以 dev-agent 的产出物视角,最小验证回路是:改前端组件 → pnpm test;新增/修改 Tauri 命令 → cd src-tauri && cargo test + 前端侧对应 tauriCommands 单测(如 app/src/utils/tauriCommands/core.test.ts)。
小结:一张日常开发命令速查表
| 场景 | 命令(在 app/ 目录) |
依据 |
|---|---|---|
| 纯前端开发 | pnpm dev |
app/package.json |
| 桌面端热重载开发 | pnpm dev:app |
同上 |
| 安装 Tauri 插件 | pnpm tauri add <name> |
dev-agent 文档 |
| 类型检查 | pnpm compile |
app/package.json |
| 前端测试 | pnpm test |
同上 |
| Rust 测试 | cd src-tauri && cargo test |
dev-agent 文档 |
| Rust 静态检查 | pnpm rust:clippy |
app/package.json |
| 全量测试 | pnpm test:all |
同上 |
dev-agent 文档的价值在于把"组件模板 → 命令三步走 → 插件 → 环境 → 测试"压缩成一条可执行 SOP;而仓库中的真实代码(app/src-tauri/src/lib.rs 的命令声明与 L3369 的 generate_handler! 注册表、app/src/utils/tauriCommands/core.ts 的 isTauri 守卫与类型化 invoke)则补齐了模板之外的工程细节:条件编译注册、跨 Web/Tauri 双模式的降级、以及可执行的 lint/test 守门。按此路径开发,新增功能的每一步都有对应源码与测试可验证。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00