# AGENTS.md ## AI 行为准则 - **称呼规范**:始终称呼用户为「思谦」或「王思谦」。 - **信息缺失处理**:遇到任何不确定、拿不准或信息缺失的情况,不要自行推测。先收集整理好问题,停下来向思谦确认后再继续。 ## Build & Test ```bash dotnet build # Build all projects dotnet test # Run all tests dotnet test --filter "FullyQualifiedName~ClassName.MethodName" # Run single test dotnet run --project src/GUI # Launch the Avalonia desktop app ``` ## Architecture - **4-project solution** (`src/Resonance.sln`): - `Core` — class library: audio file scanning, metadata reading (ATL), SQLite persistence (Dapper) - `Core.Tests` — xUnit + FluentAssertions + Moq - `AtlFieldExtractor` — CLI that dumps ATL metadata fields from WAV files to `.atl.txt` to test ATL library - `GUI` — Avalonia 12 desktop app: audio asset management UI - **MVVM architecture** (GUI project): - Based on **CommunityToolkit.Mvvm** v8.4.1 — source-generator-driven MVVM toolkit. - Base class: `ViewModelBase` (abstract, extends `ObservableObject`). Use `[ObservableProperty]` for bindable properties, `[RelayCommand]` for commands, and `SetProperty()` for manual property change notification. - View-ViewModel binding: `ViewLocator` implements `IDataTemplate` — convention-based resolution by replacing `"ViewModel"` with `"View"` in the type name (e.g., `MainWindowViewModel` → looks for `MainWindow` in `GUI.Views`). Uses `Activator.CreateInstance()`; **no DI container** is configured. - Compiled bindings are enabled by default (`AvaloniaUseCompiledBindingsByDefault=true` in `.csproj`). Annotate XAML with `x:DataType="vm:MyViewModel"` for compile-time validation. - `App.axaml` applies `FluentTheme` and registers `ViewLocator` globally. `App.axaml.cs` manually instantiates `MainWindow` → `MainWindowViewModel` in `OnFrameworkInitializationCompleted`. - Target framework: `net10.0` (requires .NET 10 SDK — currently `10.0.103`). ## Known Issues / Gotchas - **升级 Avalonia 版本时,必须同步更新所有次级包引用。** 仅修改主包 `Avalonia` 的 Version 不会自动更新 `Avalonia.Desktop`、`Avalonia.Themes.Fluent`、`Avalonia.Fonts.Inter` 等次级包。必须手动逐个修改,然后执行 `dotnet clean && dotnet restore`。否则运行时的原生库(如 `libAvaloniaNative.dylib`)会混用新旧版本,导致 macOS 上的 `StorageProvider` 文件/文件夹选择对话框在回调时 SIGSEGV 崩溃。 - 相关 Avalonia issues: [#21102](https://github.com/AvaloniaUI/Avalonia/issues/21102), [#21150](https://github.com/AvaloniaUI/Avalonia/issues/21150), [#21313](https://github.com/AvaloniaUI/Avalonia/issues/21313),修复 PR: [#21104](https://github.com/AvaloniaUI/Avalonia/pull/21104)。 - **Tests create temp files/directories** under `Path.GetTempPath()` and clean them up via `IDisposable`. Don't rely on a real audio directory for tests. - **`AudioMetadataReader` tests** use real WAV files from `data/source/` (not in git). When files are absent, tests silently return early (`if (wavFiles.Length == 0) return;`) — they pass without actually running assertions, not `Skip.If`. Running `dotnet test` will report 12 passes regardless of whether the fixture files exist. - **`.atl.txt` fixture files** are generated by `AtlFieldExtractor`. If the WAV files or the ATL library version change, re-run the extractor to regenerate them before running metadata tests. - 需要一个UI设计。现在的界面属实有点丑陋了。 ## Conventions - Code and comments are in **Chinese**. - Namespace: `OCES.Resonance.Core` (Core), `OCES.Resonance.AtlFieldExtractor` (extractor), `Core.Tests` (tests), `GUI` / `GUI.Views` / `GUI.ViewModels` (GUI app). ## AI 助手工具说明 ### 工具使用优先级 **优先使用 Rider MCP 服务器工具**(`Rider_*` 系列)。该类工具直接通过 IDE 执行操作,结果更准确、上下文更丰富。 | 场景 | 优先使用 | 回退方案 | |------|---------|---------| | 读取文件 | `Rider_read_file` / `Rider_get_file_text_by_path` | `read_file` | | 写入/编辑 | `Rider_replace_text_in_file` / `Rider_create_new_file` | `write_file` / `edit_file` | | 搜索文件 | `Rider_find_files_by_glob` / `Rider_search_file` | `list_dir` / glob | | 搜索内容 | `Rider_search_text` / `Rider_search_in_files_by_text` | `grep_files` | | 正则搜索 | `Rider_search_regex` / `Rider_search_in_files_by_regex` | `grep_files` | | 代码重构 | `Rider_rename_refactoring` / `Rider_move_type_to_namespace` | `edit_file`(手动)| | 构建 | `Rider_build_solution` | `bash dotnet build` | | 运行测试 | `Rider_execute_run_configuration` | `bash dotnet test` | | 代码问题 | `Rider_get_file_problems` | —(无等效回退) | | 符号查找 | `Rider_search_symbol` / `Rider_get_symbol_info` | `grep_files`(语义降级) | **回退规则**:仅当 Rider MCP 工具不可用(未在工具列表中、调用报错)时,才使用对应的默认工具。 ### 默认工具说明(DeepSeek TUI / OpenCode 等) 当前工作环境可能为 DeepSeek TUI 或 OpenCode,文件操作工具因平台而异,采用**延迟加载**机制的工具首次调用会触发加载并返回 schema 提示(不执行),用正确参数重试后正常执行。 ### 可用文件操作工具 | 工具 | 用途 | 参数注意事项 | |------|------|-------------| | `write_file` | 创建/覆盖文件 | `path` + `content` | | `edit_file` | 单次查找替换 | `path` + `search` + `replace`(注意不是 `old_string`/`new_string`) | | `apply_patch` | 结构化 patch(多块变更) | `path` + `patch`(unified diff 格式) | | `read_file` | 读取文件 | `path`,支持 `start_line`/`max_lines` 分页;PDF 自动提取 | | `list_dir` | 列出目录 | `path`(可选) | | `grep_files` | 正则搜索文件内容 | `pattern`,支持 `include`/`exclude` glob、`context_lines` | ### 使用模式 - 写入/编辑/打补丁:需**两次调用**(首次触发加载,第二次执行) - 读取/搜索:直接可用,单次调用