{"owner":"studyzy","repo":"imewlconverter","hasSkills":true,"totalSkillsCount":4,"totalTokensCount":5707,"categories":["claude-rule","mcp-config","marketplace","plugin-manifest"],"hasMcp":true,"mcpConfig":{"mcpServers":{"imewlconverter":{"command":"npx","args":["-y","@modelcontextprotocol/server-imewlconverter"]}}},"found":["CLAUDE.md",".cursor/mcp.json",".claude-plugin/marketplace.json",".claude-plugin/plugin.json"],"skills":{"CLAUDE.md":"\n## 快速定位\n\n> 这是你进入项目时最先需要知道的信息。根据任务类型，跳转到对应章节。\n\n| 你想做什么 | 入口文件/目录 |\n|-----------|-------------|\n| 添加新的输入法格式支持 | `src/ImeWlConverter.Formats/{Format}/` → 创建 Importer + Exporter |\n| 修改码表/字典数据（拼音、五笔、注音等） | `src/ImeWlConverter.CodeData/`（接口 + `Resources/` 嵌入码表） |\n| 修改转换管道逻辑 | `src/ImeWlConverter.Core/Pipeline/ConversionPipeline.cs` |\n| 修改 CLI 参数/行为 | `src/ImeWlConverter.Application/Cli/`（命令定义+执行链）与 `Mapping/`（参数解析） |\n| 查询 CLI 机器可读契约（退出码/JSON） | `src/ImeWlConverter.Application/Cli/ExitCodes.cs`、`docs/MIGRATION.md` |\n| 修改编码生成（拼音/五笔等） | `src/ImeWlConverter.Core/CodeGeneration/Generators/` |\n| 修改过滤器 | `src/ImeWlConverter.Core/Filters/` |\n| 修改过滤配置 DTO | `src/ImeWlConverter.Abstractions/Options/FilterConfig.cs` |\n| 修改 macOS GUI | `src/ImeWlConverterMac/ViewModels/MainWindowViewModel.cs` |\n| 修改 Windows GUI | `src/IME WL Converter Win/Forms/MainForm.cs` |\n| 添加/修改单元测试 | `src/ImeWlConverterCoreTest/` |\n| 修改 CI 流程 | `.github/workflows/ci.yml` |\n| 发布新版本 | `docs/RELEASING.md` |\n\n## 项目一句话描述\n\n深蓝词库转换（IME WL Converter）是一个跨平台的输入法词库格式转换工具，支持 50+ 种输入法格式之间的相互转换。\n\n- **语言**: C# / .NET 10.0\n- **测试框架**: xUnit 2.9.3\n- **构建系统**: Makefile + dotnet CLI\n- **版本管理**: MinVer（从 Git tag 自动生成）\n- **平台**: Windows / Linux / macOS\n\n## 日常命令\n\n```bash\nmake build              # 构建所有项目\nmake test               # 运行单元测试 (318 个，实际以 dotnet test 输出为准)\nmake integration-test   # 运行集成测试 (29 个用例，需先 make build-cmd)\nmake lint               # 检查代码格式\nmake format             # 自动格式化代码\nmake run-cmd            # 运行 CLI 工具\nmake run-mac            # 运行 macOS GUI\n```\n\n## 架构概览\n\n```\nsrc/\n├── ImeWlConverter.Abstractions/     # 接口层（零依赖）\n├── ImeWlConverter.CodeData/         # 码表数据叶子（零依赖，只读线程安全表服务）\n├── ImeWlConverter.Core/             # 业务服务层（转换管道、编码生成、过滤、简繁转换）\n├── ImeWlConverter.Formats/          # 格式实现层（107个文件，50+种格式）\n├── ImeWlConverter.Application/      # 三端共享应用层（参数映射、请求工厂、CLI 前端、引导）\n├── ImeWlConverter.SourceGenerators/ # Source Generator（编译时格式注册）\n├── ImeWlConverterCmd/               # CLI 薄入口（逻辑在 Application/Cli）\n├── ImeWlConverterMac/               # macOS GUI (Avalonia 11.2.3)\n├── IME WL Converter Win/            # Windows GUI (WinForms)\n└── ImeWlConverterCoreTest/          # xUnit 单元测试\n```\n\n### 三端统一数据流\n\n```\n┌─────────────┐   ┌─────────────┐   ┌─────────────┐\n│   CLI       │   │  WinForms   │   │  macOS GUI  │\n│ CommandBuild│   │  MainForm   │   │  ViewModel  │\n└──────┬──────┘   └──────┬──────┘   └──────┬──────┘\n       │                 │                  │\n       └────共享 Application 层────┬─────────┘\n                    ▼\n        ┌───────────────────────┐\n        │  IConversionPipeline  │  (Abstractions 层接口)\n        └───────────┬───────────┘\n                    ▼\n        ┌───────────────────────┐\n        │  ConversionPipeline   │  (Core 层统一实现)\n        │                       │\n        │  Import → Filter →    │\n        │  ChineseConvert →     │\n        │  WordRank → CodeGen → │\n        │  RemoveEmpty → Export │\n        └───────────────────────┘\n```\n\n**设计原则**：三端（CLI、WinForms、macOS GUI）共用同一个 `ConversionPipeline` 底层转换引擎，只在用户交互层不同。\n\n- CLI 通过 `Application/Cli` 与 `Application/Requests` 解析参数构建 `ConversionRequest`\n- WinForms 通过 `MainForm` 用户操作构建 `ConversionRequest`\n- macOS GUI 通过 `MainWindowViewModel` 构建 `ConversionRequest`\n- 三端共享 `FilterConfig`（`Abstractions/Options/`）、`ConversionOptions`、`IProgress<ProgressInfo>`\n\n---\n\n## 深入：项目层次\n\n以下按从外到内的顺序描述各层，你只需要读到与任务相关的层即可。\n\n### Layer 1: 前端入口\n\n#### CLI (`src/ImeWlConverterCmd/` → `src/ImeWlConverter.Application/Cli/`)\n\n| 文件 | 职责 |\n|------|------|\n| `ImeWlConverterCmd/Program.cs` | 薄入口：注册编码 Provider，调用 `CliApp.Run` |\n| `Application/Cli/CliApp.cs` | CLI 统一入口（旧参数检测 → 命令调用）；Win 内嵌 CLI 共用 |\n| `Application/Cli/CliOptions.cs` | System.CommandLine 选项定义 |\n| `Application/Cli/CliCommandFactory.cs` | 根命令装配与转换执行链（校验→组装→执行→输出） |\n| `Application/Cli/CliValidator.cs` | 必填项/文件存在性/格式 ID 校验（结构化 CliError） |\n| `Application/Cli/Output/*.cs` | 人类输出 / --json 输出 / 格式清单输出 |\n| `Application/Cli/ExitCodes.cs` | 退出码契约（0 成功 / 1 用法 / 2 输入 / 3 部分失败 / 4 内部） |\n| `Application/Mapping/*.cs` | filter/编码类型/自定义格式 spec 解析（Try 模式，可单测） |\n| `Application/Requests/ConversionRequestFactory.cs` | ConversionRequest 组装单一事实来源 |\n| `Application/Bootstrap/ImeWlConverterBootstrapper.cs` | 三端共用 DI 组装 |\n\n#### macOS GUI (`src/ImeWlConverterMac/`)\n\n| 文件 | 职责 |\n|------|------|\n| `App.axaml.cs` | 应用入口，创建 DI 容器，注入 ViewModel |\n| `ViewModels/MainWindowViewModel.cs` | MVVM ViewModel，构建 `ConversionRequest`，调用 `IConversionPipeline` |\n| `Views/FilterConfigWindow.axaml.cs` | 过滤配置 UI，使用共享 `FilterConfig` DTO |\n\n#### Windows GUI (`src/IME WL Converter Win/`)\n\n| 文件 | 职责 |\n|------|------|\n| `Program.cs` | 应用入口，创建 DI 容器 |\n| `Forms/MainForm.cs` | 主窗口，构建 `ConversionRequest`，调用 `IConversionPipeline` |\n| `Forms/FilterConfigForm.cs` | 过滤配置 UI，使用共享 `FilterConfig` DTO |\n\n### Layer 2: 转换管道 (`src/ImeWlConverter.Core/Pipeline/`)\n\n| 文件 | 职责 |\n|------|------|\n| `ConversionPipeline.cs` | 薄编排层：导入 → 委托 EntryTransformationService → 导出；合并/逐文件两种模式 |\n| `EntryTransformationService.cs` | 词条五阶段处理（Filter→ChineseConvert→WordRank→CodeGen→RemoveEmpty），两条导出路径共用 |\n| `FilterPipelineFactory.cs` + `FilterModules/` | 过滤器装配（模块注册制，开闭原则） |\n| `FilterPipeline.cs` | 过滤执行器（单条过滤 → 变换 → 批量过滤） |\n| `CodePredicates.cs` | 空编码判定谓词（两条路径共用） |\n| `SelfDefiningCodeSource.cs` | 自定义码表加载（ISelfDefiningCodeSource 实现） |\n\n`ConversionPipeline` 支持的能力：\n- **合并导出** / **逐文件导出**（`MergeToOneFile` 选项）\n- **文件输出** / **Stream 输出**（GUI 先预览再保存）\n- **从 FilterConfig 经 FilterPipelineFactory 模块化构建 FilterPipeline**\n- **IProgress 细粒度进度报告**\n- **CancellationToken 取消支持**\n- **逐文件错误捕获与结构化累积**（`ConversionResult.Errors`）\n\n### Layer 3: 格式实现 (`src/ImeWlConverter.Formats/`)\n\n每个格式拆分为独立的 Importer 和 Exporter，通过 `[FormatPlugin]` 属性标记，Source Generator 自动注册到 DI。\n\n| 基类 | 用途 |\n|------|------|\n| `TextFormatImporter` | 文本格式导入（逐行解析） |\n| `TextFormatExporter` | 文本格式导出（逐行生成） |\n| `BinaryFormatImporter` | 二进制格式导入 |\n\n### Layer 4: 核心基础设施 (`src/ImeWlConverter.Core/`)\n\n| 目录 | 内容 |\n|------|------|\n| `CodeGeneration/Generators/` | 编码生成器（拼音、五笔86/98/新世纪、郑码、仓颉、注音、超音、二笔x4） |\n| `Filters/` | IWordFilter / IWordTransform / IBatchFilter 实现（12 种） |\n| `Helpers/` | 文件操作、编码检测、拼音字典、HTTP |\n| `Language/` | 纯 .NET 简繁转换（基于 OpenCC 映射表） |\n| `WordRank/` | 默认词频生成器 |\n| `Resources/` | 嵌入式码表 + 简繁映射文件 |\n\n### Layer 5: 抽象层 (`src/ImeWlConverter.Abstractions/`)\n\n纯接口和 DTO，零依赖。供所有层引用。\n\n| 子目录 | 关键类型 |\n|--------|---------|\n| `Contracts/` | IFormatImporter, IFormatExporter, IConversionPipeline, ICodeGenerator, IWordFilter, IWordTransform, IBatchFilter |\n| `Models/` | WordEntry (sealed record), WordCode, FormatMetadata, ProgressInfo |\n| `Options/` | ConversionOptions, FilterConfig, CodeGenerationOptions, ImportOptions, ExportOptions |\n| `Results/` | Result\\<T\\>, ImportResult, ExportResult, ConversionRequest, ConversionResult |\n| `Enums/` | CodeType, SortType, PinyinType, ChineseConversionMode |\n\n---\n\n## 常见任务操作指南\n\n### 添加新的输入法格式\n\n```bash\n# 1. 在 Formats 项目中创建目录和文件\nmkdir src/ImeWlConverter.Formats/MyFormat/\n```\n\n```csharp\n// 2. 创建 Importer（注意：必须是 partial 类，且不要手写 Metadata 属性——由 Source Generator 生成）\n[FormatPlugin(\"myf\", \"我的格式\", 500)]\npublic sealed partial class MyFormatImporter : TextFormatImporter\n{\n    protected override Encoding FileEncoding => new UTF8Encoding(false);\n    protected override bool IsContentLine(string line) =>\n        !string.IsNullOrWhiteSpace(line) && !line.StartsWith(\"#\"); // 可选：跳过注释/空行\n    protected override IEnumerable<WordEntry> ParseLine(string line) { /* 解析逻辑 */ }\n}\n```\n\n```csharp\n// 3. 创建 Exporter（同样不手写 Metadata）\n[FormatPlugin(\"myf\", \"我的格式\", 500)]\npublic sealed partial class MyFormatExporter : TextFormatExporter\n{\n    protected override Encoding FileEncoding => new UTF8Encoding(false);\n    protected override string? FormatEntry(WordEntry entry) { /* 导出逻辑，返回 null 跳过该词条 */ }\n}\n```\n\nSource Generator 会自动完成两件事：\n- 将带 `[FormatPlugin]` 的类注册到 DI 容器（无需手动注册）\n- 为每个类生成 `Metadata` 属性（从 `[FormatPlugin]` 参数与基类链自动推断 `IsBinary` 等，**手写 Metadata 会与生成代码冲突**）\n\n完整真实示例见 `src/ImeWlConverter.Formats/Rime/RimeImporter.cs`。\n\n### 修改过滤逻辑\n\n过滤器位于 `src/ImeWlConverter.Core/Filters/`，实现接口：\n\n```csharp\npublic interface IWordFilter { bool ShouldKeep(WordEntry entry); }\npublic interface IWordTransform { WordEntry? Transform(WordEntry entry); }\npublic interface IBatchFilter { IReadOnlyList<WordEntry> Filter(IReadOnlyList<WordEntry> entries); }\n```\n\n`FilterConfig`（`Abstractions/Options/FilterConfig.cs`）定义了所有过滤选项，`ConversionPipeline` 内部的 `BuildFilterPipeline()` 方法将其转换为 `FilterPipeline` 实例。\n\nCLI 通过 `--filter` 参数启用过滤：`-f \"len:2-10|rm:eng|rm:num\"`\n\n### 修改编码生成\n\n编码生成器位于 `src/ImeWlConverter.Core/CodeGeneration/Generators/`，实现 `ICodeGenerator` 接口。通过 DI 注册，由 `CodeGenerationService` 根据 `CodeType` 选择对应生成器。\n\n### 修改转换管道行为\n\n- **编排与导出**：`src/ImeWlConverter.Core/Pipeline/ConversionPipeline.cs`（薄层）\n- **词条阶段处理**：`EntryTransformationService.cs`，7 步流程：\n\n1. **Import** — 逐文件导入，累积所有 WordEntry（ConversionPipeline）\n2. **Filter → ChineseConvert → WordRank → CodeGen → RemoveEmpty** — EntryTransformationService.ApplyAsync（合并模式调一次，逐文件模式每文件一次）\n3. **Export** — 导出到文件或 Stream（ConversionPipeline）\n\n### 修改过滤逻辑（注册制）\n\n- 过滤器实现位于 `src/ImeWlConverter.Core/Filters/`，装配位于 `Pipeline/FilterPipelineFactory.cs` + `Pipeline/FilterModules/`\n- **新增过滤器**：实现 `IFilterModule`（或往现有模块加一行）→ 加入 `DefaultFilterModules.Create()` 清单即可，无需修改管道\n\n---\n\n## 项目约定\n\n### 禁止操作\n\n- **禁止手动修改版本号**（由 MinVer 从 Git tag 生成，配置在 `src/Directory.Build.props`）\n- **禁止使用运行时反射注册格式**（Source Generator 自动注册）\n- **禁止硬编码路径分隔符**（用 `Path.Combine()`）\n- **禁止在 GUI 项目中重复实现转换逻辑**（统一使用 `IConversionPipeline`）\n- **禁止 GUI 内联格式识别/请求组装/预览截断**（统一用 `ImeWlConverter.Application` 的 FormatDetectionService/ConversionRequestFactory/PreviewService——历史上三端各写一份已导致 macOS 识别 Bug）\n- **禁止 CLI 输出契约随意变更**（退出码 0-4 与 --json schema 见 `Application/Cli/ExitCodes.cs` 与 `docs/MIGRATION.md`；变更必须同步基线测试 `tests/integration/cli-baseline.sh`）\n\n### DI 注册模式\n\n三端使用相同的 DI 注册方式：\n\n```csharp\nvar services = new ServiceCollection();\nservices.AddAllFormats();           // Source Generator 生成的格式注册\nservices.AddImeWlConverterCore();   // 管道、编码生成器、简繁转换、词频生成器\nvar sp = services.BuildServiceProvider();\n\n// 获取管道\nvar pipeline = sp.GetRequiredService<IConversionPipeline>();\n```\n\n### 编码处理\n\n项目处理多种字符编码（UTF-8、GBK、GB2312、Big5、Unicode）。.NET 10 已内置 CodePages 支持，但部分旧代码仍调用：\n```csharp\nEncoding.RegisterProvider(CodePagesEncodingProvider.Instance);\n```\n\n### 跨平台注意事项\n\n- CLI 工具为 framework-dependent（需 .NET 运行时）\n- macOS app bundle 为 self-contained（包含运行时）\n- Windows GUI 为 WinForms（仅 Windows）\n- 集成测试支持 Linux、macOS、Windows (Git Bash)\n\n### 测试\n\n- **单元测试**: xUnit 2.9.3，位于 `src/ImeWlConverterCoreTest/`\n- **集成测试**: shell 脚本框架，位于 `tests/integration/`\n- 测试并行执行（`xunit.runner.json` 中 `parallelizeTestCollections: true`；Phase 2 已消灭静态可变状态，码表全部走 `ImeWlConverter.CodeData` 的线程安全只读表）\n- **禁新增 static 可变字典/集合**——需要码表数据时注入 `ICodeTableLibrary`/`IPinyinTable` 等接口（见 `src/ImeWlConverter.CodeData/`）\n- `[Fact(Skip = \"...\")]` 标记按需运行的慢速测试\n\n### CI/CD\n\nGitHub Actions (`.github/workflows/ci.yml`)：\n1. Lint（格式检查，快速失败）\n2. Build + 单元测试 (Ubuntu)\n3. 多平台构建 (Win x64/x86, Linux x64/arm64, macOS x64/arm64)\n4. 集成测试 (Linux + macOS)\n\n---\n\n## 关键决策记录\n\n| 决策 | 原因 |\n|------|------|\n| 三端统一使用 ConversionPipeline | 消除重复转换逻辑，保证行为一致 |\n| FilterConfig 放在 Abstractions 层 | 三端共享过滤配置 DTO，避免各端重复定义 |\n| ConversionPipeline 支持 Stream 输出 | GUI 需要先预览内容再决定是否保存 |\n| CLI 用 FormatRegistrar 显式注册 | 消除反射，支持 AOT/Trimming |\n| Source Generator 注册新格式 | 添加格式只需加 `[FormatPlugin]` 属性 |\n| 测试并行执行 | Phase 2 建立码表数据层（CodeData），静态可变字典全部改为 DI 只读表，竞态根因消除 |\n| sealed record 实体 | 不可变性保证，不会意外修改中间状态 |\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.claude-plugin/plugin.json)"},"files":{"CLAUDE.md":"\n## 快速定位\n\n> 这是你进入项目时最先需要知道的信息。根据任务类型，跳转到对应章节。\n\n| 你想做什么 | 入口文件/目录 |\n|-----------|-------------|\n| 添加新的输入法格式支持 | `src/ImeWlConverter.Formats/{Format}/` → 创建 Importer + Exporter |\n| 修改码表/字典数据（拼音、五笔、注音等） | `src/ImeWlConverter.CodeData/`（接口 + `Resources/` 嵌入码表） |\n| 修改转换管道逻辑 | `src/ImeWlConverter.Core/Pipeline/ConversionPipeline.cs` |\n| 修改 CLI 参数/行为 | `src/ImeWlConverter.Application/Cli/`（命令定义+执行链）与 `Mapping/`（参数解析） |\n| 查询 CLI 机器可读契约（退出码/JSON） | `src/ImeWlConverter.Application/Cli/ExitCodes.cs`、`docs/MIGRATION.md` |\n| 修改编码生成（拼音/五笔等） | `src/ImeWlConverter.Core/CodeGeneration/Generators/` |\n| 修改过滤器 | `src/ImeWlConverter.Core/Filters/` |\n| 修改过滤配置 DTO | `src/ImeWlConverter.Abstractions/Options/FilterConfig.cs` |\n| 修改 macOS GUI | `src/ImeWlConverterMac/ViewModels/MainWindowViewModel.cs` |\n| 修改 Windows GUI | `src/IME WL Converter Win/Forms/MainForm.cs` |\n| 添加/修改单元测试 | `src/ImeWlConverterCoreTest/` |\n| 修改 CI 流程 | `.github/workflows/ci.yml` |\n| 发布新版本 | `docs/RELEASING.md` |\n\n## 项目一句话描述\n\n深蓝词库转换（IME WL Converter）是一个跨平台的输入法词库格式转换工具，支持 50+ 种输入法格式之间的相互转换。\n\n- **语言**: C# / .NET 10.0\n- **测试框架**: xUnit 2.9.3\n- **构建系统**: Makefile + dotnet CLI\n- **版本管理**: MinVer（从 Git tag 自动生成）\n- **平台**: Windows / Linux / macOS\n\n## 日常命令\n\n```bash\nmake build              # 构建所有项目\nmake test               # 运行单元测试 (318 个，实际以 dotnet test 输出为准)\nmake integration-test   # 运行集成测试 (29 个用例，需先 make build-cmd)\nmake lint               # 检查代码格式\nmake format             # 自动格式化代码\nmake run-cmd            # 运行 CLI 工具\nmake run-mac            # 运行 macOS GUI\n```\n\n## 架构概览\n\n```\nsrc/\n├── ImeWlConverter.Abstractions/     # 接口层（零依赖）\n├── ImeWlConverter.CodeData/         # 码表数据叶子（零依赖，只读线程安全表服务）\n├── ImeWlConverter.Core/             # 业务服务层（转换管道、编码生成、过滤、简繁转换）\n├── ImeWlConverter.Formats/          # 格式实现层（107个文件，50+种格式）\n├── ImeWlConverter.Application/      # 三端共享应用层（参数映射、请求工厂、CLI 前端、引导）\n├── ImeWlConverter.SourceGenerators/ # Source Generator（编译时格式注册）\n├── ImeWlConverterCmd/               # CLI 薄入口（逻辑在 Application/Cli）\n├── ImeWlConverterMac/               # macOS GUI (Avalonia 11.2.3)\n├── IME WL Converter Win/            # Windows GUI (WinForms)\n└── ImeWlConverterCoreTest/          # xUnit 单元测试\n```\n\n### 三端统一数据流\n\n```\n┌─────────────┐   ┌─────────────┐   ┌─────────────┐\n│   CLI       │   │  WinForms   │   │  macOS GUI  │\n│ CommandBuild│   │  MainForm   │   │  ViewModel  │\n└──────┬──────┘   └──────┬──────┘   └──────┬──────┘\n       │                 │                  │\n       └────共享 Application 层────┬─────────┘\n                    ▼\n        ┌───────────────────────┐\n        │  IConversionPipeline  │  (Abstractions 层接口)\n        └───────────┬───────────┘\n                    ▼\n        ┌───────────────────────┐\n        │  ConversionPipeline   │  (Core 层统一实现)\n        │                       │\n        │  Import → Filter →    │\n        │  ChineseConvert →     │\n        │  WordRank → CodeGen → │\n        │  RemoveEmpty → Export │\n        └───────────────────────┘\n```\n\n**设计原则**：三端（CLI、WinForms、macOS GUI）共用同一个 `ConversionPipeline` 底层转换引擎，只在用户交互层不同。\n\n- CLI 通过 `Application/Cli` 与 `Application/Requests` 解析参数构建 `ConversionRequest`\n- WinForms 通过 `MainForm` 用户操作构建 `ConversionRequest`\n- macOS GUI 通过 `MainWindowViewModel` 构建 `ConversionRequest`\n- 三端共享 `FilterConfig`（`Abstractions/Options/`）、`ConversionOptions`、`IProgress<ProgressInfo>`\n\n---\n\n## 深入：项目层次\n\n以下按从外到内的顺序描述各层，你只需要读到与任务相关的层即可。\n\n### Layer 1: 前端入口\n\n#### CLI (`src/ImeWlConverterCmd/` → `src/ImeWlConverter.Application/Cli/`)\n\n| 文件 | 职责 |\n|------|------|\n| `ImeWlConverterCmd/Program.cs` | 薄入口：注册编码 Provider，调用 `CliApp.Run` |\n| `Application/Cli/CliApp.cs` | CLI 统一入口（旧参数检测 → 命令调用）；Win 内嵌 CLI 共用 |\n| `Application/Cli/CliOptions.cs` | System.CommandLine 选项定义 |\n| `Application/Cli/CliCommandFactory.cs` | 根命令装配与转换执行链（校验→组装→执行→输出） |\n| `Application/Cli/CliValidator.cs` | 必填项/文件存在性/格式 ID 校验（结构化 CliError） |\n| `Application/Cli/Output/*.cs` | 人类输出 / --json 输出 / 格式清单输出 |\n| `Application/Cli/ExitCodes.cs` | 退出码契约（0 成功 / 1 用法 / 2 输入 / 3 部分失败 / 4 内部） |\n| `Application/Mapping/*.cs` | filter/编码类型/自定义格式 spec 解析（Try 模式，可单测） |\n| `Application/Requests/ConversionRequestFactory.cs` | ConversionRequest 组装单一事实来源 |\n| `Application/Bootstrap/ImeWlConverterBootstrapper.cs` | 三端共用 DI 组装 |\n\n#### macOS GUI (`src/ImeWlConverterMac/`)\n\n| 文件 | 职责 |\n|------|------|\n| `App.axaml.cs` | 应用入口，创建 DI 容器，注入 ViewModel |\n| `ViewModels/MainWindowViewModel.cs` | MVVM ViewModel，构建 `ConversionRequest`，调用 `IConversionPipeline` |\n| `Views/FilterConfigWindow.axaml.cs` | 过滤配置 UI，使用共享 `FilterConfig` DTO |\n\n#### Windows GUI (`src/IME WL Converter Win/`)\n\n| 文件 | 职责 |\n|------|------|\n| `Program.cs` | 应用入口，创建 DI 容器 |\n| `Forms/MainForm.cs` | 主窗口，构建 `ConversionRequest`，调用 `IConversionPipeline` |\n| `Forms/FilterConfigForm.cs` | 过滤配置 UI，使用共享 `FilterConfig` DTO |\n\n### Layer 2: 转换管道 (`src/ImeWlConverter.Core/Pipeline/`)\n\n| 文件 | 职责 |\n|------|------|\n| `ConversionPipeline.cs` | 薄编排层：导入 → 委托 EntryTransformationService → 导出；合并/逐文件两种模式 |\n| `EntryTransformationService.cs` | 词条五阶段处理（Filter→ChineseConvert→WordRank→CodeGen→RemoveEmpty），两条导出路径共用 |\n| `FilterPipelineFactory.cs` + `FilterModules/` | 过滤器装配（模块注册制，开闭原则） |\n| `FilterPipeline.cs` | 过滤执行器（单条过滤 → 变换 → 批量过滤） |\n| `CodePredicates.cs` | 空编码判定谓词（两条路径共用） |\n| `SelfDefiningCodeSource.cs` | 自定义码表加载（ISelfDefiningCodeSource 实现） |\n\n`ConversionPipeline` 支持的能力：\n- **合并导出** / **逐文件导出**（`MergeToOneFile` 选项）\n- **文件输出** / **Stream 输出**（GUI 先预览再保存）\n- **从 FilterConfig 经 FilterPipelineFactory 模块化构建 FilterPipeline**\n- **IProgress 细粒度进度报告**\n- **CancellationToken 取消支持**\n- **逐文件错误捕获与结构化累积**（`ConversionResult.Errors`）\n\n### Layer 3: 格式实现 (`src/ImeWlConverter.Formats/`)\n\n每个格式拆分为独立的 Importer 和 Exporter，通过 `[FormatPlugin]` 属性标记，Source Generator 自动注册到 DI。\n\n| 基类 | 用途 |\n|------|------|\n| `TextFormatImporter` | 文本格式导入（逐行解析） |\n| `TextFormatExporter` | 文本格式导出（逐行生成） |\n| `BinaryFormatImporter` | 二进制格式导入 |\n\n### Layer 4: 核心基础设施 (`src/ImeWlConverter.Core/`)\n\n| 目录 | 内容 |\n|------|------|\n| `CodeGeneration/Generators/` | 编码生成器（拼音、五笔86/98/新世纪、郑码、仓颉、注音、超音、二笔x4） |\n| `Filters/` | IWordFilter / IWordTransform / IBatchFilter 实现（12 种） |\n| `Helpers/` | 文件操作、编码检测、拼音字典、HTTP |\n| `Language/` | 纯 .NET 简繁转换（基于 OpenCC 映射表） |\n| `WordRank/` | 默认词频生成器 |\n| `Resources/` | 嵌入式码表 + 简繁映射文件 |\n\n### Layer 5: 抽象层 (`src/ImeWlConverter.Abstractions/`)\n\n纯接口和 DTO，零依赖。供所有层引用。\n\n| 子目录 | 关键类型 |\n|--------|---------|\n| `Contracts/` | IFormatImporter, IFormatExporter, IConversionPipeline, ICodeGenerator, IWordFilter, IWordTransform, IBatchFilter |\n| `Models/` | WordEntry (sealed record), WordCode, FormatMetadata, ProgressInfo |\n| `Options/` | ConversionOptions, FilterConfig, CodeGenerationOptions, ImportOptions, ExportOptions |\n| `Results/` | Result\\<T\\>, ImportResult, ExportResult, ConversionRequest, ConversionResult |\n| `Enums/` | CodeType, SortType, PinyinType, ChineseConversionMode |\n\n---\n\n## 常见任务操作指南\n\n### 添加新的输入法格式\n\n```bash\n# 1. 在 Formats 项目中创建目录和文件\nmkdir src/ImeWlConverter.Formats/MyFormat/\n```\n\n```csharp\n// 2. 创建 Importer（注意：必须是 partial 类，且不要手写 Metadata 属性——由 Source Generator 生成）\n[FormatPlugin(\"myf\", \"我的格式\", 500)]\npublic sealed partial class MyFormatImporter : TextFormatImporter\n{\n    protected override Encoding FileEncoding => new UTF8Encoding(false);\n    protected override bool IsContentLine(string line) =>\n        !string.IsNullOrWhiteSpace(line) && !line.StartsWith(\"#\"); // 可选：跳过注释/空行\n    protected override IEnumerable<WordEntry> ParseLine(string line) { /* 解析逻辑 */ }\n}\n```\n\n```csharp\n// 3. 创建 Exporter（同样不手写 Metadata）\n[FormatPlugin(\"myf\", \"我的格式\", 500)]\npublic sealed partial class MyFormatExporter : TextFormatExporter\n{\n    protected override Encoding FileEncoding => new UTF8Encoding(false);\n    protected override string? FormatEntry(WordEntry entry) { /* 导出逻辑，返回 null 跳过该词条 */ }\n}\n```\n\nSource Generator 会自动完成两件事：\n- 将带 `[FormatPlugin]` 的类注册到 DI 容器（无需手动注册）\n- 为每个类生成 `Metadata` 属性（从 `[FormatPlugin]` 参数与基类链自动推断 `IsBinary` 等，**手写 Metadata 会与生成代码冲突**）\n\n完整真实示例见 `src/ImeWlConverter.Formats/Rime/RimeImporter.cs`。\n\n### 修改过滤逻辑\n\n过滤器位于 `src/ImeWlConverter.Core/Filters/`，实现接口：\n\n```csharp\npublic interface IWordFilter { bool ShouldKeep(WordEntry entry); }\npublic interface IWordTransform { WordEntry? Transform(WordEntry entry); }\npublic interface IBatchFilter { IReadOnlyList<WordEntry> Filter(IReadOnlyList<WordEntry> entries); }\n```\n\n`FilterConfig`（`Abstractions/Options/FilterConfig.cs`）定义了所有过滤选项，`ConversionPipeline` 内部的 `BuildFilterPipeline()` 方法将其转换为 `FilterPipeline` 实例。\n\nCLI 通过 `--filter` 参数启用过滤：`-f \"len:2-10|rm:eng|rm:num\"`\n\n### 修改编码生成\n\n编码生成器位于 `src/ImeWlConverter.Core/CodeGeneration/Generators/`，实现 `ICodeGenerator` 接口。通过 DI 注册，由 `CodeGenerationService` 根据 `CodeType` 选择对应生成器。\n\n### 修改转换管道行为\n\n- **编排与导出**：`src/ImeWlConverter.Core/Pipeline/ConversionPipeline.cs`（薄层）\n- **词条阶段处理**：`EntryTransformationService.cs`，7 步流程：\n\n1. **Import** — 逐文件导入，累积所有 WordEntry（ConversionPipeline）\n2. **Filter → ChineseConvert → WordRank → CodeGen → RemoveEmpty** — EntryTransformationService.ApplyAsync（合并模式调一次，逐文件模式每文件一次）\n3. **Export** — 导出到文件或 Stream（ConversionPipeline）\n\n### 修改过滤逻辑（注册制）\n\n- 过滤器实现位于 `src/ImeWlConverter.Core/Filters/`，装配位于 `Pipeline/FilterPipelineFactory.cs` + `Pipeline/FilterModules/`\n- **新增过滤器**：实现 `IFilterModule`（或往现有模块加一行）→ 加入 `DefaultFilterModules.Create()` 清单即可，无需修改管道\n\n---\n\n## 项目约定\n\n### 禁止操作\n\n- **禁止手动修改版本号**（由 MinVer 从 Git tag 生成，配置在 `src/Directory.Build.props`）\n- **禁止使用运行时反射注册格式**（Source Generator 自动注册）\n- **禁止硬编码路径分隔符**（用 `Path.Combine()`）\n- **禁止在 GUI 项目中重复实现转换逻辑**（统一使用 `IConversionPipeline`）\n- **禁止 GUI 内联格式识别/请求组装/预览截断**（统一用 `ImeWlConverter.Application` 的 FormatDetectionService/ConversionRequestFactory/PreviewService——历史上三端各写一份已导致 macOS 识别 Bug）\n- **禁止 CLI 输出契约随意变更**（退出码 0-4 与 --json schema 见 `Application/Cli/ExitCodes.cs` 与 `docs/MIGRATION.md`；变更必须同步基线测试 `tests/integration/cli-baseline.sh`）\n\n### DI 注册模式\n\n三端使用相同的 DI 注册方式：\n\n```csharp\nvar services = new ServiceCollection();\nservices.AddAllFormats();           // Source Generator 生成的格式注册\nservices.AddImeWlConverterCore();   // 管道、编码生成器、简繁转换、词频生成器\nvar sp = services.BuildServiceProvider();\n\n// 获取管道\nvar pipeline = sp.GetRequiredService<IConversionPipeline>();\n```\n\n### 编码处理\n\n项目处理多种字符编码（UTF-8、GBK、GB2312、Big5、Unicode）。.NET 10 已内置 CodePages 支持，但部分旧代码仍调用：\n```csharp\nEncoding.RegisterProvider(CodePagesEncodingProvider.Instance);\n```\n\n### 跨平台注意事项\n\n- CLI 工具为 framework-dependent（需 .NET 运行时）\n- macOS app bundle 为 self-contained（包含运行时）\n- Windows GUI 为 WinForms（仅 Windows）\n- 集成测试支持 Linux、macOS、Windows (Git Bash)\n\n### 测试\n\n- **单元测试**: xUnit 2.9.3，位于 `src/ImeWlConverterCoreTest/`\n- **集成测试**: shell 脚本框架，位于 `tests/integration/`\n- 测试并行执行（`xunit.runner.json` 中 `parallelizeTestCollections: true`；Phase 2 已消灭静态可变状态，码表全部走 `ImeWlConverter.CodeData` 的线程安全只读表）\n- **禁新增 static 可变字典/集合**——需要码表数据时注入 `ICodeTableLibrary`/`IPinyinTable` 等接口（见 `src/ImeWlConverter.CodeData/`）\n- `[Fact(Skip = \"...\")]` 标记按需运行的慢速测试\n\n### CI/CD\n\nGitHub Actions (`.github/workflows/ci.yml`)：\n1. Lint（格式检查，快速失败）\n2. Build + 单元测试 (Ubuntu)\n3. 多平台构建 (Win x64/x86, Linux x64/arm64, macOS x64/arm64)\n4. 集成测试 (Linux + macOS)\n\n---\n\n## 关键决策记录\n\n| 决策 | 原因 |\n|------|------|\n| 三端统一使用 ConversionPipeline | 消除重复转换逻辑，保证行为一致 |\n| FilterConfig 放在 Abstractions 层 | 三端共享过滤配置 DTO，避免各端重复定义 |\n| ConversionPipeline 支持 Stream 输出 | GUI 需要先预览内容再决定是否保存 |\n| CLI 用 FormatRegistrar 显式注册 | 消除反射，支持 AOT/Trimming |\n| Source Generator 注册新格式 | 添加格式只需加 `[FormatPlugin]` 属性 |\n| 测试并行执行 | Phase 2 建立码表数据层（CodeData），静态可变字典全部改为 DI 只读表，竞态根因消除 |\n| sealed record 实体 | 不可变性保证，不会意外修改中间状态 |\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.claude-plugin/plugin.json)"},"items":[{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"\n## 快速定位\n\n> 这是你进入项目时最先需要知道的信息。根据任务类型，跳转到对应章节。\n\n| 你想做什么 | 入口文件/目录 |\n|-----------|-------------|\n| 添加新的输入法格式支持 | `src/ImeWlConverter.Formats/{Format}/` → 创建 Importer + Exporter |\n| 修改码表/字典数据（拼音、五笔、注音等） | `src/ImeWlConverter.CodeData/`（接口 + `Resources/` 嵌入码表） |\n| 修改转换管道逻辑 | `src/ImeWlConverter.Core/Pipeline/ConversionPipeline.cs` |\n| 修改 CLI 参数/行为 | `src/ImeWlConverter.Application/Cli/`（命令定义+执行链）与 `Mapping/`（参数解析） |\n| 查询 CLI 机器可读契约（退出码/JSON） | `src/ImeWlConverter.Application/Cli/ExitCodes.cs`、`docs/MIGRATION.md` |\n| 修改编码生成（拼音/五笔等） | `src/ImeWlConverter.Core/CodeGeneration/Generators/` |\n| 修改过滤器 | `src/ImeWlConverter.Core/Filters/` |\n| 修改过滤配置 DTO | `src/ImeWlConverter.Abstractions/Options/FilterConfig.cs` |\n| 修改 macOS GUI | `src/ImeWlConverterMac/ViewModels/MainWindowViewModel.cs` |\n| 修改 Windows GUI | `src/IME WL Converter Win/Forms/MainForm.cs` |\n| 添加/修改单元测试 | `src/ImeWlConverterCoreTest/` |\n| 修改 CI 流程 | `.github/workflows/ci.yml` |\n| 发布新版本 | `docs/RELEASING.md` |\n\n## 项目一句话描述\n\n深蓝词库转换（IME WL Converter）是一个跨平台的输入法词库格式转换工具，支持 50+ 种输入法格式之间的相互转换。\n\n- **语言**: C# / .NET 10.0\n- **测试框架**: xUnit 2.9.3\n- **构建系统**: Makefile + dotnet CLI\n- **版本管理**: MinVer（从 Git tag 自动生成）\n- **平台**: Windows / Linux / macOS\n\n## 日常命令\n\n```bash\nmake build              # 构建所有项目\nmake test               # 运行单元测试 (318 个，实际以 dotnet test 输出为准)\nmake integration-test   # 运行集成测试 (29 个用例，需先 make build-cmd)\nmake lint               # 检查代码格式\nmake format             # 自动格式化代码\nmake run-cmd            # 运行 CLI 工具\nmake run-mac            # 运行 macOS GUI\n```\n\n## 架构概览\n\n```\nsrc/\n├── ImeWlConverter.Abstractions/     # 接口层（零依赖）\n├── ImeWlConverter.CodeData/         # 码表数据叶子（零依赖，只读线程安全表服务）\n├── ImeWlConverter.Core/             # 业务服务层（转换管道、编码生成、过滤、简繁转换）\n├── ImeWlConverter.Formats/          # 格式实现层（107个文件，50+种格式）\n├── ImeWlConverter.Application/      # 三端共享应用层（参数映射、请求工厂、CLI 前端、引导）\n├── ImeWlConverter.SourceGenerators/ # Source Generator（编译时格式注册）\n├── ImeWlConverterCmd/               # CLI 薄入口（逻辑在 Application/Cli）\n├── ImeWlConverterMac/               # macOS GUI (Avalonia 11.2.3)\n├── IME WL Converter Win/            # Windows GUI (WinForms)\n└── ImeWlConverterCoreTest/          # xUnit 单元测试\n```\n\n### 三端统一数据流\n\n```\n┌─────────────┐   ┌─────────────┐   ┌─────────────┐\n│   CLI       │   │  WinForms   │   │  macOS GUI  │\n│ CommandBuild│   │  MainForm   │   │  ViewModel  │\n└──────┬──────┘   └──────┬──────┘   └──────┬──────┘\n       │                 │                  │\n       └────共享 Application 层────┬─────────┘\n                    ▼\n        ┌───────────────────────┐\n        │  IConversionPipeline  │  (Abstractions 层接口)\n        └───────────┬───────────┘\n                    ▼\n        ┌───────────────────────┐\n        │  ConversionPipeline   │  (Core 层统一实现)\n        │                       │\n        │  Import → Filter →    │\n        │  ChineseConvert →     │\n        │  WordRank → CodeGen → │\n        │  RemoveEmpty → Export │\n        └───────────────────────┘\n```\n\n**设计原则**：三端（CLI、WinForms、macOS GUI）共用同一个 `ConversionPipeline` 底层转换引擎，只在用户交互层不同。\n\n- CLI 通过 `Application/Cli` 与 `Application/Requests` 解析参数构建 `ConversionRequest`\n- WinForms 通过 `MainForm` 用户操作构建 `ConversionRequest`\n- macOS GUI 通过 `MainWindowViewModel` 构建 `ConversionRequest`\n- 三端共享 `FilterConfig`（`Abstractions/Options/`）、`ConversionOptions`、`IProgress<ProgressInfo>`\n\n---\n\n## 深入：项目层次\n\n以下按从外到内的顺序描述各层，你只需要读到与任务相关的层即可。\n\n### Layer 1: 前端入口\n\n#### CLI (`src/ImeWlConverterCmd/` → `src/ImeWlConverter.Application/Cli/`)\n\n| 文件 | 职责 |\n|------|------|\n| `ImeWlConverterCmd/Program.cs` | 薄入口：注册编码 Provider，调用 `CliApp.Run` |\n| `Application/Cli/CliApp.cs` | CLI 统一入口（旧参数检测 → 命令调用）；Win 内嵌 CLI 共用 |\n| `Application/Cli/CliOptions.cs` | System.CommandLine 选项定义 |\n| `Application/Cli/CliCommandFactory.cs` | 根命令装配与转换执行链（校验→组装→执行→输出） |\n| `Application/Cli/CliValidator.cs` | 必填项/文件存在性/格式 ID 校验（结构化 CliError） |\n| `Application/Cli/Output/*.cs` | 人类输出 / --json 输出 / 格式清单输出 |\n| `Application/Cli/ExitCodes.cs` | 退出码契约（0 成功 / 1 用法 / 2 输入 / 3 部分失败 / 4 内部） |\n| `Application/Mapping/*.cs` | filter/编码类型/自定义格式 spec 解析（Try 模式，可单测） |\n| `Application/Requests/ConversionRequestFactory.cs` | ConversionRequest 组装单一事实来源 |\n| `Application/Bootstrap/ImeWlConverterBootstrapper.cs` | 三端共用 DI 组装 |\n\n#### macOS GUI (`src/ImeWlConverterMac/`)\n\n| 文件 | 职责 |\n|------|------|\n| `App.axaml.cs` | 应用入口，创建 DI 容器，注入 ViewModel |\n| `ViewModels/MainWindowViewModel.cs` | MVVM ViewModel，构建 `ConversionRequest`，调用 `IConversionPipeline` |\n| `Views/FilterConfigWindow.axaml.cs` | 过滤配置 UI，使用共享 `FilterConfig` DTO |\n\n#### Windows GUI (`src/IME WL Converter Win/`)\n\n| 文件 | 职责 |\n|------|------|\n| `Program.cs` | 应用入口，创建 DI 容器 |\n| `Forms/MainForm.cs` | 主窗口，构建 `ConversionRequest`，调用 `IConversionPipeline` |\n| `Forms/FilterConfigForm.cs` | 过滤配置 UI，使用共享 `FilterConfig` DTO |\n\n### Layer 2: 转换管道 (`src/ImeWlConverter.Core/Pipeline/`)\n\n| 文件 | 职责 |\n|------|------|\n| `ConversionPipeline.cs` | 薄编排层：导入 → 委托 EntryTransformationService → 导出；合并/逐文件两种模式 |\n| `EntryTransformationService.cs` | 词条五阶段处理（Filter→ChineseConvert→WordRank→CodeGen→RemoveEmpty），两条导出路径共用 |\n| `FilterPipelineFactory.cs` + `FilterModules/` | 过滤器装配（模块注册制，开闭原则） |\n| `FilterPipeline.cs` | 过滤执行器（单条过滤 → 变换 → 批量过滤） |\n| `CodePredicates.cs` | 空编码判定谓词（两条路径共用） |\n| `SelfDefiningCodeSource.cs` | 自定义码表加载（ISelfDefiningCodeSource 实现） |\n\n`ConversionPipeline` 支持的能力：\n- **合并导出** / **逐文件导出**（`MergeToOneFile` 选项）\n- **文件输出** / **Stream 输出**（GUI 先预览再保存）\n- **从 FilterConfig 经 FilterPipelineFactory 模块化构建 FilterPipeline**\n- **IProgress 细粒度进度报告**\n- **CancellationToken 取消支持**\n- **逐文件错误捕获与结构化累积**（`ConversionResult.Errors`）\n\n### Layer 3: 格式实现 (`src/ImeWlConverter.Formats/`)\n\n每个格式拆分为独立的 Importer 和 Exporter，通过 `[FormatPlugin]` 属性标记，Source Generator 自动注册到 DI。\n\n| 基类 | 用途 |\n|------|------|\n| `TextFormatImporter` | 文本格式导入（逐行解析） |\n| `TextFormatExporter` | 文本格式导出（逐行生成） |\n| `BinaryFormatImporter` | 二进制格式导入 |\n\n### Layer 4: 核心基础设施 (`src/ImeWlConverter.Core/`)\n\n| 目录 | 内容 |\n|------|------|\n| `CodeGeneration/Generators/` | 编码生成器（拼音、五笔86/98/新世纪、郑码、仓颉、注音、超音、二笔x4） |\n| `Filters/` | IWordFilter / IWordTransform / IBatchFilter 实现（12 种） |\n| `Helpers/` | 文件操作、编码检测、拼音字典、HTTP |\n| `Language/` | 纯 .NET 简繁转换（基于 OpenCC 映射表） |\n| `WordRank/` | 默认词频生成器 |\n| `Resources/` | 嵌入式码表 + 简繁映射文件 |\n\n### Layer 5: 抽象层 (`src/ImeWlConverter.Abstractions/`)\n\n纯接口和 DTO，零依赖。供所有层引用。\n\n| 子目录 | 关键类型 |\n|--------|---------|\n| `Contracts/` | IFormatImporter, IFormatExporter, IConversionPipeline, ICodeGenerator, IWordFilter, IWordTransform, IBatchFilter |\n| `Models/` | WordEntry (sealed record), WordCode, FormatMetadata, ProgressInfo |\n| `Options/` | ConversionOptions, FilterConfig, CodeGenerationOptions, ImportOptions, ExportOptions |\n| `Results/` | Result\\<T\\>, ImportResult, ExportResult, ConversionRequest, ConversionResult |\n| `Enums/` | CodeType, SortType, PinyinType, ChineseConversionMode |\n\n---\n\n## 常见任务操作指南\n\n### 添加新的输入法格式\n\n```bash\n# 1. 在 Formats 项目中创建目录和文件\nmkdir src/ImeWlConverter.Formats/MyFormat/\n```\n\n```csharp\n// 2. 创建 Importer（注意：必须是 partial 类，且不要手写 Metadata 属性——由 Source Generator 生成）\n[FormatPlugin(\"myf\", \"我的格式\", 500)]\npublic sealed partial class MyFormatImporter : TextFormatImporter\n{\n    protected override Encoding FileEncoding => new UTF8Encoding(false);\n    protected override bool IsContentLine(string line) =>\n        !string.IsNullOrWhiteSpace(line) && !line.StartsWith(\"#\"); // 可选：跳过注释/空行\n    protected override IEnumerable<WordEntry> ParseLine(string line) { /* 解析逻辑 */ }\n}\n```\n\n```csharp\n// 3. 创建 Exporter（同样不手写 Metadata）\n[FormatPlugin(\"myf\", \"我的格式\", 500)]\npublic sealed partial class MyFormatExporter : TextFormatExporter\n{\n    protected override Encoding FileEncoding => new UTF8Encoding(false);\n    protected override string? FormatEntry(WordEntry entry) { /* 导出逻辑，返回 null 跳过该词条 */ }\n}\n```\n\nSource Generator 会自动完成两件事：\n- 将带 `[FormatPlugin]` 的类注册到 DI 容器（无需手动注册）\n- 为每个类生成 `Metadata` 属性（从 `[FormatPlugin]` 参数与基类链自动推断 `IsBinary` 等，**手写 Metadata 会与生成代码冲突**）\n\n完整真实示例见 `src/ImeWlConverter.Formats/Rime/RimeImporter.cs`。\n\n### 修改过滤逻辑\n\n过滤器位于 `src/ImeWlConverter.Core/Filters/`，实现接口：\n\n```csharp\npublic interface IWordFilter { bool ShouldKeep(WordEntry entry); }\npublic interface IWordTransform { WordEntry? Transform(WordEntry entry); }\npublic interface IBatchFilter { IReadOnlyList<WordEntry> Filter(IReadOnlyList<WordEntry> entries); }\n```\n\n`FilterConfig`（`Abstractions/Options/FilterConfig.cs`）定义了所有过滤选项，`ConversionPipeline` 内部的 `BuildFilterPipeline()` 方法将其转换为 `FilterPipeline` 实例。\n\nCLI 通过 `--filter` 参数启用过滤：`-f \"len:2-10|rm:eng|rm:num\"`\n\n### 修改编码生成\n\n编码生成器位于 `src/ImeWlConverter.Core/CodeGeneration/Generators/`，实现 `ICodeGenerator` 接口。通过 DI 注册，由 `CodeGenerationService` 根据 `CodeType` 选择对应生成器。\n\n### 修改转换管道行为\n\n- **编排与导出**：`src/ImeWlConverter.Core/Pipeline/ConversionPipeline.cs`（薄层）\n- **词条阶段处理**：`EntryTransformationService.cs`，7 步流程：\n\n1. **Import** — 逐文件导入，累积所有 WordEntry（ConversionPipeline）\n2. **Filter → ChineseConvert → WordRank → CodeGen → RemoveEmpty** — EntryTransformationService.ApplyAsync（合并模式调一次，逐文件模式每文件一次）\n3. **Export** — 导出到文件或 Stream（ConversionPipeline）\n\n### 修改过滤逻辑（注册制）\n\n- 过滤器实现位于 `src/ImeWlConverter.Core/Filters/`，装配位于 `Pipeline/FilterPipelineFactory.cs` + `Pipeline/FilterModules/`\n- **新增过滤器**：实现 `IFilterModule`（或往现有模块加一行）→ 加入 `DefaultFilterModules.Create()` 清单即可，无需修改管道\n\n---\n\n## 项目约定\n\n### 禁止操作\n\n- **禁止手动修改版本号**（由 MinVer 从 Git tag 生成，配置在 `src/Directory.Build.props`）\n- **禁止使用运行时反射注册格式**（Source Generator 自动注册）\n- **禁止硬编码路径分隔符**（用 `Path.Combine()`）\n- **禁止在 GUI 项目中重复实现转换逻辑**（统一使用 `IConversionPipeline`）\n- **禁止 GUI 内联格式识别/请求组装/预览截断**（统一用 `ImeWlConverter.Application` 的 FormatDetectionService/ConversionRequestFactory/PreviewService——历史上三端各写一份已导致 macOS 识别 Bug）\n- **禁止 CLI 输出契约随意变更**（退出码 0-4 与 --json schema 见 `Application/Cli/ExitCodes.cs` 与 `docs/MIGRATION.md`；变更必须同步基线测试 `tests/integration/cli-baseline.sh`）\n\n### DI 注册模式\n\n三端使用相同的 DI 注册方式：\n\n```csharp\nvar services = new ServiceCollection();\nservices.AddAllFormats();           // Source Generator 生成的格式注册\nservices.AddImeWlConverterCore();   // 管道、编码生成器、简繁转换、词频生成器\nvar sp = services.BuildServiceProvider();\n\n// 获取管道\nvar pipeline = sp.GetRequiredService<IConversionPipeline>();\n```\n\n### 编码处理\n\n项目处理多种字符编码（UTF-8、GBK、GB2312、Big5、Unicode）。.NET 10 已内置 CodePages 支持，但部分旧代码仍调用：\n```csharp\nEncoding.RegisterProvider(CodePagesEncodingProvider.Instance);\n```\n\n### 跨平台注意事项\n\n- CLI 工具为 framework-dependent（需 .NET 运行时）\n- macOS app bundle 为 self-contained（包含运行时）\n- Windows GUI 为 WinForms（仅 Windows）\n- 集成测试支持 Linux、macOS、Windows (Git Bash)\n\n### 测试\n\n- **单元测试**: xUnit 2.9.3，位于 `src/ImeWlConverterCoreTest/`\n- **集成测试**: shell 脚本框架，位于 `tests/integration/`\n- 测试并行执行（`xunit.runner.json` 中 `parallelizeTestCollections: true`；Phase 2 已消灭静态可变状态，码表全部走 `ImeWlConverter.CodeData` 的线程安全只读表）\n- **禁新增 static 可变字典/集合**——需要码表数据时注入 `ICodeTableLibrary`/`IPinyinTable` 等接口（见 `src/ImeWlConverter.CodeData/`）\n- `[Fact(Skip = \"...\")]` 标记按需运行的慢速测试\n\n### CI/CD\n\nGitHub Actions (`.github/workflows/ci.yml`)：\n1. Lint（格式检查，快速失败）\n2. Build + 单元测试 (Ubuntu)\n3. 多平台构建 (Win x64/x86, Linux x64/arm64, macOS x64/arm64)\n4. 集成测试 (Linux + macOS)\n\n---\n\n## 关键决策记录\n\n| 决策 | 原因 |\n|------|------|\n| 三端统一使用 ConversionPipeline | 消除重复转换逻辑，保证行为一致 |\n| FilterConfig 放在 Abstractions 层 | 三端共享过滤配置 DTO，避免各端重复定义 |\n| ConversionPipeline 支持 Stream 输出 | GUI 需要先预览内容再决定是否保存 |\n| CLI 用 FormatRegistrar 显式注册 | 消除反射，支持 AOT/Trimming |\n| Source Generator 注册新格式 | 添加格式只需加 `[FormatPlugin]` 属性 |\n| 测试并行执行 | Phase 2 建立码表数据层（CodeData），静态可变字典全部改为 DI 只读表，竞态根因消除 |\n| sealed record 实体 | 不可变性保证，不会意外修改中间状态 |\n","isInternal":false,"tokens":4807,"sizeBytes":15974},{"name":"marketplace.json","path":".claude-plugin/marketplace.json","rawUrl":"https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.claude-plugin/marketplace.json","title":"Claude Plugin Marketplace Catalog","category":"marketplace","format":"json","content":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.claude-plugin/marketplace.json)","tokens":300,"sizeBytes":201},{"name":"plugin.json","path":".claude-plugin/plugin.json","rawUrl":"https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.claude-plugin/plugin.json","title":"claude-plugin Plugin Manifest","category":"plugin-manifest","format":"json","content":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.claude-plugin/plugin.json)","tokens":300,"sizeBytes":187},{"name":"mcp.json","path":".cursor/mcp.json","rawUrl":"https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.cursor/mcp.json","title":"Model Context Protocol (MCP) Configuration","category":"mcp-config","format":"json","content":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.cursor/mcp.json)","tokens":300,"sizeBytes":180}],"systemPromptSnippet":"<yakaai_skills repo=\"studyzy/imewlconverter\">\n<!-- File: CLAUDE.md (Tokens: ~4807 | Category: claude-rule) -->\n## 快速定位\n\n> 这是你进入项目时最先需要知道的信息。根据任务类型，跳转到对应章节。\n\n| 你想做什么 | 入口文件/目录 |\n|-----------|-------------|\n| 添加新的输入法格式支持 | `src/ImeWlConverter.Formats/{Format}/` → 创建 Importer + Exporter |\n| 修改码表/字典数据（拼音、五笔、注音等） | `src/ImeWlConverter.CodeData/`（接口 + `Resources/` 嵌入码表） |\n| 修改转换管道逻辑 | `src/ImeWlConverter.Core/Pipeline/ConversionPipeline.cs` |\n| 修改 CLI 参数/行为 | `src/ImeWlConverter.Application/Cli/`（命令定义+执行链）与 `Mapping/`（参数解析） |\n| 查询 CLI 机器可读契约（退出码/JSON） | `src/ImeWlConverter.Application/Cli/ExitCodes.cs`、`docs/MIGRATION.md` |\n| 修改编码生成（拼音/五笔等） | `src/ImeWlConverter.Core/CodeGeneration/Generators/` |\n| 修改过滤器 | `src/ImeWlConverter.Core/Filters/` |\n| 修改过滤配置 DTO | `src/ImeWlConverter.Abstractions/Options/FilterConfig.cs` |\n| 修改 macOS GUI | `src/ImeWlConverterMac/ViewModels/MainWindowViewModel.cs` |\n| 修改 Windows GUI | `src/IME WL Converter Win/Forms/MainForm.cs` |\n| 添加/修改单元测试 | `src/ImeWlConverterCoreTest/` |\n| 修改 CI 流程 | `.github/workflows/ci.yml` |\n| 发布新版本 | `docs/RELEASING.md` |\n\n## 项目一句话描述\n\n深蓝词库转换（IME WL Converter）是一个跨平台的输入法词库格式转换工具，支持 50+ 种输入法格式之间的相互转换。\n\n- **语言**: C# / .NET 10.0\n- **测试框架**: xUnit 2.9.3\n- **构建系统**: Makefile + dotnet CLI\n- **版本管理**: MinVer（从 Git tag 自动生成）\n- **平台**: Windows / Linux / macOS\n\n## 日常命令\n\n```bash\nmake build              # 构建所有项目\nmake test               # 运行单元测试 (318 个，实际以 dotnet test 输出为准)\nmake integration-test   # 运行集成测试 (29 个用例，需先 make build-cmd)\nmake lint               # 检查代码格式\nmake format             # 自动格式化代码\nmake run-cmd            # 运行 CLI 工具\nmake run-mac            # 运行 macOS GUI\n```\n\n## 架构概览\n\n```\nsrc/\n├── ImeWlConverter.Abstractions/     # 接口层（零依赖）\n├── ImeWlConverter.CodeData/         # 码表数据叶子（零依赖，只读线程安全表服务）\n├── ImeWlConverter.Core/             # 业务服务层（转换管道、编码生成、过滤、简繁转换）\n├── ImeWlConverter.Formats/          # 格式实现层（107个文件，50+种格式）\n├── ImeWlConverter.Application/      # 三端共享应用层（参数映射、请求工厂、CLI 前端、引导）\n├── ImeWlConverter.SourceGenerators/ # Source Generator（编译时格式注册）\n├── ImeWlConverterCmd/               # CLI 薄入口（逻辑在 Application/Cli）\n├── ImeWlConverterMac/               # macOS GUI (Avalonia 11.2.3)\n├── IME WL Converter Win/            # Windows GUI (WinForms)\n└── ImeWlConverterCoreTest/          # xUnit 单元测试\n```\n\n### 三端统一数据流\n\n```\n┌─────────────┐   ┌─────────────┐   ┌─────────────┐\n│   CLI       │   │  WinForms   │   │  macOS GUI  │\n│ CommandBuild│   │  MainForm   │   │  ViewModel  │\n└──────┬──────┘   └──────┬──────┘   └──────┬──────┘\n       │                 │                  │\n       └────共享 Application 层────┬─────────┘\n                    ▼\n        ┌───────────────────────┐\n        │  IConversionPipeline  │  (Abstractions 层接口)\n        └───────────┬───────────┘\n                    ▼\n        ┌───────────────────────┐\n        │  ConversionPipeline   │  (Core 层统一实现)\n        │                       │\n        │  Import → Filter →    │\n        │  ChineseConvert →     │\n        │  WordRank → CodeGen → │\n        │  RemoveEmpty → Export │\n        └───────────────────────┘\n```\n\n**设计原则**：三端（CLI、WinForms、macOS GUI）共用同一个 `ConversionPipeline` 底层转换引擎，只在用户交互层不同。\n\n- CLI 通过 `Application/Cli` 与 `Application/Requests` 解析参数构建 `ConversionRequest`\n- WinForms 通过 `MainForm` 用户操作构建 `ConversionRequest`\n- macOS GUI 通过 `MainWindowViewModel` 构建 `ConversionRequest`\n- 三端共享 `FilterConfig`（`Abstractions/Options/`）、`ConversionOptions`、`IProgress<ProgressInfo>`\n\n---\n\n## 深入：项目层次\n\n以下按从外到内的顺序描述各层，你只需要读到与任务相关的层即可。\n\n### Layer 1: 前端入口\n\n#### CLI (`src/ImeWlConverterCmd/` → `src/ImeWlConverter.Application/Cli/`)\n\n| 文件 | 职责 |\n|------|------|\n| `ImeWlConverterCmd/Program.cs` | 薄入口：注册编码 Provider，调用 `CliApp.Run` |\n| `Application/Cli/CliApp.cs` | CLI 统一入口（旧参数检测 → 命令调用）；Win 内嵌 CLI 共用 |\n| `Application/Cli/CliOptions.cs` | System.CommandLine 选项定义 |\n| `Application/Cli/CliCommandFactory.cs` | 根命令装配与转换执行链（校验→组装→执行→输出） |\n| `Application/Cli/CliValidator.cs` | 必填项/文件存在性/格式 ID 校验（结构化 CliError） |\n| `Application/Cli/Output/*.cs` | 人类输出 / --json 输出 / 格式清单输出 |\n| `Application/Cli/ExitCodes.cs` | 退出码契约（0 成功 / 1 用法 / 2 输入 / 3 部分失败 / 4 内部） |\n| `Application/Mapping/*.cs` | filter/编码类型/自定义格式 spec 解析（Try 模式，可单测） |\n| `Application/Requests/ConversionRequestFactory.cs` | ConversionRequest 组装单一事实来源 |\n| `Application/Bootstrap/ImeWlConverterBootstrapper.cs` | 三端共用 DI 组装 |\n\n#### macOS GUI (`src/ImeWlConverterMac/`)\n\n| 文件 | 职责 |\n|------|------|\n| `App.axaml.cs` | 应用入口，创建 DI 容器，注入 ViewModel |\n| `ViewModels/MainWindowViewModel.cs` | MVVM ViewModel，构建 `ConversionRequest`，调用 `IConversionPipeline` |\n| `Views/FilterConfigWindow.axaml.cs` | 过滤配置 UI，使用共享 `FilterConfig` DTO |\n\n#### Windows GUI (`src/IME WL Converter Win/`)\n\n| 文件 | 职责 |\n|------|------|\n| `Program.cs` | 应用入口，创建 DI 容器 |\n| `Forms/MainForm.cs` | 主窗口，构建 `ConversionRequest`，调用 `IConversionPipeline` |\n| `Forms/FilterConfigForm.cs` | 过滤配置 UI，使用共享 `FilterConfig` DTO |\n\n### Layer 2: 转换管道 (`src/ImeWlConverter.Core/Pipeline/`)\n\n| 文件 | 职责 |\n|------|------|\n| `ConversionPipeline.cs` | 薄编排层：导入 → 委托 EntryTransformationService → 导出；合并/逐文件两种模式 |\n| `EntryTransformationService.cs` | 词条五阶段处理（Filter→ChineseConvert→WordRank→CodeGen→RemoveEmpty），两条导出路径共用 |\n| `FilterPipelineFactory.cs` + `FilterModules/` | 过滤器装配（模块注册制，开闭原则） |\n| `FilterPipeline.cs` | 过滤执行器（单条过滤 → 变换 → 批量过滤） |\n| `CodePredicates.cs` | 空编码判定谓词（两条路径共用） |\n| `SelfDefiningCodeSource.cs` | 自定义码表加载（ISelfDefiningCodeSource 实现） |\n\n`ConversionPipeline` 支持的能力：\n- **合并导出** / **逐文件导出**（`MergeToOneFile` 选项）\n- **文件输出** / **Stream 输出**（GUI 先预览再保存）\n- **从 FilterConfig 经 FilterPipelineFactory 模块化构建 FilterPipeline**\n- **IProgress 细粒度进度报告**\n- **CancellationToken 取消支持**\n- **逐文件错误捕获与结构化累积**（`ConversionResult.Errors`）\n\n### Layer 3: 格式实现 (`src/ImeWlConverter.Formats/`)\n\n每个格式拆分为独立的 Importer 和 Exporter，通过 `[FormatPlugin]` 属性标记，Source Generator 自动注册到 DI。\n\n| 基类 | 用途 |\n|------|------|\n| `TextFormatImporter` | 文本格式导入（逐行解析） |\n| `TextFormatExporter` | 文本格式导出（逐行生成） |\n| `BinaryFormatImporter` | 二进制格式导入 |\n\n### Layer 4: 核心基础设施 (`src/ImeWlConverter.Core/`)\n\n| 目录 | 内容 |\n|------|------|\n| `CodeGeneration/Generators/` | 编码生成器（拼音、五笔86/98/新世纪、郑码、仓颉、注音、超音、二笔x4） |\n| `Filters/` | IWordFilter / IWordTransform / IBatchFilter 实现（12 种） |\n| `Helpers/` | 文件操作、编码检测、拼音字典、HTTP |\n| `Language/` | 纯 .NET 简繁转换（基于 OpenCC 映射表） |\n| `WordRank/` | 默认词频生成器 |\n| `Resources/` | 嵌入式码表 + 简繁映射文件 |\n\n### Layer 5: 抽象层 (`src/ImeWlConverter.Abstractions/`)\n\n纯接口和 DTO，零依赖。供所有层引用。\n\n| 子目录 | 关键类型 |\n|--------|---------|\n| `Contracts/` | IFormatImporter, IFormatExporter, IConversionPipeline, ICodeGenerator, IWordFilter, IWordTransform, IBatchFilter |\n| `Models/` | WordEntry (sealed record), WordCode, FormatMetadata, ProgressInfo |\n| `Options/` | ConversionOptions, FilterConfig, CodeGenerationOptions, ImportOptions, ExportOptions |\n| `Results/` | Result\\<T\\>, ImportResult, ExportResult, ConversionRequest, ConversionResult |\n| `Enums/` | CodeType, SortType, PinyinType, ChineseConversionMode |\n\n---\n\n## 常见任务操作指南\n\n### 添加新的输入法格式\n\n```bash\n# 1. 在 Formats 项目中创建目录和文件\nmkdir src/ImeWlConverter.Formats/MyFormat/\n```\n\n```csharp\n// 2. 创建 Importer（注意：必须是 partial 类，且不要手写 Metadata 属性——由 Source Generator 生成）\n[FormatPlugin(\"myf\", \"我的格式\", 500)]\npublic sealed partial class MyFormatImporter : TextFormatImporter\n{\n    protected override Encoding FileEncoding => new UTF8Encoding(false);\n    protected override bool IsContentLine(string line) =>\n        !string.IsNullOrWhiteSpace(line) && !line.StartsWith(\"#\"); // 可选：跳过注释/空行\n    protected override IEnumerable<WordEntry> ParseLine(string line) { /* 解析逻辑 */ }\n}\n```\n\n```csharp\n// 3. 创建 Exporter（同样不手写 Metadata）\n[FormatPlugin(\"myf\", \"我的格式\", 500)]\npublic sealed partial class MyFormatExporter : TextFormatExporter\n{\n    protected override Encoding FileEncoding => new UTF8Encoding(false);\n    protected override string? FormatEntry(WordEntry entry) { /* 导出逻辑，返回 null 跳过该词条 */ }\n}\n```\n\nSource Generator 会自动完成两件事：\n- 将带 `[FormatPlugin]` 的类注册到 DI 容器（无需手动注册）\n- 为每个类生成 `Metadata` 属性（从 `[FormatPlugin]` 参数与基类链自动推断 `IsBinary` 等，**手写 Metadata 会与生成代码冲突**）\n\n完整真实示例见 `src/ImeWlConverter.Formats/Rime/RimeImporter.cs`。\n\n### 修改过滤逻辑\n\n过滤器位于 `src/ImeWlConverter.Core/Filters/`，实现接口：\n\n```csharp\npublic interface IWordFilter { bool ShouldKeep(WordEntry entry); }\npublic interface IWordTransform { WordEntry? Transform(WordEntry entry); }\npublic interface IBatchFilter { IReadOnlyList<WordEntry> Filter(IReadOnlyList<WordEntry> entries); }\n```\n\n`FilterConfig`（`Abstractions/Options/FilterConfig.cs`）定义了所有过滤选项，`ConversionPipeline` 内部的 `BuildFilterPipeline()` 方法将其转换为 `FilterPipeline` 实例。\n\nCLI 通过 `--filter` 参数启用过滤：`-f \"len:2-10|rm:eng|rm:num\"`\n\n### 修改编码生成\n\n编码生成器位于 `src/ImeWlConverter.Core/CodeGeneration/Generators/`，实现 `ICodeGenerator` 接口。通过 DI 注册，由 `CodeGenerationService` 根据 `CodeType` 选择对应生成器。\n\n### 修改转换管道行为\n\n- **编排与导出**：`src/ImeWlConverter.Core/Pipeline/ConversionPipeline.cs`（薄层）\n- **词条阶段处理**：`EntryTransformationService.cs`，7 步流程：\n\n1. **Import** — 逐文件导入，累积所有 WordEntry（ConversionPipeline）\n2. **Filter → ChineseConvert → WordRank → CodeGen → RemoveEmpty** — EntryTransformationService.ApplyAsync（合并模式调一次，逐文件模式每文件一次）\n3. **Export** — 导出到文件或 Stream（ConversionPipeline）\n\n### 修改过滤逻辑（注册制）\n\n- 过滤器实现位于 `src/ImeWlConverter.Core/Filters/`，装配位于 `Pipeline/FilterPipelineFactory.cs` + `Pipeline/FilterModules/`\n- **新增过滤器**：实现 `IFilterModule`（或往现有模块加一行）→ 加入 `DefaultFilterModules.Create()` 清单即可，无需修改管道\n\n---\n\n## 项目约定\n\n### 禁止操作\n\n- **禁止手动修改版本号**（由 MinVer 从 Git tag 生成，配置在 `src/Directory.Build.props`）\n- **禁止使用运行时反射注册格式**（Source Generator 自动注册）\n- **禁止硬编码路径分隔符**（用 `Path.Combine()`）\n- **禁止在 GUI 项目中重复实现转换逻辑**（统一使用 `IConversionPipeline`）\n- **禁止 GUI 内联格式识别/请求组装/预览截断**（统一用 `ImeWlConverter.Application` 的 FormatDetectionService/ConversionRequestFactory/PreviewService——历史上三端各写一份已导致 macOS 识别 Bug）\n- **禁止 CLI 输出契约随意变更**（退出码 0-4 与 --json schema 见 `Application/Cli/ExitCodes.cs` 与 `docs/MIGRATION.md`；变更必须同步基线测试 `tests/integration/cli-baseline.sh`）\n\n### DI 注册模式\n\n三端使用相同的 DI 注册方式：\n\n```csharp\nvar services = new ServiceCollection();\nservices.AddAllFormats();           // Source Generator 生成的格式注册\nservices.AddImeWlConverterCore();   // 管道、编码生成器、简繁转换、词频生成器\nvar sp = services.BuildServiceProvider();\n\n// 获取管道\nvar pipeline = sp.GetRequiredService<IConversionPipeline>();\n```\n\n### 编码处理\n\n项目处理多种字符编码（UTF-8、GBK、GB2312、Big5、Unicode）。.NET 10 已内置 CodePages 支持，但部分旧代码仍调用：\n```csharp\nEncoding.RegisterProvider(CodePagesEncodingProvider.Instance);\n```\n\n### 跨平台注意事项\n\n- CLI 工具为 framework-dependent（需 .NET 运行时）\n- macOS app bundle 为 self-contained（包含运行时）\n- Windows GUI 为 WinForms（仅 Windows）\n- 集成测试支持 Linux、macOS、Windows (Git Bash)\n\n### 测试\n\n- **单元测试**: xUnit 2.9.3，位于 `src/ImeWlConverterCoreTest/`\n- **集成测试**: shell 脚本框架，位于 `tests/integration/`\n- 测试并行执行（`xunit.runner.json` 中 `parallelizeTestCollections: true`；Phase 2 已消灭静态可变状态，码表全部走 `ImeWlConverter.CodeData` 的线程安全只读表）\n- **禁新增 static 可变字典/集合**——需要码表数据时注入 `ICodeTableLibrary`/`IPinyinTable` 等接口（见 `src/ImeWlConverter.CodeData/`）\n- `[Fact(Skip = \"...\")]` 标记按需运行的慢速测试\n\n### CI/CD\n\nGitHub Actions (`.github/workflows/ci.yml`)：\n1. Lint（格式检查，快速失败）\n2. Build + 单元测试 (Ubuntu)\n3. 多平台构建 (Win x64/x86, Linux x64/arm64, macOS x64/arm64)\n4. 集成测试 (Linux + macOS)\n\n---\n\n## 关键决策记录\n\n| 决策 | 原因 |\n|------|------|\n| 三端统一使用 ConversionPipeline | 消除重复转换逻辑，保证行为一致 |\n| FilterConfig 放在 Abstractions 层 | 三端共享过滤配置 DTO，避免各端重复定义 |\n| ConversionPipeline 支持 Stream 输出 | GUI 需要先预览内容再决定是否保存 |\n| CLI 用 FormatRegistrar 显式注册 | 消除反射，支持 AOT/Trimming |\n| Source Generator 注册新格式 | 添加格式只需加 `[FormatPlugin]` 属性 |\n| 测试并行执行 | Phase 2 建立码表数据层（CodeData），静态可变字典全部改为 DI 只读表，竞态根因消除 |\n| sealed record 实体 | 不可变性保证，不会意外修改中间状态 |\n\n<!-- File: .claude-plugin/marketplace.json (Tokens: ~300 | Category: marketplace) -->\n# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.claude-plugin/marketplace.json)\n\n<!-- File: .claude-plugin/plugin.json (Tokens: ~300 | Category: plugin-manifest) -->\n# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.claude-plugin/plugin.json)\n\n<!-- File: .cursor/mcp.json (Tokens: ~300 | Category: mcp-config) -->\n# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/studyzy/imewlconverter/HEAD/.cursor/mcp.json)\n</yakaai_skills>"}