| 121 | } |
| 122 | |
| 123 | static void handle_ui_config(cbm_http_conn_t *c, const cbm_http_req_t *req) { |
| 124 | const char *lang = NULL; |
| 125 | char cache_dir[1024]; |
| 126 | snprintf(cache_dir, sizeof(cache_dir), "%s", cbm_resolve_cache_dir()); |
| 127 | cbm_config_t *cfg = cbm_config_open(cache_dir); |
| 128 | if (cfg) { |
| 129 | const char *pinned = cbm_config_get(cfg, CBM_CONFIG_UI_LANG, "auto"); |
| 130 | if (strcmp(pinned, "zh") == 0 || strcmp(pinned, "en") == 0) { |
| 131 | lang = pinned; |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | char lang_buf[8]; |
| 136 | snprintf(lang_buf, sizeof(lang_buf), "%s", lang ? lang : detect_ui_lang(req->accept_language)); |
| 137 | if (cfg) { |
| 138 | cbm_config_close(cfg); |
| 139 | } |
| 140 | /* upstream_issues_url: where the missed-coverage callout (#963) sends |
| 141 | * edge-case reports. Served from the backend on purpose — the UI security |
| 142 | * audit forbids hardcoded external URLs in graph-ui source (external |
| 143 | * targets must come from an auditable backend response, same pattern as |
| 144 | * the /api/repo-info deep-links). */ |
| 145 | cbm_http_replyf(c, 200, g_cors_json, "{\"lang\":\"%s\",\"upstream_issues_url\":\"%s\"}", |
| 146 | lang_buf, "https://github.com/DeusData/codebase-memory-mcp/issues/new"); |
| 147 | } |
| 148 | |
| 149 | /* ── Server state ─────────────────────────────────────────────── */ |
| 150 |
no test coverage detected