docs: 添加 AI 编码代理开发指南
- 创建 AGENTS.md 文件以提供 AI 编码代理在该项目中的开发指南,涵盖项目概览、构建命令、代码风格规范、Tauri 通信模式、依赖管理及常见陷阱。
This commit is contained in:
283
AGENTS.md
Normal file
283
AGENTS.md
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
# AGENTS.md - Coding Agent Guide
|
||||||
|
|
||||||
|
This file provides essential information for AI coding agents working in this repository.
|
||||||
|
|
||||||
|
## 📋 Project Overview
|
||||||
|
|
||||||
|
**Tech Stack**: Tauri 2.x Desktop Application
|
||||||
|
- **Frontend**: Vanilla TypeScript + Vite 6.0.3
|
||||||
|
- **Backend**: Rust (edition 2021)
|
||||||
|
- **Package Manager**: Bun (preferred) or npm
|
||||||
|
- **Build Tool**: Vite + Tauri CLI
|
||||||
|
- **Runtime**: mise (for Rust toolchain management)
|
||||||
|
|
||||||
|
**Project Structure**:
|
||||||
|
```
|
||||||
|
tauri-demo/
|
||||||
|
├── src/ # Frontend TypeScript/HTML/CSS
|
||||||
|
│ ├── main.ts # Application entry point
|
||||||
|
│ ├── styles.css # Global styles
|
||||||
|
│ └── assets/ # Static resources
|
||||||
|
├── src-tauri/ # Rust backend
|
||||||
|
│ ├── src/ # Rust source code
|
||||||
|
│ │ ├── main.rs # Rust entry
|
||||||
|
│ │ └── lib.rs # Tauri commands
|
||||||
|
│ ├── Cargo.toml # Rust dependencies
|
||||||
|
│ ├── tauri.conf.json # Tauri configuration
|
||||||
|
│ ├── capabilities/ # Permission configs
|
||||||
|
│ └── icons/ # Multi-platform icons
|
||||||
|
├── index.html # HTML entry
|
||||||
|
├── package.json # Node.js config
|
||||||
|
├── tsconfig.json # TypeScript config
|
||||||
|
└── vite.config.ts # Vite config
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Build/Lint/Test Commands
|
||||||
|
|
||||||
|
### Development
|
||||||
|
```bash
|
||||||
|
# Start frontend dev server (port 1420)
|
||||||
|
bun run dev
|
||||||
|
|
||||||
|
# Start Tauri in dev mode (recommended for full app testing)
|
||||||
|
bun run tauri dev
|
||||||
|
|
||||||
|
# Preview production build
|
||||||
|
bun run preview
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building
|
||||||
|
```bash
|
||||||
|
# Build frontend only (TypeScript compile + Vite bundle)
|
||||||
|
bun run build
|
||||||
|
|
||||||
|
# Build complete Tauri application (all platforms)
|
||||||
|
bun run tauri build
|
||||||
|
|
||||||
|
# Build for specific platform
|
||||||
|
bun run tauri build --target x86_64-pc-windows-msvc # Windows
|
||||||
|
bun run tauri build --target x86_64-apple-darwin # macOS
|
||||||
|
bun run tauri build --target x86_64-unknown-linux-gnu # Linux
|
||||||
|
```
|
||||||
|
|
||||||
|
### Type Checking
|
||||||
|
```bash
|
||||||
|
# TypeScript type check (run before build)
|
||||||
|
tsc --noEmit
|
||||||
|
|
||||||
|
# Watch mode for continuous type checking
|
||||||
|
tsc --noEmit --watch
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rust Commands
|
||||||
|
```bash
|
||||||
|
# Check Rust code (fast compile check)
|
||||||
|
cd src-tauri && cargo check
|
||||||
|
|
||||||
|
# Format Rust code
|
||||||
|
cd src-tauri && cargo fmt
|
||||||
|
|
||||||
|
# Lint Rust code
|
||||||
|
cd src-tauri && cargo clippy
|
||||||
|
|
||||||
|
# Run Rust tests
|
||||||
|
cd src-tauri && cargo test
|
||||||
|
|
||||||
|
# Run a specific Rust test
|
||||||
|
cd src-tauri && cargo test test_name
|
||||||
|
|
||||||
|
# Run tests with output
|
||||||
|
cd src-tauri && cargo test -- --nocapture
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
**Note**: No test framework is currently configured. To add testing:
|
||||||
|
|
||||||
|
**Frontend Testing** (recommended: Vitest):
|
||||||
|
```bash
|
||||||
|
bun add -D vitest @vitest/ui
|
||||||
|
# Run all tests: bun run vitest
|
||||||
|
# Run single test: bun run vitest path/to/test.test.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rust Testing**: Use built-in `cargo test` (see above)
|
||||||
|
|
||||||
|
## 📐 Code Style Guidelines
|
||||||
|
|
||||||
|
### TypeScript/JavaScript
|
||||||
|
|
||||||
|
#### Imports
|
||||||
|
- Use ES6 imports: `import { foo } from "bar"`
|
||||||
|
- Tauri API imports: `import { invoke } from "@tauri-apps/api/core"`
|
||||||
|
- Group imports: external packages first, then local modules
|
||||||
|
- No unused imports (enforced by `noUnusedLocals`)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```typescript
|
||||||
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
import { open } from "@tauri-apps/plugin-opener";
|
||||||
|
|
||||||
|
import { helperFunction } from "./utils";
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Types
|
||||||
|
- **Always use explicit types** for function parameters and return values
|
||||||
|
- Use type inference for simple variable assignments
|
||||||
|
- Prefer `interface` for object shapes, `type` for unions/intersections
|
||||||
|
- Enable all strict mode checks (already configured in tsconfig.json)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```typescript
|
||||||
|
// Good ✅
|
||||||
|
async function greet(name: string): Promise<string> {
|
||||||
|
return await invoke("greet", { name });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bad ❌
|
||||||
|
async function greet(name) {
|
||||||
|
return await invoke("greet", { name });
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Naming Conventions
|
||||||
|
- **Variables/Functions**: camelCase (`greetUser`, `userName`)
|
||||||
|
- **Constants**: UPPER_SNAKE_CASE (`MAX_RETRIES`, `API_URL`)
|
||||||
|
- **Types/Interfaces**: PascalCase (`UserData`, `AppConfig`)
|
||||||
|
- **Private members**: prefix with underscore (`_internalState`)
|
||||||
|
|
||||||
|
#### Error Handling
|
||||||
|
- Always handle promises with `async/await` or `.catch()`
|
||||||
|
- Use try-catch for critical operations
|
||||||
|
- Provide meaningful error messages
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```typescript
|
||||||
|
async function callRustCommand(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const result = await invoke<string>("greet", { name: "World" });
|
||||||
|
console.log(result);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to call Rust command:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rust
|
||||||
|
|
||||||
|
#### Formatting
|
||||||
|
- Use `cargo fmt` (rustfmt) for automatic formatting
|
||||||
|
- 4 spaces for indentation (standard Rust)
|
||||||
|
- Line length: 100 characters (rustfmt default)
|
||||||
|
|
||||||
|
#### Naming Conventions
|
||||||
|
- **Functions/Variables**: snake_case (`greet_user`, `user_name`)
|
||||||
|
- **Types/Structs/Enums**: PascalCase (`UserData`, `AppState`)
|
||||||
|
- **Constants**: SCREAMING_SNAKE_CASE (`MAX_CONNECTIONS`)
|
||||||
|
- **Lifetimes**: lowercase single letter (`'a`, `'static`)
|
||||||
|
|
||||||
|
#### Tauri Commands
|
||||||
|
- Mark with `#[tauri::command]` attribute
|
||||||
|
- Use `&str` for string parameters (efficient)
|
||||||
|
- Return owned types (`String`, not `&str`)
|
||||||
|
- Register in `invoke_handler!` macro
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```rust
|
||||||
|
#[tauri::command]
|
||||||
|
fn process_data(input: &str, count: i32) -> Result<String, String> {
|
||||||
|
if count < 0 {
|
||||||
|
return Err("Count must be non-negative".to_string());
|
||||||
|
}
|
||||||
|
Ok(format!("Processed {} with count {}", input, count))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register in lib.rs:
|
||||||
|
.invoke_handler(tauri::generate_handler![process_data])
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Error Handling
|
||||||
|
- Use `Result<T, E>` for fallible operations
|
||||||
|
- Prefer `?` operator for error propagation
|
||||||
|
- Use `expect()` only when panic is acceptable
|
||||||
|
- Return descriptive error messages
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```rust
|
||||||
|
#[tauri::command]
|
||||||
|
fn read_config() -> Result<Config, String> {
|
||||||
|
let data = std::fs::read_to_string("config.json")
|
||||||
|
.map_err(|e| format!("Failed to read config: {}", e))?;
|
||||||
|
|
||||||
|
serde_json::from_str(&data)
|
||||||
|
.map_err(|e| format!("Invalid JSON: {}", e))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔌 Tauri-Specific Patterns
|
||||||
|
|
||||||
|
### Frontend → Rust Communication
|
||||||
|
```typescript
|
||||||
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
|
||||||
|
// Simple command
|
||||||
|
const result = await invoke<string>("command_name", { param: value });
|
||||||
|
|
||||||
|
// With error handling
|
||||||
|
try {
|
||||||
|
const data = await invoke<ReturnType>("command", args);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Command failed:", error);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adding New Commands
|
||||||
|
1. Define in `src-tauri/src/lib.rs`:
|
||||||
|
```rust
|
||||||
|
#[tauri::command]
|
||||||
|
fn new_command(param: &str) -> String {
|
||||||
|
// implementation
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Register in `invoke_handler`:
|
||||||
|
```rust
|
||||||
|
.invoke_handler(tauri::generate_handler![greet, new_command])
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Call from frontend:
|
||||||
|
```typescript
|
||||||
|
await invoke("new_command", { param: "value" });
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📦 Dependencies
|
||||||
|
|
||||||
|
### Adding Dependencies
|
||||||
|
|
||||||
|
**Frontend**:
|
||||||
|
```bash
|
||||||
|
bun add package-name # Production dependency
|
||||||
|
bun add -D package-name # Dev dependency
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rust**:
|
||||||
|
```bash
|
||||||
|
cd src-tauri
|
||||||
|
cargo add package-name # Production dependency
|
||||||
|
cargo add --dev package-name # Dev dependency
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚠️ Common Pitfalls
|
||||||
|
|
||||||
|
1. **Port conflicts**: Dev server uses port 1420, HMR uses 1421
|
||||||
|
2. **Type mismatches**: Ensure Rust return types match TypeScript expectations
|
||||||
|
3. **Missing command registration**: New Tauri commands must be added to `generate_handler!`
|
||||||
|
4. **Permission issues**: Update `src-tauri/capabilities/default.json` for new capabilities
|
||||||
|
5. **Build errors**: Run `tsc` before `vite build` (automated in build script)
|
||||||
|
|
||||||
|
## 🚀 Workflow Tips
|
||||||
|
|
||||||
|
- Always run `tsc --noEmit` before committing to catch type errors
|
||||||
|
- Test Tauri commands with `bun run tauri dev`, not just `bun run dev`
|
||||||
|
- Use `cargo clippy` to catch common Rust mistakes
|
||||||
|
- Check both frontend and Rust console for errors during development
|
||||||
|
- Clear Vite cache if seeing stale builds: `rm -rf node_modules/.vite`
|
||||||
Reference in New Issue
Block a user