fix: build errors — nlohmann include path, fn_log printf style, crypt32 link
- Fix nlohmann include: 'vendor/nlohmann/json.hpp' -> 'nlohmann/json.hpp'
(cpp/vendor is in include path, no double-vendor prefix needed)
- Fix fn_log API: log_info/log_warn/log_error (not info/warn/error)
- Fix format strings: {} -> %s (logger uses printf-style, not fmtlib)
- CMakeLists: add crypt32 link for Windows DPAPI (MinGW needs explicit link,
#pragma comment(lib) only works with MSVC)
- Build: exit 0, exe 22MB, .rsrc section present (icon embedded)
Issue: 0129
Co-Authored-By: fn-orquestador <noreply@fn-registry.local>
This commit is contained in:
@@ -19,4 +19,6 @@ endif()
|
|||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set_target_properties(agents_dashboard PROPERTIES WIN32_EXECUTABLE TRUE)
|
set_target_properties(agents_dashboard PROPERTIES WIN32_EXECUTABLE TRUE)
|
||||||
|
# secret_store.cpp uses CryptProtectData / CryptUnprotectData (crypt32)
|
||||||
|
target_link_libraries(agents_dashboard PRIVATE crypt32)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "core/http_get_json.h"
|
#include "core/http_get_json.h"
|
||||||
#include "core/sse_client.h"
|
#include "core/sse_client.h"
|
||||||
#include "infra/secret_store.h"
|
#include "infra/secret_store.h"
|
||||||
#include "vendor/nlohmann/json.hpp"
|
#include "nlohmann/json.hpp"
|
||||||
|
|
||||||
// SQLite (vendored via fn_framework)
|
// SQLite (vendored via fn_framework)
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
@@ -127,7 +127,7 @@ static bool db_open(AppState& s) {
|
|||||||
if (s.db) return true;
|
if (s.db) return true;
|
||||||
const char* path = fn::local_path("agents_dashboard.db");
|
const char* path = fn::local_path("agents_dashboard.db");
|
||||||
if (sqlite3_open(path, &s.db) != SQLITE_OK) {
|
if (sqlite3_open(path, &s.db) != SQLITE_OK) {
|
||||||
fn_log::error("[db] open failed: {}", sqlite3_errmsg(s.db));
|
fn_log::log_error("[db] open failed: %s", sqlite3_errmsg(s.db));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Apply migrations embedded in source
|
// Apply migrations embedded in source
|
||||||
@@ -153,7 +153,7 @@ static bool db_open(AppState& s) {
|
|||||||
for (const char** m = migrations; *m; ++m) {
|
for (const char** m = migrations; *m; ++m) {
|
||||||
char* errmsg = nullptr;
|
char* errmsg = nullptr;
|
||||||
if (sqlite3_exec(s.db, *m, nullptr, nullptr, &errmsg) != SQLITE_OK) {
|
if (sqlite3_exec(s.db, *m, nullptr, nullptr, &errmsg) != SQLITE_OK) {
|
||||||
fn_log::warn("[db] migration warning: {}", errmsg ? errmsg : "?");
|
fn_log::log_warn("[db] migration warning: %s", errmsg ? errmsg : "?");
|
||||||
sqlite3_free(errmsg);
|
sqlite3_free(errmsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@ static void db_save_connection(AppState& s) {
|
|||||||
if (!s.db) return;
|
if (!s.db) return;
|
||||||
auto blob = fn_secret::encrypt(s.apikey_buf);
|
auto blob = fn_secret::encrypt(s.apikey_buf);
|
||||||
if (blob.empty()) {
|
if (blob.empty()) {
|
||||||
fn_log::warn("[db] encrypt failed, not saving apikey");
|
fn_log::log_warn("[db] encrypt failed, not saving apikey");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Upsert connection id=1
|
// Upsert connection id=1
|
||||||
@@ -181,7 +181,7 @@ static void db_save_connection(AppState& s) {
|
|||||||
sqlite3_bind_blob(stmt, 2, blob.data(), (int)blob.size(), SQLITE_TRANSIENT);
|
sqlite3_bind_blob(stmt, 2, blob.data(), (int)blob.size(), SQLITE_TRANSIENT);
|
||||||
sqlite3_step(stmt);
|
sqlite3_step(stmt);
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
fn_log::info("[db] connection saved");
|
fn_log::log_info("[db] connection saved");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void db_load_connection(AppState& s) {
|
static void db_load_connection(AppState& s) {
|
||||||
@@ -200,7 +200,7 @@ static void db_load_connection(AppState& s) {
|
|||||||
std::string key = fn_secret::decrypt(b);
|
std::string key = fn_secret::decrypt(b);
|
||||||
if (!key.empty()) {
|
if (!key.empty()) {
|
||||||
snprintf(s.apikey_buf, sizeof(s.apikey_buf), "%s", key.c_str());
|
snprintf(s.apikey_buf, sizeof(s.apikey_buf), "%s", key.c_str());
|
||||||
fn_log::info("[db] credentials loaded");
|
fn_log::log_info("[db] credentials loaded");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -288,7 +288,7 @@ static void agent_action(AppState& s, const std::string& agent_id,
|
|||||||
} else {
|
} else {
|
||||||
fb = "[" + action + " " + agent_id + "] HTTP " + std::to_string(res.status);
|
fb = "[" + action + " " + agent_id + "] HTTP " + std::to_string(res.status);
|
||||||
}
|
}
|
||||||
fn_log::info("{}", fb.c_str());
|
fn_log::log_info("%s", fb.c_str());
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(s.action_mu);
|
std::lock_guard<std::mutex> lk(s.action_mu);
|
||||||
s.action_feedback = fb;
|
s.action_feedback = fb;
|
||||||
@@ -358,7 +358,7 @@ static void start_status_sse(AppState& s) {
|
|||||||
static bool g_self_test = false;
|
static bool g_self_test = false;
|
||||||
|
|
||||||
static bool run_self_test() {
|
static bool run_self_test() {
|
||||||
fn_log::info("[self-test] checking subsystems...");
|
fn_log::log_info("[self-test] checking subsystems...");
|
||||||
|
|
||||||
// 1. DB
|
// 1. DB
|
||||||
if (!db_open(g_state)) {
|
if (!db_open(g_state)) {
|
||||||
@@ -460,7 +460,7 @@ static void draw_connection_panel(AppState& s) {
|
|||||||
if (ImGui::Button(TI_PLUG " Test Connection")) {
|
if (ImGui::Button(TI_PLUG " Test Connection")) {
|
||||||
s.connect_error.clear();
|
s.connect_error.clear();
|
||||||
s.connected = false;
|
s.connected = false;
|
||||||
fn_log::info("[connect] testing {}...", s.base_url);
|
fn_log::log_info("[connect] testing %s...", s.base_url);
|
||||||
// Synchronous health check (small timeout)
|
// Synchronous health check (small timeout)
|
||||||
fn_http::Request req;
|
fn_http::Request req;
|
||||||
req.method = "GET";
|
req.method = "GET";
|
||||||
@@ -470,13 +470,13 @@ static void draw_connection_panel(AppState& s) {
|
|||||||
auto res = fn_http::request(req);
|
auto res = fn_http::request(req);
|
||||||
if (!res.error.empty()) {
|
if (!res.error.empty()) {
|
||||||
s.connect_error = "Transport error: " + res.error;
|
s.connect_error = "Transport error: " + res.error;
|
||||||
fn_log::warn("[connect] {}", s.connect_error.c_str());
|
fn_log::log_warn("[connect] %s", s.connect_error.c_str());
|
||||||
} else if (res.status != 200) {
|
} else if (res.status != 200) {
|
||||||
s.connect_error = "HTTP " + std::to_string(res.status) + " from /health";
|
s.connect_error = "HTTP " + std::to_string(res.status) + " from /health";
|
||||||
fn_log::warn("[connect] {}", s.connect_error.c_str());
|
fn_log::log_warn("[connect] %s", s.connect_error.c_str());
|
||||||
} else {
|
} else {
|
||||||
s.connected = true;
|
s.connected = true;
|
||||||
fn_log::info("[connect] OK");
|
fn_log::log_info("[connect] OK");
|
||||||
db_save_connection(s);
|
db_save_connection(s);
|
||||||
// Start SSEs
|
// Start SSEs
|
||||||
start_status_sse(s);
|
start_status_sse(s);
|
||||||
|
|||||||
Reference in New Issue
Block a user