diff --git a/enrichers.cpp b/enrichers.cpp index e55d9a8..a016879 100644 --- a/enrichers.cpp +++ b/enrichers.cpp @@ -108,19 +108,34 @@ int enrichers_load(const char* enrichers_dir) { g_enrichers.clear(); if (!enrichers_dir || !*enrichers_dir) return -1; - DIR* d = opendir(enrichers_dir); - if (!d) return -1; + // En Windows los UNC paths esperan backslashes consistentes; mixed + // separators (`\\wsl$\\foo/bar`) confunden a opendir de MinGW. + std::string dir = enrichers_dir; +#ifdef _WIN32 + for (char& c : dir) if (c == '/') c = '\\'; +#endif + + DIR* d = opendir(dir.c_str()); + if (!d) { + std::fprintf(stderr, "[enrichers] opendir failed: %s\n", dir.c_str()); + return -1; + } struct dirent* ent; while ((ent = readdir(d)) != nullptr) { if (ent->d_name[0] == '.') continue; - std::string sub = std::string(enrichers_dir) + "/" + ent->d_name; +#ifdef _WIN32 + const char sep = '\\'; +#else + const char sep = '/'; +#endif + std::string sub = dir + sep + ent->d_name; struct stat st{}; if (stat(sub.c_str(), &st) != 0 || !S_ISDIR(st.st_mode)) continue; - std::string manifest = sub + "/manifest.yaml"; - std::string runpy = sub + "/run.py"; + std::string manifest = sub + sep + "manifest.yaml"; + std::string runpy = sub + sep + "run.py"; if (stat(manifest.c_str(), &st) != 0) continue; if (stat(runpy.c_str(), &st) != 0) continue; diff --git a/main.cpp b/main.cpp index c5f47f4..4cc99f4 100644 --- a/main.cpp +++ b/main.cpp @@ -252,14 +252,35 @@ static bool load_input(bool first_load = true); // Registry path resolution (issue 0026) // ---------------------------------------------------------------------------- +#ifdef _WIN32 +// Detecta la distro WSL "default" buscando que UNC `\\wsl.localhost\\` +// existe y contiene `home/lucas/fn_registry/registry.db`. Devuelve "" si no +// encuentra ninguna. Probamos las distros comunes — el usuario sobrescribe +// con FN_REGISTRY_ROOT si tiene una con nombre raro. +static std::string detect_wsl_distro() { + const char* candidates[] = { + "Ubuntu", "Ubuntu-24.04", "Ubuntu-22.04", "Ubuntu-20.04", + "Debian", "kali-linux", "Fedora", "openSUSE-Tumbleweed", + nullptr + }; + for (int i = 0; candidates[i]; ++i) { + std::string probe = std::string("\\\\wsl.localhost\\") + candidates[i] + + "\\home\\lucas\\fn_registry\\registry.db"; + FILE* f = std::fopen(probe.c_str(), "rb"); + if (f) { std::fclose(f); return candidates[i]; } + } + return ""; +} +#endif + // Devuelve el path absoluto al root de fn_registry. Estrategia: // 1) FN_REGISTRY_ROOT env var (acepta path Linux o UNC Windows -// `\\\\wsl.localhost\\Ubuntu\\home\\...`). +// `\\\\wsl.localhost\\\\home\\...`). // 2) Sube desde getcwd() buscando un dir con `registry.db`. -// 3) En Windows, fallback al UNC default `\\\\wsl.localhost\\Ubuntu\\home\\ -// lucas\\fn_registry` (la build se distribuye al desktop fuera del -// arbol del registry, asi que getcwd nunca lo encuentra). -// 4) "" si no se encuentra. +// 3) En Windows, sondear UNCs de las distros comunes hasta encontrar +// una con `registry.db`. La build se distribuye al desktop fuera del +// arbol del registry, asi que getcwd nunca lo encuentra. +// 4) "" si no se encuentra (los enrichers quedan desactivados). static std::string resolve_registry_root() { if (const char* env = std::getenv("FN_REGISTRY_ROOT")) { if (env && *env) return env; @@ -268,7 +289,6 @@ static std::string resolve_registry_root() { if (getcwd(cwd, sizeof(cwd)) != nullptr) { std::string p = cwd; #ifdef _WIN32 - // Normalizar separadores para comparar. for (char& c : p) if (c == '\\') c = '/'; #endif for (int i = 0; i < 8; ++i) { @@ -281,9 +301,15 @@ static std::string resolve_registry_root() { } } #ifdef _WIN32 - // Fallback Windows: el UNC apunta al WSL del usuario. Ajustar el nombre - // de la distro si no es "Ubuntu". La build Linux/WSL nunca llega aqui. - return "\\\\wsl.localhost\\Ubuntu\\home\\lucas\\fn_registry"; + std::string distro = detect_wsl_distro(); + if (!distro.empty()) { + return std::string("\\\\wsl.localhost\\") + distro + + "\\home\\lucas\\fn_registry"; + } + std::fprintf(stderr, + "[graph_explorer] no se detecta la distro WSL — " + "setea FN_REGISTRY_ROOT con el UNC del registry.\n"); + return ""; #else return ""; #endif @@ -676,18 +702,23 @@ static void render_context_menu() { // issue 0026 — listamos enrichers cuyo applies_to incluye este type. const char* type_name = (n.type_id < (uint16_t)g_graph.type_count) ? g_graph.types[n.type_id].name : ""; - auto specs = ge::enrichers_for_type(type_name); + const auto& all = ge::enrichers_all(); + auto specs = ge::enrichers_for_type(type_name); if (!sql_id) { ImGui::TextDisabled("(node has no entity id)"); + } else if (all.empty()) { + ImGui::TextDisabled("(no enrichers cargados)"); + ImGui::TextDisabled("revisa FN_REGISTRY_ROOT"); } else if (specs.empty()) { - ImGui::TextDisabled("(no enrichers para tipo '%s')", type_name); + ImGui::TextDisabled("(0/%d enrichers para tipo '%s')", + (int)all.size(), type_name); } else { for (const auto& s : specs) { if (ImGui::MenuItem(s.name.c_str())) { char job_id[64]; bool ok = ge::jobs_submit(s.id.c_str(), sql_id, lbl, "{}", job_id, sizeof(job_id)); - if (ok) g_app.panel_jobs = true; // abrir panel auto + if (ok) g_app.panel_jobs = true; } if (!s.description.empty() && ImGui::IsItemHovered()) { ImGui::SetTooltip("%s", s.description.c_str());