| 4330 | } |
| 4331 | |
| 4332 | static char *handle_get_code_snippet(cbm_mcp_server_t *srv, const char *args) { |
| 4333 | char *qn = cbm_mcp_get_string_arg(args, "qualified_name"); |
| 4334 | char *project = get_project_arg(args); |
| 4335 | bool include_neighbors = cbm_mcp_get_bool_arg(args, "include_neighbors"); |
| 4336 | |
| 4337 | if (!qn) { |
| 4338 | free(project); |
| 4339 | return cbm_mcp_text_result("qualified_name is required", true); |
| 4340 | } |
| 4341 | |
| 4342 | cbm_store_t *store = resolve_store(srv, project); |
| 4343 | if (!store) { |
| 4344 | char *_err = build_project_list_error("project not found or not indexed"); |
| 4345 | char *_res = cbm_mcp_text_result(_err, true); |
| 4346 | free(_err); |
| 4347 | free(qn); |
| 4348 | free(project); |
| 4349 | return _res; |
| 4350 | } |
| 4351 | |
| 4352 | char *not_indexed = verify_project_indexed(store, project); |
| 4353 | if (not_indexed) { |
| 4354 | free(qn); |
| 4355 | free(project); |
| 4356 | return not_indexed; |
| 4357 | } |
| 4358 | |
| 4359 | /* Default to current project (same as all other tools) */ |
| 4360 | const char *effective_project = project ? project : srv->current_project; |
| 4361 | |
| 4362 | /* Tier 1: Exact QN match */ |
| 4363 | cbm_node_t node = {0}; |
| 4364 | int rc = cbm_store_find_node_by_qn(store, effective_project, qn, &node); |
| 4365 | if (rc == CBM_STORE_OK) { |
| 4366 | char *result = build_snippet_response(srv, &node, NULL, include_neighbors, NULL, 0); |
| 4367 | free_node_contents(&node); |
| 4368 | free(qn); |
| 4369 | free(project); |
| 4370 | return result; |
| 4371 | } |
| 4372 | |
| 4373 | /* Tier 2: Suffix match — handles partial QNs ("main.HandleRequest") |
| 4374 | * and short names ("ProcessOrder") via LIKE '%.X'. */ |
| 4375 | cbm_node_t *suffix_nodes = NULL; |
| 4376 | int suffix_count = 0; |
| 4377 | cbm_store_find_nodes_by_qn_suffix(store, effective_project, qn, &suffix_nodes, &suffix_count); |
| 4378 | |
| 4379 | if (suffix_count == SKIP_ONE) { |
| 4380 | copy_node(&suffix_nodes[0], &node); |
| 4381 | cbm_store_free_nodes(suffix_nodes, suffix_count); |
| 4382 | char *result = build_snippet_response(srv, &node, "suffix", include_neighbors, NULL, 0); |
| 4383 | free_node_contents(&node); |
| 4384 | free(qn); |
| 4385 | free(project); |
| 4386 | return result; |
| 4387 | } |
| 4388 | |
| 4389 | if (suffix_count > SKIP_ONE) { |
no test coverage detected