MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / attach_result_source

Function attach_result_source

src/mcp/mcp.c:9044–9110  ·  view source on GitHub ↗

Attach source or context lines to a search result JSON item. */

Source from the content-addressed store, hash-verified

9042
9043/* Attach source or context lines to a search result JSON item. */
9044static void attach_result_source(yyjson_mut_doc *doc, yyjson_mut_val *item, search_result_t *r,
9045 int mode, int context_lines, const char *root_path) {
9046 enum { MODE_FULL = 1 };
9047 if (r->start_line <= 0 || r->end_line <= 0) {
9048 return;
9049 }
9050 char abs_path[CBM_SZ_1K];
9051 snprintf(abs_path, sizeof(abs_path), "%s/%s", root_path, r->file);
9052
9053 /* Containment: a search result whose indexed path resolves outside the
9054 * project root (a `..` segment, or a symlink/junction that discovery
9055 * followed) must not be read back into the response. Same guard the
9056 * snippet path already uses. */
9057 if (!cbm_path_within_root(root_path, abs_path)) {
9058 return;
9059 }
9060
9061 if (mode == MODE_FULL) {
9062 /* Cap each hit's source at a match-anchored window: uncapped
9063 * whole-symbol dumps ran to 5.7KB × N hits (142KB responses). The
9064 * complete symbol stays one get_code_snippet call away;
9065 * source_start/source_truncated make the cut explicit. */
9066 enum { SC_FULL_MAX_LINES = 60, SC_FULL_LEAD = 5 };
9067 int s = r->start_line;
9068 int e = r->end_line;
9069 bool truncated = false;
9070 if (e - s + 1 > SC_FULL_MAX_LINES) {
9071 if (r->match_count > 0 && r->match_lines[0] - SC_FULL_LEAD > s) {
9072 s = r->match_lines[0] - SC_FULL_LEAD;
9073 }
9074 e = s + SC_FULL_MAX_LINES - 1;
9075 if (e > r->end_line) {
9076 e = r->end_line;
9077 }
9078 truncated = true;
9079 }
9080 char *source = read_file_lines(abs_path, s, e);
9081 if (source) {
9082 char *safe_source = sanitize_utf8_lossy(source);
9083 if (safe_source) {
9084 yyjson_mut_obj_add_strcpy(doc, item, "source", safe_source);
9085 free(safe_source);
9086 }
9087 free(source);
9088 if (truncated) {
9089 yyjson_mut_obj_add_int(doc, item, "source_start", s);
9090 yyjson_mut_obj_add_bool(doc, item, "source_truncated", true);
9091 }
9092 }
9093 } else if (context_lines > 0 && r->match_count > 0) {
9094 int ctx_start = r->match_lines[0] - context_lines;
9095 int ctx_end = r->match_lines[r->match_count - SKIP_ONE] + context_lines;
9096 if (ctx_start < SKIP_ONE) {
9097 ctx_start = SKIP_ONE;
9098 }
9099 char *ctx = read_file_lines(abs_path, ctx_start, ctx_end);
9100 if (ctx) {
9101 char *safe_context = sanitize_utf8_lossy(ctx);

Callers 1

assemble_search_outputFunction · 0.85

Calls 3

cbm_path_within_rootFunction · 0.85
read_file_linesFunction · 0.85
sanitize_utf8_lossyFunction · 0.85

Tested by

no test coverage detected