MiniMax-AI / MiniMax-AI/cli

[Bug] Windows 下 agent setup 无法识别仅大小写不同的重复配置路径

Open
#257 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.2k
Forks
181
Avg merge
9h 4m
Merged PRs (30d)
13

Description

[Bug] Windows 下 agent setup 无法识别仅大小写不同的重复配置路径

问题描述

在 Windows 上,如果 CLAUDE_CONFIG_DIRPI_CODING_AGENT_DIR 使用不同的字母大小写指向同一个目录,Claude Code 与 Pi 实际会使用同一个 settings.json,但当前的重复目标预检会把它们识别成两个不同路径。

当前 main 中,writeTarget() 使用 realpathSync() 生成目标路径;Windows 上该调用会保留调用方提供的路径大小写。随后 assertDistinctConfigurationTargets() 使用区分大小写的 Set<string> 判重,因此同一物理路径的不同大小写形式能够绕过预检。

最小复现

在 Windows 上准备一个包含合法 settings.json 的共享目录,让 CLAUDE_CONFIG_DIRPI_CODING_AGENT_DIR 以不同大小写指向该目录,然后同时准备 Claude Code 和 Pi 的配置。

  • 预期:按照现有测试契约,在创建文件或备份前报告重复配置目标。
  • 实际:两个逻辑路径指向同一个物理文件,但因字符串大小写不同而绕过重复目标预检。

核验情况

我已经检索所有状态的 issue 和 PR,并检查开放 PR 涉及的文件,未发现等价报告、现有实现或正在进行的同文件修改。该问题可以使用 Windows 临时目录完全离线验证,不需要 API key、账号或网络。

建议修复方案

我建议保留 writeTarget() 生成的 targetPath 作为唯一真实读写路径,不修改它的大小写;另派生一个只用于判重的路径身份键:

function configurationTargetIdentity(
  targetPath: string,
  platform = process.platform,
): string {
  const normalized = platform === 'win32'
    ? win32.normalize(targetPath)
    : normalize(targetPath);
  return platform === 'win32' ? normalized.toLowerCase() : normalized;
}

assertDistinctConfigurationTargets() 中的 Set 改为保存这个身份键,而不是直接保存 file.targetPath。这样 C:\Users\A\Config\settings.jsonc:\users\a\config\SETTINGS.JSON 在 Windows 下会得到同一个比较键,并在任何写入或备份前触发现有的重复目标错误。

真实的 file.targetPath 仍用于读取、写入、错误提示和回滚,因此不会因为判重而改写用户路径,也不会引入第二份可变路径状态。准备阶段与写入前复检继续调用同一个 assertDistinctConfigurationTargets(),保证只有一套判重规则。

计划补充以下聚焦测试:

  • 保留现有“完全相同路径必须在创建文件或备份前失败”的测试。
  • 给纯身份函数传入 win32 平台语义,验证盘符、目录名和文件名仅大小写不同的路径得到相同身份键;这样现有 Ubuntu CI 也能稳定覆盖 Windows 比较规则。
  • 验证非 Windows 平台仍保持大小写敏感,避免改变其他平台行为。
  • 在 Windows 本地执行端到端回归,确认不同大小写指向同一共享目录时,准备阶段直接失败且没有生成文件或备份。

本次范围只处理 Windows 大小写路径碰撞,不比较文件内容,不改变 Agent 配置格式、安装流程、认证、事务写入或回滚行为,也不扩展到硬链接等其他文件别名。

请问维护者是否同意由我提交这个 PR?在获得明确许可前,我不会开始实现。

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading writeTarget() and assertDistinctConfigurationTargets(), then locate the existing duplicate-target tests and the preparation/write flow that calls them. Add focused coverage for Windows case-insensitive identity keys and non-Windows case sensitivity; done means the shared target fails before file creation or backup while the original targetPath remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.