diff --git a/src/cli/cli.c b/src/cli/cli.c index 3db818c28..365c31fd2 100644 --- a/src/cli/cli.c +++ b/src/cli/cli.c @@ -20,6 +20,7 @@ #include "daemon/runtime.h" #include "daemon/version_cohort.h" #include "foundation/compat.h" +#include "foundation/compat_fs.h" #include "foundation/platform.h" #include "foundation/constants.h" #include "foundation/json_writer.h" @@ -2718,12 +2719,8 @@ int cbm_remove_zed_mcp_owned(const char *binary_path, const char *config_path) { /* ── Agent detection ──────────────────────────────────────────── */ static bool dir_exists(const char *path) { - struct stat st; -#ifndef _WIN32 - return lstat(path, &st) == 0 && S_ISDIR(st.st_mode); -#else - return stat(path, &st) == 0 && S_ISDIR(st.st_mode); -#endif + cbm_path_info_t info = {0}; + return cbm_path_info_utf8(path, &info) == CBM_PATH_INFO_OK && info.is_directory; } /* Resolve the Claude Code config dir. diff --git a/tests/test_cli.c b/tests/test_cli.c index e3383be78..c3a84c5fb 100644 --- a/tests/test_cli.c +++ b/tests/test_cli.c @@ -15281,6 +15281,29 @@ TEST(cli_detect_agents_finds_zed_in_roaming_appdata) { } #endif +#ifdef _WIN32 +/* #2145: a profile path outside the ANSI code page must stay visible to agent + * detection. The directory is created with th_mkdir_p, which goes through the + * wide-char API: test_mkdirp uses cbm_mkdir, the narrow _mkdir on Windows, + * which would create a code-page-mangled name instead of this one. Cursor is + * detected by its directory alone, so the assertion goes through dir_exists. */ +TEST(cli_detect_agents_handles_non_ascii_windows_profile) { + char home[1024]; + snprintf(home, sizeof(home), "%s/cbm-用户-profile", cbm_tmpdir()); + test_rmdir_r(home); + char cursor_dir[1024]; + snprintf(cursor_dir, sizeof(cursor_dir), "%s/.cursor", home); + if (th_mkdir_p(cursor_dir) != 0) + FAIL("could not create non-ASCII Windows profile path"); + + cbm_detected_agents_t agents = cbm_detect_agents(home); + test_rmdir_r(home); + if (!agents.cursor) + FAIL("agent detection must support non-ASCII Windows profile paths"); + PASS(); +} +#endif + TEST(cli_detect_agents_finds_antigravity) { char tmpdir[256]; snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-detect-XXXXXX"); @@ -19351,6 +19374,7 @@ SUITE(cli) { #endif #ifdef _WIN32 RUN_TEST(cli_detect_agents_finds_zed_in_roaming_appdata); + RUN_TEST(cli_detect_agents_handles_non_ascii_windows_profile); #endif RUN_TEST(cli_detect_agents_finds_antigravity); RUN_TEST(cli_detect_agents_finds_kilocode);