diff --git a/src/discover/discover.c b/src/discover/discover.c index 314c00c5..31b15baa 100644 --- a/src/discover/discover.c +++ b/src/discover/discover.c @@ -131,6 +131,32 @@ static bool str_contains(const char *s, const char *sub) { return strstr(s, sub) != NULL; } +/* Windows IDE auto-index integrations can accidentally pass the IDE install + * directory itself as the repository root. These are not source projects and + * are mostly binary/runtime assets. Match on the normalized full path because + * cbm_should_skip_dir() only sees basenames during the walk. */ +static bool looks_like_ide_install_root(const char *path) { + if (!path) { + return false; + } + + char normalized[CBM_SZ_4K]; + size_t i = 0; + for (; path[i] && i + 1 < sizeof(normalized); i++) { + char c = path[i]; + if (c == '\\') { + c = '/'; + } + if (c >= 'A' && c <= 'Z') { + c = (char)(c - 'A' + 'a'); + } + normalized[i] = c; + } + normalized[i] = '\0'; + + return strstr(normalized, "appdata/local/programs/antigravity") != NULL; +} + /* ── Public filter functions ─────────────────────── */ bool cbm_should_skip_dir(const char *dirname, cbm_index_mode_t mode) { @@ -541,6 +567,10 @@ int cbm_discover_ex(const char *repo_path, const cbm_discover_opts_t *opts, cbm_ return CBM_NOT_FOUND; } + if (looks_like_ide_install_root(repo_path)) { + return 0; + } + /* Load gitignore if .git directory exists */ cbm_gitignore_t *gitignore = NULL; char gi_path[CBM_SZ_4K]; diff --git a/tests/test_discover.c b/tests/test_discover.c index af51a928..69ed4ff3 100644 --- a/tests/test_discover.c +++ b/tests/test_discover.c @@ -309,6 +309,29 @@ TEST(discover_skips_git_dir) { PASS(); } +TEST(discover_skips_antigravity_install_root_issue403) { + char *base = th_mktempdir("cbm_disc_ide403"); + ASSERT(base != NULL); + + char ide_root[512]; + snprintf(ide_root, sizeof(ide_root), "%s/AppData/Local/Programs/Antigravity IDE", base); + th_mkdir_p(ide_root); + th_write_file(TH_PATH(ide_root, "resources/app/main.js"), "console.log('ide runtime');\n"); + th_write_file(TH_PATH(ide_root, "resources/app/package.json"), "{\"name\":\"antigravity\"}\n"); + + cbm_discover_opts_t opts = {0}; + cbm_file_info_t *files = NULL; + int count = 0; + + int rc = cbm_discover(ide_root, &opts, &files, &count); + ASSERT_EQ(rc, 0); + ASSERT_EQ(count, 0); + + cbm_discover_free(files, count); + th_cleanup(base); + PASS(); +} + TEST(discover_with_gitignore) { char *base = th_mktempdir("cbm_disc_gi"); ASSERT(base != NULL); @@ -777,6 +800,7 @@ SUITE(discover) { /* Integration tests (cross-platform) */ RUN_TEST(discover_simple); RUN_TEST(discover_skips_git_dir); + RUN_TEST(discover_skips_antigravity_install_root_issue403); RUN_TEST(discover_with_gitignore); RUN_TEST(discover_gitignore_dir_excluded_issue234); RUN_TEST(discover_max_file_size);