MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / resolve_project_tail

Function resolve_project_tail

src/mcp/mcp.c:1441–1487  ·  view source on GitHub ↗

#1025: agents naturally pass the repo FOLDER name ("codebase-memory-mcp"), * but indexed project names derive from the full path * (E:\project\graph\x -> "E-project-graph-x"), so the exact lookup fails * while list_projects clearly shows the project. When no .db exists, * scan cache-dir FILENAMES for a segment-aligned tail match ("- .db"): * exactly one match adopts the full

Source from the content-addressed store, hash-verified

1439 * the existing not-found error (which lists all candidates) fires. Filename-
1440 * level only — internal-name drift stays #704's fallback in resolve_store. */
1441static char *resolve_project_tail(char *project) {
1442 if (!project || !cbm_validate_project_name(project)) {
1443 return project;
1444 }
1445 char dir[CBM_SZ_1K];
1446 cache_dir(dir, sizeof(dir));
1447 char exact[CBM_SZ_2K];
1448 snprintf(exact, sizeof(exact), "%s/%s.db", dir, project);
1449 if (cbm_file_exists(exact)) {
1450 return project; /* exact name — untouched fast path */
1451 }
1452 size_t plen = strlen(project);
1453 char match[CBM_SZ_1K] = "";
1454 int matches = 0;
1455 cbm_dir_t *d = cbm_opendir(dir);
1456 if (!d) {
1457 return project;
1458 }
1459 cbm_dirent_t *entry;
1460 while ((entry = cbm_readdir(d)) != NULL) {
1461 const char *n = entry->name;
1462 size_t len = strlen(n);
1463 if (!is_project_db_file(n, len)) {
1464 continue;
1465 }
1466 size_t stem_len = len - MCP_DB_EXT; /* strip ".db" */
1467 if (stem_len <= plen + 1 || stem_len >= sizeof(match)) {
1468 continue;
1469 }
1470 if (n[stem_len - plen - 1] != '-' || strncmp(n + stem_len - plen, project, plen) != 0) {
1471 continue;
1472 }
1473 matches++;
1474 if (matches > 1) {
1475 break; /* ambiguous — keep the original name */
1476 }
1477 memcpy(match, n, stem_len);
1478 match[stem_len] = '\0';
1479 }
1480 cbm_closedir(d);
1481 if (matches == 1) {
1482 cbm_log_info("mcp.project_tail_resolved", "passed", project, "resolved", match);
1483 free(project);
1484 return heap_strdup(match);
1485 }
1486 return project;
1487}
1488
1489/* Resolve the project argument, accepting the canonical "project" key plus the
1490 * aliases a caller naturally reaches for (#640): list_projects surfaces the

Callers 1

get_project_argFunction · 0.85

Calls 8

cache_dirFunction · 0.85
cbm_file_existsFunction · 0.85
cbm_opendirFunction · 0.85
cbm_readdirFunction · 0.85
is_project_db_fileFunction · 0.85
cbm_closedirFunction · 0.85
heap_strdupFunction · 0.70

Tested by

no test coverage detected