commit 2ff42eb1104e4314002559c7401f5457fbbb04c9 Author: Warren Lo Date: Thu Mar 19 00:30:54 2026 +0800 Add comprehensive AGENTS.md with build/test commands and code style guidelines diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..3e19801 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,373 @@ +# MoMentry Playground - AGENTS.md + +## 概述 + +MoMentry Playground 是一個整合式桌面應用程式,提供: +- 多格式媒體播放(視頻、音頻、圖片) +- Markdown/PDF/HTML 檢視 +- Frame-精確的視頻控制 +- 與 momentry_core 處理模組的進度監控 +- Database 查詢功能 + +## 技術棧 + +| 元件 | 技術 | +|------|------| +| 語言 | Rust 2021 | +| 桌面框架 | tao + wry | +| 視頻播放 | SDL2 + FFmpeg-sidecar | +| 前端 | HTML/CSS/JS (WebView) | +| 後端接口 | HTTP API (momentry_core port 3002) | +| 數據庫 | PostgreSQL, MongoDB, Qdrant (via API) | + +--- + +## 構建/測試/代碼質量命令 + +### 構建 +```bash +# Debug 構建 +cargo build + +# Release 構建 +cargo build --release + +# 運行 +cargo run + +# 指定功能運行 +cargo run --features "youtube,cloud" +``` + +### 測試 +```bash +# 運行所有測試 +cargo test + +# 運行單個測試 +cargo test test_name + +# 運行並顯示輸出 +cargo test -- --nocapture + +# 運行 doc tests +cargo test --doc +``` + +### 代碼質量 +```bash +# 格式化代碼 +cargo fmt + +# 檢查格式化 +cargo fmt -- --check + +# Lint + 自動修復 +cargo clippy --fix --allow-dirty --allow-staged + +# Lint 檢查 +cargo clippy + +# 類型檢查 +cargo check + +# 完整檢查(相當於所有以上) +cargo build --all-targets +``` + +### WASM 目標(如使用 Yew) +```bash +# 添加 WASM 目標 +rustup target add wasm32-unknown-unknown + +# 使用 Trunk 開發 +trunk serve + +# Production 構建 +trunk build --release +``` + +--- + +## 代碼風格指南 + +### 格式規範 +- **最大行長**: 100 字符 +- **縮進**: 4 空格(使用 `rustfmt` 自動處理) +- **換行**: Unix 風格 (`\n`) + +### 命名慣例 +```rust +// 類型/結構體/枚舉: PascalCase +struct VideoPlayer; +enum PlaybackState; +trait MediaViewer; + +// 函數/方法/變量: snake_case +fn play_video(); +let current_frame = 0; +let is_playing = true; + +// 常量: SCREAMING_SNAKE_CASE +const MAX_FRAME_BUFFER: usize = 10; +const SEEK_DELAY_MS: u64 = 500; + +// 模塊: snake_case +mod video_player; +pub mod ffmpeg; + +// 公開 API: 完整單詞 +fn get_playback_position() -> Duration; +fn set_volume() -> Result<(), PlayerError>; +``` + +### 錯誤處理 +```rust +// 使用 anyhow 進行應用級錯誤處理 +use anyhow::{Context, Result, anyhow}; + +fn load_video(path: &str) -> Result { + let file = File::open(path) + .with_context(|| format!("Failed to open video: {}", path))?; + // ... +} + +// 定義專用錯誤枚舉 +#[derive(Debug, thiserror::Error)] +pub enum PlayerError { + #[error("Codec not supported: {0}")] + UnsupportedCodec(String), + + #[error("Seek failed: {0}")] + SeekFailed(String), + + #[error("FFmpeg error: {stderr}")] + FFmpegError { stderr: String }, +} +``` + +### 模塊結構 +```rust +// src/lib.rs - 庫入口 +pub mod player; +pub mod ui; +pub mod viewer; +pub mod api; + +// 每個模塊的組織 +mod player { + pub mod video; // 公開子模塊 + mod controls; // 私有實現 + + pub use video::{VideoPlayer, VideoEvent}; +} +``` + +### 並發安全 +```rust +// 使用 Arc> 共享狀態 +let player = Arc::new(Mutex::new(VideoPlayer::new())); + +// 在多線程間共享 Frame buffer +type FrameBuffer = Arc>>; + +// Spawn 線程時克隆 Arc +let player_clone = Arc::clone(&player); +std::thread::spawn(move || { + // ... +}); +``` + +### 文檔注釋 +```rust +/// 視頻播放器核心結構 +/// +/// # Example +/// ``` +/// let player = VideoPlayer::new(); +/// player.open("video.mp4")?; +/// player.play()?; +/// ``` +pub struct VideoPlayer { + // ... +} + +/// 播放事件 +#[derive(Debug, Clone, PartialEq)] +pub enum PlayEvent { + /// 播放開始 + Play, + /// 播放暫停 + Pause, + /// 進度更新 (當前幀, 總幀數) + Progress(u64, u64), + /// 播放結束 + End, +} +``` + +### 依賴管理 +```toml +# 明確版本範圍 +[dependencies] +anyhow = "1.0" +serde = { version = "1.0", features = ["derive"] } + +# 避免使用 * 導入 +# 錯誤: use std::collections::*; +# 正確: use std::collections::{HashMap, HashSet}; +``` + +### API 設計 +```rust +// 使用 Result 明確錯誤 +fn command(&self, cmd: &str) -> Result; + +// 公開方法要有文檔 +/// 發送播放命令 +/// +/// # Arguments +/// * `cmd` - 命令字串 ("play", "pause", "seek