Skip to content

feat: 添加游戏资源链接管理工具 - #71

Open
UranusNo7 wants to merge 3 commits into
MuNET-OSS:mainfrom
UranusNo7:feat/resource-junction-manager-official
Open

feat: 添加游戏资源链接管理工具#71
UranusNo7 wants to merge 3 commits into
MuNET-OSS:mainfrom
UranusNo7:feat/resource-junction-manager-official

Conversation

@UranusNo7

@UranusNo7 UranusNo7 commented Aug 2, 2026

Copy link
Copy Markdown

功能说明

新增“游戏资源链接”工具,用 Windows Junction 在多个 maimai 游戏目录之间共享体积较大的资源文件。

  • 仅处理 AssetBundleImagesMovieDataSoundData
  • 目标默认使用 MaiChartManager 当前游戏目录,也可在当前会话中独立手动选择,不修改全局游戏配置或触发游戏数据重载
  • 启动工具时从游戏路径历史及当前游戏相邻目录中查找候选,递归统计三类资源文件并自动选择文件总数最多的完整目录
  • 保留手动源目录选择;候选数量并列时要求用户手动确认
  • 显示源目录、目标目录、三类文件数量和每个 Junction 的当前状态

安全边界

  • 源目录始终只读
  • 普通目录、文件、符号链接及指向其他位置的 Junction 均不会被覆盖或删除
  • 仅移除正确指向当前源目录的三个 Junction,且删除前后都会重新检查
  • 远程导出模式拒绝相关接口;Linux 构建只返回不支持,不执行 Junction 操作
  • 建立和移除前均有界面二次确认

验证

  • dotnet test MaiChartManager.Tests/MaiChartManager.Tests.csproj -c Debug --no-restore:18 项通过
  • pnpm build:通过
  • dotnet build MaiChartManager/MaiChartManager.csproj -c LinuxDebugBackend:通过

测试覆盖目录归一化、自动候选排名、并列处理、直接 Sinmai_Data 布局、嵌套重解析点跳过、手动源/目标覆盖、固定范围不可变、源目标重合保护、现有目录冲突、错误 Junction 拒绝,以及包含空格与 & 的临时路径下真实 Junction 的建立、读取和移除。

Summary by Sourcery

引入一个游戏资源链接管理工具,通过 Windows 目录联接(junction)在多个 maimai 游戏安装之间共享大型资源目录,并提供严格的安全检查以及按会话选择资源源目录/目标目录的功能。

New Features:

  • 添加后端服务和 HTTP API,用于检查、自动选择和管理用于游戏资源目录的 Windows 目录联接。

  • 暴露一个新的前端工具弹窗,用于查看资源链接状态、选择源/目标游戏目录以及创建或移除目录联接。

  • 扩展客户端 API 类型和枚举,以表示资源联接总览、条目和状态,并将该工具集成到主工具面板中。

  • 为新的游戏资源链接管理工具添加英语、简体中文和繁体中文的本地化 UI 字符串。

Documentation:

  • 添加面向用户的文档,说明游戏资源链接工具如何选择目录、管理哪些资源文件夹以及其安全规则。

Tests:

  • 为资源联接服务添加单元测试,覆盖路径规范化、自动源目录选择排序及并列处理、手动覆盖、冲突检测以及安全创建/移除目录联接等场景。
Original summary in English

Summary by Sourcery

Introduce a game resource link management tool that shares large resource directories between maimai game installs via Windows junctions, with strict safety checks and per-session source/target selection.

New Features:

  • Add backend service and HTTP API for inspecting, auto-selecting, and managing Windows junctions for game resource directories.
  • Expose a new front-end tool modal to view resource link status, choose source/target game directories, and create or remove junctions.
  • Extend client API types and enums to represent resource junction overview, items, and status, and integrate the tool into the main tools dashboard.

Enhancements:

  • Refine store purchase result status to use a typed enum instead of a raw integer.
  • Add localized UI strings in English, Simplified Chinese, and Traditional Chinese for the new game resource link management tool.

Documentation:

  • Add user-facing documentation describing how the game resource link tool selects directories, which resource folders it manages, and its safety rules.

Tests:

  • Add unit tests for the resource junction service covering path normalization, auto source selection ranking and tie-handling, manual overrides, conflict detection, and safe creation/removal of junctions.
## AI 协作信息

本 PR 使用 AI 辅助实现,供审核参考:

  • 模型:Codex,GPT-5.6 Sol Medium
  • Harness:Codex
  • Skills / MCP / 子代理:本任务未调用专用 skill、MCP 工具或子代理
  • 提示词摘要:将独立的 maimai 资源链接工具合入 MaiChartManager;仅允许管理 AssetBundleImagesMovieDataSoundData;目标默认使用当前游戏目录且可按会话单独选择;源目录打开工具时自动按三类资源文件总数选择,同时保留手动选择;切换目标不触发游戏数据重载;源目录只读,不覆盖普通目录或错误链接;补测试、文档,并提交官方 PR。

未在正文复制系统提示词或仓库代理指令;实现过程遵循仓库 AGENTS.md

工具的作用为:在例如SDGA,SDGB游戏文件的A000目录下建立符号链接,指向SDEZ的AssetBundleImages,MovieData和SoundData,实现复用SDEZ的主要资源文件,减少磁盘空间占用,已在本地和多台电脑上验证可用。

第一次传pr,可能有不当的操作打扰到各位了,抱歉捏

Summary by Sourcery

引入一个游戏资源链接管理工具,通过 Windows 连接点在多个 maimai 游戏安装之间共享大型资源目录,并支持按会话选择来源/目标目录以及严格的安全检查。

New Features:

  • 添加后端服务、控制器端点以及客户端 API 类型,用于检查、自动选择和管理游戏资源目录连接点。
  • 暴露一个新的前端工具弹窗,用于查看资源链接状态、选择来源/目标游戏目录,以及创建或移除连接点,并集成到主工具面板中。
  • 为新的游戏资源链接管理工具新增英文、简体中文和繁体中文的本地化 UI 字符串。

Documentation:

  • 添加面向用户的文档,说明游戏资源链接工具如何选择目录、管理哪些资源文件夹以及其安全规则。

Tests:

  • 为资源连接点服务添加单元测试,覆盖路径规范化、自动来源选择、手动覆盖、冲突处理以及安全创建/移除连接点等场景。
Original summary in English

Summary by Sourcery

Introduce a game resource link management tool that shares large resource directories between maimai game installs via Windows junctions, with per-session source/target selection and strict safety checks.

New Features:

  • Add backend service, controller endpoints, and client API types for inspecting, auto-selecting, and managing game resource directory junctions.
  • Expose a new front-end tools modal to view resource link status, choose source/target game directories, and create or remove junctions, integrated into the main tools panel.
  • Add localized UI strings in English, Simplified Chinese, and Traditional Chinese for the new game resource link management tool.

Documentation:

  • Add user-facing documentation describing how the game resource link tool selects directories, which resource folders it manages, and its safety rules.

Tests:

  • Add unit tests for the resource junction service covering path normalization, auto source selection, manual overrides, conflict handling, and safe creation/removal of junctions.

Copilot AI review requested due to automatic review settings August 2, 2026 11:17
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@sourcery-ai

sourcery-ai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

引入一个新的游戏资源链接管理工具,通过 Windows junction 让用户在多份 maimai 安装之间共享 AssetBundleImages/MovieData/SoundData 目录,并包含后端服务、HTTP API、前端弹窗、本地化、文档和测试,且受严格安全规则约束,并支持按会话选择资源源目录和目标目录。

游戏资源 junction 管理流程时序图

sequenceDiagram
  actor User
  participant ResourceJunctionModal
  participant ApiClient as Api
  participant ResourceJunctionController
  participant ResourceJunctionService

  User->>ResourceJunctionModal: trigger()
  ResourceJunctionModal->>ApiClient: AutoSelectResourceJunctionSource
  ApiClient->>ResourceJunctionController: AutoSelectResourceJunctionSource
  ResourceJunctionController->>ResourceJunctionService: AutoSelectSource
  ResourceJunctionService-->>ResourceJunctionController: ResourceJunctionOverview
  ResourceJunctionController-->>ApiClient: ResourceJunctionOverview
  ApiClient-->>ResourceJunctionModal: overview

  User->>ResourceJunctionModal: click selectSource
  ResourceJunctionModal->>ApiClient: SelectResourceJunctionSource
  ApiClient->>ResourceJunctionController: SelectResourceJunctionSource
  ResourceJunctionController->>ResourceJunctionService: SelectManualSource
  ResourceJunctionService-->>ResourceJunctionController: ResourceJunctionOverview
  ResourceJunctionController-->>ApiClient: ResourceJunctionOverview
  ApiClient-->>ResourceJunctionModal: overview

  User->>ResourceJunctionModal: confirm create
  ResourceJunctionModal->>ApiClient: CreateResourceJunctions
  ApiClient->>ResourceJunctionController: CreateResourceJunctions
  ResourceJunctionController->>ResourceJunctionService: CreateLinks
  ResourceJunctionService-->>ResourceJunctionController: ResourceJunctionItem[]
  ResourceJunctionController-->>ApiClient: ResourceJunctionOverview(items)
  ApiClient-->>ResourceJunctionModal: updated overview

  User->>ResourceJunctionModal: confirm remove
  ResourceJunctionModal->>ApiClient: RemoveResourceJunctions
  ApiClient->>ResourceJunctionController: RemoveResourceJunctions
  ResourceJunctionController->>ResourceJunctionService: RemoveLinks
  ResourceJunctionService-->>ResourceJunctionController: ResourceJunctionItem[]
  ResourceJunctionController-->>ApiClient: ResourceJunctionOverview(items)
  ApiClient-->>ResourceJunctionModal: updated overview
Loading

File-Level Changes

Change Details Files
添加后端服务和 HTTP API,用于在严格安全规则下检查、自动选择、创建和移除游戏资源目录的 Windows junction。
  • 引入 ResourceJunctionService 封装与 junction 相关的安全操作,包括路径规范化、自动源选择、手动源/目标选择、junction 检查、创建和删除。
  • 添加 ResourceJunctionStatus 与 ResourceSourceSelectionMode 枚举,以及用于 junction 条目、文件计数和总览的 DTO 记录,并包含围绕重解析点(reparse points)、候选筛选和操作系统支持的安全检查。
  • 在服务器 DI 容器中注册 ResourceJunctionService,并暴露带保护端点的 ResourceJunctionController,用于状态、自动/手动选择以及创建/移除操作,同时强制仅本地访问并禁止导出模式。
MaiChartManager/Services/ResourceJunctionService.cs
MaiChartManager/ServerManager.cs
MaiChartManager/Controllers/Tools/ResourceJunctionController.cs
扩展客户端 API 类型和生成的客户端,以支持资源 junction 工具及其后端端点。
  • 在生成的 API 类型中添加 ResourceSourceSelectionMode 和 ResourceJunctionStatus 枚举,以及 ResourceDirectoryFileCount、ResourceJunctionItem 和 ResourceJunctionOverview 接口。
  • 在 ResourceJunction 标签下扩展 Api 客户端,新增 GetResourceJunctionStatus、AutoSelectResourceJunctionSource、SelectResourceJunctionSource、SelectResourceJunctionTarget、CreateResourceJunctions 和 RemoveResourceJunctions 方法。
MaiChartManager/Front/src/client/apiGen.ts
在前端添加集成到 Tools 视图中的 “Game Resource Links” 工具弹窗,并与新 API 连接,支持确认和状态展示。
  • 创建 ResourceJunctionModal 组件,用于获取/更新总览状态,允许自动/手动选择源和目标,并通过具有事务性确认对话框和状态颜色编码的方式执行创建/删除操作。
  • 将 ResourceJunctionModal 集成到工具面板中,添加新的工具卡片和触发 ref。
MaiChartManager/Front/src/views/Tools/ResourceJunctionModal.tsx
MaiChartManager/Front/src/views/Tools/index.tsx
为资源 junction 工具添加英文、简体中文和繁体中文的本地化 UI 文本。
  • 在 en、zh 和 zh-TW 语言文件中定义标签、按钮文本、选择模式标签、状态标签以及确认消息。
MaiChartManager/Front/src/locales/en.yaml
MaiChartManager/Front/src/locales/zh.yaml
MaiChartManager/Front/src/locales/zh-TW.yaml
编写资源 junction 工具的行为文档,并添加单元测试以保证安全和选择逻辑。
  • 添加面向用户的文档,说明源/目标目录是如何解析的、哪些资源文件夹在范围内,以及详细的安全规则。
  • 添加 ResourceJunctionServiceTests,覆盖资源范围不变量、自动选择规则(包括并列与同级发现)、重解析点处理、手动覆盖、目标/会话行为、冲突检测、junction 生命周期和清理。
docs/resource-junction-manager.md
MaiChartManager.Tests/Services/ResourceJunctionServiceTests.cs

Tips and commands

Interacting with Sourcery

  • 触发新的代码审查: 在 pull request 上评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub issue: 通过回复某条审查评论,要求 Sourcery 基于该评论创建一个 issue。你也可以直接回复审查评论 @sourcery-ai issue 来创建对应的 issue。
  • 生成 pull request 标题: 在 pull request 标题中任意位置写上 @sourcery-ai,即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 摘要: 在 pull request body 中任意位置写上 @sourcery-ai summary,即可在对应位置生成 PR 摘要。也可以在 pull request 中评论 @sourcery-ai summary 来(重新)生成摘要。
  • 生成审查者指南: 在 pull request 中评论 @sourcery-ai guide,即可(重新)生成审查者指南。
  • 一次性解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,将所有 Sourcery 评论标记为已解决。这在你已经处理完所有评论且不希望再看到它们时非常有用。
  • 驳回所有 Sourcery 审查: 在 pull request 中评论 @sourcery-ai dismiss,以驳回所有现有的 Sourcery 审查。尤其适用于你想从头开始新的审查时——别忘了再评论 @sourcery-ai review 来触发新的审查!

Customizing Your Experience

访问你的 dashboard,可以:

  • 启用或禁用审查功能,例如 Sourcery 生成的 pull request 摘要、审查者指南等。
  • 更改审查语言。
  • 添加、删除或编辑自定义审查指令。
  • 调整其他审查设置。

Getting Help

Original review guide in English

Reviewer's Guide

Introduce a new game resource link management tool that lets users share AssetBundleImages/MovieData/SoundData directories between maimai installs via Windows junctions, with a backend service, HTTP APIs, a frontend modal, localization, documentation, and tests, all constrained by strict safety rules and per-session source/target selection.

Sequence diagram for game resource junction management flow

sequenceDiagram
  actor User
  participant ResourceJunctionModal
  participant ApiClient as Api
  participant ResourceJunctionController
  participant ResourceJunctionService

  User->>ResourceJunctionModal: trigger()
  ResourceJunctionModal->>ApiClient: AutoSelectResourceJunctionSource
  ApiClient->>ResourceJunctionController: AutoSelectResourceJunctionSource
  ResourceJunctionController->>ResourceJunctionService: AutoSelectSource
  ResourceJunctionService-->>ResourceJunctionController: ResourceJunctionOverview
  ResourceJunctionController-->>ApiClient: ResourceJunctionOverview
  ApiClient-->>ResourceJunctionModal: overview

  User->>ResourceJunctionModal: click selectSource
  ResourceJunctionModal->>ApiClient: SelectResourceJunctionSource
  ApiClient->>ResourceJunctionController: SelectResourceJunctionSource
  ResourceJunctionController->>ResourceJunctionService: SelectManualSource
  ResourceJunctionService-->>ResourceJunctionController: ResourceJunctionOverview
  ResourceJunctionController-->>ApiClient: ResourceJunctionOverview
  ApiClient-->>ResourceJunctionModal: overview

  User->>ResourceJunctionModal: confirm create
  ResourceJunctionModal->>ApiClient: CreateResourceJunctions
  ApiClient->>ResourceJunctionController: CreateResourceJunctions
  ResourceJunctionController->>ResourceJunctionService: CreateLinks
  ResourceJunctionService-->>ResourceJunctionController: ResourceJunctionItem[]
  ResourceJunctionController-->>ApiClient: ResourceJunctionOverview(items)
  ApiClient-->>ResourceJunctionModal: updated overview

  User->>ResourceJunctionModal: confirm remove
  ResourceJunctionModal->>ApiClient: RemoveResourceJunctions
  ApiClient->>ResourceJunctionController: RemoveResourceJunctions
  ResourceJunctionController->>ResourceJunctionService: RemoveLinks
  ResourceJunctionService-->>ResourceJunctionController: ResourceJunctionItem[]
  ResourceJunctionController-->>ApiClient: ResourceJunctionOverview(items)
  ApiClient-->>ResourceJunctionModal: updated overview
Loading

File-Level Changes

Change Details Files
Add backend service and HTTP APIs to inspect, auto-select, create, and remove Windows junctions for game resource directories with strict safety rules.
  • Introduce ResourceJunctionService to encapsulate junction-safe operations, including path normalization, auto source selection, manual source/target selection, junction inspection, creation, and removal.
  • Add ResourceJunctionStatus and ResourceSourceSelectionMode enums and DTO records for junction items, file counts, and overview, including safety checks around reparse points, candidate filtering, and OS support.
  • Register ResourceJunctionService in the server DI container and expose a ResourceJunctionController with guarded endpoints for status, auto/manual selection, and create/remove operations, enforcing local-only access and export-mode forbids.
MaiChartManager/Services/ResourceJunctionService.cs
MaiChartManager/ServerManager.cs
MaiChartManager/Controllers/Tools/ResourceJunctionController.cs
Extend client API types and generated client to support the resource junction tool and its backend endpoints.
  • Add ResourceSourceSelectionMode and ResourceJunctionStatus enums plus ResourceDirectoryFileCount, ResourceJunctionItem, and ResourceJunctionOverview interfaces to the generated API types.
  • Extend the Api client with GetResourceJunctionStatus, AutoSelectResourceJunctionSource, SelectResourceJunctionSource, SelectResourceJunctionTarget, CreateResourceJunctions, and RemoveResourceJunctions methods under the ResourceJunction tag.
MaiChartManager/Front/src/client/apiGen.ts
Add a frontend "Game Resource Links" tool modal integrated into the Tools view, wired to the new APIs with confirmation and status display.
  • Create ResourceJunctionModal component that fetches/updates overview state, allows auto/manual source and target selection, and runs create/remove actions with transactional confirmation dialogs and status color coding.
  • Integrate ResourceJunctionModal into the tools dashboard with a new tool card and trigger ref.
MaiChartManager/Front/src/views/Tools/ResourceJunctionModal.tsx
MaiChartManager/Front/src/views/Tools/index.tsx
Add localized UI strings for the resource junction tool in English, Simplified Chinese, and Traditional Chinese.
  • Define labels, button text, selection mode labels, status labels, and confirmation messages for the resource junction tool in en, zh, and zh-TW locale files.
MaiChartManager/Front/src/locales/en.yaml
MaiChartManager/Front/src/locales/zh.yaml
MaiChartManager/Front/src/locales/zh-TW.yaml
Document the resource junction tool behavior and add unit tests to enforce safety and selection logic.
  • Add user-facing documentation explaining how source/target directories are resolved, which resource folders are in scope, and detailed safety rules.
  • Add ResourceJunctionServiceTests covering resource scope invariants, auto-selection rules (including ties and sibling discovery), handling of reparse points, manual overrides, target/session behavior, conflict detection, junction lifecycle, and cleanup.
docs/resource-junction-manager.md
MaiChartManager.Tests/Services/ResourceJunctionServiceTests.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并给出了一些整体反馈:

  • ResourceJunctionController 中的文件夹选择提示(“Select a source game directory or Package directory” / “Select a target game directory or Package directory”)是直接硬编码为英文的;建议把它们移到现有的 i18n/本地化系统中,以便与其他 UI 文本保持一致。
  • 使用 mklink 的连接创建逻辑在 ResourceJunctionService 和 ResourceJunctionServiceTests 中都有重复;建议将这部分逻辑集中到一个共享的辅助方法中,避免实现出现差异,并让后续调整实现更容易(例如,如果以后不再通过调用 cmd 来完成)。
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- ResourceJunctionController 中的文件夹选择提示(“Select a source game directory or Package directory” / “Select a target game directory or Package directory”)是直接硬编码为英文的;建议把它们移到现有的 i18n/本地化系统中,以便与其他 UI 文本保持一致。
- 使用 `mklink` 的连接创建逻辑在 ResourceJunctionService 和 ResourceJunctionServiceTests 中都有重复;建议将这部分逻辑集中到一个共享的辅助方法中,避免实现出现差异,并让后续调整实现更容易(例如,如果以后不再通过调用 `cmd` 来完成)。

## Individual Comments

### Comment 1
<location path="MaiChartManager/Services/ResourceJunctionService.cs" line_range="384-393" />
<code_context>
+        Directory.Delete(root, true);
+    }
+
+    private static void CreateJunction(string source, string target)
+    {
+        var startInfo = new System.Diagnostics.ProcessStartInfo
+        {
+            FileName = Environment.GetEnvironmentVariable("ComSpec") ?? "cmd.exe",
+            UseShellExecute = false,
+            CreateNoWindow = true,
+        };
+        startInfo.ArgumentList.Add("/d");
+        startInfo.ArgumentList.Add("/c");
+        startInfo.ArgumentList.Add("mklink");
+        startInfo.ArgumentList.Add("/J");
+        startInfo.ArgumentList.Add(target);
+        startInfo.ArgumentList.Add(source);
+        using var process = System.Diagnostics.Process.Start(startInfo)!;
+        process.WaitForExit();
</code_context>
<issue_to_address>
**issue (bug_risk):** 在使用 `cmd.exe mklink` 创建连接时,如果不对路径进行引号包裹,包含空格或特殊字符的路径会导致失败。

由于 `ArgumentList` 传递给 `mklink` 的参数没有加引号,`source``target` 中的任何空格或特殊字符都会让 `cmd` 错误解析这些参数,进而导致连接创建失败。请在构造命令时确保两个路径都经过适当的引号包裹/转义,或者用直接的 Win32 实现(通过 `CreateFile` + `DeviceIoControl` 调用 `FSCTL_SET_REPARSE_POINT`)或托管辅助方法来替代 `cmd mklink` 调用。至少需要保证在诸如 `Program Files` 和用户配置文件等典型路径位置下,连接创建是健壮可靠的。
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈改进后续的评审。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • The folder selection prompts in ResourceJunctionController ("Select a source game directory or Package directory" / "Select a target game directory or Package directory") are hardcoded in English; consider moving them into the existing i18n/localization system so they match the rest of the UI.
  • The junction-creation logic using mklink is duplicated in both ResourceJunctionService and ResourceJunctionServiceTests; consider centralizing this into a shared helper to avoid divergence and make it easier to adjust the implementation (e.g., if you later switch away from shelling out to cmd).
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The folder selection prompts in ResourceJunctionController ("Select a source game directory or Package directory" / "Select a target game directory or Package directory") are hardcoded in English; consider moving them into the existing i18n/localization system so they match the rest of the UI.
- The junction-creation logic using `mklink` is duplicated in both ResourceJunctionService and ResourceJunctionServiceTests; consider centralizing this into a shared helper to avoid divergence and make it easier to adjust the implementation (e.g., if you later switch away from shelling out to `cmd`).

## Individual Comments

### Comment 1
<location path="MaiChartManager/Services/ResourceJunctionService.cs" line_range="384-393" />
<code_context>
+        Directory.Delete(root, true);
+    }
+
+    private static void CreateJunction(string source, string target)
+    {
+        var startInfo = new System.Diagnostics.ProcessStartInfo
+        {
+            FileName = Environment.GetEnvironmentVariable("ComSpec") ?? "cmd.exe",
+            UseShellExecute = false,
+            CreateNoWindow = true,
+        };
+        startInfo.ArgumentList.Add("/d");
+        startInfo.ArgumentList.Add("/c");
+        startInfo.ArgumentList.Add("mklink");
+        startInfo.ArgumentList.Add("/J");
+        startInfo.ArgumentList.Add(target);
+        startInfo.ArgumentList.Add(source);
+        using var process = System.Diagnostics.Process.Start(startInfo)!;
+        process.WaitForExit();
</code_context>
<issue_to_address>
**issue (bug_risk):** Creating junctions via `cmd.exe mklink` without quoting paths will break for paths with spaces or special characters.

Because `ArgumentList` passes `mklink` arguments without quoting, any spaces or special characters in `source` or `target` will cause `cmd` to parse them incorrectly and the junction creation to fail. Please either ensure both paths are properly quoted/escaped when constructing the command, or replace the `cmd mklink` call with a direct Win32-based implementation (`FSCTL_SET_REPARSE_POINT` via `CreateFile` + `DeviceIoControl`) or a managed helper. At minimum, junction creation must be robust for paths under typical locations like `Program Files` and user profiles.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +384 to +393
private static void CreateJunction(string source, string target)
{
var startInfo = new ProcessStartInfo
{
FileName = Environment.GetEnvironmentVariable("ComSpec") ?? "cmd.exe",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): 在使用 cmd.exe mklink 创建连接时,如果不对路径进行引号包裹,包含空格或特殊字符的路径会导致失败。

由于 ArgumentList 传递给 mklink 的参数没有加引号,sourcetarget 中的任何空格或特殊字符都会让 cmd 错误解析这些参数,进而导致连接创建失败。请在构造命令时确保两个路径都经过适当的引号包裹/转义,或者用直接的 Win32 实现(通过 CreateFile + DeviceIoControl 调用 FSCTL_SET_REPARSE_POINT)或托管辅助方法来替代 cmd mklink 调用。至少需要保证在诸如 Program Files 和用户配置文件等典型路径位置下,连接创建是健壮可靠的。

Original comment in English

issue (bug_risk): Creating junctions via cmd.exe mklink without quoting paths will break for paths with spaces or special characters.

Because ArgumentList passes mklink arguments without quoting, any spaces or special characters in source or target will cause cmd to parse them incorrectly and the junction creation to fail. Please either ensure both paths are properly quoted/escaped when constructing the command, or replace the cmd mklink call with a direct Win32-based implementation (FSCTL_SET_REPARSE_POINT via CreateFile + DeviceIoControl) or a managed helper. At minimum, junction creation must be robust for paths under typical locations like Program Files and user profiles.

@clansty

clansty commented Aug 2, 2026

Copy link
Copy Markdown
Member

不如 PR 正文写一下你的提示词和使用的模型,还有 harness 和装了哪些 skills,这样我审核的更快

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new “Game Resource Links” tool to MaiChartManager to share large maimai resource folders across multiple game installs by creating/removing Windows Junctions, with a front-end modal + backend API/service, safety checks, localization, docs, and unit tests.

Changes:

  • Introduce ResourceJunctionService + ResourceJunctionController to inspect/auto-select source/target roots and create/remove Junctions for AssetBundleImages, MovieData, SoundData.
  • Add a new Tools modal entry in the Vue UI to show selection info, file counts, Junction status, and to run create/remove with confirmation.
  • Update generated client types/endpoints, add i18n strings, add user documentation, and add unit tests for selection + Junction behavior.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
MaiChartManager/Services/ResourceJunctionService.cs Core logic: candidate discovery, file counting, Junction inspection/create/remove, and safety checks.
MaiChartManager/ServerManager.cs Registers ResourceJunctionService in DI.
MaiChartManager/Front/src/views/Tools/ResourceJunctionModal.tsx New modal UI for selecting source/target and managing Junctions.
MaiChartManager/Front/src/views/Tools/index.tsx Adds the new tool entry to the Tools panel and mounts the modal.
MaiChartManager/Front/src/locales/zh.yaml Adds Simplified Chinese strings for the new tool.
MaiChartManager/Front/src/locales/zh-TW.yaml Adds Traditional Chinese strings for the new tool.
MaiChartManager/Front/src/locales/en.yaml Adds English strings for the new tool.
MaiChartManager/Front/src/client/apiGen.ts Updates generated API client types/endpoints (resource junction APIs + store purchase enum change).
MaiChartManager/Controllers/Tools/ResourceJunctionController.cs New HTTP API endpoints for status/auto/manual select/create/remove, including local-action header gating for POSTs.
MaiChartManager.Tests/Services/ResourceJunctionServiceTests.cs Adds unit tests for source selection logic and Junction create/remove safety behavior.
MaiChartManager.Tests/MaiChartManager.Tests.csproj Updates test target framework to Windows TFM.
docs/resource-junction-manager.md User-facing documentation describing selection rules, scope, and safety boundaries.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +314 to +318
var directory = new DirectoryInfo(Path.Combine(root, name));
if (!directory.Exists || (directory.Attributes & FileAttributes.ReparsePoint) != 0)
throw new IOException($"{name} is missing or is a reparse point.");
return new ResourceDirectoryFileCount(name, directory.EnumerateFiles("*", SearchOption.AllDirectories).LongCount());
}).ToArray();
Comment on lines 414 to +417
export interface RequestPurchaseResult {
errorMessage?: string | null;
/** @format int32 */
status?: number;
status?: StorePurchaseStatus;
}
Comment on lines +63 to +67
const statusClass = (status?: ResourceJunctionStatus) => {
if (['Created', 'AlreadyLinked', 'Removed'].includes(status)) return 'text-green-700';
if (status === 'Ready') return 'text-blue-700';
return 'text-red-700';
};

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 12 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="MaiChartManager/Services/ResourceJunctionService.cs">

<violation number="1" location="MaiChartManager/Services/ResourceJunctionService.cs:208">
P1: Removal is vulnerable to a filesystem race: a verified junction can be swapped after `Inspect` and before this path-based delete, causing an ordinary replacement (including an empty directory) to be removed. An opened reparse-point handle with an atomic, identity-checked delete would preserve the no-wrong-target deletion guarantee.</violation>
</file>

<file name="MaiChartManager.Tests/MaiChartManager.Tests.csproj">

<violation number="1" location="MaiChartManager.Tests/MaiChartManager.Tests.csproj:3">
P3: Changing the test project to a Windows-only TFM (net10.0-windows10.0.17763.0) makes `dotnet test`/`dotnet build` of this project fail on non-Windows machines/CI unless the Windows targeting pack is available. The main project deliberately keeps a net10.0 Linux configuration, but the test project now has no such escape hatch, so a Linux `dotnet test MaiChartManager.Tests` no longer works. Consider adding `<EnableWindowsTargeting>true</EnableWindowsTargeting>` so the project (and any future Linux CI) can still restore/build the Windows reference assemblies — this only affects build-time downloads and does not change runtime behavior.</violation>
</file>

<file name="MaiChartManager/ServerManager.cs">

<violation number="1" location="MaiChartManager/ServerManager.cs:107">
P2: ResourceJunctionService is registered as a singleton but stores the whole interactive selection session in mutable instance fields (`selectedSourceRoot`, `selectedTargetRoot`, `selectionMode`, ...). Since the local Kestrel services requests on the thread pool, two concurrent requests (a status poll racing a Create/Remove, or the tool opened in two tabs) can interleave mutations of these shared fields mid-operation, so the create/remove/verify sequence can observe another request's selection values. Either keep the per-request selection out of the singleton (pass source/target explicitly to the mutating methods), add synchronization, or register it scoped so each request owns its own state.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic


try
{
Directory.Delete(item.Target, false);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Removal is vulnerable to a filesystem race: a verified junction can be swapped after Inspect and before this path-based delete, causing an ordinary replacement (including an empty directory) to be removed. An opened reparse-point handle with an atomic, identity-checked delete would preserve the no-wrong-target deletion guarantee.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At MaiChartManager/Services/ResourceJunctionService.cs, line 208:

<comment>Removal is vulnerable to a filesystem race: a verified junction can be swapped after `Inspect` and before this path-based delete, causing an ordinary replacement (including an empty directory) to be removed. An opened reparse-point handle with an atomic, identity-checked delete would preserve the no-wrong-target deletion guarantee.</comment>

<file context>
@@ -0,0 +1,457 @@
+
+            try
+            {
+                Directory.Delete(item.Target, false);
+                var verified = Inspect(name, sourceRoot, targetRoot);
+                return verified.Status == ResourceJunctionStatus.Ready
</file context>

Comment thread MaiChartManager/Front/src/client/apiGen.ts Outdated
Comment thread MaiChartManager/Controllers/Tools/ResourceJunctionController.cs
Comment thread MaiChartManager/Services/ResourceJunctionService.cs Outdated
Comment thread MaiChartManager/Services/ResourceJunctionService.cs Outdated
.AddSingleton<MaidataImportService>()
.AddSingleton<MuModService>()
.AddSingleton<ModConfigService>()
.AddSingleton<MaiChartManager.Services.ResourceJunctionService>()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: ResourceJunctionService is registered as a singleton but stores the whole interactive selection session in mutable instance fields (selectedSourceRoot, selectedTargetRoot, selectionMode, ...). Since the local Kestrel services requests on the thread pool, two concurrent requests (a status poll racing a Create/Remove, or the tool opened in two tabs) can interleave mutations of these shared fields mid-operation, so the create/remove/verify sequence can observe another request's selection values. Either keep the per-request selection out of the singleton (pass source/target explicitly to the mutating methods), add synchronization, or register it scoped so each request owns its own state.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At MaiChartManager/ServerManager.cs, line 107:

<comment>ResourceJunctionService is registered as a singleton but stores the whole interactive selection session in mutable instance fields (`selectedSourceRoot`, `selectedTargetRoot`, `selectionMode`, ...). Since the local Kestrel services requests on the thread pool, two concurrent requests (a status poll racing a Create/Remove, or the tool opened in two tabs) can interleave mutations of these shared fields mid-operation, so the create/remove/verify sequence can observe another request's selection values. Either keep the per-request selection out of the singleton (pass source/target explicitly to the mutating methods), add synchronization, or register it scoped so each request owns its own state.</comment>

<file context>
@@ -104,6 +104,7 @@ public static Task StartApp(bool export, Action<string>? onStart = null, bool se
             .AddSingleton<MaidataImportService>()
             .AddSingleton<MuModService>()
             .AddSingleton<ModConfigService>()
+            .AddSingleton<MaiChartManager.Services.ResourceJunctionService>()
             .AddEndpointsApiExplorer()
             .AddSwaggerGen(options => { options.CustomSchemaIds(type => type.Name == "Config" ? type.FullName : type.Name); })
</file context>

Comment thread MaiChartManager/Services/ResourceJunctionService.cs Outdated
Comment thread MaiChartManager/Front/src/views/Tools/ResourceJunctionModal.tsx Outdated
Comment thread MaiChartManager/Front/src/views/Tools/ResourceJunctionModal.tsx Outdated
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<TargetFramework>net10.0-windows10.0.17763.0</TargetFramework>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Changing the test project to a Windows-only TFM (net10.0-windows10.0.17763.0) makes dotnet test/dotnet build of this project fail on non-Windows machines/CI unless the Windows targeting pack is available. The main project deliberately keeps a net10.0 Linux configuration, but the test project now has no such escape hatch, so a Linux dotnet test MaiChartManager.Tests no longer works. Consider adding <EnableWindowsTargeting>true</EnableWindowsTargeting> so the project (and any future Linux CI) can still restore/build the Windows reference assemblies — this only affects build-time downloads and does not change runtime behavior.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At MaiChartManager.Tests/MaiChartManager.Tests.csproj, line 3:

<comment>Changing the test project to a Windows-only TFM (net10.0-windows10.0.17763.0) makes `dotnet test`/`dotnet build` of this project fail on non-Windows machines/CI unless the Windows targeting pack is available. The main project deliberately keeps a net10.0 Linux configuration, but the test project now has no such escape hatch, so a Linux `dotnet test MaiChartManager.Tests` no longer works. Consider adding `<EnableWindowsTargeting>true</EnableWindowsTargeting>` so the project (and any future Linux CI) can still restore/build the Windows reference assemblies — this only affects build-time downloads and does not change runtime behavior.</comment>

<file context>
@@ -1,6 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFramework>net10.0</TargetFramework>
+    <TargetFramework>net10.0-windows10.0.17763.0</TargetFramework>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
</file context>
Suggested change
<TargetFramework>net10.0-windows10.0.17763.0</TargetFramework>
<TargetFramework>net10.0-windows10.0.17763.0</TargetFramework>
<EnableWindowsTargeting>true</EnableWindowsTargeting>

@UranusNo7

Copy link
Copy Markdown
Author

已按一次集中提交 8336763 处理审查反馈,避免多次推送增加审核成本。

已修复:

  • 文件计数跳过所有嵌套重解析点,并补真实 Junction 回归测试。
  • 从 Linux Swagger 重新生成 apiGen.ts,移除无关的购买状态枚举差异;自动选择改为带本地操作头的 POST。
  • 状态样式和创建/移除按钮均使用 ResourceJunctionStatus 枚举;Created 可直接移除,Removed 可直接重建。
  • 固定三目录范围改为只读集合,避免调用方修改。
  • 修复直接 Sinmai_Data 布局下相邻游戏目录发现层级,并补回归测试。
  • 测试项目按 Linux 配置切回 net10.0,Windows 与 LinuxDebugBackend 均通过 18/18。

核实后未改动:

  • ProcessStartInfo.ArgumentList 会负责进程参数引用;测试临时根目录现包含空格和 &,真实 Junction 创建/读取/移除均通过,因此不再手工拼接引号。
  • 服务的选择状态按设计属于本次桌面应用会话。前端串行操作,创建/移除在入口处快照源和目标,其他请求不会改变正在执行的三个路径;改为 scoped 反而会丢失跨请求的手动选择。
  • 外部本机进程在检查与删除之间恶意替换目录的 TOCTOU 理论上存在,但需要引入基于重解析点句柄的 Win32 删除实现。当前本机单用户工具已在删除前验证正确 Junction、只做非递归删除并在删除后验证,本 PR 不为该威胁模型扩展底层实现。
  • 文件夹选择标题本地化、把测试 mklink 与生产私有实现合并属于非阻断建议;后者会让测试依赖生产实现,降低独立验证价值,本次保持范围不变。

验证:

  • dotnet test MaiChartManager.Tests/MaiChartManager.Tests.csproj -c Debug:18/18
  • dotnet test MaiChartManager.Tests/MaiChartManager.Tests.csproj -c LinuxDebugBackend:18/18
  • pnpm build:通过
  • dotnet build MaiChartManager/MaiChartManager.csproj -c LinuxDebugBackend --no-restore:通过
  • 本地 Swagger 已确认自动选择端点为 POST;apiGen.ts 生成成功。生成脚本随后访问无关的远端 AquaMai OpenAPI 时遇到 ECONNRESET,未影响本地客户端文件。

PR 正文也已补充模型、harness、实际工具、skills 使用情况和用户提示词摘要。

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 7 files (changes from recent commits).

Requires human review: Auto-approval blocked by 3 unresolved issues from previous reviews.

Re-trigger cubic

@clansty

clansty commented Aug 2, 2026

Copy link
Copy Markdown
Member

你是什么模型

@UranusNo7 UranusNo7 closed this Aug 2, 2026
@UranusNo7 UranusNo7 reopened this Aug 2, 2026
@UranusNo7

Copy link
Copy Markdown
Author

你是什么模型

5.6sol捏,思考深度是中

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:

  • 目前控制器方法中重复进行了 Export/LocalAction 头部检查;可以考虑提取一个小的辅助函数或过滤器来集中处理这些校验,从而减少在各个 ResourceJunction 端点之间的重复代码。
  • ResourceJunctionController 中的文件夹选择提示目前是硬编码的英文字符串;如果能通过现有的本地化系统来传递这些文案,可以与其他 UI 保持一致,避免出现混合语言的对话框。
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The controller methods currently repeat the `Export`/`LocalAction` header checks; consider extracting a small helper or filter to centralize this validation and reduce duplication across the ResourceJunction endpoints.
- Folder selection prompts in `ResourceJunctionController` are hard-coded English strings; wiring these through your existing localization system would keep them consistent with the rest of the UI and avoid mixed-language dialogs.

## Individual Comments

### Comment 1
<location path="MaiChartManager/Front/src/views/Tools/ResourceJunctionModal.tsx" line_range="22-31" />
<code_context>
+    const request = async (action: 'auto' | 'status' | 'manual' | 'manualTarget' | 'create' | 'remove') => {
</code_context>
<issue_to_address>
**suggestion:** Client-side error handling discards specific server error messages, which could be surfaced to improve UX.

The API returns BadRequest with a plain string for validation issues (e.g., invalid source/target), but Axios errors are always mapped to a generic `requestFailed` toast. Please read the response payload (e.g., `error.response?.data`) and include that message in the toast when available, so users see the specific validation error instead of a generic failure.

Suggested implementation:

```typescript
      } catch (error) {
        let detail: string | undefined;

        // Try to surface server-side validation / error messages when available
        if (axios.isAxiosError(error)) {
          const payload = error.response?.data;

          if (typeof payload === 'string') {
            // API returns plain string for validation issues
            detail = payload;
          } else if (payload && typeof payload === 'object') {
            // Fallback for common structured error shapes
            const { message, error: errorMessage } = payload as { message?: string; error?: string };
            detail = message ?? errorMessage;
          }
        }

        toast.add({
          severity: 'error',
          summary: t('tools.resourceJunction.requestFailed'),
          detail,
          life: 5000,
        });
      } finally {
        loading.value = false;
      }

```

1. Ensure `axios` is imported at the top of this file, for example:
   `import axios from 'axios';`
2. If your toast implementation uses a different property than `detail` for the message body, adjust the `toast.add` call to match the existing convention (e.g., `message` or `description`).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
请帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据这些反馈改进后续的代码审查。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • The controller methods currently repeat the Export/LocalAction header checks; consider extracting a small helper or filter to centralize this validation and reduce duplication across the ResourceJunction endpoints.
  • Folder selection prompts in ResourceJunctionController are hard-coded English strings; wiring these through your existing localization system would keep them consistent with the rest of the UI and avoid mixed-language dialogs.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The controller methods currently repeat the `Export`/`LocalAction` header checks; consider extracting a small helper or filter to centralize this validation and reduce duplication across the ResourceJunction endpoints.
- Folder selection prompts in `ResourceJunctionController` are hard-coded English strings; wiring these through your existing localization system would keep them consistent with the rest of the UI and avoid mixed-language dialogs.

## Individual Comments

### Comment 1
<location path="MaiChartManager/Front/src/views/Tools/ResourceJunctionModal.tsx" line_range="22-31" />
<code_context>
+    const request = async (action: 'auto' | 'status' | 'manual' | 'manualTarget' | 'create' | 'remove') => {
</code_context>
<issue_to_address>
**suggestion:** Client-side error handling discards specific server error messages, which could be surfaced to improve UX.

The API returns BadRequest with a plain string for validation issues (e.g., invalid source/target), but Axios errors are always mapped to a generic `requestFailed` toast. Please read the response payload (e.g., `error.response?.data`) and include that message in the toast when available, so users see the specific validation error instead of a generic failure.

Suggested implementation:

```typescript
      } catch (error) {
        let detail: string | undefined;

        // Try to surface server-side validation / error messages when available
        if (axios.isAxiosError(error)) {
          const payload = error.response?.data;

          if (typeof payload === 'string') {
            // API returns plain string for validation issues
            detail = payload;
          } else if (payload && typeof payload === 'object') {
            // Fallback for common structured error shapes
            const { message, error: errorMessage } = payload as { message?: string; error?: string };
            detail = message ?? errorMessage;
          }
        }

        toast.add({
          severity: 'error',
          summary: t('tools.resourceJunction.requestFailed'),
          detail,
          life: 5000,
        });
      } finally {
        loading.value = false;
      }

```

1. Ensure `axios` is imported at the top of this file, for example:
   `import axios from 'axios';`
2. If your toast implementation uses a different property than `detail` for the message body, adjust the `toast.add` call to match the existing convention (e.g., `message` or `description`).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread MaiChartManager/Front/src/views/Tools/ResourceJunctionModal.tsx
@UranusNo7

Copy link
Copy Markdown
Author

Addressed the latest Sourcery review in 5f932b1:

  • Surface backend validation details from the generated Fetch client's HttpResponse.error payload in the existing toast (this project does not use Axios).
  • Centralize the repeated Export/local-action POST guards.
  • Localize the native source and target folder-picker titles in English, Simplified Chinese, and Traditional Chinese.
  • Update the user documentation for detailed validation errors.

Validation:

  • dotnet test MaiChartManager.Tests/MaiChartManager.Tests.csproj -c Debug (18/18)
  • dotnet test MaiChartManager.Tests/MaiChartManager.Tests.csproj -c LinuxDebugBackend (18/18)
  • pnpm build
  • git diff --check

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 6 files (changes from recent commits).

Requires human review: Auto-approval blocked by 3 unresolved issues from previous reviews.

Re-trigger cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants