From 3ad26e4f6bf2d1e5d8831be316c47ada60a13eb6 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Tue, 19 May 2026 00:31:34 +0200 Subject: [PATCH] chore: auto-commit (4 archivos) - app.md - appicon.ico - autoextract_panel.cpp - recipes_panel.cpp Co-Authored-By: Claude Opus 4.7 (1M context) --- app.md | 23 ++++----- appicon.ico | Bin 11470 -> 17150 bytes autoextract_panel.cpp | 1 + recipes_panel.cpp | 116 +++++++++++++++++++++++++++++------------- 4 files changed, 92 insertions(+), 48 deletions(-) diff --git a/app.md b/app.md index 605affd..418c07a 100644 --- a/app.md +++ b/app.md @@ -2,21 +2,10 @@ name: navegator_dashboard lang: cpp domain: tools +version: 0.1.0 description: "Cuadro de mandos para gestionar instancias Chrome con remote debugging. Lista navegadores corriendo (visibles + headless), permite lanzar/matar perfiles, inspeccionar pestañas, ejecutar JS, ver peticiones de red. Puente WSL→Windows que centraliza el control que hoy hacemos por scripts dispersos." tags: [imgui, browser, cdp, dashboard, windows, navegator, auto-extract, recipes, picker] uses_functions: - - data_table_cpp_viz - - viz_render_cpp_viz - - compute_stage_cpp_core - - compute_pipeline_cpp_core - - tql_emit_cpp_core - - tql_apply_cpp_core - - lua_engine_cpp_core - - join_tables_cpp_core - - auto_detect_type_cpp_core - - compute_column_stats_cpp_core - - llm_anthropic_cpp_core - - tql_to_sql_cpp_core - claude_cli_prompt_py_infra - cdp_get_ax_tree_py_pipelines - llm_propose_scraping_schema_py_infra @@ -132,3 +121,13 @@ Casos de uso: - v1: CDP HTTP/WS in-process + Tabs + Tab Detail + Network panel. - v2: HTTP API local + integracion con `cdp-cli` (cdp-cli puede delegar al dashboard si esta vivo). - v3: streaming live de pestañas (CDP `Page.startScreencast`) — arquitectura ya prevista en issue 0038. + + +## Capability growth log + +Una linea por bump SemVer. Bump-type segun `.claude/commands/version.md`: +- `major`: breaking observable (CLI args, schema BBDD propia, formato wire). +- `minor`: feature aditiva (nuevo panel, endpoint, opcion). +- `patch`: bugfix sin cambio observable. + +- v0.1.0 (2026-05-18) — baseline. diff --git a/appicon.ico b/appicon.ico index c0ca60cea9f0eed3a77e2cc3378e0a1214c9166f..e3cb7fb9d085621b4215776d35fb8ea5a3cef167 100644 GIT binary patch literal 17150 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 w2?%n`FMRpF3+$6Yq>b#;gbzwZr2 g_back_recipes; + static std::vector g_ptrs_recipes; - for (size_t i = 0; i < rows_copy.size(); ++i) { - const RecipeRow& r = rows_copy[i]; - ImGui::TableNextRow(); - ImGui::PushID((int)i); - ImGui::TableNextColumn(); - ImGui::TextUnformatted(r.name.c_str()); - ImGui::TableNextColumn(); - ImGui::TextWrapped("%s", r.url_pattern.c_str()); - ImGui::TableNextColumn(); - ImGui::TextUnformatted(r.last_run_status.empty() ? "-" : r.last_run_status.c_str()); - ImGui::TableNextColumn(); - ImGui::TextUnformatted(r.last_run_at.empty() ? "-" : r.last_run_at.c_str()); - ImGui::TableNextColumn(); - ImGui::Text("%d", r.rows_last_run); - ImGui::TableNextColumn(); - if (ImGui::SmallButton("Run")) run_recipe_async(r.yaml_path); - ImGui::SameLine(); - if (ImGui::SmallButton("Edit")) { + g_back_recipes.clear(); + for (const auto& r : rows_copy) { + g_back_recipes.push_back(r.name); + g_back_recipes.push_back(r.url_pattern); + g_back_recipes.push_back(r.last_run_status.empty() ? "-" : r.last_run_status); + g_back_recipes.push_back(r.last_run_at.empty() ? "-" : r.last_run_at); + g_back_recipes.push_back(std::to_string(r.rows_last_run)); + g_back_recipes.push_back("Run"); // col 5: accion run + g_back_recipes.push_back("Edit"); // col 6: accion edit + g_back_recipes.push_back("Delete"); // col 7: accion delete + g_back_recipes.push_back("Open"); // col 8: accion open_df + } + g_ptrs_recipes.clear(); + for (const auto& s : g_back_recipes) g_ptrs_recipes.push_back(s.c_str()); + + data_table::TableInput tbl; + tbl.name = "recipes_tbl"; + tbl.headers = {"name", "url_pattern", "last_status", "last_at", "rows", + "run", "edit", "delete", "open"}; + tbl.types = { + data_table::ColumnType::String, data_table::ColumnType::String, + data_table::ColumnType::String, data_table::ColumnType::String, + data_table::ColumnType::Int, + data_table::ColumnType::String, data_table::ColumnType::String, + data_table::ColumnType::String, data_table::ColumnType::String, + }; + tbl.cells = g_ptrs_recipes.data(); + tbl.rows = (int)rows_copy.size(); + tbl.cols = 9; + + tbl.column_specs.resize(tbl.cols); + for (int i = 0; i < tbl.cols; i++) tbl.column_specs[i].id = tbl.headers[i]; + // last_status → CategoricalChip + tbl.column_specs[2].renderer = data_table::CellRenderer::CategoricalChip; + tbl.column_specs[2].chips = { + {"ok", "#22c55e"}, {"success", "#22c55e"}, + {"error", "#ef4444"}, {"failed", "#ef4444"}, + {"-", "#a3a3a3"}, + }; + // Botones de accion + tbl.column_specs[5].renderer = data_table::CellRenderer::Button; + tbl.column_specs[5].button_action = "run_recipe"; + tbl.column_specs[5].button_label = "Run"; + tbl.column_specs[5].button_color_hex = "#3b82f6"; + tbl.column_specs[6].renderer = data_table::CellRenderer::Button; + tbl.column_specs[6].button_action = "edit_recipe"; + tbl.column_specs[6].button_label = "Edit"; + tbl.column_specs[7].renderer = data_table::CellRenderer::Button; + tbl.column_specs[7].button_action = "delete_recipe"; + tbl.column_specs[7].button_label = "Delete"; + tbl.column_specs[7].button_color_hex = "#ef4444"; + tbl.column_specs[8].renderer = data_table::CellRenderer::Button; + tbl.column_specs[8].button_action = "open_df"; + tbl.column_specs[8].button_label = "Open"; + + std::vector rec_events; + ImGui::BeginChild("##recipes_tbl_host", ImVec2(-1, 300)); + data_table::render("##recipes_dt", {tbl}, g_st_recipes, &rec_events); + ImGui::EndChild(); + + for (const auto& ev : rec_events) { + if (ev.kind != data_table::TableEventKind::ButtonClick) continue; + if (ev.row < 0 || ev.row >= (int)rows_copy.size()) continue; + const RecipeRow& r = rows_copy[ev.row]; + if (ev.action_id == "run_recipe") { + run_recipe_async(r.yaml_path); + } else if (ev.action_id == "edit_recipe") { std::string body = slurp(r.yaml_path); std::lock_guard lk(g_rs.mu); - g_rs.editing_idx = (int)i; + g_rs.editing_idx = ev.row; g_rs.edit_buf = body; std::snprintf(g_rs.edit_textarea, sizeof(g_rs.edit_textarea), "%s", body.c_str()); - } - ImGui::SameLine(); - if (ImGui::SmallButton("Delete")) delete_recipe(r.yaml_path); - ImGui::SameLine(); - if (ImGui::SmallButton("Open in data_factory")) { - // placeholder — solo loguea + } else if (ev.action_id == "delete_recipe") { + delete_recipe(r.yaml_path); + } else if (ev.action_id == "open_df") { std::lock_guard lk(g_rs.mu); g_rs.status = "open in data_factory: " + r.name + " (not wired)"; } - ImGui::PopID(); } - ImGui::EndTable(); } if (editing_idx >= 0 && editing_idx < (int)rows_copy.size()) {